(function(window, undef) {
	window.functionsQueue = function(caller) {
		var liste = []
		,pointeur = -1
		,depile = function() {
			var fct;
			pointeur++;
			if(liste.length === pointeur) {
				pointeur = -1;
				return;
			}

			if(liste[pointeur] instanceof Array) {
				liste[pointeur][1]--;
				fct = liste[pointeur][0];
				if(liste[pointeur][1] == 0) {
					remove(pointeur--);
				}
			}
			else {
				fct = liste[pointeur];
			}
			if(typeof fct === 'function') {
				// cette fonction depile devrait pouvoir être déclarée une fois pour toute pour
				// l'instance, car tant que l'on est en attente d'un retour, toute l'instance de file d'attente est bloqué.
				fct.continuer = (function() {
					var done = false;
					return function() {
						if(!done) {
							done = true;
							depile();
						}
					};
				})();
				if(fct.call(caller) !== false) {
					depile();
				}
			} else {
				remove(pointeur--);
				depile();
			}
		}
		,remove = function(idx) {
			if(liste.length === 1) {
				liste = [];
			}
			else if(idx === liste.length -1) {
				liste.length = liste.length -1;
			}
			else {
				var i, copie = [];
				for(i = 0; i < liste.length; i++) {
					if(i !== idx) {
						copie[copie.length] = liste[i];
					}
				}
				liste = copie;
			}
		};
		return function(fct, iterations) {
			if(arguments.length === 0) {
				if(pointeur !== -1) {
					return;
				}
				depile();
			}
			else if(fct !== undef) {
				if(fct instanceof Array) {
					if(fct.length <= 2 && typeof fct[0] === 'function' && (fct[1] === undef || typeof fct[1] === 'number')) {
						arguments.callee(fct[0], fct[1] || iterations);
					}
					else {
						for(var i = 0; i < fct.length; i++) {
							arguments.callee(fct[i], iterations);
						}
					}
				}
				else {
					if(typeof fct !== 'function') {
						throw new Error('Impossible de mettre en attente autre chose qu\'une fonction');
					}
					if(typeof iterations === 'number') {
						fct = [fct, iterations];
					}
					liste[liste.length] = fct;
				}
			}
		};
	};

	window.callbacksManager = function(caller) {
		var i, key, listes = []
		,cbm = function(liste) {
			if(arguments.length === 1) {
				if(typeof liste === 'object') {
					for(var key in liste) {
						cbm(key, liste[key]);
					}
				}
				else if(listes[liste] !== undef) {
					return listes[liste]();
				}
			}
			else if(arguments.length > 1) {
				if(listes[liste] === undef) {
					listes[liste] = window.functionsQueue(caller);
				}
				listes[liste].apply(caller, Array.prototype.slice.call(arguments, 1));
			}
		}

		,methodHandler = function(methodName) {
			return function() {
				if(typeof this[methodName] === 'function')
					return this[methodName].apply(this, arguments);
			};
		};

		cbm.handleMethods = function(methodName, listeName) {
			if(typeof methodName === 'string') {
				cbm(listeName, methodHandler(methodName));
			}
			else if(typeof methodName === 'object') {
				for(var i in methodName) {
					arguments.callee(i, methodName[i]);
				}
			}
		};

		for(i = 1; i < arguments.length; i++) {
			if(typeof arguments[i] === 'object') {
				for(key in arguments[i]) {
					cbm(key, arguments[i][key]);
				}
			}
		}
		return cbm;
	};
})(this);
(function(window, undef) {
	window.dynamicOptionsManager = window.dynamicOptionsManager || function() {
/**
 * Gestion d'une liste d'options dynamiques
 *
 * DynamicOptionsManager permet de générer une liste de variables/champs.
 * DynamicOptionsManager permet de modifier ou de récupérer les valeurs des différents champs de
 * la liste définie.
 * Chaque champ peut avoir une valeur par défaut, qui sera reprise en cas de réinitialisation du
 * champ (attribution de la valeur undefined).
 * Lorsque l'on récupère la valeur d'un champ, si celui-ci contient une fonction, c'est 
 * le résultat de l'execution de cette fonction qui sera retourné.
 * Lors de la définition d'un nouvel objet DynamicOptionsManager, il est possible de spécifier un
 * objet appelant, qui sera utiliser pour exécuter les fonctions en tant que méthode de cet objet.
 *
 *
 * Utilisation :
 *
 * var monObj = {val:'test'};
 * var options = window.dynamicOptionsManager(monObj, {champ1:'val1', champ2: function() {return 'val2'+this.val;}});
 *
 * options('champ3', 'val3');
 * options('champ1', 'val1b');
 *
 * alert(options('champ3')); // Affiche 'val3'
 * alert(options('champ1')); // Affiche 'val1b'
 *
 * options('champ1', undef);
 * options('champ3', undef);
 * alert(options('champ1')); // Affiche 'val1'
 * alert(options('champ3')); // Affiche 'undef'
 *
 * alert(options('champ2')); // Affiche 'val2test'
 * monObj.val = 'testb';
 * alert(options('champ2')); // Affiche 'val2testb'
 *
 */
		var i, args,

		// constantes servant à optimiser le code minimisé
		PROTO = 'prototype',
		CONSTR = 'constructor',
		CALLEE = 'callee',

		$self = arguments[CALLEE],
		caller = this,
		defaultOptions = {},
		construct = function() {
			var construct = function() {
				for(var i in this) {
					if(typeof this[i] === 'function' && !this[i].jquery) {
						this[i] = this[i].call(caller);
					}
				}
			};
			return construct;
		},
		opts = construct(),
		obj = function(property, value) {
			if(arguments.length === 0) {
				return new opts();
			}
			var args = arguments,
			values = [].slice.call(args, 1),
			ret, i;
			if (args.length === 1) {
				if(typeof property === 'string') {
					return args[CALLEE]([property])[property];
				}
				else if(typeof property === 'object') {
					if(property instanceof Array) {
						ret = construct();
						for(i = 0; i < property.length; i++) {
							if(opts[PROTO][property[i]] !== undef)
								ret[PROTO][property[i]] = opts[PROTO][property[i]];
						}
						return new ret();
					}
					else {
						for(i in property) {
							args[CALLEE](i, property[i]);
						}
					}
				}
				else if((property || {})[CONSTR] === $self) {
					args[CALLEE](property.raw());
				}
			}
			else if(typeof property === 'string') {
				if(value === undef) {
					if(defaultOptions[property] === undef) {
						delete(opts[PROTO][property]);
					}
					else {
						opts[PROTO][property] = defaultOptions[property];
					}
				}
				else if(value === null) {
					delete(opts[PROTO][property]);
				}
				else if((opts[PROTO][property] || {})[CONSTR] === $self) {
					return opts[PROTO][property].apply(caller, values);
				}
			// Bug potentiel ici : Si on fourni plusieurs valeurs, seule la première est controlée. Donc si on fourni un objet, et ensuite des objets jQuery ou des tableaux, ceux-ci seront concidérés comme des objets et donc ça merde.
				else if(typeof value === 'object' && !(value instanceof Array) && !(value instanceof (window.jQuery || function() {}))) {
					opts[PROTO][property] = $self.apply(caller, values);
				}
				else {
					if(values.length > 1) {
						opts[PROTO][property] = $self.apply(caller)
						opts[PROTO][property].apply(caller, values);
					}
					else {
						opts[PROTO][property] = value;
					}
				}
			}
		};

		obj.defined = function(property) {
			var args = arguments;
			if(property instanceof Array) {
				for(var i = 0; i < property.length; i++) {
					if(!args[CALLEE](property[i])) {
						return false;
					}
				}
				return true;
			}
			if(args.length > 1) {
				if((opts[PROTO][property] || {})[CONSTR] === $self) {
					return opts[PROTO][property].defined.apply(caller, [].slice.call(args, 1));
				}
				return;
			}
			return opts[PROTO][property] !== undef;
		};

		obj.raw = function(property) {
			if(arguments.length === 0) {
				var i
				,ret
				,retClass = function() {};

				retClass[PROTO] = opts[PROTO];
				ret = new retClass();
				for(i in ret) {
					if(ret[i][CONSTR] === $self)
						ret[i] = ret[i].raw();
				}
				return ret;
			}
			if((opts[PROTO][property] || {})[CONSTR] === $self) {
				return opts[PROTO][property].raw.apply(caller, [].slice.call(arguments, 1));
			}
			return opts[PROTO][property];
		};

		obj.reset = function() {
			opts[PROTO] = {};
			for(var i in defaultOptions) {
				obj(i, defaultOptions[i]);
			}
		};

		obj[CONSTR] = $self;

		if(arguments.length) {
			args = $self();
			for(i = 0; i < arguments.length; i++) {
				args(arguments[i]);
			}
			defaultOptions = args.raw();
		}

		obj.reset();

		return obj;
	};
})(this);
(function(window, $, undef) {
	if($ === undef) {
		throw 'Dépendence non satisfaite : jQuery';
	}

	var nodeCss = {
		 position: 'relative'
		,overflow: 'hidden'
		,background: 'black'
		,'text-align': 'center'
		,'font-size': '12px'
		,'font-family': 'Arial, sans-serif'
		,color: 'white'
	}
	,pCss = {
		 margin: '20px 20px 10px'
		,padding: '70px 0 0'
		,background: 'transparent url(/layoutftv/arches/common/images/video/warning.png) no-repeat center 0'
	}
	,btnCss = {
		 margin: '0 auto'
		,width: '219px'
		,height: '28px'
		,background: 'transparent url(/layoutftv/arches/common/images/video/bouton-continue.png) no-repeat center 0'
		,color: 'black'
		,'line-height': '26px'
		,cursor: 'pointer'
	}
	,closeBtnCss = {
		 position: 'absolute'
		,top: 0
		,right: 0
		,cursor: 'pointer'
	};

	window.dialog = function(msg, action) {
		if(!(this instanceof arguments.callee)) {
			return new arguments.callee(msg, action);
		}
		var $this = this
		,answers = []
		,defaultAction
		,size = {}
		,node;

		this.setDefaultAction = function(action) {
			defaultAction = action || function() {};
		};

		this.setAnswer = function(txt, action) {
			answers.push({
				 txt	: txt
				,action	: action
			});
		};

		this.setDefaultAnswer = function(txt) {
			$this.setAnswer(txt, function() {
				defaultAction.call($this);
			});
		};

		this.setSize = function(newSize) {
			if(newSize === undef)
				return;
			size.height = ((newSize.height || 0) < 300) ? 300 : newSize.height;
			size.width = ((newSize.width || 0) < 380) ? 380 : newSize.width;
			if(node !== undef) {
				node.height(size.height);
				node.width(size.width);
			}
		};

		this.createNode = function() {
			node = $('<div class="pluginErrorMsg">')
				.css(nodeCss)
				.width(size.width)
				.height(size.height)
				.append(
					$('<p class="alerte" />')
						.css(pCss)
						.append(msg)
				)
				.append(
					$('<div class="closeBtn"><img src="/layoutftv/arches/common/stylesheets/img/buttons/closedialog.png" alt="Fermer" /></div>')
						.css(closeBtnCss)
						.click(function() {
							$this.remove();
							if(answers.length !== 0) {
								defaultAction.call($this);
							}
						})
				);

			if(answers.length === 0) {
				defaultAction.call($this);
			}
			else {
				for(var i = 0; i < answers.length; i++) {
					(function(element) {
						$('<p class="bouton">'+element.txt+'</p>')
							.css(btnCss)
							.click(function() {
								$this.remove();
								element.action.call($this);
							})
							.appendTo(node);
					})(answers[i])
				}
			}
		};

		this.getNode = function() {
			if(node === undef) {
				$this.createNode();
			}
			return node;
		};

		this.remove = function() {
			if(node !== undef) {
				node.remove();
			}
		};

		this.setDefaultAction(action);
	};
})(this, this.jQuery);
(function(window, undef) {
	window.relationObject = function() {
		var data = {}
		,getter = function(arg1) {
			if(arguments.length > 0) {
				if(arg1 instanceof Array) {
					var i, j, k, doublon, results = [];
					for(i = 0; i < arg1.length; i++) {
						if(data[arg1[i]] === undef) {
							continue;
						}
						for(j = 0; j < data[arg1[i]].length; j++) {
							doublon = false;
							for(k = 0; k < results.length; k++) {
								if(results[k] === data[arg1[i]][j]) {
									doublon = true;
									break;
								}
							}
							if(!doublon) {
								results.push(data[arg1[i]][j]);
							}
						}
					}
					return (results.length > 0) ? results : undef;
				}
				return data[arg1];
			}
			return data;
		};

		getter.set = function(arg1, arg2) {
			var i, newData;
			if(arguments.length === 1) {
				for(i in arg1) {
					getter.set(i, arg1[i]);
				}
			}
			else if(arg1 instanceof Array) {
				for(i = 0; i < arg1.length; i++) {
					getter.set(arg1[i], arg2);
				}
			}
			else if(arg2 instanceof Array) {
				for(i = arg2.length - 1; i >= 0; i--) {
					getter.set(arg1, arg2[i]);
				}
			}
			else if(arg1 !== undef && arg2 !== undef) {
				newData = [arg2];
				if(data[arg1] instanceof Array) {
					for(i = 0; i < data[arg1].length; i++) {
						if(data[arg1][i] !== arg2) {
							newData.push(data[arg1][i]);
						}
					}
				}
				data[arg1] = newData;
			}
		};

		getter.remove = function(arg1) {
			var i, j, k, newData;
			for(i in data) {
				for(j = 0; j < data[i].length; j++) {
					if(data[i][j] === arg1) {
						newData = data[i].slice(0, j-1);
						for(k = j+1; k < data[i].length; k++) {
							newData.push(data[i][k]);
						}
						data[i] = newData;
						j--;
					}
				}
			}
		};

		return getter;
	};
})(this);
(function(window, undef) {
	(function(dep) {
		for(var i in dep) {
			if(!dep[i]) {
				throw 'Dépendence non satisfaite : '+i;
			}
		}
	})({
		dynamicOptionsManager	: !!window.dynamicOptionsManager,
		callbacksManager		: !!window.callbacksManager,
		RelationObject			: !!window.relationObject,
		Dialog					: !!window.dialog,
		'MediaObject already exists' : !window.MediaObject
	});

	var baseObjectOptions = {
		attrs	: {
					 style	:{}
				},
		params	: {}
	},

	BuilderCollection = function(buildersList, options) {
		if(!(this instanceof BuilderCollection)) {
			return new BuilderCollection(buildersList, options);
		}

		var $this = this,
		current = -1,
		length = 0,
		callbacks,

		init = function() {
			// On convertit les options en objet dynamicOptionsManager
			$this.options = options = window.dynamicOptionsManager.call($this, options);
			$this.callbacks = callbacks = window.callbacksManager($this);

			$this.add(buildersList);
		},

		// Cette méthode va chercher le prochain constructeur à exécuter, le paramétrer, et lancer
		// son exécution. Elle se charge également de mettre en place la récurcivité des appels de
		// constructeurs (Lorsque l'exécution d'un constructeur se termine, rappeler cette même méthode)
		deQueue = function() {
			var results, builder;
			if(++current >= length) {
				if(length == 0) {
					results = 'Aucun constructeur trouvé pour ce média';
				}
				else {
					results = {};
					for(var i = 0; i < length; i++) {
						results[$this[i].name] = $this[i].result;
					}
				}
				finish(false, results, options);
				return;
			}

			builder = new ObjectBuilder($this[current], options);

			// Interception de l'événement finish du constructeur. Soit on a obtenu un résultat
			// positif, et donc on arrete tout là, sinon on renvois sur la methode deQueue pour
			// que le constructeur suivant soit appelé.
			builder.callbacks('finish', function() {

				// On remplace le fonction builder de la liste de builder à executer par l'objet
				// builder, résultat de l'exécution de la fonction builder. Au final, on aura
				// donc, à la place de la liste de fonctions de construction, une liste de
				// résultats d'exécution. On pourra donc analyser l'exécution complète en
				// parcourant l'objet BuilderCollection.
				$this[current] = this;

				if(!this.success) {
					deQueue();
				}
				else {
					finish(true, this.result, this.resultOptions);
				}
			});

			builder.callbacks('unsync', function() {
				callbacks('unsync');
			});

			builder.callbacks('interact', function() {
				$this.interactData = this.interactData;
				callbacks('interact');
			});

			builder.execute();
		},

		/*
		Le fait de recevoir les trois valeurs séparément permet de décoréler le résultat de
		l'objet result du constructeur. Ca permet d'éviter des problèmes de potentiel changements de
		cet objet result après l'appel de fonction finish.
		*/
		finish = function(success, value, options) {
			$this.success = success;
			$this.result = value;
			$this.resultOptions = options;
			$this.resultBuilder = success ? $this[current] : undef;

			if(success) {
				callbacks('finish', function() {
					callbacks('success', arguments.callee.continuer);
					callbacks('success');
					return false;
				});
			}
			callbacks('finish');
		};

		this.add = function(buildersList) {
			if(buildersList instanceof Array) {
				for(var i = 0; i < buildersList.length; i++) {
					$this.add(buildersList[i]);
				}
			}
			else if(typeof buildersList === 'string' && BuilderCollection.builders[buildersList] !== undef) {
				$this[length++] = BuilderCollection.builders[buildersList];
			}
		};

		this.execute = function() {
			delete($this.execute);
			deQueue();
		};

		this.current = function() {
			return current;
		};

		this.length = function() {
			return length;
		};

		init();
	},

	ObjectBuilder = function(builder, options) {
		if(builder instanceof Array) {
			return new BuilderCollection(builder, options);
		}

		/*
		Inutile car de toute façon cette classe est privée, donc accessible que par ce script. Donc
		à moi de bien instancier les objets

		if(!(this instanceof arguments.callee)) {
			return new arguments.callee(builder, options);
		}

		De même, on devrait controler ici que builder est bien valide mais comme on est en contexte
		privé, on peu se permettre d'économiser ces contrôles
		*/

		var $this = this,

		// flag définissant si on est en mode d'exécution asynchrone ou pas
		async = false,

		// Objet vide mais unique pour cette instance de ObjectBuilder, qui permettra d'identifier les
		// exceptions lancées par l'objet ObjectBuilder.
		returnException = {},

		callbacks,

		// Object contenant des méthodes qui seront rendue publique uniquement après l'appel de la 
		// méthode execute
		afterExec = {},

		init = function() {
			$this.name = builder.builderName;
			$this.callbacks = callbacks = window.callbacksManager($this);
			$this.options = options = window.dynamicOptionsManager.call($this, baseObjectOptions, builder.options, options);

			options.transfert = function(to, toMove, convertions) {
				var key, value;
				convertions = convertions || {};
				toMove = options(toMove);
				options(to, {});
				for(key in toMove) {
					value = toMove[key];
					if(convertions[key] !== undef)
						key = convertions[key];
					if(!options.defined(to, key)) {
						options(to, key, value);
					}
				}
			};
		},

		unsync = function() {
			if(async)
				return;
			async = true;
			callbacks('unsync');
		},

		finish = function(success, value, options) {
			delete($this.setResult);
			delete($this.abort);
			delete($this.createDialog);
			delete($this.build);
			delete($this.buildAndReturn);
			delete($this.wait);

			$this.success = success;
			$this.result = value;
			$this.resultOptions = options || $this.options;

			callbacks('finish');

			// Empêche l'exécution de codes après l'appel à setResult ou abort.
			// Cette fonction n'est pas indispensable, et peu avoir un effet pervert de dissimulation
			// de builder mal codé. En contre partie ça peu éviter des problèmes.
			forceReturn();
		},

		// Empêche l'exécution de codes après l'appel à setResult ou abort.
		// Cette fonction n'est pas indispensable, et peu avoir un effet pervert de dissimulation
		// de builder mal codé. En contre partie ça peu éviter des problèmes.
		forceReturn = function() {
			if(!async) {
				throw returnException;
			}
		};

		this.execute = function() {
			delete($this.execute);
			delete($this.callbacks);

			var key, retour;

			for(key in afterExec) {
				$this[key] = afterExec[key];
			}

			try {
				retour = builder.call($this);

				// Si une valeur à été retournée par le constructeur, qu'aucun résultat n'est défini, et qu'on n'est pas en mode asynchrone
				if(retour !== undef && $this.result === undef && !async) {
					$this.setResult(retour);
				}
			}
			catch(e) {
				if(e !== returnException) {
					throw e;
				}
			}
		};

		afterExec.setResult = function(value, options, arg3) {
			if(typeof value === 'boolean') {
				finish(value, options, arg3);
			}
			else {
				finish(true, value, options);
			}
		};

		afterExec.abort = function(msg, options) {
			finish(false, msg, options);
		};

		afterExec.createDialog		= function(msg) {
			var dialog = new window.dialog(msg);
			dialog.setSize($this.options(['height', 'width']));
			return dialog;
		};

		afterExec.build = function(builderName, options) {
			options = window.dynamicOptionsManager($this.options, options);
			var child = (!builderName) ?
				window.MediaObject(options('url'), options) :
				new BuilderCollection(builderName, options);

			child.callbacks('unsync', unsync);
			child.callbacks('interact', function() {
				$this.interactData = this.interactData;
				callbacks('interact');
			});
			$this[$this.length++] = child;

			return child;
		};

		afterExec.buildAndReturn = function(builderName, options) {
			var builder = $this.build(builderName, options);
			builder.callbacks('finish', function() {
				finish(this.success, this.result, this.resultOptions);
			});
			builder.execute();

			// Empêche l'exécution de code après l'appel à buildAndReturn. Cela peu éviter, dans le
			// cas d'un builder mal codé, l'exécution de code entre l'appel de buildAndReturn et
			// l'exécution de la fonction de callback finish définie juste au dessus.
			forceReturn();
		};

// La methode wait est à améliorer, surrement en définissant des types d'attentes
		afterExec.wait = function(data, action) {
			var quiet = $this.options('quiet')
			,defaultAction = function() {
				if(typeof action === 'function') {
					action.call($this);
				}
			};
			if(data.readyState !== undef) {
				unsync();
			}
			else if(typeof data === 'number') {
				unsync();
				window.setTimeout(defaultAction, data * 1000);
			}
			else if(!quiet) {
				unsync();
				if(data instanceof window.dialog)
					data.setDefaultAction(defaultAction);
				$this.interactData = data;
				callbacks('interact');
			}
			else {
				defaultAction();
			}
		};

		afterExec.length = 0;

		init();
	},

	setBuilderDefaultAction = function(builders) {
		return function() {
			this.buildAndReturn(builders);
		};
	},

	mediaObjectOptionsCleaner = {extension:null, type: null, builder: null},
	builderOptionsCleaner = {extensions: null, types:null},
	getExtensionPattern = /\.([a-z0-9]+)(\?|$)/i,

	MediaObject = window.MediaObject = function(url, options) {
		var types = [],

		addExtension = function(extension) {
			addType(MediaObject.extensionsTypes(extension));
		},

		addType = function(type) {
			var i, newTypes;
			if(type instanceof Array) {
				for(i = type.length - 1; i >= 0; i--) {
					addType(type[i]);
				}
			}
			else if(typeof type === 'string') {
				newTypes = [type];
				for(i = 0; i < types.length; i++) {
					newTypes.push(types[i]);
				}
				types = newTypes;
			}
		},

		addBuilder = function(BuilderName) {
			if(BuilderCollection.builders[BuilderName] === undef)
				return;
			MediaObject.typesBuilders.set('constructeur/specifique', BuilderName);
			addType('constructeur/specifique');
		};

		options = window.dynamicOptionsManager(options, {url:url});

		addExtension((getExtensionPattern.exec(url) || [])[1]);
		addExtension(options('extension'));
		addType(options('type'));
		addBuilder(options('builder'));
		options(mediaObjectOptionsCleaner);

		return new BuilderCollection(MediaObject.typesBuilders(types), options);
	};

	BuilderCollection.builders = {};

	/**
	 * Set a new Builder
	 *
	 */
	MediaObject.setBuilder = function(name, action, options) {
		if(typeof action !== 'function') {
			action = setBuilderDefaultAction(action);
		}
		action.builderName = name;
		action.options = window.dynamicOptionsManager();
		BuilderCollection.builders[name] = action;
		MediaObject.typesBuilders.remove(name);
		MediaObject.setBuilderOptions(name, options);
	};

	/**
	 * Edit a builder Options
	 *
	 */
	MediaObject.setBuilderOptions = function(name, options) {
		var builder = BuilderCollection.builders[name];
		if(builder !== undef) {
			builder.options(options);

			MediaObject.setExtensionBuilder(builder.options('extensions'), name);
			MediaObject.typesBuilders.set(builder.options('types'), name);
			builder.options(builderOptionsCleaner);
		}
	};

	MediaObject.extensionsTypes = window.relationObject();
	MediaObject.typesBuilders = window.relationObject();

	MediaObject.setExtensionBuilder = function(extension, builder) {
		var i, types;
		if(extension instanceof Array) {
			for(i = 0; i < extension.length; i++) {
				arguments.callee(extension[i], builder);
			}
		}
		else if (typeof extension === 'string' && typeof builder === 'string') {
			types = MediaObject.extensionsTypes(extension);
			if(types === undef) {
				types = 'extension/'+extension;
				MediaObject.extensionsTypes.set(extension, types);
			}
			MediaObject.typesBuilders.set(types, builder);
		}
	};

	// Fonction utilisé dans les constructeurs afin de tester l'existence de plugins.
	MediaObject.getPluginByType = (function() {
		try {
			if(window.navigator.plugins === undef
			  || window.navigator.mimeTypes === undef
			  || window.navigator.plugins.length === undef
			  || window.navigator.plugins.refresh === undef) {
				throw 'no plugins infos';
			}
		}
		catch(e) {
			return function() {};
		}
		return function(type) {
			window.navigator.plugins.refresh();
			if(window.navigator.mimeTypes[type] !== undef
			  && window.navigator.mimeTypes[type].enabledPlugin) {
				return window.navigator.mimeTypes[type].enabledPlugin;
			}
		};
	})();

	// Valeur disponible pour les constructeurs, de manière à uniformiser le temps de rafraichissement des plugins
	MediaObject.pluginRefreshTime = 2000;

})(this);
(function(window) {
	if(!(window.MediaObject &&
	     window.MediaObject.extensionsTypes &&
	     window.MediaObject.extensionsTypes.set)) {
		throw 'Dépendence non satisfaite : MediaObject';
	}

	window.MediaObject.extensionsTypes.set({
		 html			: ['text/html', 'application/xhtml+xml']
		,xhtml			: ['text/html', 'application/xhtml+xml']
		,pdf			: 'application/pdf'

		,asx			: ['application/asx', 'video/x-ms-asf']
		,asf			: ['video/x-ms-asf', 'application/asf']
		,wma			: 'audio/x-ms-wma'
		,wmv			: ['audio/x-ms-wmv', 'video/x-ms-wmv']
		,wsx			: 'video/wsx'

		,swf			: 'application/x-shockwave-flash'
		,flv			: 'video/x-flv'
		,mp3			: ['audio/mpeg', 'audio/x-mpeg']

		,rm				: 'application/vnd.rn-realmedia'
		,rv				: ['video/x-pn-realvideo', 'video/vnd.rn-realvideo']
		,ra				: ['audio/x-pn-realaudio', 'audio/x-pn-realaudio']
		,ram			: ['video/x-pn-realvideo']
		,rpm			: 'audio/x-pn-realaudio-plugin'

		,mpg			: 'video/mpeg'
		,mpeg			: 'video/mpeg'
		,mp4			: 'video/mpeg'
		,avi			: 'video/x-msvideo'
		,mov			: 'video/quicktime'
		,qt				: 'video/quicktime'
		,au				: 'audio/basic'
		,aif			: 'audio/x-aiff'
		,aac			: 'audio/aac'

		,xap			: ['application/x-silverlight', 'application/x-silverlight-2']
		,xaml			: ['application/x-silverlight', 'application/x-silverlight-2']
	});
})(this);
(function(window) {
	if(!(window.MediaObject && window.MediaObject.setBuilder)) {
		throw 'Dépendence non satisfaite : MediaObject';
	}

	var objectToString = function(object, process) {
		var resultArray = []
		,valueArray;
		process = process || arguments.callee.pattern;
		process.elements = process.elements || [];
		for(var key in object) {
			valueArray = [
				 process.elements[1]
				,key
				,process.elements[2]
			];
			if((process.children || {})[key] && typeof object[key] === 'object') {
				valueArray.push(arguments.callee(object[key], process.children[key]));
			}
			else {
				valueArray.push(''+object[key]);
			}
			if(valueArray[3] === '') {
				continue;
			}
			valueArray.push(process.elements[3]);
			resultArray.push(valueArray.join(''));
		}
		return resultArray.join(process.elements[0]);
	};
	objectToString.pattern = {
		 elements : [' ', '', '="', '"']
		,children: {
			 style		: {
				elements : [';', '', ':', '']
			}
			,flashvars	: {
				elements : ['&amp;', '', '=', '']
			}
		}
	};
	objectToString.patternParams = {
		 elements : ['', '<param name="', '" value="', '" />']
		,children: objectToString.pattern.children
	};
	objectToString.setPatterns = function(patterns) {
		for(key in patterns) {
			objectToString.pattern.children[key] = patterns[key];
		}
	};

	window.MediaObject.setBuilder(
		 'generateObject'
		,function() {
			this.options.transfert(
				 'attrs'
				,[
					 'width'
					,'height'
				]
			);

			if(!this.options.defined('attrs', 'id')) {
				this.options('attrs', 'id', 'MediaObject'+(+new Date));
			}

			objectToString.setPatterns(this.options('objectToStringPatterns'));

			return '<object '+
				objectToString(this.options('attrs'))+
				'>'+
				objectToString(this.options('params'), objectToString.patternParams)+
				'<\/object>'+
				'<script type="text/javascript">'+
					'window.setTimeout(function() {'+
						'jQuery && '+
						'jQuery(\'#'+this.options('attrs', 'id')+'\')'+
							'.trigger(\'MediaObjectDOMInsert\');'+
					'}, 200);'+
				'</script>';
		}
	);

	window.MediaObject.setBuilder(
		 'generateEmbed'
		,function() {
			this.options.transfert(
				 'attrs'
				,[
					 'width'
					,'height'
				]
			);

			this.options('attrs', this.options('params') || {});

			objectToString.setPatterns(this.options('objectToStringPatterns'));

			return '<embed '+
				objectToString(this.options('attrs'))+
				'><\/embed>';
		}
	);

	window.MediaObject.setBuilder(
		 'iframe'
		,function() {
			this.options.transfert(
				 'attrs'
				,[
					 'url'
					,'width'
					,'height'
					,'border'
				]
				,{
					 url	: 'src'
					,border	: 'frameBorder'
				}
			);

			if(this.options.defined('bgColor')) {
				this.options('attrs', 'style', 'background-color', this.options('bgColor'));
			}

			objectToString.setPatterns(this.options('objectToStringPatterns'));

			return '<iframe '+
				objectToString(this.options('attrs'))+
				' />';
		}
		,{
			 width		: 400
			,height		: 400
			,attrs		: {
							 allowTransparency	: 'allowTransparency'
							,frameBorder		: 0
						}
			,types		: ['text/html', 'application/xhtml+xml', 'application/pdf']
		}
	);
})(this);
(function(window) {
	if(!(window.MediaObject && window.MediaObject.setBuilder)) {
		throw 'Dépendence non satisfaite : MediaObject';
	}

	window.MediaObject.setBuilder(
		 'quicktimePlayer'
		,function() {
			var url = this.options('url');
			this.options('attrs' ,{
				 data		: url
			});

			if(window.ActiveXObject) {
				this.options('attrs', {
					 classid	: 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B'
					,codeBase	: 'http://www.apple.com/qtactivex/qtplugin.cab'
				});
			}

			this.options('params', {
				 src		: url
				,wmode		: null
			});

			if(this.options.defined('autostart')) {
				this.options('params', 'autoplay', this.options('autostart'));
			}

			this.buildAndReturn('generateObject');
		}
		,{
			 width		: 388
			,height		: 288
			,autostart	: false
			,extensions	: ['mp4', 'mov']
		}
	);

	window.MediaObject.setBuilder(
		 'quicktimePlayerAudio'
		,'quicktimePlayer'
		,{
			 height		: 18
			,extensions	: ['au', 'aac', 'aif']
		}
	);

})(this);
(function(window, undef) {
	if(!(window.MediaObject && window.MediaObject.setBuilder)) {
		throw 'Dépendence non satisfaite : MediaObject';
	}

	window.MediaObject.setBuilder(
		 'realPlayerObject'
		,(function() {
			var pluginPresent = function() {
				var plugin;

				if(window.ActiveXObject !== undef) {
					return true;
				}
				if((plugin = window.MediaObject.getPluginByType('audio/x-pn-realaudio-plugin'))) {
					return true;
				}
				return false;
			};
			return function() {
				if(!pluginPresent()) {
					this.abort('Plugin RealPlayer non disponible');
				}
				if(window.ActiveXObject !== undef) {
					this.options('attrs', {
						 classid	: 'clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA'
					});
				}
				else {
					this.options('attrs' ,{
						 type		: 'audio/x-pn-realaudio-plugin'
					});
				}

				this.options('params', {
					 src		: this.options('url')
				});
				this.options('params', {
					 wmode		: null
				});

				this.options('params', 'console', 'video');
				this.options('params', 'autostart', this.options('autostart'));

				this.buildAndReturn((window.ActiveXObject !== undef) ? 'generateObject' : 'generateEmbed');
			};
		})()
		,{
			 width		: 388
			,height		: 288
			,autostart	: true
		}
	);

	window.MediaObject.setBuilder(
		 'realPlayerControls'
		,'realPlayerObject'
		,{
			 height		: 25
			,params		: {
							 controls	: 'controlpanel'
						}
		}
	);

	window.MediaObject.setBuilder(
		 'realPlayerImageWindow'
		,'realPlayerObject'
		,{
			 params		: {
							 controls	: 'ImageWindow'
						}
		}
	);

	window.MediaObject.setBuilder(
		 'realPlayerVideo'
		,function() {
			var $this = this
			,options
			,firstBuilder;

			if(this.options.defined('height')) {
				options = {height: this.options('height')-25};
			}

			firstBuilder = this.build('realPlayerImageWindow', options);

			firstBuilder.callbacks('finish', function() {
				if(!this.success) {
					$this.abort(this.result, this.resultOptions);
					return;
				}

				if($this.options.defined('height')) {
					options = {height: 25};
				}

				var secondBuilder = $this.build('realPlayerControls', options);

				secondBuilder.callbacks('finish', function() {
					if(!this.success) {
						$this.abort(this.result, this.resultOptions);
						return;
					}

					$this.setResult(
						 '<div><div>'+
						firstBuilder.result+
						'</div><div>'+
						this.result+
						'</div></div>'
						,$this.options
					);
				});
				secondBuilder.execute();
			});
			firstBuilder.execute();
		}
		,{
			 extensions	: ['ram', 'rm', 'rpm', 'rv']
		}
	);

	window.MediaObject.setBuilder(
		 'realPlayerAudio'
		,'realPlayerControls'
		,{
			 extensions	: 'ra'
		}
	);

})(this);
(function(window, $, undef) {
	(function(dep) {
		for(var i in dep) {
			if(!dep[i]) {
				throw 'Dépendence non satisfaite : '+i;
			}
		}
	})({
		dynamicOptionsManager	: !!window.dynamicOptionsManager,
		callbacksManager		: !!window.callbacksManager,
		jQuery					: !!$,
		MediaObject				: !!window.MediaObject,
		'jQuery.mediaObject already exists' : !!($ && $.fn && !$.fn.mediaObject)
	});

	var parseClassPattern = /(height|width)((=|:)([^ ]+))?/i,
	parseClass = function(cls) {
		if(typeof cls != 'string') {
			return {};
		}
		var key, matches
		,options = {}
		,params = cls.split(' ');
		for(key = 0; key < params.length; key++) {
			matches = params[key].match(parseClassPattern);
			if(!matches)
				continue;
			options[matches[1]] = matches[4];
		}
		return options;
	},

	displayReport = function(resultObject, element) {
		// Récolte d'infos et affichage de formulaire de rapport
		var collect = {};
		collect['language'] = window.navigator.language || window.navigator.userLanguage || window.navigator.systemLanguage;
		collect['userAgent'] = window.navigator.userAgent;
		collect['appCodeName'] = window.navigator.appCodeName;
		collect['appName'] = window.navigator.appName;
		collect['appVersion'] = window.navigator.appVersion;
		collect['platform'] = window.navigator.platform;
		collect['cpuClass'] = window.navigator.cpuClass;

		collect['cookieEnabled'] = window.navigator.cookieEnabled;
		if(typeof window.navigator.javaEnabled === 'function') {
			collect['javaEnabled'] = window.navigator.javaEnabled();
		}

		collect.plugins = {};
		try {
			window.navigator.plugins.refresh();
			for(var i = 0; i < window.navigator.plugins.length; i++) {
				collect.plugins[window.navigator.plugins[i].name] = window.navigator.plugins[i].description.substr(0, 50);
			}
		}
		catch(e) {}

		collect.location = window.location.toString();
		collect.mediaUrl = resultObject.resultOptions('url');

		collect.builders = resultObject.result;

		// Transformation des données collectées en chaine de caractères
		collect = (function(obj, prefix) {
			var content = [], value;
			prefix = prefix || '';
			for(var key in obj) {
				if(typeof obj[key] === 'object') {
					value = '\n'+arguments.callee(obj[key], prefix ? ' '+prefix+' ' : ' - ')+'\n';
				}
				else {
					value = obj[key];
				}
				content.push(prefix+key+' : '+value);
			}
			return content.join('\n');
		})(collect);

		var showElement = function() {
			element.show();
		},
		dialog = new window.dialog(
			 '<strong>Aucune solution n\'a été trouvée pour afficher <a href="'+resultObject.options('url')+'">ce contenu</a>.</strong>'+
			 '<br />'+
			 'Vous pouvez nous envoyer le rapport ci-après qui nous aidera à améliorer notre service.'+
			 '<br /><br />'+
			 '<textarea style="width:100%;height:3em">'+collect+'</textarea>'+
			 '<br /><br />'+
			 'e-mail (facultatif) : '+
			 '<input type="text" />'
			,showElement
		);
		dialog.setSize(resultObject.resultOptions(['width', 'height']));
		dialog.setAnswer(
			 'Envoyer le rapport'
			,function() {
				$.ajax({
					 url	: '/appftv/mediatools/rapport.php'
					,type	: 'POST'
					,data	: {
								 rapport	: this.getNode().find('textarea').val()
								,email		: this.getNode().find('input').val()
							}
				});
				window.alert('Merci de votre aide');
				showElement();
			}
		);
		dialog.setDefaultAnswer('Ne pas envoyer le rapport');
		element
			.hide()
			.after(dialog.getNode());
	};

	$.fn.mediaObject = function(options) {
		var $selection = $([]),
		finished = false;

		options = window.dynamicOptionsManager(options);

		this.each(function() {

		// On commence par controler que l'objet est bien exploitable : un lien, ou une image contenant un type adapté (flash, Silverlight....)
			if(
				!(this.nodeName === 'A' || this.nodeName === 'IMG') ||
				(
					this.nodeName === 'IMG' &&
					!(
						/\.(swf|xap)(\?.*)?(#.*)?$/.test(this.src) ||
						this.type === 'application/x-shockwave-flash' ||
						this.type === 'application/x-silverlight' ||
						this.type === 'application/x-silverlight-2'
					)
				)
			) {
				$selection = $selection.add(this);
				return;
			}

			var obj,
			href = this.nodeName === 'IMG' ? this.src : this.href,
			$localisor	= $('<span />').insertBefore(this),
			$elem = $(this).appendTo($('<div style="display: none;" />')),

			goBack = function() {
				$localisor.after($elem).remove();
			};

		// On place dans la selection l'objet d'origine dans un premier temps.
			$selection = $selection.add(this);

		// On réinitialise les options
			options.reset();

		// Pour le cas d'une image, on fait évoluer les options de dimensions
			if(this.nodeName === 'IMG') {
				if(!options.defined('width')) {
					options('width', $elem.attr('width') || null);
				}
				if(!options.defined('height')) {
					options('height', $elem.attr('height') || null);
				}
			}

		// On fait évoluer les options en fonctions des propriétés du Node cible
			options(parseClass(this.className));
			options('attrs', 'class', this.className || undef);
			options('attrs', 'id', this.id || undef);
			options('type', [options.raw('type'), this.type || undef]);

		// On génère l'objet MediaObject (BuilderCollection plus exactement)
			obj = window.MediaObject(href, options);
			
		// Si la version de jQuery le permet (>= 1.2.3), on enregistre en data l'instance de MediaObject obtenu
			if($elem.data !== undef) {
				$elem.data('mediaObject', {instance: obj});
			}

		// On défini ses callbacks
			obj.callbacks('finish', function() {
				if(!this.success) {
					// Si la construction de l'objet echoue, on replace l'element d'origine dans le
					// DOM puis on affiche un message d'erreur
					goBack();
					if(!this.resultOptions('quiet')) {
						displayReport(this, $elem);
					}
				}
				else {
					// On s'assure que le résultat soit bien un objet jQuery
					// De plus on place les object dans un div hors DOM en display none pour eviter que l'objet soit initialisé par IE avant qu'on le souhaite
					this.result = $(this.result)
						.not('script')
							.appendTo('<div style="display:none;" />')
						.end();

					// On place l'element cible d'origine dans le object/embed/iframe obtenu (Le premier si le résultat est composé de plusieurs éléments HTML)
					try {
						this.result
							.each(function() {
								if($(this).is('object, embed, iframe')) {
									$(this).append($elem);
									return false;
								}
								return !$(this)
									.find('object, embed, iframe')
									.eq(0)
									.append($elem)
									.length;
							});
					}
					catch(e) {}

					// On ajoute un callback finish qui replacera le resultat correctement dans le DOM après que les autres callbacks finish est été exécutés
					this.callbacks('finish', function() {
						$localisor
							.after(this.result)
							.remove();

						// si le flag finished n'est pas à true, l'exécution c'est fait de manière
						// synchrone, et donc la fonction jQuery n'a pas encore fait de retour. Donc il
						// est encore temps de modifier la selection jQuery qui sera retourné de manière
						// à ce qu'elle contienne, non pas l'élément d'origine, mais l'element object généré
						if(!finished) {
							$selection = $selection.not($elem).add(this.result);
						}
					});
				}
			});

			obj.callbacks('interact', function() {
				if(this.interactData instanceof window.dialog) {
					$localisor.after(this.interactData.getNode());
				}
			});
			obj.callbacks(options.raw('callbacks'));

		// On l'execute
			obj.execute();
		});

		finished = true;
		return $selection;
	};
})(this, this.jQuery);
/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};
(function(window, undef) {

	var pattern = ['(\\?|&amp;|&)(', ')(=([^&#]*))?(?=(&amp;|&|#|$))'],

	/**
	 * Récupère des valeurs de la query string d'une URL
	 *
	 * @param	{Array}		aNames		Liste des paramètres à récupérer
	 * @param	{String}	sUrl		URL à traiter (optionel)
	 *
	 * @return	{Object}				Liste des valeurs pour les paramètre trouvés
	 *
	 * Récupère les valeurs d'une liste de paramètres de l'URL fournie (ou de celle courante)
	 */
	getQueryStringValues = function(aNames, sUrl) {
		if(!(aNames instanceof Array))
			throw 'La liste de paramètre doit être un tableau';
		sUrl = (sUrl || window.location.toString());
		var match, results = {}
		,reg = new RegExp(pattern[0]+aNames.join('|')+pattern[1], 'g');
		while(match = reg.exec(sUrl)) {
			results[match[2]] = match[4] || '';
		}
		return results;
	},

	/**
	 * Ajoute une valeur à la query string d'une URL
	 *
	 * @param	{String}				sName			Nom du paramètre à ajouter
	 * @param	{String|undefined|null}	sValue			Valeur du paramètre à ajouter (Suppression du paramètre si undefined ou null)
	 * @param	{String}				sUrl			URL à traiter (optionel)
	 * @param	{String}				bHtmlEntity		utilisation ou non de l'entité HTML &amp; pour le & (optionel)
	 *
	 * @return	{String}								l'URL modifiée
	 *
	 * Récupère les valeurs d'une liste de paramètres de l'URL fournie (ou de celle courante)
	 */
	setQueryStringValue = function(sName, sValue, sUrl, bHtmlEntity) {
		sUrl = (sUrl+'' || window.location+'');
		var sParam
		,aMatches = sUrl.match(new RegExp('^(.*)'+pattern[0]+sName+pattern[1]+'(.*)$'))
		,bDelete = (sValue === null);

		if(!aMatches) {
			if(bDelete) {
				return sUrl;
			}
			sParam = ((sUrl.indexOf('?') != -1) ? (bHtmlEntity ? '&amp;' : '&') : '?')+sName+(sValue?'='+sValue:'');
			return sUrl.replace(/(#.*)?$/, sParam+'$1');
		}
		if(bDelete) {
			if(aMatches[7] === '') {
				return aMatches[1];
			}
			if(aMatches[6] === '#') {
				return aMatches[1] + aMatches[7];
			}
			return aMatches[1] + aMatches[2] + aMatches[7].substr(1);
		}
		return aMatches[1] + aMatches[2] + aMatches[3] + (sValue?'='+sValue:'') + aMatches[7];
	};

	String.prototype.getQueryStringValue = function(sName) {
		return getQueryStringValues([sName], this)[sName];
	};

	String.prototype.getQueryStringValues = function(aNames) {
		return getQueryStringValues(aNames, this);
	};

	String.prototype.setQueryStringValue = function(sName, sValue, bHtmlEntity) {
		return setQueryStringValue(sName, sValue, this+'', bHtmlEntity);
	};
})(this);
(function(window, $, undef) {
	(function(dep) {
		for(var i in dep) {
			if(!dep[i]) {
				throw 'Dépendence non satisfaite : '+i;
			}
		}
	})({
		jQuery					: !!$,
		MediaObject				: !!window.MediaObject
	});

	var ctrlFuncPattern = /^(play|pause|stop|fastForward|fastReverse)$/
	,ctrlVarPattern = /^(current(Position(Timecode)?|Item|Marker|AudioLanguage(Index)?))$/i
	,wmpControl = function(event, data) {
		$(this)
			.each(function() {
				try {
					if(ctrlFuncPattern.test(event.type)) {
						this.controls[event.type]();
					}
					else if(ctrlVarPattern.test(event.type)) {
						this.controls[event.type] = data;
					}
					else if(event.type === 'kill') {
						this.controls.stop();
						this.close();
						$(this).remove();
					}
					else if(event.type === 'hide') {
						this.controls.stop();
						$(this).hide();
					}
					else if(event.type === 'show') {
						$(this).show();
					}
					else if(event.type === 'fullscreen') {
						if(this.fullScreen === true) {
							this.fullScreen = false;
						}
						else {
							if(this.playState !== 3 && this.playState !== 2) {
								this.controls.play();
								this.controls.pause();
								this.fullScreen = true;
							}
							if(this.playState === 3 || this.playState === 2) {
								this.fullScreen = true;
							}
							else {
								alert('Vous ne pouvez passer en plein écran que si la vidéo est en cours de lecture ou en pause.');
							}
						}
					}
					else if(event.type === 'playItem') {
						data = parseInt(data);
						if(isNaN(data) || this.currentPlaylist.count <= data) {
							this.controls.playItem(this.currentPlaylist.item(0));
						}
						else {
							this.controls.playItem(this.currentPlaylist.item(data));
						}
					}
				}
				catch (e) {
					//alert('Le controle du player vidéo ne semble pas possible pour votre navigateur ou votre plugin.');
				}
			});
	}
	,callCybermonitor = (function() {
		var pattern_url = /^http:\/\//;
		return function(tagcyber) {
			if(typeof tagcyber !== 'string' || !pattern_url.test(tagcyber)) {
				if(typeof tagcyber === 'string') {
					var tagcyberArray = tagcyber.split('_');
					tagcyber = {
						 client		: tagcyberArray[0]
						,section	: tagcyberArray[1]
						,rubrique	: tagcyberArray.slice(2).join('_')
					}
				}
				var client_section = [tagcyber.client, tagcyber.section].join('_')
				,client_section_rub = client_section;
				if(tagcyber.rubrique) {
					client_section_rub+= '_'+tagcyber.rubrique;
				}
				tagcyber = 'http://stat3.cybermonitor.com/'+
					tagcyber.client+
					'_v?R='+
					client_section_rub+
					'&S=total;'+
					client_section+
					'&random='+
					Math.random();
			}
			(new Image())
				.src = tagcyber;
		};
	})(),

	IEPluginClassId = 'CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6',

	t_builderNotForMacReport = 'Constructeurs non adaptés aux Mac',

	t_noIeWmpPluginAvailable = 'Pas de plugin WMP pour IE dispo',

	t_browserNotMozillaWin = 'Le navigateur ne semble pas être un Firefox sous Windows',

	t_mozillaWinPluginNotAvailable = 'Vous ne possédez pas le plugin permettant de profiter au maximum '+
			'des vidéos Windows Media Player avec Firefox.<br /><br />'+
			'(Windows XP SP2 ou supérieur necésaire)',

	t_mozillaWinPluginNotAvailableReport = 'Plugin WMP spécial Firefox non dispo',

	t_downloadFlash = 'Télécharger ce plugin',

	t_waitMozillaWinPlugin = 'Attente du plugin Windows Media Player pour Firefox',

	t_noFlashUse = 'Ne pas le télécharger';

	window.MediaObject.setBuilder(
		 'WMVFamily'
		,['MediaPlayerFamily', 'videoFlip4MacFamily']
		,{
			 width					: 384
			,autostart				: true
			,extensions				: ['asx', 'wmv', 'asf', 'wsx']
		}
	);

	window.MediaObject.setBuilder(
		 'WMAFamily'
		,['audioMediaPlayerFamily', 'audioFlip4MacFamily']
		,{
			 width					: 384
			,autostart				: true
			,extensions				: 'wma'
		}
	);

	window.MediaObject.setBuilder(
		 'MediaPlayerFamily'
		,function() {
			if(window.navigator.appVersion.indexOf('Mac') !== -1) {
				this.abort(t_builderNotForMacReport);
				return;
			}
			this.buildAndReturn(['mediaPlayerMozillaWin', 'mediaPlayerIE', 'mediaPlayerOthers']);
		}
		,{
			 height					: 288
			,soustitre				: undef
			,soustitreNode			: undef
			,soustitreId			: 'soustitres'
			,soustitreNodeReturn	: undef
		}
	);

	window.MediaObject.setBuilder(
		 'audioMediaPlayerFamily'
		,'MediaPlayerFamily'
		,{
			 height					: 45
		}
	);

	window.MediaObject.setBuilder(
		 'videoFlip4MacFamily'
		,'Flip4Mac'
		,{
			 height					: 232
		}
	);

	window.MediaObject.setBuilder(
		 'audioFlip4MacFamily'
		,'Flip4Mac'
		,{
			 height					: 16
		}
	);

	window.MediaObject.setBuilder(
		 'mediaPlayerCommon'
		,function() {
			var $this = this,
			i,
			soustitre = (this.options('soustitre') || '').match(/^(sami):(.*)$/i),
			soustitreNode,
			soustitreId,
			finalSoustitreId,
			finalBuilder;


			if($.browser.msie) {
				// On désactive l'autostart. Pour des raisons de bug sous IE, on fait
				// l'autostart manuellement grâce à l'événement MediaObjectDOMInsert
				if(!this.options.defined('realAutostart')) {
					this.options('realAutostart', this.options('autostart'));
				}

				this.options('autostart', false);
			}

			if(this.options.defined('tag-cyber')) {
				callCybermonitor(this.options('tag-cyber'));
			}

			this.options.transfert(
				 'params'
				,[
					 'url'
					,'autostart'
				]
			);

			this.options('params', {wmode : null});

			// Gestion des soustitres
			if(soustitre) {
				// Définition du noeud DOM d'insertion des soustitres
				soustitreNode = $(this.options('soustitreNode') || []);
				if(soustitreNode.length === 0) {
					soustitreNode = $('<div />');
					this.options('soustitreNodeReturn', true);
				}
				// Définition de l'ID de ce noeud DOM
				if(!(soustitreId = soustitreNode.attr('id'))) {
					soustitreId = this.options('soustitreId') || 'soustitres';
					i = -1;
					while($('#'+soustitreId + (++i || '')).length !== 0);
					soustitreId = soustitreId + (i || '');
					soustitreNode.attr('id', soustitreId);
				}
				// traitements spécifiques en fonction du type de sous titre
				switch(soustitre[1]) {
					case 'sami':
						this.options('params', {
							 SAMIFileName: soustitre[2]
							,captioningID: soustitreId
						});

						if(!this.options.defined('params', 'SAMIStyle'))
							this.options('params', 'SAMIStyle', 'Small Print');
						if(!this.options.defined('params', 'SAMILang'))
							this.options('params', 'SAMILang', 'French');
						break;
					default:
						this.options('soustitreNodeReturn', false);
						break;
				}
			}

			finalBuilder = this.build('generateObject');

			finalBuilder.callbacks('finish', function() {
				if(!this.success) {
					$this.abort(this.result, this.resultOptions);
					return;
				}

				if($.browser.msie) {
					var autostart = this.options('realAutostart');
				}

				$this.setResult(
					$(this.result)
						.bind('play', wmpControl)
						.bind('pause', wmpControl)
						.bind('stop', wmpControl)
						.bind('fastForward', wmpControl)
						.bind('fastReverse', wmpControl)
						.bind('currentPosition', wmpControl)
						.bind('fullscreen', wmpControl)
						.bind('playItem', wmpControl)
						.bind('kill', wmpControl)
						.bind('hide', wmpControl)
						.bind('show', wmpControl)
						.bind('MediaObjectDOMInsert.WMP', function() {
							if($.browser.msie && autostart) {
								$(this).trigger('play');
							}
						})
						.add($this.options('soustitreNodeReturn') ? soustitreNode || [] : [])
					,this.resultOptions
				);
			});
			finalBuilder.execute();
		}
		,{
			 params					: {
										 uiMode				: 'full'
										,enableContextMenu	: true
										,stretchToFit		: 1
									}
		}
	);

	window.MediaObject.setBuilder(
		 'mediaPlayerIE'
		,(function() {
			var pluginPresent = function() {
				var pluginPresent;
				$('<object classid="'+IEPluginClassId+'" />')
					.each(function() {
						pluginPresent = !!this.controls;
					});
				return pluginPresent;
			};

			return function() {
				if(!pluginPresent()) {
					this.abort(t_noIeWmpPluginAvailable);
					return;
				}
				this.buildAndReturn('mediaPlayerCommon');
			};
		})()
		,{
			 attrs			: {
								 classid	: IEPluginClassId
							}
		}
	);

	window.MediaObject.setBuilder(
		'mediaPlayerMozillaWin',
		(function() {
			var pluginPresent = function() {
				if(window.navigator.plugins !== undef && window.navigator.mimeTypes !== undef) {
					window.navigator.plugins.refresh();
					return (
						window.navigator.mimeTypes['application/x-ms-wmp'] !== undef
						&& window.navigator.mimeTypes['application/x-ms-wmp'].enabledPlugin
						&& window.navigator.mimeTypes['application/x-ms-wmp'].enabledPlugin.description === 'np-mswmp'
					);
				}
				return false;
			};

			return function() {
				if(!($.browser.mozilla && window.navigator.appVersion.indexOf('Win') != -1)) {
					this.abort(t_browserNotMozillaWin);
					return;
				}
				if(!pluginPresent()) {
					var $this = this
					,timeout
					,dialog = this.createDialog(t_mozillaWinPluginNotAvailable)
					,abortBuilding = function() {
						window.clearTimeout(timeout);
						this.abort(t_mozillaWinPluginNotAvailableReport);
					};
					dialog.setAnswer(
						t_downloadFlash,
						function() {
							dialog = $this.createDialog('Attente du plugin Windows Media Player pour Firefox');
							dialog.setDefaultAnswer('Stopper l\'attente');
							$this.wait(dialog, abortBuilding);
							window.open('http://medias2.francetv.fr/videosread/externe/wmv-firefox-plugin/WindowsMedia-Firefox-Plugin.exe');
						}
					);
					dialog.setDefaultAnswer('Ne pas le télécharger');

					this.wait(dialog, abortBuilding);
					timeout = window.setTimeout(function() {
						if(!pluginPresent()) {
							timeout = window.setTimeout(arguments.callee, window.MediaObject.pluginRefreshTime);
						}
						else {
							dialog.remove();
							$this.buildAndReturn('mediaPlayerCommon');
						}
					}, window.MediaObject.pluginRefreshTime);
					return;
				}
				this.buildAndReturn('mediaPlayerCommon');
			};
		})(),
		{
			 attrs	: {
						 type	: 'video/x-ms-wmv'
					}
		}
	);

	window.MediaObject.setBuilder(
		 'mediaPlayerOthers'
		,(function() {
			var pluginPresent = function(type) {
				if(window.navigator.plugins !== undef && window.navigator.mimeTypes !== undef) {
					window.navigator.plugins.refresh();
					return (
						window.navigator.mimeTypes[type] !== undef
						&& window.navigator.mimeTypes[type].enabledPlugin
					);
				}
			}

			return function() {
				if(!pluginPresent(this.options('attrs', 'type'))) {
					this.abort('Aucun plugin adapté n\'a été trouvé.');
					return;
				}
				// necessaire au moins pour Mozilla si le plugin specifique Firefox n'est pas présent
				this.options('attrs', 'data', this.options('url'));
				this.buildAndReturn('mediaPlayerCommon');
			};
		})()
		,{
			 attrs	: {
						 type	: 'video/x-ms-wmv'
					}
		}
	);

	window.MediaObject.setBuilder(
		 'Flip4Mac'
		,(function() {
			var versionCheckPattern = /flip4mac.*?((2\.\d*[3-9]|\d*[3-9])(\.\d+)*)/i
			,getInstalledVersion = function() {
				var i = 0
				,matches
				,versions = [2, 2.1, 2.2, 2.3]
				,version = 0;

				if(window.navigator.plugins !== undef && window.navigator.mimeTypes !== undef) {
					window.navigator.plugins.refresh();
					if(window.navigator.mimeTypes['application/x-mplayer2'] !== undef
						&& window.navigator.mimeTypes['application/x-mplayer2'].enabledPlugin
						&& (matches = window.navigator.mimeTypes['application/x-mplayer2'].enabledPlugin.name.match(versionCheckPattern))) {
						version = parseFloat(matches[1]);
						while(versions[++i] <= version);
						version = versions[i-1];
					}
				}
				return version || 0;
			}
			,finishBuilding = function() {
				this.options.transfert(
					 'attrs'
					,[
						 'url'
						,'autostart'
					]
					,{
						 url		: 'src'
						,autostart	: 'AutoStart'
					}
				);

				this.options('params', {
					 wmode		: null
				});

				var $this = this
				,finalBuilder = this.build('generateEmbed');

				finalBuilder.callbacks('finish', function() {
					if(!this.success) {
						$this.abort(this.result, this.resultOptions);
						return;
					}
					$this.setResult(
						 $(this.result)
							.bind('play', wmpControl)
							.bind('pause', wmpControl)
							.bind('stop', wmpControl)
							.bind('kill', wmpControl)
							.bind('hide', wmpControl)
							.bind('show', wmpControl)
						,this.resultOptions
					);
				});
				finalBuilder.execute();
			};
			return function() {
				if(window.navigator.appVersion.indexOf('Mac') === -1) {
					this.abort('Constructeur non adapté à la plateforme');
					return;
				}
				var minVersion = 2.3
				,version = getInstalledVersion()
				,getUrl = 'http://www.apple.com/downloads/macosx/video/flip4macwindowsmediacomponentsforquicktime.html';
				if(version < minVersion) {
					var $this = this
					,dialog, timeout
					,installF4M = function() {
						dialog = $this.createDialog('Un redémarage de votre navigateur sera nécéssaire');
						dialog.setDefaultAnswer('Fermer ce message');
						$this.wait(dialog, abortAction);
						window.open(getUrl);
						abortMsg = 'Installation plugin Flip4Mac';
					}
					,abortAction = function() {
						window.clearTimeout(timeout);
						$this.abort(abortMsg);
					}
					,abortMsg;
					if(version === 0) {
						dialog = this.createDialog('Le plugin Flip4Mac n\'est pas disponible sur votre navigateur');
						dialog.setAnswer(
							 'Télécharger ce plugin'
							,installF4M
						);
						abortMsg = 'Le plugin Flip4Mac ne semble pas disponible (refus install)';
					}
					else {
						dialog = this.createDialog('Le plug-in Flip4Mac disponible sur votre navigateur ne semble pas suffisemment à jour');
						dialog.setAnswer(
							 'Mettre à jour ce plugin'
							,installF4M
						);
						abortMsg = 'Le plugin Flip4Mac ne semble pas à jour (refus install). Version dispo : '+version;
					}
					timeout = window.setTimeout(function() {
						var newVersion = getInstalledVersion();
						if(newVersion === version) {
							timeout = window.setTimeout(arguments.callee, window.MediaObject.pluginRefreshTime);
						}
						else if(newVersion < $this.options('minVersion')) {
							dialog.remove();
							dialog = $this.createDialog('La version de Flash installée ne semble pas assez récente');
							dialog.setDefaultAnswer('Ok');
							abortMsg = 'echec mise à jour de Flash. Version dispo : '+version;
							$this.wait(dialog, abortAction);
							window.open(getUrl);
						}
						else {
							dialog.remove();
							finishBuilding.call($this);
						}
					}, window.MediaObject.pluginRefreshTime);
					dialog.setDefaultAnswer('Ne pas utiliser Flip4Mac');
					this.wait(dialog, abortAction);
					return;
				}
				finishBuilding.call(this);
			};
		})()
		,{
			 attrs		: {
							 type						: 'application/x-mplayer2'
							,showControls				: true
							,showStatusBar				: false
							,scale						: 'ASPECT'
							,kioskmode					: true
//							,showTracker				: 0
//							,sendPlayStateChangeEvents	: 0
//							,transparentAtStart			: 0
//							,displaySize				: 0
//							,autoSize					: 0
//							,stretchToFit				: 1
						}
		}
	);
})(this, this.jQuery);
(function(window, $, undef) {
	(function(dep) {
		for(var i in dep) {
			if(!dep[i]) {
				throw 'Dépendence non satisfaite : '+i;
			}
		}
	})({
		jQuery					: !!$,
		MediaObject				: !!window.MediaObject
	});

	var t_rebootNeeded = 'Un redémarage de votre navigateur sera probablement nécessaire',

	t_closeDialog = 'Fermer ce message',

	t_installReport = 'Installation plugin Flash',

	t_noFlashAvailable = 'Le plugin Flash n\'est pas disponible sur votre navigateur',

	t_downloadFlash = 'Télécharger ce plugin',

	t_noFlashNoInstallReport = 'Le plugin Flash ne semble pas disponible (refus install)',

	t_flashOutdated = 'Le plug-in Flash disponible sur votre navigateur ne semble pas suffisemment à jour',

	t_updateFlash = 'Mettre à jour ce plugin',

	t_flashOutdatedNoInstallReport = 'Le plugin Flash ne semble pas à jour (refus install). Version dispo : [VERSION]',

	t_flashInstalledOutdated = 'La version de Flash installée ne semble pas assez récente',

	t_ok = 'Ok',

	t_flashInstalledOutdatedReport = 'echec mise à jour de Flash. Version dispo : [VERSION]',

	noFlashUse = 'Ne pas utiliser Flash';

	window.MediaObject.setBuilder(
		 'flashObject'
		,(function() {
			var getInstalledVersion = function() {
				var plugin, version
				,i = 0
				,versions = [1, 9, 10];

				if(window.ActiveXObject !== undef) {
					try {
						plugin = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
						version = parseFloat(plugin.GetVariable("$version").replace(/^[^\d]+/, ''));
						plugin = null;
					}
					catch(e) {}
				}
				if(version === undef
				  && (plugin = window.MediaObject.getPluginByType('application/x-shockwave-flash'))) {
					version = parseFloat(plugin.description.replace(/^[^\d]+/, ''));
				}
				if(!version) {
					return 0;
				}
				while(version >= versions[++i]);
				return versions[i-1];
			}

			,finishBuilding = function() {
				var url = this.options('url');
				this.options('params', {movie : url});
				this.options('attrs', {data : url});

				if(!this.options.defined('attrs', 'id')) {
					this.options('attrs', 'id', 'flashObject'+(+new Date));
				}

				this.buildAndReturn('generateObject');
			};

			return function() {
				var version = getInstalledVersion()
				,getUrl = 'http://get.adobe.com/flashplayer/';
				if(version < this.options('minVersion')) {
					var $this = this
					,dialog, timeout
					,installFlash = function() {
						dialog = $this.createDialog(t_rebootNeeded);
						dialog.setDefaultAnswer(t_closeDialog);
						$this.wait(dialog, abortAction);
						window.open(getUrl);
						abortMsg = t_installReport;
					}
					,abortAction = function() {
						window.clearTimeout(timeout);
						$this.abort(abortMsg);
					}
					,abortMsg;
					if(version === 0) {
						dialog = this.createDialog(t_noFlashAvailable);
						dialog.setAnswer(
							 t_downloadFlash
							,installFlash
						);
						abortMsg = t_noFlashNoInstallReport;
					}
					else {
						dialog = this.createDialog(t_flashOutdated);
						dialog.setAnswer(
							 t_updateFlash
							,installFlash
						);
						abortMsg = t_flashOutdatedNoInstallReport.replace('[VERSION]', version);
					}
					timeout = window.setTimeout(function() {
						var newVersion = getInstalledVersion();
						if(newVersion === version) {
							timeout = window.setTimeout(arguments.callee, window.MediaObject.pluginRefreshTime);
						}
						else if(newVersion < $this.options('minVersion')) {
							dialog.remove();
							dialog = $this.createDialog(t_flashInstalledOutdated);
							dialog.setDefaultAnswer(t_ok);
							abortMsg = t_flashInstalledOutdatedReport.replace('[VERSION]', version);
							$this.wait(dialog, abortAction);
							window.open(getUrl);
						}
						else {
							dialog.remove();
							finishBuilding.call($this);
						}
					}, window.MediaObject.pluginRefreshTime);
					dialog.setDefaultAnswer(noFlashUse);
					this.wait(dialog, abortAction);
					return;
				}
				finishBuilding.call(this);
			};
		})()
		,{
			 width				: 400
			,height				: 400
			,minVersion			: 10
			,attrs				: {
									 type				: 'application/x-shockwave-flash'
									,classid			: (window.ActiveXObject !== undef) ? 'clsid:D27CDB6E-AE6D-11CF-96B8-444553540000' : undef
								}
			,params				: {
									 wmode				: 'transparent'
								}
			,extensions			: 'swf'
		}
	);

	window.MediaObject.setBuilder(
		 'flashPlayer'
		,function() {
			this.options('params', 'flashvars', {});
			this.options('params', 'flashvars', this.options('fileKeyName'), this.options('url'));
			if(this.options.defined('autostart'))
				this.options('params', 'flashvars', 'autostart', this.options('autostart'));

			this.options('url', this.options('player'));

			this.buildAndReturn('flashObject');
		}
		,{
			 player			: '/layoutftv/players/jw_player/mediaplayer.swf'
			,fileKeyName	: 'file'
			,autostart		: true
			,extensions		: ['mp4', 'flv']
			,types			: 'video/x-flv'
		}
	);

	window.MediaObject.setBuilder(
		 'flashPlayerAudio'
		,'flashPlayer'
		,{
			 height: 20
			,extensions	: 'mp3'
		}
	);
})(this, this.jQuery);
(function(window, $, undef) {
	(function(dep) {
		for(var i in dep) {
			if(!dep[i]) {
				throw 'Dépendence non satisfaite : '+i;
			}
		}
	})({
		jQuery					: !!$,
		MediaObject				: !!window.MediaObject,
		getQueryStringValue		: !!(String && String.prototype.getQueryStringValue),
		'jQuery.cookie'			: !!($ && $.cookie)
	});

	// Variables de textes, pour simplifier les modifications des textes affichés
	var t_noSLAndNoInstallAbort = 'Silverlight non dispo et cookie noInstall',

	t_noSLAvailable = 'Le plugin Silverlight n\'est pas disponible sur votre navigateur',
	t_downloadSL = 'Télécharger ce plugin',

	t_waitForSL = 'Attente de l\'installation du plugin Silverlight',
	t_waitStop = 'Stopper l\'attente',
	t_waitStopReport = 'Annulation de l\'attente du plugin Silverlight',

	t_installedOutdatedSL = 'La version de Silverlight installée ne semble pas assez récente (installé : [VERSION], requis : [REQUIS])',
	t_installedOutdatedSLReport = 'version installée pas à jour',

	t_outdatedSL = 'Le plugin Silverlight de votre navigateur ne semble pas à jour (installé : [VERSION], requis : [REQUIS])',

	t_updateSL = 'Mettre à jour ce plugin',

	t_afterUpdateReboot = 'Après la mise à jour de Silverlight, vous devrez relancer votre navigateur pour que cette mise à jour soit prise en compte',

	t_noSLUse = 'Ne pas utiliser Silverlight',
	t_noSLUseReport = 'Refus téléchargement Silverlight',

	t_noCappuIdReport = 'Identifiant Cappucino non disponible',

	themes_player = {
		france2 : true,
		france3 : true,
		france4 : true,
		france5 : true,
		rfo : true
	};


	window.MediaObject.setBuilder(
		 'SilverlightObject'
		,(function() {
			var getInstalledVersion = function() {
				var i, plugin, version
				,versions = [1, 2, 3];

				if(window.ActiveXObject) {
					try {
						plugin = new ActiveXObject('AgControl.AgControl');
						for(i = versions.length; i > 0; i--) {
							// Le numero de version fourni doit être une String contenant au moins un truc du genre "1.0". Un entier n'est pas supporté
							if(plugin.IsVersionSupported((''+versions[i-1]).replace(/^([^\.]*)$/, '$1.0'))) {
								version = versions[i-1];
								break;
							}
						}
						plugin = null;
					}
					catch(e) {}
				}
				if(version === undef
				  && (plugin = window.MediaObject.getPluginByType('application/x-silverlight'))) {
					version = parseFloat(plugin.description);
					// Si le plugin à une extension .so, on est sous linux, donc moonlight, et donc
					// si on à un numero de version 3.0.40818.0 (on va dire 3.0.x) ou inferieur, ce n'est pas vraiment
					// compatible Silverlight 3.
					if(/\.so$/.test(plugin.filename)) {
						if(version >= 3 && version < 3.1) {
							version = 2;
						}
					}
					i = 0;
					while(version >= versions[++i]);
					version = versions[i-1];
				}
				if(!version) {
					return 0;
				}
				else {
					return version;
				}
			}

			,finishBuilding = function() {
				this.options.transfert(
					 'params'
					,[
						 'url'
						,'maxFramerate'
						,'framerate'
						,'windowless'
						,'isWindowless'
						,'background'
					]
					,{
						 url			: 'source'
						,framerate		: 'maxFramerate'
						,isWindowless	: 'windowless'
					}
				);

				this.buildAndReturn('generateObject');
			};

			return function() {
				var version = getInstalledVersion(),
				$this = this,
				dialog, timeout;

				if(version < this.options('minVersion')) {
					if($.cookie('noSilverlightDownload') || ($.cookie('silverlightInstallTries') > 1)) {
						this.abort(t_noSLAndNoInstallAbort);
						return;
					}
					if(version === 0) {
						dialog = this.createDialog(t_noSLAvailable);
						dialog.setAnswer(
							 t_downloadSL
							,function() {
								$.cookie('silverlightInstallTries', (parseInt($.cookie('silverlightInstallTries')) || 0)+1);
								dialog = $this.createDialog(t_waitForSL);
								dialog.setDefaultAnswer(t_waitStop);
								$this.wait(dialog, function() {
									window.clearTimeout(timeout);
									$this.abort(t_waitStopReport);
									/* Logger SL Start  /
									if(typeof window.SLS.logInstallFlow == 'function' && SLS.appName !== undef) {
										window.SLS.logInstallFlow(window.SLS.statusChooseReject);
									}
									/* Logger SL end */
								});
								/* Logger SL Start  /
								if(typeof window.InstallClicked == 'function' && SLS.appName !== undef) {
									window.InstallClicked();
								}
								else {*/
									window.open('http://go2.microsoft.com/fwlink/?LinkID=114576');
								/*}
								/* Logger SL end */
							}
						);

						timeout = window.setTimeout(function() {
							window.clearTimeout(timeout);
							var newVersion = getInstalledVersion();
							if(newVersion === version) {
								timeout = window.setTimeout(arguments.callee, window.MediaObject.pluginRefreshTime);
							}
							else if(newVersion < $this.options('minVersion')) {
								dialog.remove();
								dialog = $this.createDialog(t_installedOutdatedSL.replace('[VERSION]', newVersion).replace('[REQUIS]', $this.options('minVersion')));
								$this.wait(dialog, function() {
									dialog.remove();
									window.clearTimeout(timeout);
									$this.abort(t_installedOutdatedSLReport);
									/* Logger SL Start  /
									if(typeof window.SLS.logInstallFlow == 'function' && SLS.appName !== undef)
									{
										window.SLS.logInstallFlow(window.SLS.statusChooseReject);
									}
									/* Logger SL end */
								});
								/* Logger SL Start /
								if(typeof window.UpgradeClicked == 'function' && SLS.appName !== undef) {
									UpgradeClicked();
								}
								else {*/
									window.open('http://go2.microsoft.com/fwlink/?LinkID=114576');
								/*}
								/* Logger SL end */
							}
							else {
								dialog.remove();
								/* Logger SL Start /
								alert('Silverlight a été installé correctement');
								if(typeof window.SLS.logInstallFlow == 'function' && SLS.appName !== undef) {
									window.SLS.logInstallFlow(window.SLS.statusSuccess);
								}
								/* Logger SL end */
								finishBuilding.call($this);
							}
						}, window.MediaObject.pluginRefreshTime);
					}
					else {
						dialog = this.createDialog(t_outdatedSL.replace('[VERSION]', version).replace('[REQUIS]', $this.options('minVersion')));
						dialog.setAnswer(
							 t_updateSL
							,function() {
								dialog = $this.createDialog(t_afterUpdateReboot);
								$this.wait(dialog);
								/* Logger SL Start /
								if(typeof window.UpgradeClicked == 'function' && SLS.appName !== undef) {
									UpgradeClicked();
								}
								else {*/
									window.open('http://go2.microsoft.com/fwlink/?LinkID=114576');
								/*}
								/* Logger SL end */
							}
						);
					}
					dialog.setDefaultAnswer(t_noSLUse);
					this.wait(dialog, function() {
						$.cookie('noSilverlightDownload', 'true');
						window.clearTimeout(timeout);
						$this.abort(t_noSLUseReport);
					});
					return;
				}
				$.cookie('silverlightInstallTries', null);
				$.cookie('noSilverlightDownload', null);
				finishBuilding.call(this);
			};
		})()
		,{
			 width				: 400
			,height				: 400
			,background			: 'transparent'
			,minVersion			: 3
			,paramsSeparator	: ','
			,maxFramerate		: undef
			,windowless			: true
			,attrs				: {
									 data					: 'data:application/x-silverlight,'
									,type					: 'application/x-silverlight'
								}
			,params				: {
									 autoUpgrade			: false
									,minRuntimeVersion		: '3.0.40624.0'
									,EnableGPUAcceleration	: true
									,wmode					: 'transparent'
								}
			,extensions			: ['xap', 'xaml']
		}
	);

	window.MediaObject.setBuilder(
		 'SilverlightPlayer'
		,function() {

			if(typeof ftvi_portail === 'string' && !this.options.defined('theme')) {
				this.options('theme', ftvi_portail);
			}

			if(themes_player[this.options('theme')] === undef) {
				this.options('theme', null);
			}

			this.options.transfert(
				 'params'
				,[
					 'autostart'

					,'bgColor'
					,'theme'
					,'autohidebuttons'

					,'enablerating'
					,'displayrating'

					,'displaysequence'
					,'defaultenablesequence'
					,'numberdisplaysequence'

					,'displayincrust'
					,'fontsizeincrust'

					,'displaycaption'
					,'defaultenablecaption'
					,'fontsizecaption'

					,'region'
					,'timecode'
					,'sequence'
				]
				,{
					 autostart	: 'autoplay'
					,bgColor	: 'background'
				}
			);

			this.options('url', this.options('player'));

			this.buildAndReturn('SilverlightObject');
		}
		,{
			 player					: '/layoutftv/players/player_video_simple/player_video_simple.sl3.xap'

			,width					: 384
			,height					: 221

			,autostart				: true

			,bgColor				: 'white'
//			,theme					: 'france2'
			,autohidebuttons		: true

			,enablerating			: true
			,displayrating			: true

			,displaysequence		: true
			,defaultenablesequence	: true
			,numberdisplaysequence	: 5

			,displayincrust			: true
			,fontsizeincrust		: 18

			,displaycaption			: true
			,defaultenablecaption	: true
			,fontsizecaption		: 18

//			,region					: undef
//			,timecode				: undef
//			,sequence				: undef
		}
	);

	window.MediaObject.setBuilder(
		 'SilverlightPlayerCappu'
		,function() {
			if(!this.options.defined('cappuid')) {
				this.abort(t_noCappuIdReport);
			}

			this.options.transfert(
				 'params'
				,[
					 'cappuid'
				]
				,{
					 cappuid	: 'videoid'
				}
			);

			this.buildAndReturn('SilverlightPlayer');
		}
	);

	window.MediaObject.setBuilder(
		 'SilverlightPlayerVideo'
		,function() {
			this.options.transfert(
				 'params'
				,[
					 'url'
				]
				,{
					 url	: 'videourl'
				}
			);

			this.buildAndReturn('SilverlightPlayer');
		}
		,{
			 extensions		: ['asx', 'wmv', 'wsx', 'mp4']
		}
	);

	window.MediaObject.setBuilder(
		 'SilverlightPlayerAudio'
		,'SilverlightPlayerVideo'
		,{
			 height				: 100
			,autohidebuttons	: false
			,extensions			: ['wma', 'mp3']
		}
	);

})(this, this.jQuery);
(function(window, $, undef) {
	(function(dep) {
		for(var i in dep) {
			if(!dep[i]) {
				throw 'Dépendence non satisfaite : '+i;
			}
		}
	})({
		jQuery					: !!$,
		MediaObject				: !!window.MediaObject,
		getQueryStringValue		: !!(String && String.prototype.getQueryStringValue)
	});

	// Variables de textes, pour simplifier les modifications des textes affichés
	var t_noCappuGetInfosInTime = 'Impossible d\'obtenir les infos dans le temps imparti pour l\'identifiant "[CAPPUID]"',
	t_noCappuGetInfos = 'Impossible d\'obtenir les infos pour l\'identifiant "[CAPPUID]"',
	t_noCappuIdReport = 'Identifiant Cappucino non disponible',

	basesMms = {
		''					: 'mms://a988.v101995.c10199.e.vm.akamaistream.net/'+
								'7/988/10199/3f97c7e6/ftvigrp.download.akamai.com/'+
								'10199/cappuccino/production/publication',
		'France DOM-TOM'	: 'mms://videozones.francetv.fr/france-dom-tom'
	};


	window.MediaObject.setBuilder(
		'cappuccino',
		function() {
			// Récupération de l'identifiant cappuccino
			this.options('cappuid', (this.options('url') || '').getQueryStringValue('id-video'));

			this.buildAndReturn(['SilverlightPlayerCappu', 'cappuccinoNoSL']);
		},
		{
			types	: 'video/cappuccino'
		}
	);

	window.MediaObject.setBuilder(
		'cappuccinoNoSL',
		(function() {
			var got = {
				getInfosVideo	: false
			},
			gotElement = function(element) {
				got[element] = true;

				for(var key in got) {
					if(got[key] === false) {
						return;
					}
				}

				abort(false);

				this.buildAndReturn();
			},
			abort = (function() {
				canceled = false;
				return function(doAbort) {
					if(doAbort === false) {
						canceled = true;
					}
					if(!canceled) {
						this.abort(t_noCappuGetInfosInTime.replace('[CAPPUID]', this.options('cappuid')));
					}
				};
			})();

			return function() {
				if(!this.options.defined('cappuid')) {
					this.abort(t_noCappuIdReport);
					return;
				}

				var $this = this,
				cappuid = this.options('cappuid');

				// Récupération de l'URL et extension de la vidéo
				$.ajax({
					 url		: '/appftv/webservices/video/getInfosVideo.php?src=cappuccino&video-type=simple&template=ftvi&template-format=complet&id-externe='+cappuid
					,dataType	: 'xml'
					,timeout	: 15000
					,success	: function(data) {
									var noinfo = 'noinfo',
									geolocalisation = '';

									// tag cyberistat, inutile mais indispenssable pour que le player SL ne plante pas
									$this.options('tag-cyber', window.ftvi_portail+'_'+window.ftvi_section+'_'+window.ftvi_rubrique);

									$('> video', data.documentElement)
										.find('> geolocalisation')
											.each(function() {
												geolocalisation = $(this).text();
											})
										.end()
										.find('> fichiers > fichier:first')
											.each(function() {
												$this.options(
													 'url'
													,(basesMms[geolocalisation] || basesMms[''])+
													 $('chemin', this).text().replace(/\/geoloc\/[^\/]+/, '')+
													 $('nom', this).text()
												);
												$this.options('extension', $('extension', this).text().toLowerCase());
											});

									gotElement.call($this, 'getInfosVideo');
								}
					,error		: function(data) {
									$this.abort(t_noCappuGetInfos.replace('[CAPPUID]', cappuid));
								}
				});

				this.wait(15, abort);
			};
		})()
	);

})(this, this.jQuery);
(function(window, $, undef) {
	(function(dep) {
		for(var i in dep) {
			if(!dep[i]) {
				throw 'Dépendence non satisfaite : '+i;
			}
		}
	})({
		dynamicOptionsManager	: !!window.dynamicOptionsManager,
		callbacksManager		: !!window.callbacksManager,
		jQuery					: !!$,
		'jQuery.mediaObject'	: !!($ && $.fn && $.fn.mediaObject)
	});

	var PreRoll = window.PreRoll = function(element, options) {
		if(!(this instanceof PreRoll)) {
			return new PreRoll(element, options);
		}
		// Identifiant utilisé pour le bouton play ( ~ ligne 356), pour avoir une instance unique du bouton pour chaque instance de préRoll.
		// Il doit y avoir moyen de faire sans cet ID, et ce serait probablement plus propre.
		this.uid = +new Date;

		this.options = window.dynamicOptionsManager.call(this, PreRoll.defaultOptions, options);

		var $elem = $(element || []),
		init			= function() {
								$this.options('preFinish', null);
								$this.options('postFinish', null);
								wrapper
									.bind('click', bypass)
									.bind('dblclick', bypass)
									.bind('mousedown', bypass);

								$(window)
									.unload(destroy);

								displayPlayButton();
							}

		,umount				= function() {
								if(mounted()) {
									wrapper
										.after(element)
										.remove();
								}
							}

		,mount				= function() {
								if(!mounted()) {
									$elem
										.after(wrapper)
										// On place l'element dans un div hors DOM, en display none afin
										// que IE n'initialise pas un objet trop tot (objets Flash, Silverlight, WMP...)
										.appendTo($('<div style="display:none;" />'));
								}
								else {
									clear();
								}
							}

		,mounted			= function() {
								if((wrapper.parents('body').length === 0)) {
									if($elem.parents('body').length === 0) {
										destroy();
										throw interupteur;
									}
									return false;
								}
								return true;
							}

		,clear				= function() {
								window.clearTimeout(timeout);
								wrapper
									.empty();
							}

		,displayPlayButton	= function() {
								if($this.options('playButtonVisible')) {
									try {
										mount();
										wrapper
											.append(playButton);
									}
									catch(e) {
										if(e !== interupteur) throw e;
									}
								}
								else {
									displayPub();
								}
							}

		,displayPub			= function() {
								var pubObject = false;
								// pub est encapsulé dans un div en display:none pour éviter un bug IE qui lance le Flash, même
								// s'il n'est pas inséré dans le DOM, s'il n'est pas dans un conteneur en display:none.
								pub = $this.pub = pub.add(
									$('<div style="display: none;" />')
										.append(
											!$.browser.msie ?
												$($this.options('pubSelector')).children().not('script').clone() :
												(function() {
													var $pubContainer = $($this.options('pubSelector')),
													html = $pubContainer.html() || '',
													flashvars = $pubContainer
															.find('param')
																.filter(function() {
																	return /^flashvars$/i.test(this.name);
																})
																	.attr('value');

													return html
														.replace(/<script(.|\s)*?\/script>/ig, '')
														.replace(
															/<param( name="flashvars"| value="[^"]*"){2}(\s*\/?>)/ig,
															'<param name="flashvars" value="' + flashvars + '"$2'
														);
												})()
										)
										.find('object')
											.each(function() {
												pubObject = true;
												return false;
											})
										.end()
										.contents()
										.filter(function() {return this.nodeType == 1;})
											.css({position: 'relative', 'z-index': 1})
											.filter(function() {return this.id === 'FinContentMiddle31' && $(this).children().length === 0;})
												.css('display', 'none')
											.end()
											.filter(function() {return pubObject && this.tagName === 'IMG';})
												.css('display', 'none')
											.end()
										.end()
										.add(timeLine)
								);

								if($this.options('pubVisible')) {
									if($this.options('logoVisible')) {
										displayLogo();
									}
									else {
										doDisplayPub();
									}
								}
								else {
									displayElement();
								}
							}

		,displayLogo		= function() {
								try {
									mount();
									wrapper
										.append(logo);
									if($.browser.msie) {
										logo.css($this.options('logoCss'));
									}
									timeout = window.setTimeout(doDisplayPub, $this.options('logoTime') * 1000);
								}
								catch(e) {
									if(e !== interupteur) throw e;
								}
							}

		,doDisplayPub		= function() {
								try {
									mount();
									// On commence par masquer le wrapper, on insère la pub, puis on
									// réaffiche le wrapper. Cela evite quelques erreurs plus ou moins
									// aléatoires sur le lancement des anims Flash (player qui ne charge
									// pas le contenu par exemple)
									wrapper
										.hide()
										.append(pub)
										.show();

									interval = window.setInterval(rebourPub, 1000);
									rebourPub();
								}
								catch(e) {
									if(e !== interupteur) throw e;
								}
							}

		,rebourPub			= function() {
								try {
									if(!mounted()) {
										return;
									}
									else if(--chrono > 0) {
										timeLine.html($this.options('rebourText'));
									}
									else {
										window.clearInterval(interval);
										displayElement();
									}
								}
								catch(e) {
									if(e !== interupteur) throw e;
								}
							}

		,displayElement		= function() {
								clear();
								callbacks('preFinish', doDisplayElement, 1);
								callbacks('preFinish');
							}

		,doDisplayElement	= function() {
								umount();
								callbacks('postFinish', destroy, 1);
								callbacks('postFinish');
							}

		,bypass				= (function() {
								var count = 0;
								return function(e) {
									if(	e.type === 'mousedown'
										|| (e.type === 'dblclick' && !$.browser.msie)
										|| !$(timeLine)
												.add(logo)
												.add(playButton)
												.add(playButton.children())
												.add(wrapper)
												.filter(function() {return this === e.target;})
												.length
											) {
										return false;
									}
									if(++count === 4) {
										displayElement();
									}
									window.setTimeout(function() {count--;}, 450);
									return false;
								};
							})()

		,destroy			= function() {
								window.clearTimeout(timeout);
								window.clearInterval(interval);
								playButton
									.find('.'+$this.options('playButtonClickCls'))
									.unbind();
								logo.unbind();
								wrapper.unbind();
								delete($this.chrono);
								delete($this.logo);
								delete($this.pub);
								delete($this.wrapper);
								delete(playButton);
								delete(logo);
								delete(timeLine);
								delete(pub);
								delete(wrapper);
								delete($elem);
								delete(element);
								delete($this);
							}

		,$this				= this

		,interval, timeout

		,interupteur		= {}

		,callbacks			= window.callbacksManager(this, {
								 preFinish	: this.options.raw('preFinish')
								,postFinish	: this.options.raw('postFinish')
							})

		,chrono				= $this.options('pubTime') + 1

		,playButton			= $('<div />')
								.append($($this.options('playButton')))
								.find('.'+$this.options('playButtonClickCls'))
									.one('click', displayPub)
								.end()
								.contents()

		,logo = this.logo	= $('<img src="'+$this.options('logoUrl')+'" alt="'+$this.options('logoAlt')+'" />')
								.load(function() {
									if($.browser.msie) {
										return;
									}
									$(this)
										.css($this.options('logoCss'));
								})

		,timeLine			= $('<div />')
								.css($this.options('rebourCss'))

		// On initialise l'objet pub avec seulement la timeline. Dans un deuxième temps, au moment
		// de l'affichage de la pub, on récupèrera en plus le contenu de la pub dans cet objet jQuery.
		// On ne récupère pas la pub immédiatement pour éviter des problèmes si la pub n'a pas le
		// temps de se charger complètement (du coup on attend le temps du bouton play avant de récupérer la pub)
		,pub = this.pub		= $([])

		,wrapper = this.wrapper	= $('<div />')
								.css($this.options('wrapperCss'));

		this.chrono = function() {
			return chrono;
		};

		init();
	};

	PreRoll.defaultOptions = {
		minHeight				: 250,
		minWidth				: 300,
		wrapperCss				: function() {
									var width = (this.options('width') || 0),
									height = (this.options('height') || 0),
									minSize;

									if(this.options('pubVisible')) {
										minSize = this.options(['minHeight', 'minWidth']);
										width = (width < minSize.minWidth) ? minSize.minWidth : width;
										height = (height < minSize.minHeight) ? minSize.minHeight : height;
									}

									this.options('height', height);
									this.options('width', width);

									return {
										display			: 'block',
										position		: 'relative',
										width			: width + 'px',
										height			: (250 + ((height - 250) / 2)) + 'px',
										'padding-top'	: ((height - 250) / 2) + 'px',
										background		: 'black',
										overflow		: 'hidden',
										'text-align'	: 'center',
										color			: 'white'
									};
								},
		playButtonVisible		: true,
		playButtonClickCls		: 'preRollPlay',
		playButton				: function() {
									return $([])
										.add(this.options('playButtonBg') || $([]))
										.add(this.options('playButtonMasqueBg') || $([]))
										.add(this.options('playButtonFg') || $([]))
										.add(this.options('playButtonMasqueFg') || $([]));
								},
		playButtonBg			: function() {
									return $(this.options('playButtonBgObject'))
										.css(this.options('playButtonBgCss'));
								},
		playButtonBgObject		: function() {
									return $('<img src="'+this.options('playButtonBgSrc')+'" />')
										.mediaObject({quiet:true});
								},
		playButtonBgSrc		: '/layoutftv/arches/common/images/video/playButtonBg.swf',
		playButtonBgCss		: {
									position		: 'absolute',
									top				: 0,
									left			: 0,
									height			: '100%',
									width			: '100%'
								},
		playButtonMasqueBgVisible	: function() {
									return this.options.raw('playButtonBgSrc') !== PreRoll.defaultOptions.playButtonBgSrc
										|| this.options.raw('playButtonBgObject') !== PreRoll.defaultOptions.playButtonBgObject;
								},
		playButtonMasqueBg		: function() {
									if(!this.options('playButtonMasqueBgVisible'))
										return;
									return $('<div />')
											.css(this.options('playButtonMasqueBgCss'));
								},
		playButtonMasqueBgCss	: {
									 position	: 'absolute'
									,'z-index'	: '1'
									,top		: '0'
									,left		: '0'
									,width		: '100%'
									,height		: '100%'
									,background	: 'black'
									,opacity	: '0.2'
								},
		playButtonFg			: (function() {
									var obj = {};
									return function() {
										if(obj[this.uid] === undef) {
											// Le texte alternatif devrait être tiré du label du lien d'origine, plutot que d'être fixe.
											obj[this.uid] = $('<img src="'+this.options('playButtonFgSrc')+'" alt="Cliquez pour voir la vidéo" />')
												.mediaObject({quiet:true})
												.css(this.options('playButtonFgCss'));
										}
										return obj[this.uid];
									};
								})(),
		playButtonFgSrc		: '/layoutftv/arches/common/images/video/playButton.swf',
		playButtonFgCss		: {
									 position		: 'absolute'
									,'z-index'		: '2'
									,top			: '50%'
									,left			: '50%'
									,'margin-top'	: '-40px'
									,'margin-left'	: '-90px'
									,height			: '80px'
									,width			: '180px'
								}
		,playButtonMasqueFg		: function() {
									var $object = this.options('playButtonFg').get(0);
									return $('<div class="'+this.options('playButtonClickCls')+'" />')
											.css(this.options('playButtonMasqueFgCss'))
											.bind('mouseover', function() {
												if(typeof $object.mouseover === 'function') {
													$object.mouseover();
												}
											});
								}
		,playButtonMasqueFgCss	: {
									 position	: 'absolute'
									,'z-index'	: '3'
									,top		: '0'
									,left		: '0'
									,width		: '100%'
									,height		: '100%'
									,background	: 'black'
									,opacity	: '0'
									,cursor		: 'pointer'
								}

		,logoVisible			: true
		,logoTime				: 2
		,logoUrl				: function() { return '/layoutftv/arches/common/images/video/ecran-'+this.options('portail')+'.jpg';}
		,logoAlt				: function() { return 'Publicité '+this.options('portail');}
		,logoCss				: {
									position			: 'absolute',
									top					: function() {
															return (this.options('height') - this.logo.get(0).height) / 2;
														},
									left				: function() {
															return (this.options('width') - this.logo.get(0).width) / 2;
														}
								}

		,pubVisible				: function() {
									var visible = (
										(window.forceactivepub === true) ||
										(
											window.activepub === true &&
											($(this.options('pubSelector')).children().not('script').length > 0)
										)
									);
									this.options('pubVisible', visible);
									return visible;
								}
		,pubSelector			: '#adMiddle03,#eGetPubMiddle3'
		,pubTime				: function() {return (typeof timepub === 'number') ? timepub : 5;}

		,rebourCss				: {
									position		: 'absolute',
									'z-index'		: 2,
									bottom			: '2px',
									left			: '0',
									width			: '100%',
									'font-weight'	: 'bold',
									'line-height'	: '1em',
									cursor			: 'default'
								}
		,rebourText				: function() {
									return this.chrono() + ' seconde' + (this.chrono() > 1 ? 's':'') + ' avant votre vidéo';
								}

		,portail				: typeof ftvi_portail == 'string' ? ftvi_portail : 'france2'
		,preFinish				: undef
		,postFinish				: undef
	};

	$.fn.preRoll = function(options) {
		var $this = this;
		options = window.dynamicOptionsManager.call(this, options);
		this.each(function() {

			if($(this).is('a') && !options.defined('playButtonBgSrc') && !options.defined('playButtonBgObject')) {
				if($(this).children('object').length) {
					options('playButtonBgObject', $(this).children('object'));
				}
				else if($(this).children('img').length) {
					options('playButtonBgSrc', $(this).children('img').attr('src'));
				}
			}

			var obj = new PreRoll(this, options);
			$this = $this.add(obj.wrapper || []);
		});
		return $this;
	};
})(this, this.jQuery);
(function(window, $, undef) {
	(function(dep) {
		for(var i in dep) {
			if(!dep[i]) {
				throw 'Dépendence non satisfaite : '+i;
			}
		}
	})({
		dynamicOptionsManager	: !!window.dynamicOptionsManager,
		jQuery					: !!$,
		'jQuery.mediaObject'	: !!($ && $.fn && $.fn.mediaObject),
		'jQuery.preRoll'		: !!($ && $.fn && $.fn.preRoll),
		'jQuery.mediaObjectPreRoll already exists' :  !!($ && $.fn && !$.fn.mediaObjectPreRoll)
	});

	var playPreRoll = function() {
		var options = window.dynamicOptionsManager(),
		result = this.result,
		$localisor = $('<span/>');

		this.result = $localisor;

		// On récupère les dimensions de l'object généré pour le préroll
		options(this.resultOptions(['width', 'height']));

		// On récupère les options pour le préroll sorties du builder. Cela laisse la possibilité au builder de manipuler
		// les options de preRoll, ce qui peut être intéressant dans le cas de builders specifiques.
		options(this.resultOptions.raw('preRollOptions'));

		options('postFinish', [function() {
			$localisor
				.after(result)
				.remove();
		}, options.raw('postFinish')]);

		this.callbacks('finish', function() {
			this.result
				.preRoll(options);
		});
	};

	$.fn.mediaObjectPreRoll = function(options) {
		var $selection = $([]);
		options = window.dynamicOptionsManager(options);
		options('callbacks', 'success', [options.raw('callbacks', 'success'), playPreRoll]);

		this.each(function() {
			var opt = window.dynamicOptionsManager(options),
			$elem = $(this);

			if($elem.is('a') && !opt.defined('preRollOptions', 'playButtonBgSrc') && !opt.defined('preRollOptions', 'playButtonBgObject')) {
				if($elem.children('object').length) {
					opt('preRollOptions', 'playButtonBgObject', $elem.children('object'));
				}
				else if($elem.children('img').length) {
					opt('preRollOptions', 'playButtonBgSrc', $elem.children('img').attr('src'));
				}
			}

			if(!opt.defined('autostart')) {
				opt('autostart', true);
			}

			$selection = $selection.add($elem.mediaObject(opt));
		});
		return $selection;
	};
})(this, this.jQuery);