//#17.0.1.0 WDUtil.js
//VersionVI: 30F170078n
// Le seul support technique disponible pour cette librairie est
// accessible a travers le service "Assistance Directe".

// Attention a ne pas mettre d'accent dans ce fichier COMMENTAIRES inclus

// Utilisation d'un objet comme espace de nommage
var clWDUtil = {};

clWDUtil.bTestNav = function bTestNav(sTest)
{
	return (-1 != navigator.userAgent.toLowerCase().indexOf(sTest));
};

// Detection du navigateur

var bOpr = clWDUtil.bTestNav("opera");
// Cas particulier de Opera qui s'annonce par defaut comme IE
var bIE = (!bOpr) && (-1 != navigator.appName.indexOf("Microsoft"));
var nIE = 0;
var bIEQuirks = false;
var oRes;
// On fait un cas particulier pour IE7
if (bIE)
{
	oRes = (new RegExp("MSIE (\\d)+[\\.\\d]*")).exec(navigator.userAgent);
	if (oRes && oRes[1])
	{
		nIE = parseInt(oRes[1], 10);
	}
	oRes = null;
	// Detecte le "quirks mode"
	bIEQuirks = (document.compatMode == "BackCompat");
}
// Detection de gecko pour avoir les autres browser ?
var bFF = clWDUtil.bTestNav("firefox/");
if (bFF)
{
	oRes = (new RegExp("Fire[Ff]ox/\\s*(\\d+)\\.*(\\d+)")).exec(navigator.userAgent);
	var bFF35 = (oRes && oRes[1] && (((parseInt(oRes[1], 10) >= 3) && oRes[2] && (parseInt(oRes[2], 10) >= 5)) || (parseInt(oRes[1], 10) >= 4)));
	oRes = null;
}
// Il faut chercher "chrome/" car sinon on trougve des faux positif (par exemple "chromeframe/")
var bCrm = clWDUtil.bTestNav("chrome/");
var bSfr = (!bCrm) && clWDUtil.bTestNav("safari");
var bMac = clWDUtil.bTestNav("Mac");
var bWK = bCrm || bSfr;
var bTouch = clWDUtil.bTestNav("ipad") || clWDUtil.bTestNav("iphone") || clWDUtil.bTestNav("android");

// Manipulation des Cookies : utilisation d'un objet comme espace de nommage
var clWDCookie = {
	ms_sSeparateurCookie: ";",
	ms_sSeparateurValeur: "="
};

// Recupere le cookie
clWDCookie.GetCookie = function GetCookie(sNom, tabSuffixe)
{
	var sNom = clWDUtil.sSupprimeEspacesDebutFin(sNom);
	var tabCookies = document.cookie.split(this.ms_sSeparateurCookie);
	var i;
	var nLimiteI = tabCookies.length;
	for (i = 0; i < nLimiteI; i++)
	{
		var tabCookie = tabCookies[i].split(this.ms_sSeparateurValeur);
		tabCookie[0] = clWDUtil.sSupprimeEspacesDebutFin(tabCookie[0]);
		var sNomCookie = tabCookie[0];
		if (tabSuffixe)
		{
			sNomCookie = sNomCookie.substr(0, sNom.length);
		}
		if (tabCookie[1] && (sNomCookie == sNom))
		{
			if (tabSuffixe)
			{
				tabSuffixe[0] = tabCookie[0].substr(sNom.length);
			}
			return unescape(tabCookie[1]);
		}
	}
	return "";
};

// Ecrit un cookie
clWDCookie.SetCookie = function SetCookie(sNom, sValeur)
{
	var sExp = "Mon, 31 Dec 2010 23:59:59 UTC";
	// Si on est dans le futur (Apres 2009) : On met une autre date
	if (parseInt((new Date()).getFullYear(), 10) >= 2009)
	{
		sExp = new Date((new Date()).getTime() + 30 * 24 * 3600 * 1000).toGMTString();
	}
	this.__SetCookie(sNom, sValeur, sExp);
};

// Supprime un cookie
clWDCookie.ClearCookie = function ClearCookie(sNom)
{
	this.__SetCookie(sNom, "", "Fri, 02 Jan 1970 00:00:00 UTC");
};

// Ecrit un cookie, version interne
clWDCookie.__SetCookie = function __SetCookie(sNom, sValeur, sExp)
{
	document.cookie = sNom + this.ms_sSeparateurValeur + escape(sValeur) + "; expires=" + sExp + "; path=/;";
};

// Un timeout de 1ms est trop faible pour Chrome
// Il faut une valeur vraiment importante pour les versions recente de Chrome (il y a alors quand meme un leger lag visuel) et aussi pour safari
clWDUtil.nTimeoutImmediat = (bWK) ? 200 : 1;

// Numero du bouton gauche de la souris
clWDUtil.nBoutonGauche = ((bIEQuirks || (bIE && (document.documentMode < 9))) ? 1 : 0);
clWDUtil.bValideBouton = function bValideBouton(oEvent)
{
	return (!bTouch && (oEvent.button == clWDUtil.nBoutonGauche)) || (bTouch && (1 >= oEvent.touches.length));
};

// Manipule les tag en forme normalise (normalement inutile sur les navigateurs recents)
clWDUtil.sGetTagName = function sGetTagName(oBalise)
{
	return (oBalise.tagName ? oBalise.tagName.toLowerCase() : "");
};
// Indique si la balise est du bon type
clWDUtil.bBaliseEstTag = function bBaliseEstTag(oBalise, sTag)
{
	return (this.sGetTagName(oBalise) == sTag);
};

// Sens de lecture
clWDUtil.bRTL = ((bIE ? document : document.documentElement).dir == "rtl");
clWDUtil.GetStyleLeft = function GetStyleLeft(oStyle)
{
	return (this.bRTL ? oStyle.right : oStyle.left);
};
clWDUtil.SetStyleLeft = function SetStyleLeft(oStyle, nVal, nOffset)
{
	if (this.bRTL)
	{
		oStyle.right = (nVal - nOffset) + "px";
	}
	else
	{
		oStyle.left = (nVal + nOffset) + "px";
	}
};

// Fonction
if (bIE)
{
	clWDUtil.oGetOriginalTarget = function oGetOriginalTarget(oEvent) { return oEvent.srcElement; };
}
else if (bFF && !bWK)
{
	clWDUtil.oGetOriginalTarget = function oGetOriginalTarget(oEvent) { return oEvent.explicitOriginalTarget; };
}
else
{
	clWDUtil.oGetOriginalTarget = function oGetOriginalTarget(oEvent) { return oEvent.target; };
}

if (bIE && ((nIE < 8) || bIEQuirks))
{
	clWDUtil.sGetDisplayBlock = function _sGetDisplayBlock(oBalise)
	{
		return "block";
	};
}
else
{
	clWDUtil.sGetDisplayBlock = function _sGetDisplayBlock(oBalise)
	{
		switch (this.sGetTagName(oBalise))
		{
		case "table": return "table";
		case "tr": return "table-row";
		case "td": return "table-cell";
		default: return "block";
		}
	};
}

clWDUtil.sGetDisplayPourAffiche = function sGetDisplayPourAffiche(oBalise, bAffiche)
{
	return (bAffiche ? this.sGetDisplayBlock(oBalise) : "none");
};

clWDUtil.SetDisplay = function SetDisplay(oBalise, bAffiche)
{
	if (oBalise && oBalise.style)
	{
		oBalise.style.display = this.sGetDisplayPourAffiche(oBalise, bAffiche);
	}
};

clWDUtil.bEstDisplay = function bEstDisplay(oElement, oDocument, bTestHidden)
{
	var oBody = oDocument.body;
	while (oElement && (oElement != oBody))
	{
		var oCurrentStyle = _JGCS(oElement);
		if ((oCurrentStyle.display == "none") || (bTestHidden && (oCurrentStyle.visibility == "hidden")))
		{
			return false;
		}
		oElement = oElement.parentNode;
	}
	return true;
};

if (bOpr)
{
	// Contournement pour createContextualFragment avec opera (perd les attributs de la racine dans certains cas)
	// Ne marche que s'il n'y a qu'un fils
	clWDUtil.oCreateContextualFragment = function oCreateContextualFragment(oRange, sHTML)
	{
		var oDiv = document.createElement('div');
		oDiv.innerHTML = sHTML;
		var oFils = oDiv.firstChild;
		while (oFils && (oFils.nodeName == "#text"))
		{
			oFils = oFils.nextSibling;
		}
		return oFils;
	};
}
else if (!bIE)
{
	clWDUtil.oCreateContextualFragment = function oCreateContextualFragment(oRange, sHTML) { return oRange.createContextualFragment(sHTML); };
}
if (!bIE)
{
	clWDUtil.oCreateContextualFragmentSelonElement = function oCreateContextualFragmentSelonElement(oElement, sHTML)
	{
		// Pour les autres navigateur
		var oRange = document.createRange(); // Pas disponible pour IE donc pas d'unification possible
		oRange.setStartBefore(oElement);
		return this.oCreateContextualFragment(oRange, sHTML);
	};
}

// Recupere le HTML dans un commentaire HTML
clWDUtil.sGetHTMLDansCommentaire = function sGetHTMLDansCommentaire(oConteneur)
{
	var tabHTML = [];

	// Et lit la valeur de la balise commentaire
	var i;
	var nLimiteI = oConteneur.childNodes.length;
	var oTBody;
	for (i = 0; i < nLimiteI; i++)
	{
		var oFils = oConteneur.childNodes[i];
		// Si c'est la balise commentaire
		if (oFils.nodeName == "#comment")
		{
			tabHTML.push(oFils.nodeValue);
		}
		else if (oFils.nodeName == "!")
		{
			// Cas special pour IE5.5
			var sValeur = oFils.text + "";
			// Supprime le <!-- initial et le --> final
			tabHTML.push(sValeur.substr(4, sValeur.length - 7));
		}
		else if (this.bBaliseEstTag(oFils, "tbody"))
		{
			oTBody = oFils;
		}
	}

	// Si on est dans une balise table, pour etre W3C, il y a un <tr><td></td></tr> + commentaire
	// Certains navigateur ajoutent le tbody et place le commentaires dans le tbody
	if ((tabHTML.length == 0) && oTBody)
	{
		return this.sGetHTMLDansCommentaire(oTBody);
	}
	else
	{
		// Remplace maintenant les commentaires
		var sHTML = tabHTML.join("");
		return sHTML.replace(/\[%COMMENT%\]/g, "<!-- -->");
	}
};

// Supprime les espaces d'une chaine
clWDUtil.ms_oRegExpEspaces = new RegExp("\\s", "g");
clWDUtil.sSupprimeEspaces = function sSupprimeEspaces(sValeur)
{
	return sValeur.replace(this.ms_oRegExpEspaces, "");
};
// Supprime les espaces en debut et en fin
clWDUtil.ms_oRegExpEspacesDebutFin = new RegExp("[\\s\\r\\n\\b]*([^\\s\\r\\n\\b]*([\\s\\r\\n\\b]*[^\\s\\r\\n\\b]+)*)[\\s\\r\\n\\b]*", ""),
clWDUtil.sSupprimeEspacesDebutFin = function sSupprimeEspacesDebutFin(sValeur)
{
	return sValeur.replace(this.ms_oRegExpEspacesDebutFin, "$1");
};

// Ajoute au debut d'une URI
// sPrefixe est generalement le repertoire _WEB
clWDUtil.sCompleteURI = function sCompleteURI(sPrefixe, sURI)
{
	if ((sURI.substr(0, 5) == "http:") || (sURI.substr(0, 6) == "https:") || (sURI.substr(0, sPrefixe.length) == sPrefixe))
	{
		return sURI;
	}
	else
	{
		return sPrefixe + sURI;
	}
};

clWDUtil.m_pfVide = function() { return true; };

// Recupere tous les elements formulaire d'une cellule
clWDUtil.tabGetElements = function tabGetElements(oCellule, bAvecLien)
{
	var tabElements = [];

	if (oCellule)
	{
		// Ajoute dans le tableau les 4 types de champ formulaire
		// La valeur retournee par getElementsByTagName n'est pas un tableau donc :
		// tabElements = tabElements.concat(oCellule.getElementsByTagName("xxx")); ne fonctionne pas

		tabElements = this._tabGetUnTypeElement(oCellule, "button", tabElements);
		tabElements = this._tabGetUnTypeElement(oCellule, "input", tabElements);
		tabElements = this._tabGetUnTypeElement(oCellule, "select", tabElements);
		tabElements = this._tabGetUnTypeElement(oCellule, "textarea", tabElements);
		if (bAvecLien)
		{
			tabElements = this._tabGetUnTypeElement(oCellule, "a", tabElements);
		}
	}

	return tabElements;
};

// Fusionne le retour de getElementsByTagName avec un tableau
clWDUtil._tabGetUnTypeElement = function _tabGetUnTypeElement(oCellule, sTag, tabElements)
{
	// Trouve les elements
	var tabElementsByTagName = oCellule.getElementsByTagName(sTag);
	// Fusionne les tableaux
	var i;
	var nLimiteI = tabElementsByTagName.length;
	for (i = 0; i < nLimiteI; i++)
	{
		tabElements.push(tabElementsByTagName[i]);
	}
	// Et retourne le tableau resultat
	return tabElements;
};

// Indique si on a clique sur le fond d'un element (= ignore les champs formulaires)
clWDUtil.bClickDansFond = function bClickDansFond(oEvent, oFond)
{
	// Recupere la liste des elements exclus
	var tabElementsExclus = this.tabGetElements(oFond, true);

	// Remonte la liste des elements depuis la partie clique
	var oElement = this.oGetOriginalTarget(oEvent);
	while (oElement && oElement != oFond)
	{
		// Si l'element est dans la liste : on ne clique pas sur le fond
		if (this.bDansTableau(tabElementsExclus, oElement))
		{
			return false;
		}
		oElement = oElement.parentNode;
	}
	return true;
};

// Indique si un element est dans un tableau
clWDUtil.bDansTableau = function bDansTableau(tabTableau, oElement)
{
	return (-1 != this.nDansTableau(tabTableau, oElement));
};
// Indique la position d'un element dans un tableau
clWDUtil.nElementInconnu = -1;
clWDUtil.nEgalite = function nEgalite(oElement1, oElement2)
{
	return (oElement1 == oElement2);
}
clWDUtil.nDansTableau = function nDansTableau(tabTableau, oElement)
{
	return this.nDansTableauFct(tabTableau, this.nEgalite, oElement);
};
clWDUtil.nDansTableauFct = function nDansTableauFct(tabTableau, fComparaison, oParametre)
{
	var i;
	var nLimiteI = tabTableau.length;
	for (i = 0; i < nLimiteI; i++)
	{
		if (fComparaison(tabTableau[i], oParametre))
		{
			return i;
		}
	}
	return this.nElementInconnu;
};
// Supprime un element dans le tableai
clWDUtil.SupprimeDansTableau = function SupprimeDansTableau(tabTableau, oElement)
{
	return this.SupprimeDansTableauFct(tabTableau, this.nEgalite, oElement);
};
clWDUtil.SupprimeDansTableauFct = function SupprimeDansTableauFct(tabTableau, fComparaison, oParametre)
{
	var nElement = this.nDansTableauFct(tabTableau, fComparaison, oParametre);
	if (-1 != nElement)
	{
		tabTableau[nElement] = null;
		tabTableau.splice(nElement, 1);
	}
};
// Stop la propagation des evenements
// Gere le cas de l'event sous IE
clWDUtil.bStopPropagation = function bStopPropagation(oEvent)
{
	return clWDUtil.bStopPropagationCond(oEvent, true);
};

// Stoppe conditionnelement la propagation
// Gere le cas de l'event sous IE
clWDUtil.bStopPropagationCond = function bStopPropagationCond(oEvent, bStop)
{
	if (bStop)
	{
		oEvent = oEvent || event;
		if (bIE)
		{
			oEvent.returnValue = false;
		}
		else if (oEvent.preventDefault)
		{
			oEvent.preventDefault();
		}
		return false;
	}
	else
	{
		return true;
	}
};

clWDUtil.AttacheDetacheEvent = function AttacheDetacheEvent(bAttache, oCible, sEvent, fFonction, bCapture)
{
	(bAttache ? HookOnXXX : UnhookOnXXX)(oCible, "on" + sEvent, sEvent, fFonction, bCapture);
};

// Attache une fonction a un evenement
function HookOnXXX (oCible, sEventIE, sEventFF, fFonction, bCapture)
{
	if (oCible.addEventListener)
	{
		oCible.addEventListener(sEventFF, fFonction, bCapture ? true : false);
	}
	else if (oCible.attachEvent)
	{
		oCible.attachEvent(sEventIE, fFonction);
	}
	else
	{
		// Cas d'un objet sorti du DOM dans opera : ne fait rien
	}
}

// Detache une fonction d'un evenement
function UnhookOnXXX(oCible, sEventIE, sEventFF, fFonction, bCapture)
{
	if (oCible.removeEventListener)
	{
		oCible.removeEventListener(sEventFF, fFonction, bCapture ? true : false);
	}
	else if (oCible.detachEvent)
	{
		oCible.detachEvent(sEventIE, fFonction);
	}
	else
	{
		// Cas d'un objet sorti du DOM dans opera : ne fait rien
	}
}

// Fixe directement le onxxx de l'element
clWDUtil.SetOnXxx = function SetOnXxx(oElement, sOnXxx, oThis, fFonction, tabParametres, bAppelAvantAutre)
{
	var fAutre = oElement[sOnXxx];
	// On ne se rehook pas
	if (fAutre && (fAutre.toString().match(/^function\s+SetOnCB/) != null))
	{
		return;
	}
	// Il est possible de recevoir null ici comme evenement (appel manuel de la fonction)
	var fAutreAvant = !bAppelAvantAutre ? fAutre : null;
	var fAutreApres = bAppelAvantAutre ? fAutre : null;
	oElement[sOnXxx] = function SetOnCB(oEvent)
	{
		oEvent = oEvent || (bIE ? event : null);
		if (fAutreAvant)
		{
			fAutreAvant.apply(oElement, [oEvent]);
		}
		fFonction.apply(oThis, [oEvent, tabParametres]);
		if (fAutreApres)
		{
			fAutreApres.apply(oElement, [oEvent]);
		}
	};
};

// Indique si un element est fils d'un autre
function bEstFils (oElement, oParent, oDocument)
{
	var oBody = oDocument.body;
	while (oElement && (oElement != oBody))
	{
		if (oElement == oParent)
		{
			return true;
		}
		oElement = oElement.parentNode;
	}
	return false;
}

// Supprime un fils de son parent
clWDUtil.oSupprimeElement = function oSupprimeElement(oElement)
{
	// Si l'element existe et est dans le document
	if (oElement && (oElement.parentNode))
	{
		return oElement.parentNode.removeChild(oElement);
	}
	else
	{
		return oElement;
	}
};

// Supprime tous les fils d'un elements et detache les fonctions JS de focus/modification
clWDUtil.SupprimeFilsEtOnFocus = function SupprimeFilsEtOnFocus(oParent, bAvecLien)
{
	// Supprime les elements JavaScript pour les reference circulaires entre le DOM et le JS
	var tabElements = this.tabGetElements(oParent, bAvecLien);
	var i;
	var nLimiteI = tabElements.length;
	for (i = 0; i < nLimiteI; i++)
	{
		// Gestion des anciennes fonctions : non on supprime l'element
		var oElement = tabElements[i];
		oElement.onchange = null;
		oElement.onblur = null;
		oElement.onfocus = null;
	}
	SupprimeFils(oParent);
};

// Supprime tous les fils d'un elements
function SupprimeFils(oParent)
{
	var tabChildNodes = oParent.childNodes;
	while (tabChildNodes.length > 0)
	{
		oParent.removeChild(tabChildNodes[0]);
	}
}

// Donne le focus a un champ (fonctionne avec tous les navigateurs)
clWDUtil._DonneFocus = function _DonneFocus(oChamp)
{
	clWDUtil.DonneFocus = clWDUtil.m_pfVide;
	var oChampLocal = oChamp;
	setTimeout(function() { oChampLocal.focus(); setTimeout(function() { clWDUtil.DonneFocus = clWDUtil._DonneFocus }, 1); }, 1);
};
clWDUtil.DonneFocus = clWDUtil._DonneFocus;

// Supprime une variable du HTML si elle existe
// Retourne si la variable existait
clWDUtil.bHTMLVideDepuisVariable = function bHTMLVideDepuisVariable(oObjet, sNomVariable)
{
	if (oObjet[sNomVariable])
	{
		// Si la variable existe, la supprime du HTML et de l'objet
		this.oSupprimeElement(oObjet[sNomVariable]);
		oObjet[sNomVariable] = null;
		delete oObjet[sNomVariable];
		return true;
	}
	else
	{
		// Supprime par securite (variable existante mais vide)
		delete oObjet[sNomVariable];
		return false;
	}
};

// Construit les parametres d'une fonction serveur appelee
// nNbParamIgnore contient le nombre de parametres a ignorer dans tabParamOriginaux
clWDUtil.sConstuitProcedureParams = function sConstuitProcedureParams(nNbParamIgnore, tabParamsOriginaux)
{
	var i;
	var nLimiteI = tabParamsOriginaux.length;
	// + Car on laisse le premier indice vide donc comme ca on a automatiquement le "&" initial
	var tabParams = new Array(nLimiteI - nNbParamIgnore + 1);
	tabParams[0] = "";
	for (i = nNbParamIgnore; i < nLimiteI; i++)
	{
		var nIndiceReel = i - nNbParamIgnore + 1;
		// Si l'arguement est un booleen alors on envoi 0/1 pour faux/vrai
		// Car le cast en chaine du false/true du JS donne "false"/"true", ce que le serveur ne sait pas bien convertir en boolen
		var oParam = tabParamsOriginaux[i];
		tabParams[nIndiceReel] = "PA" + (i - nNbParamIgnore + 1) + "=" + ((oParam === true) ? "1" : ((oParam === false) ? "0" : clWDEncode.sEncodePOST(oParam + "")));
	}
	return tabParams.join("&");
};

// Recupere l'action depuis le location
clWDUtil._sGetPageActionDepuisLocation = function _sGetPageActionDepuisLocation(sAction)
{
	// On prend l'URL si on n'a pas d'action
	sAction = location.href + sAction;
	// On vire l'ancre
	var nAncreTaille = location.hash.length;
	if (nAncreTaille > 0)
	{
		var nAncrePos = sAction.indexOf(location.hash);
		sAction = sAction.substr(0, nAncrePos) + sAction.substr(nAncrePos + nAncreTaille);
	}
	return sAction;
};

// Recupere l'action d'une page
// oPage : formulaire a utiliser (null possible)
// bParamSuppr : indique s'il faut supprimer les parametres de l'URL
// bIDSession : Indique s'il faut ajouter l'ID de session
// bPourRepRes : Indique que la reference est avec le repertoire res et qu'il faut eviter les chemin relatifs
clWDUtil.sGetPageAction = function sGetPageAction(oPage, bParamSuppr, bIDSession, bPourRepRes)
{
	// Trouve la page si besoin
	if (!oPage)
	{
		oPage = _PAGE_;
	}

	// Calcule l'URL
	var sAction = (oPage.action.length > 0) ? oPage.action : "";
	if ((sAction.length == 0) || (sAction.charAt(0) == "?"))
	{
		// Si l'action se retourve deja dans l'URL de la page, on ne la double pas
		if (-1 != location.href.indexOf(sAction))
		{
			sAction = this._sGetPageActionDepuisLocation("");
		}
		else
		{
			sAction = this._sGetPageActionDepuisLocation(sAction);
		}
	}
	// Implicitement on a sAction > 0 (teste dans le premier if)
	else if ((nIE >= 8) && !bIEQuirks)
	{
		// En mode non quirks, IE retourne une addresse absolue pour FORM.action
		// Sauf que dans une page AWP l'action est vide. IE complete quand meme et retourne donc le chemin de la page
		// Evidement ce n'est pas une action valide au final
		var sActionAttribut = _PAGE_.getAttributeNode("action").value;
		if ((0 == sActionAttribut.length) || ("?" == sActionAttribut.charAt(0)))
		{
			sAction = this._sGetPageActionDepuisLocation(sActionAttribut);
		}
	}

	// Implicitement (sAction.length > 0) exclus le cas AWP. Il faut aussi exlcure le cas .php
	if (bPourRepRes && (sAction.indexOf("/") == -1) && (sAction.length > 0) && (sAction.toLowerCase().indexOf(".php") == -1))
	{
		sAction = "../" + sAction;
	}

	// Vire les parametres
	if (bParamSuppr && (sAction.indexOf("?") != -1))
	{
		sAction = sAction.substr(0, sAction.indexOf("?"));
	}

	// Ajoute l'ID de session si besoin
	if (bIDSession)
	{
		if ((sAction.indexOf("AWPID=") == -1) && (window["_AWPID_A_"] !== undefined))
		{
			// Ajoute le separateur et la session
			var sID = (sAction.indexOf("?") != -1) ? _AWPID_A_ : _AWPID_P_;
			// Et s'il est vide prend le cookie de session s'il existe :
			// Firefox et chrome qui en donnent pas leurs cookies au plugins (= Flash)
			if ((bFF || bWK) && (sID.length == 0))
			{
				var tabSuffixe = [];
				sID = clWDCookie.GetCookie("AWP_CSESSION", tabSuffixe);
				if (sID.length > 0)
				{
					sID = ((sAction.indexOf("?") != -1) ? "&" : "?") + "AWPID" + tabSuffixe[0] + "=" + sID;
				}
			}
			sAction += sID;
		}
		else if (window["_PHPID_"] !== undefined)
		{
			var tabPHPID = _PHPID_.split("=");
			if ((tabPHPID.length > 0) && (sAction.indexOf(tabPHPID[0] + "=") == -1))
			{
				// Ajoute le separateur et la session
				sAction += ((sAction.indexOf("?") != -1) ? "&" : "?") + _PHPID_;
			}
		}
	}
	// Renvoie la valeur
	return sAction;
};

// Ajoute une regle CSS
clWDUtil.CreeStyle = function CreeStyle(oFeuilleStyle, sNomStyle, sTexteStyle)
{
	// Ne cree pas un style vide
	if (sTexteStyle.length)
	{
		// Ajoute un style dans la feuille de style donnee
		if (oFeuilleStyle.addRule)
		{
			oFeuilleStyle.addRule(sNomStyle, sTexteStyle);
		}
		else
		{
			oFeuilleStyle.insertRule(sNomStyle + " {" + sTexteStyle + "}", oFeuilleStyle.cssRules.length);
		}
	}
};

// Creation d'une feuille de style
clWDUtil.oCreeFeuilleStyle = function oCreeFeuilleStyle()
{
	// Creation de la feuille de style
	var oStyle = document.getElementsByTagName("head")[0].appendChild(document.createElement("style"));
	if (bWK)
	{
		oStyle.appendChild(document.createTextNode(""));
	}
	return (oStyle.styleSheet ? oStyle.styleSheet : oStyle.sheet);
};

// Recupere le CSS d'une regle de style (recherche globale)
clWDUtil.sGetCSSTexte = function sGetCSSTexte(sSelecteur)
{
	return this.sGetCSSTexteElement(this.oStyleTrouve(sSelecteur));
};

// Recupere le style sous forme de texte avec un ; terminal si le style est non vide
clWDUtil.sGetCSSTexteElement = function sGetCSSTexteElement(oElement)
{
	// Uniquement si le style existe
	if (oElement && oElement.style)
	{
		var sCSSTexte = oElement.style.cssText;
		if (sCSSTexte)
		{
			// Ajoute le ";" si besoin
			if ((sCSSTexte.length > 0) && (sCSSTexte.substring(sCSSTexte.length - 1) != ";"))
			{
				sCSSTexte += ";";
			}
			return sCSSTexte;
		}
	}
	return "";
};

// Recupere une regle de style (recherche globale)
clWDUtil.oStyleTrouve = function oStyleTrouve(sSelecteur)
{
	// On recherche le style a la racine
	var tabStyles = document.getElementsByTagName("style");
	var i;
	var nLimiteI = tabStyles.length;
	var oRule;
	for (i = 0; i < nLimiteI; i++)
	{
		oRule = this.oStyleTrouveDansBalise(tabStyles[i], sSelecteur);
		if (oRule)
		{
			return oRule;
		}
	}

	// On recherche les styles dans les feuilles de style externes
	tabStyles = document.getElementsByTagName("link");
	nLimiteI = tabStyles.length;
	for (i = 0; i < nLimiteI; i++)
	{
		// Unique les feuilles de style
		if (tabStyles[i].rel.toLowerCase() == "stylesheet")
		{
			oRule = this.oStyleTrouveDansBalise(tabStyles[i], sSelecteur);
			if (oRule)
			{
				return oRule;
			}
		}
	}
	return null;
};


// Recherche un style dans la feuille de style
clWDUtil.oStyleTrouveDansBalise = function oStyleTrouveDansBalise(oFeuille, sSelecteur)
{
	// Selon les navigateur et la recherche est toujours complexe
	return this.oStyleTrouveDansFeuille(oFeuille.styleSheet ? oFeuille.styleSheet : oFeuille.sheet, sSelecteur, false);
};
clWDUtil.oStyleTrouveDansFeuille = function oStyleTrouveDansFeuille(oFeuilleStyle, sSelecteur, bSimple)
{
	return this.oStyleTrouveDansRules(bIE ? oFeuilleStyle.rules : oFeuilleStyle.cssRules, sSelecteur, bSimple);
};
clWDUtil.oStyleTrouveDansRules = function oStyleTrouveDansRules(tabRules, sSelecteur, bSimple)
{
	var nIndice = this.nStyleTrouveDansRules(tabRules, sSelecteur, bSimple);
	return ((-1 != nIndice) ? tabRules[nIndice] : null);
};

// Recherche l'indice d'un style dans la feuille de style
clWDUtil.nStyleTrouve = function nStyleTrouve(oFeuilleStyle, sSelecteur, bSimple)
{
	return this.nStyleTrouveDansRules(bIE ? oFeuilleStyle.rules : oFeuilleStyle.cssRules, sSelecteur, bSimple);
};
clWDUtil.nStyleTrouveDansRules = function nStyleTrouveDansRules(tabRules, sSelecteur, bSimple)
{
	return ((bSimple || bIE) ? this.__nStyleTrouveDansRulesSimple : this.__nStyleTrouveDansRulesComplexe).apply(this, [tabRules, sSelecteur]);
};
clWDUtil.__nStyleTrouveDansRulesSimple = function __nStyleTrouveDansRulesSimple(tabRules, sSelecteur)
{
	return this.nDansTableauFct(tabRules, function(oRule, sSelecteur) { return (oRule.selectorText == sSelecteur); }, sSelecteur);
};
clWDUtil.__nStyleTrouveDansRulesComplexe = function __nStyleTrouveDansRulesComplexe(tabRules, sSelecteur)
{
	// Normalise en avance le nom : supprime les espaces de formatage (ajoute entre les ',')
	// et passe en minuscule pour chrome
	sSelecteur = this.sSupprimeEspaces(sSelecteur).toLowerCase();

	var i;
	var nLimiteI = tabRules.length;
	for (i = 0; i < nLimiteI; i++)
	{
		// On recupere la liste des styles pour voir si notre style y est
		// Comme les styles sont groupes par le moteur selon des styles qui doivent reste identique il sufit de trouver notre style une fois
		// Ici les styles sont groupe donc il faut faire un parsing
		// selectorText n'existe pas dans les CSSMediaRule
		var sSTexte = tabRules[i].selectorText;
		if (sSTexte)
		{
			var nIndice = this.nDansTableauFct(sSTexte.split(","), function(oNom, sSelecteur) { return (oNom.replace(/ /g, "").toLowerCase() == sSelecteur); }, sSelecteur);
			if (this.nElementInconnu != nIndice)
			{
				return i;
			}
		}
	}

	// Non trouve
	return -1;
};

if (bIE)
{
	clWDUtil.StyleSupprime = function StyleSupprime(oFeuilleStyle, nStyle) { oFeuilleStyle.removeRule(nStyle); };
}
else
{
	clWDUtil.StyleSupprime = function StyleSupprime(oFeuilleStyle, nStyle) { oFeuilleStyle.deleteRule(nStyle); };
}


// Encodage des valeurs

function WDEncode (bUTF8)
{
	// On aura besoin de transforme les chaines recus pour gerer les caratere interdit en ISO-8859-1 si besoin
	// Pas besoin de le faire en UTF-8 car il on deja ete encode pour avoir au final la bonne valeur unicode
	if (bUTF8 === undefined)
	{
		bUTF8 = ((document.charset ? document.charset : (document.characterSet ? document.characterSet : "iso-8859-1")).toLowerCase() != "iso-8859-1");
	}

	if (!bUTF8)
	{
		// On defini notre fonction d'encodage des parametres
		this.sEncodePOST = WDEncode.prototype.sEncodePOST_CP1252;

		// Et d'ecriture de valeur dans le HTML
		this.sEncodeCharset = WDEncode.prototype.sEncodeCharset_CP1252;
	}
	else
	{
		// Le fonctionnement par defaut des fonctions est OK
	}
}

// Fonctionnement par defaut des fonctions d'encodage : pour les pages UTF8
// Encodage pour l'ecriture dans le POST : simple echapement
WDEncode.prototype.sEncodePOST = function sEncodePOST(sValeur)
{
	return encodeURIComponent(sValeur);
};

// Encodage pour l'ecriture dans la page : ne fait rien
WDEncode.prototype.sEncodeCharset = function sEncodeCharset(sValeur)
{
	return sValeur;
};

// Version pour les pages non UTF8 (CP1252) des fonctions d'encodage
// Encodage pour l'ecriture dans le POST : remplacement de tous les carateres unicodes par leur valeur CP1252 si possible
WDEncode.prototype.sEncodePOST_CP1252 = function sEncodePOST_CP1252(sValeur)
{
	// Traite les carateres unicodes
	sValeur = sValeur.replace(/[\u0100-\uFFFF]/g, function(sCar) { var n = sCar.charCodeAt(0); var i; var nLimiteI = WDEncode.prototype.tabConvCP1252.length; for(i = 0; i < nLimiteI; i++) { if(WDEncode.prototype.tabConvCP1252[i] == n) { return String.fromCharCode(i + 128); } } return sCar; } );
	// Escape le tout
	sValeur = escape(sValeur);
	// Et remplace le + car il represente l'encodage de l'espace
	return sValeur.replace(/\+/g, "%2B");
};

// Encodage pour l'ecriture dans la page : remplace les carateres qui ne sont pas dans l'alphabet par leur valeur UNICODE
WDEncode.prototype.sEncodeCharset_CP1252 = function sEncodeCharset_CP1252(sValeur, bHTML)
{
	// Le jeu de caratere de windows est CP1252. Qui est un surensemble de ISO-8859-1
	// Il faut convertir tous les carateres entre 0x80 et 0x9F en leur version unicode

	// Puis les caractere de la plage
	// 128 = 0x80
	sValeur = sValeur.replace(/[\x80-\x9F]/g, function(sCar) { return String.fromCharCode(WDEncode.prototype.tabConvCP1252[sCar.charCodeAt(0) - 128]); } );

	if (bHTML)
	{
		// Les caracteres restant (0xA0-0xFF) sont encode normalement en HTML
		sValeur = sValeur.replace(/[\xA0-\xFF]/g, function(sCar) { return "&#" + sCar.charCodeAt(0) + ";"; } );
	}

	// Renvoi de la valeur convertie
	return sValeur;
};

// Le tableau pour la conversion depuis CP1252
//										128		129?	130		131		132		133		134		135		136		137		138		139		140		141?	142		143?	144?	145		146		147		148		149		150		151		152		153		154		155		156		157?	158		159
//										0x80	0x81	0x82	0x83	0x84	0x85	0x86	0x87	0x88	0x89	0x8A	0x8B	0x8C	0x8D	0x8E	0x8F	0x90	0x91	0x92	0x93	0x94	0x95	0x96	0x97	0x98	0x99	0x9A	0x9B	0x9C	0x9D	0x9E	0x9F
WDEncode.prototype.tabConvCP1252 = [	8364,	129,	8218,	402,	8222,	8230,	8224,	8225,	710,	8240,	352,	8249,	338,	141,	381,	143,	144,	8216,	8217,	8220,	8221,	8226,	8211,	8212,	732,	8482,	353,	8250,	339,	157,	382,	376	];

// Fonction de reencodage en HTML
WDEncode.prototype.sEncodeInnerHTML = function sEncodeInnerHTML(sValeur, bRemplaceBR, bPasEncodeBalise, bSansHTMLDansEncodeCharset)
{
	// Remplace le minimum de caracteres
	if (!bPasEncodeBalise)
	{
		sValeur = sValeur.replace(/&/g, "&amp;");
		sValeur = sValeur.replace(/</g, "&lt;");
		sValeur = sValeur.replace(/>/g, "&gt;");
//		sValeur = sValeur.replace(/\'/g, "&apos;");
//		sValeur = sValeur.replace(/\"/g, "&quot;");
	}

	// Si le charset de la page est Latin1 (Donc pas en UTF-8)
	// => On transforme les caractere de CP1252 en leur equivalent unicode qui va fonctionner
	// => On encode les autres caracteres > 127
	// Appele le pointeru qui pointe deja sur la bonne fonction
	sValeur = this.sEncodeCharset(sValeur, bSansHTMLDansEncodeCharset ? false : true);

	if (bRemplaceBR)
	{
		// Met des balises BR pour les marques de lignes
		sValeur = sValeur.replace(/\r\n/g, "<br />");
		sValeur = sValeur.replace(/\n/g, "<br />");
	}

	// Renvoi de la valeur
	return sValeur;
};

// Instancie un objet principal
var clWDEncode = new WDEncode(_bUTF8_);

// Classe de base des types avances
function WDTypeAvance(bConstructeur)
{
	if (bConstructeur)
	{
	}
}

// Lire une propriete : a definir dans chaque type
WDTypeAvance.prototype.GetProp = function GetProp(nPropriete)
{
	return null;
};

// Gestion des elements popup de la page
function WDPopupAutomatique (oObjetParent)
{
	// Memorise les parametres
	this.m_oObjetParent = oObjetParent;

	var oThis = this;
	// Cree la methode de hook dans la classe
	this.m_fOnFocus = function(oEvent) { return oThis.OnFocus(oEvent || event); };
	this.m_fOnBlur = function(oEvent) { return oThis.OnBlur(oEvent || event); };

	// Cree une fonction qui appele la fonction de masquage
	this.m_fTimeout = function(oEvent) { oThis.Masque(oEvent, true); };
}

WDPopupAutomatique.prototype =
{
//	m_oElement:				null,
//	m_oObjetParent:			null,
//	m_nTimeoutFocus:		null,

	// Affiche le champ
	Affiche:function (oEvent, oElement, oParam)
	{
		// Si on a 'deja' un element, masque l'element precedent
		if (this.m_oElement)
		{
			this.Masque(oEvent, true);
		}
		// Memorise que l'on a un element
		this.m_oElement = oElement;

		// Efface le timeout existant si besoin
		this.__ClearTimeout();

		// Hook les onfocus/onblur des elements
		this.__HookOnFocusBlurRecursif(oElement);

		// Si on est pas en mode quirks, IE presente le offsetParent d'un element display:none sur le document
		// donc on montre la popup avant de la placer
		clWDUtil.SetDisplay(this.m_oElement, true);

		// Appel le champ hote
		this.m_oObjetParent.AfficheInterne(oEvent, oElement, oParam);

		// Donne le focus au premier champ APRES l'affichage
		try
		{
			this.m_oElement.getElementsByTagName("a")[0].focus();
		}
		catch (e)
		{
		}
	},

	// Notification de que champ doit etre masquer
	Masque:function (oEvent, bLostFocus)
	{
		// Efface le timeout existant si besoin
		this.__ClearTimeout();

		// Seulement si l'element existe (il peut ne pas existe si la popup n'a pas ete affichee
		if (this.m_oElement)
		{
			this.__UnhookOnFocusBlurRecursif(this.m_oElement);

			// Masque le champ
			clWDUtil.SetDisplay(this.m_oElement, false);
		}

		// Appel le champ hote
		this.m_oObjetParent.MasqueInterne(oEvent, bLostFocus);

		// Supprime l'element
		delete this.m_oElement;
	},

	// Hook les onfocus/onblur des liens
	__HookOnFocusBlurRecursif:function (oElement)
	{
		// Hook l'element uniquement s'il peut recevoir le focus
		if (oElement.focus)
		{
			HookOnXXX(oElement, "onfocus", "focus", this.m_fOnFocus);
			HookOnXXX(oElement, "onblur", "blur", this.m_fOnBlur);
		}

		// Et ses fils qui ne sont pas du texte simple
		var oFils = oElement.firstChild;
		while (oFils)
		{
			if (oFils.nodeName != "#text")
			{
				this.__HookOnFocusBlurRecursif(oFils);
			}
			oFils = oFils.nextSibling;
		}
	},

	// Supprime les hooks
	__UnhookOnFocusBlurRecursif:function (oElement)
	{
		// Unhook l'element uniquement s'il peut recevoir le focus
		if (oElement.focus)
		{
			UnhookOnXXX(oElement, "onfocus", "focus", this.m_fOnFocus);
			UnhookOnXXX(oElement, "onblur", "blur", this.m_fOnBlur);
		}

		// Et ses fils qui ne sont pas du texte simple
		var oFils = oElement.firstChild;
		while (oFils)
		{
			if (oFils.nodeName != "#text")
			{
				this.__UnhookOnFocusBlurRecursif(oFils);
			}
			oFils = oFils.nextSibling;
		}
	},

	// Evenement avant l'affectation en AJAX du contenu du calendrier
	PreAffecteHTML:function (bDepuisAJAX)
	{
		// Si le champ est affiche : supprime les hooks
		if (this.m_oElement && (this.m_oElement.style.display == clWDUtil.sGetDisplayBlock(this.m_oElement)))
		{
			this.__UnhookOnFocusBlurRecursif(this.m_oElement);
		}
	},

	// Evenement apres l'affectation en AJAX du contenu du calendrier
	PostAffecteHTML:function (bDepuisAJAX)
	{
		// Si le champ est affiche : restaure les hooks
		if (this.m_oElement && (this.m_oElement.style.display == clWDUtil.sGetDisplayBlock(this.m_oElement)))
		{
			this.__HookOnFocusBlurRecursif(this.m_oElement);
		}
		// Donne le focus au premier champ
		try
		{
			this.m_oElement.getElementsByTagName("a")[0].focus();
		}
		catch (e)
		{
		}
	},

	// Notification qu'un lien a pris le focus.
	OnFocus:function (oEvent)
	{
		// Efface le timeout existant si besoin
		this.__ClearTimeout();
	},

	// Notification que le champ a perdu le focus.
	// Il faut tester si le focus est parti dans un autre champ du calendrier ou a l'exterieur
	OnBlur:function (oEvent)
	{
		// On veut detecter les pertes de focus du calendrier
		// Sauf que la perte de focus d'un lien peut donner le focus a un autre lien du calendrier
		// => On fait un timeout de 1ms qui sera annule par le onfocus de l'autre lien si besoin
		if (!this.m_nTimeoutFocus)
		{
			this.m_nTimeoutFocus = setTimeout(this.m_fTimeout, clWDUtil.nTimeoutImmediat);
		}
	},

	// Efface le timeout existant si besoin
	__ClearTimeout:function ()
	{
		// Supprime le timeout actif
		if (this.m_nTimeoutFocus)
		{
			// Invalide le timeout aupres du systeme
			clearTimeout(this.m_nTimeoutFocus);

			// Supprime le membre
			delete this.m_nTimeoutFocus;
		}
	}
};

// Gestion d'un champ de saisie temporaire
function WDPopupSaisie (oObjetParent, bValideSurBlur)
{
	// Si on est pas dans l'init d'un protoype
	if (oObjetParent)
	{
		// Memorise les parametres
		this.m_oObjetParent = oObjetParent;
		this.m_bValideSurBlur = bValideSurBlur;
	}
}

// Initialisation
WDPopupSaisie.prototype.Init = function Init()
{
	// Fonction de validation (attention on suppose que l'on a un formulaire)
	var oThis = this;
	this.m_fValide = function(oEvent) { oThis.Valide(oEvent || event, oThis.m_oSaisie.value); return clWDUtil.bStopPropagation(oEvent); };
	this.m_fAnnule = function(oEvent) { oThis.Annule(); return clWDUtil.bStopPropagation(oEvent); };
	this.m_fAnnuleSiEsc = function(oEvent)
	{
		if (27 == (oEvent || event).keyCode)
		{
			return oThis.m_fAnnule();
		}
	};
};

// Debut de la saisie
// nReductionLargeur : pour la saisie dans le champ table : on ne prend pas toute la largeur
WDPopupSaisie.prototype.Debut = function Debut(oConteneurParent, nReductionLargeur)
{
	// Annulle l'ancienne saisie si besoin (arrive dans des combinaisons d'evenements bizarres)
	this.Annule();

	// Appel de la methode personnalisable
	this._vDebut.apply(this, arguments);

	// Et donne le focus au champ de saisie
	this.m_oSaisie.focus();
	var oThis = this;
	setTimeout(function() { oThis.__DonneFocusSaisie(); }, 1);
};

// Fixe le focus
WDPopupSaisie.prototype.__DonneFocusSaisie = function __DonneFocusSaisie()
{
	// Si le champ de saisie est directement supprime de la page, .focus ne fonctionne pas
	// Dans ce cas selon le navigateur, oSaisie.parentNode est null ou est le document, en tous cas ce n'est pas le formulaire
	if (this.m_oSaisie)
	{
		var oParent = this.m_oSaisie.parentNode;
		if (oParent && ("form" == clWDUtil.sGetTagName(oParent)))
		{
			this.m_oSaisie.focus();
		}
	}
};

// Debut de la saisie
// nReductionLargeur : pour la saisie dans le champ table : on ne prend pas toute la largeur
WDPopupSaisie.prototype._vDebut = function _vDebut(oConteneurParent, nReductionLargeur)
{
	// Cree dynamiquement la zone de recherche
	var oFormulaire = document.createElement("form");
	// Avec son action
	oFormulaire.method = "post";
	oFormulaire.action = "javascript:return false;";
	// Puis on place le formulaire au bon endroit
	oFormulaire.style.position = "absolute";
	oFormulaire.style.top = "0px";
	oFormulaire.style.left = "0px";
	oFormulaire.style.width = (oConteneurParent.offsetWidth - nReductionLargeur - 1) + "px";
	oFormulaire.style.height = "100%";

	// Ensuite on fait le champs de saisie
	var oSaisie = document.createElement("input");
	oSaisie.type = "text";
	// On l'attache a son parent
	oSaisie = oFormulaire.appendChild(oSaisie);
	// Et lui defini son style
	oSaisie.style.position = "absolute";
	oSaisie.style.top = "0px";
	oSaisie.style.left = "0px";
	oSaisie.style.width = "100%";
	oSaisie.style.height = "100%";
	oSaisie.style.borderWidth = "0";
	oSaisie.style.borderStyle = "solid";
	// Si la hauteur du parent est faible : reduit la taille de la police
	if ((oConteneurParent.offsetHeight <= 18) && (oConteneurParent.offsetHeight > 0))
	{
		oSaisie.style.fontSize = Math.max(oConteneurParent.offsetHeight - 4, 6) + "px";
	}

	// On met le tout dans la cellule de recherche
	this.m_oFormulaire = oConteneurParent.appendChild(oFormulaire);
	this.m_oSaisie = this.m_oFormulaire.elements[0];

	// Et la methode de validation qui renvoie toujours faux pour ne pas valider le formulaire
	HookOnXXX(this.m_oFormulaire, "onsubmit", "submit", this.m_fValide);
	// Gere la perte du focus et l'annulation
	HookOnXXX(this.m_oSaisie, "onblur", "blur", this.m_bValideSurBlur ? this.m_fValide : this.m_fAnnule);
	HookOnXXX(this.m_oSaisie, "onkeydown", "keydown", this.m_fAnnuleSiEsc);
};

// Valide la saisie
WDPopupSaisie.prototype.Valide = function Valide(oEvent, sValeur)
{
	// Si on est dans une annulation
	if (this.m_bDansAnnule)
	{
		return;
	}

	// Seulement si on a une saisie
	if (this.m_oFormulaire)
	{
		// Appel de la methode personnalisable
		this._vValide.apply(this, arguments);
	}

	// Supprime le HTML de la saisie
	this.Annule();
};

// Valide la saisie
WDPopupSaisie.prototype._vValide = function _vValide(oEvent, sValeur)
{
	// Rien
};

// Annule la saisie
WDPopupSaisie.prototype.Annule = function Annule()
{
	try
	{
		// Sur certains navigateur (tablettes) on recoit un onblur lors de la destruction du champ)
		this.m_bDansAnnule = true;

		// Seulement si on a deja une saisie en cours
		if (this.m_oFormulaire)
		{
			// Appel de la methode personnalisable
			this._vAnnule.apply(this, arguments);

			// Supprime les evenements
			UnhookOnXXX(this.m_oSaisie, "onkeypress", "keypress", this.m_fAnnuleSiEsc);
			UnhookOnXXX(this.m_oSaisie, "onblur", "blur", this.m_fAnnule);
			UnhookOnXXX(this.m_oFormulaire, "onsubmit", "submit", this.m_fValide);
		}

		// Supprime le onblur de l'element de saisie pour eviter que le navigateur (IE) ne s'emelle les pinceau si on creer un nouvel objet)
		clWDUtil.bHTMLVideDepuisVariable(this, "m_oSaisie");
		clWDUtil.bHTMLVideDepuisVariable(this, "m_oFormulaire");
	}
	catch (e)
	{
		throw e;
	}
	finally
	{
		delete this.m_bDansAnnule;
	}
};

// Annule la saisie
WDPopupSaisie.prototype._vAnnule = function _vAnnule()
{
	// Rien
};

// Feuille de style avec un cache (permet d'eviter de couteuse recherche
function WDStyleCache (bConstructeur)
{
	if (bConstructeur)
	{
		this.m_oFeuilleStyle = null;
		this.m_oFeuilleStyleRules = null;
		this.m_tabStyle = [];
	}
};

// Creation/Recreation de la feuille de style
WDStyleCache.prototype.Creation = function Creation()
{
	// Si la feuille n'existe pas : creation
	if (!this.m_oFeuilleStyle)
	{
		this.m_oFeuilleStyle = clWDUtil.oCreeFeuilleStyle();
		this.m_oFeuilleStyleRules = bIE ? this.m_oFeuilleStyle.rules : this.m_oFeuilleStyle.cssRules;
	}
	this.m_tabStyleNew = [];
};

// Creation/Recreation de la feuille de style
WDStyleCache.prototype.CreationAjout = function CreationAjout()
{
	this.m_tabStyleNew = [];
	var tabStyleOld = this.m_tabStyle;
	var tabStyleNew = this.m_tabStyleNew;

	// Creation ou modification des nouveaux styles
	for (var sNomStyle in tabStyleOld)
	{
		tabStyleNew[sNomStyle] = tabStyleOld[sNomStyle];
	}
};

// Applique les modifications (en creation et modification)
WDStyleCache.prototype.CreationFlush = function CreationFlush()
{
	var tabStyleOld = this.m_tabStyle;
	var tabStyleNew = this.m_tabStyleNew;

	// Creation ou modification des nouveaux styles
	for (var sNomStyle in tabStyleNew)
	{
		var sStyleNew = tabStyleNew[sNomStyle];
		var sStyleOld = tabStyleOld[sNomStyle];
		if (sStyleNew == sStyleOld)
		{
			// Non modifie ne fait rien
			continue;
		}
		else if (sStyleOld !== undefined)
		{
			// Mofifie : supprimer pour recreer
			this.__StyleSupprime(sNomStyle);
		}
		else
		{
			// Nouveau : creer
		}
		tabStyleOld[sNomStyle] = sStyleNew;
		clWDUtil.CreeStyle(this.m_oFeuilleStyle, sNomStyle, sStyleNew);
	}
};

// Fin de la creation de la feuille de style (reporte les modifications)
WDStyleCache.prototype.CreationFin = function CreationFin()
{
	var tabStyleOld = this.m_tabStyle;
	var tabStyleNew = this.m_tabStyleNew;
	this.m_tabStyle = [];

	// Reporte les modifications
	var sNomStyle;
	var sStyleNew;
	for (sNomStyle in tabStyleOld)
	{
		sStyleNew = tabStyleNew[sNomStyle];
		if (tabStyleOld[sNomStyle] == sStyleNew)
		{
			// Le style n'a pas change : on ne fait rien sans le feuille de style : supprime le style de tabStyleNew pour ne pas le cree
			this.m_tabStyle[sNomStyle] = sStyleNew;
			delete tabStyleNew[sNomStyle];
		}
		else
		{
			// Le style n'existe plus ou a ete modifie : le supprime
			this.__StyleSupprime(sNomStyle);
		}
	}

	// Creation des nouveaux styles
	for (sNomStyle in tabStyleNew)
	{
		sStyleNew = tabStyleNew[sNomStyle];
		this.m_tabStyle[sNomStyle] = sStyleNew;
		clWDUtil.CreeStyle(this.m_oFeuilleStyle, sNomStyle, sStyleNew);
	}

	// Vide m_tabStyleNew pour les prochaines modifications
	delete this.m_tabStyleNew;
};

// Ajoute un style
WDStyleCache.prototype.Ajoute = function Ajoute(sNomStyle, tabStyle)
{
	if (0 < tabStyle.length)
	{
		// On n'a this.m_tabStyleNew que en creation
		// L'ajoute dans tous les cas dans le nouveau cache
		this.m_tabStyleNew[sNomStyle] = tabStyle.join(';');
	}
};

// Complete un style
WDStyleCache.prototype.Complete = function Complete(sNomStyle, tabStyle)
{
	if (0 < tabStyle.length)
	{
		// Recherche le style dans le cache
		var sStyleNew = this.m_tabStyleNew[sNomStyle];
		if ((sStyleNew !== undefined) && (0 < sStyleNew.length))
		{
			this.m_tabStyleNew[sNomStyle] += ';' + tabStyle.join(';');
		}
		else
		{
			// Non trouve : le cree
			this.Ajoute(sNomStyle, tabStyle);
		}
	}
};

// Supprime un style
WDStyleCache.prototype.__StyleSupprime = function __StyleSupprime(sNomStyle)
{
	var nStyle = this.__nStyleTrouve(sNomStyle);
	if (-1 != nStyle)
	{
		clWDUtil.StyleSupprime(this.m_oFeuilleStyle, nStyle);
	}
};

// Trouve un style
WDStyleCache.prototype.__nStyleTrouve = function __nStyleTrouve (sNomStyle)
{
	return clWDUtil.nStyleTrouveDansRules(this.m_oFeuilleStyleRules, sNomStyle);
};
