// prevent execution of jQuery if included more than once
if(typeof window.jQuery == "undefined") {
/*
 * jQuery 1.1.3.1 - New Wave Javascript
 *
 * Copyright (c) 2007 John Resig (jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2007-07-05 00:43:24 -0400 (Thu, 05 Jul 2007) $
 * $Rev: 2243 $
 */

// Global undefined variable
window.undefined = window.undefined;
var jQuery = function(a,c) {
  // If the context is global, return a new object
  if ( window == this || !this.init )
    return new jQuery(a,c);

  return this.init(a,c);
};

// Map over the $ in case of overwrite
if ( typeof $ != "undefined" )
  jQuery._$ = $;

// Map the jQuery namespace to the '$' one
var $ = jQuery;

jQuery.fn = jQuery.prototype = {
  init: function(a,c) {
    // Make sure that a selection was provided
    a = a || document;

    // HANDLE: $(function)
    // Shortcut for document ready
    if ( jQuery.isFunction(a) )
      return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( a );

    // Handle HTML strings
    if ( typeof a  == "string" ) {
      // HANDLE: $(html) -> $(array)
      var m = /^[^<]*(<(.|\s)+>)[^>]*$/.exec(a);
      if ( m )
        a = jQuery.clean( [ m[1] ] );

      // HANDLE: $(expr)
      else
        return new jQuery( c ).find( a );
    }

    return this.setArray(
      // HANDLE: $(array)
      a.constructor == Array && a ||

      // HANDLE: $(arraylike)
      // Watch for when an array-like object is passed as the selector
      (a.jquery || a.length && a != window && !a.nodeType && a[0] != undefined && a[0].nodeType) && jQuery.makeArray( a ) ||

      // HANDLE: $(*)
      [ a ] );
  },
  jquery: "1.1.3.1",

  size: function() {
    return this.length;
  },

  length: 0,

  get: function( num ) {
    return num == undefined ?

      // Return a 'clean' array
      jQuery.makeArray( this ) :

      // Return just the object
      this[num];
  },
  pushStack: function( a ) {
    var ret = jQuery(a);
    ret.prevObject = this;
    return ret;
  },
  setArray: function( a ) {
    this.length = 0;
    [].push.apply( this, a );
    return this;
  },
  each: function( fn, args ) {
    return jQuery.each( this, fn, args );
  },
  index: function( obj ) {
    var pos = -1;
    this.each(function(i){
      if ( this == obj ) pos = i;
    });
    return pos;
  },

  attr: function( key, value, type ) {
    var obj = key;

    // Look for the case where we're accessing a style value
    if ( key.constructor == String )
      if ( value == undefined )
        return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined;
      else {
        obj = {};
        obj[ key ] = value;
      }

    // Check to see if we're setting style values
    return this.each(function(index){
      // Set all the styles
      for ( var prop in obj )
        jQuery.attr(
          type ? this.style : this,
          prop, jQuery.prop(this, obj[prop], type, index, prop)
        );
    });
  },

  css: function( key, value ) {
    return this.attr( key, value, "curCSS" );
  },

  text: function(e) {
    if ( typeof e == "string" )
      return this.empty().append( document.createTextNode( e ) );

    var t = "";
    jQuery.each( e || this, function(){
      jQuery.each( this.childNodes, function(){
        if ( this.nodeType != 8 )
          t += this.nodeType != 1 ?
            this.nodeValue : jQuery.fn.text([ this ]);
      });
    });
    return t;
  },

  wrap: function() {
    // The elements to wrap the target around
    var a, args = arguments;

    // Wrap each of the matched elements individually
    return this.each(function(){
      if ( !a )
        a = jQuery.clean(args, this.ownerDocument);

      // Clone the structure that we're using to wrap
      var b = a[0].cloneNode(true);

      // Insert it before the element to be wrapped
      this.parentNode.insertBefore( b, this );

      // Find the deepest point in the wrap structure
      while ( b.firstChild )
        b = b.firstChild;

      // Move the matched element to within the wrap structure
      b.appendChild( this );
    });
  },
  append: function() {
    return this.domManip(arguments, true, 1, function(a){
      this.appendChild( a );
    });
  },
  prepend: function() {
    return this.domManip(arguments, true, -1, function(a){
      this.insertBefore( a, this.firstChild );
    });
  },
  before: function() {
    return this.domManip(arguments, false, 1, function(a){
      this.parentNode.insertBefore( a, this );
    });
  },
  after: function() {
    return this.domManip(arguments, false, -1, function(a){
      this.parentNode.insertBefore( a, this.nextSibling );
    });
  },
  end: function() {
    return this.prevObject || jQuery([]);
  },
  find: function(t) {
    var data = jQuery.map(this, function(a){ return jQuery.find(t,a); });
    return this.pushStack( /[^+>] [^+>]/.test( t ) || t.indexOf("..") > -1 ?
      jQuery.unique( data ) : data );
  },
  clone: function(deep) {
    // Need to remove events on the element and its descendants
    var $this = this.add(this.find("*"));
    $this.each(function() {
      this._$events = {};
      for (var type in this.$events)
        this._$events[type] = jQuery.extend({},this.$events[type]);
    }).unbind();

    // Do the clone
    var r = this.pushStack( jQuery.map( this, function(a){
      return a.cloneNode( deep != undefined ? deep : true );
    }) );

    // Add the events back to the original and its descendants
    $this.each(function() {
      var events = this._$events;
      for (var type in events)
        for (var handler in events[type])
          jQuery.event.add(this, type, events[type][handler], events[type][handler].data);
      this._$events = null;
    });

    // Return the cloned set
    return r;
  },

  filter: function(t) {
    return this.pushStack(
      jQuery.isFunction( t ) &&
      jQuery.grep(this, function(el, index){
        return t.apply(el, [index])
      }) ||

      jQuery.multiFilter(t,this) );
  },

  not: function(t) {
    return this.pushStack(
      t.constructor == String &&
      jQuery.multiFilter(t, this, true) ||

      jQuery.grep(this, function(a) {
        return ( t.constructor == Array || t.jquery )
          ? jQuery.inArray( a, t ) < 0
          : a != t;
      })
    );
  },

  add: function(t) {
    return this.pushStack( jQuery.merge(
      this.get(),
      t.constructor == String ?
        jQuery(t).get() :
        t.length != undefined && (!t.nodeName || t.nodeName == "FORM") ?
          t : [t] )
    );
  },
  is: function(expr) {
    return expr ? jQuery.multiFilter(expr,this).length > 0 : false;
  },

  val: function( val ) {
    return val == undefined ?
      ( this.length ? this[0].value : null ) :
      this.attr( "value", val );
  },

  html: function( val ) {
    return val == undefined ?
      ( this.length ? this[0].innerHTML : null ) :
      this.empty().append( val );
  },
  domManip: function(args, table, dir, fn){
    var clone = this.length > 1, a;

    return this.each(function(){
      if ( !a ) {
        a = jQuery.clean(args, this.ownerDocument);
        if ( dir < 0 )
          a.reverse();
      }

      var obj = this;

      if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
        obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));

      jQuery.each( a, function(){
        fn.apply( obj, [ clone ? this.cloneNode(true) : this ] );
      });

    });
  }
};

jQuery.extend = jQuery.fn.extend = function() {
  // copy reference to target object
  var target = arguments[0], a = 1;

  // extend jQuery itself if only one argument is passed
  if ( arguments.length == 1 ) {
    target = this;
    a = 0;
  }
  var prop;
  while ( (prop = arguments[a++]) != null )
    // Extend the base object
    for ( var i in prop ) target[i] = prop[i];

  // Return the modified object
  return target;
};

jQuery.extend({
  noConflict: function() {
    if ( jQuery._$ )
      $ = jQuery._$;
    return jQuery;
  },

  // This may seem like some crazy code, but trust me when I say that this
  // is the only cross-browser way to do this. --John
  isFunction: function( fn ) {
    return !!fn && typeof fn != "string" && !fn.nodeName &&
      fn.constructor != Array && /function/i.test( fn + "" );
  },

  // check if an element is in a XML document
  isXMLDoc: function(elem) {
    return elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
  },

  nodeName: function( elem, name ) {
    return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
  },
  // args is for internal usage only
  each: function( obj, fn, args ) {
    if ( obj.length == undefined )
      for ( var i in obj )
        fn.apply( obj[i], args || [i, obj[i]] );
    else
      for ( var i = 0, ol = obj.length; i < ol; i++ )
        if ( fn.apply( obj[i], args || [i, obj[i]] ) === false ) break;
    return obj;
  },

  prop: function(elem, value, type, index, prop){
      // Handle executable functions
      if ( jQuery.isFunction( value ) )
        value = value.call( elem, [index] );

      // exclude the following css properties to add px
      var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;

      // Handle passing in a number to a CSS property
      return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ?
        value + "px" :
        value;
  },

  className: {
    // internal only, use addClass("class")
    add: function( elem, c ){
      jQuery.each( c.split(/\s+/), function(i, cur){
        if ( !jQuery.className.has( elem.className, cur ) )
          elem.className += ( elem.className ? " " : "" ) + cur;
      });
    },

    // internal only, use removeClass("class")
    remove: function( elem, c ){
      elem.className = c != undefined ?
        jQuery.grep( elem.className.split(/\s+/), function(cur){
          return !jQuery.className.has( c, cur );
        }).join(" ") : "";
    },

    // internal only, use is(".class")
    has: function( t, c ) {
      return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1;
    }
  },
  swap: function(e,o,f) {
    for ( var i in o ) {
      e.style["old"+i] = e.style[i];
      e.style[i] = o[i];
    }
    f.apply( e, [] );
    for ( var i in o )
      e.style[i] = e.style["old"+i];
  },

  css: function(e,p) {
    if ( p == "height" || p == "width" ) {
      var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];

      jQuery.each( d, function(){
        old["padding" + this] = 0;
        old["border" + this + "Width"] = 0;
      });

      jQuery.swap( e, old, function() {
        if ( jQuery(e).is(':visible') ) {
          oHeight = e.offsetHeight;
          oWidth = e.offsetWidth;
        } else {
          e = jQuery(e.cloneNode(true))
            .find(":radio").removeAttr("checked").end()
            .css({
              visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0"
            }).appendTo(e.parentNode)[0];

          var parPos = jQuery.css(e.parentNode,"position") || "static";
          if ( parPos == "static" )
            e.parentNode.style.position = "relative";

          oHeight = e.clientHeight;
          oWidth = e.clientWidth;

          if ( parPos == "static" )
            e.parentNode.style.position = "static";

          // #1242
          if (jQuery.browser.msie) {
            e.outerHTML="  ";
          } else {
            e.parentNode.removeChild( e );
          }
        }
      });

      return p == "height" ? oHeight : oWidth;
    }

    return jQuery.curCSS( e, p );
  },

  curCSS: function(elem, prop, force) {
    var ret;

    if (prop == "opacity" && jQuery.browser.msie) {
      ret = jQuery.attr(elem.style, "opacity");
      return ret == "" ? "1" : ret;
    }

    if (prop.match(/float/i))
      prop = jQuery.styleFloat;

    if (!force && elem.style[prop])
      ret = elem.style[prop];

    else if (document.defaultView && document.defaultView.getComputedStyle) {

      if (prop.match(/float/i))
        prop = "float";

      prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
      var cur = document.defaultView.getComputedStyle(elem, null);

      if ( cur )
        ret = cur.getPropertyValue(prop);
      else if ( prop == "display" )
        ret = "none";
      else
        jQuery.swap(elem, { display: "block" }, function() {
            var c = document.defaultView.getComputedStyle(this, "");
            ret = c && c.getPropertyValue(prop) || "";
        });

    } else if (elem.currentStyle) {
      var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});
      ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
    }

    return ret;
  },

  clean: function(a, doc) {
    var r = [];
    doc = doc || document;

    jQuery.each( a, function(i,arg){
      if ( !arg ) return;

      if ( arg.constructor == Number )
        arg = arg.toString();

      // Convert html string into DOM nodes
      if ( typeof arg == "string" ) {
        // Trim whitespace, otherwise indexOf won't work as expected
        var s = jQuery.trim(arg).toLowerCase(), div = doc.createElement("div"), tb = [];

        var wrap =
          // option or optgroup
          !s.indexOf("<opt") &&
          [1, "<select>", "</select>"] ||

          !s.indexOf("<leg") &&
          [1, "<fieldset>", "</fieldset>"] ||

          (!s.indexOf("<thead") || !s.indexOf("<tbody") || !s.indexOf("<tfoot") || !s.indexOf("<colg")) &&
          [1, "<table>", "</table>"] ||

          !s.indexOf("<tr") &&
          [2, "<table><tbody>", "</tbody></table>"] ||

           // <thead> matched above
          (!s.indexOf("<td") || !s.indexOf("<th")) &&
          [3, "<table><tbody><tr>", "</tr></tbody></table>"] ||

          !s.indexOf("<col") &&
          [2, "<table><colgroup>", "</colgroup></table>"] ||

          [0,"",""];

        // Go to html and back, then peel off extra wrappers
        div.innerHTML = wrap[1] + arg + wrap[2];

        // Move to the right depth
        while ( wrap[0]-- )
          div = div.firstChild;

        // Remove IE's autoinserted <tbody> from table fragments
        if ( jQuery.browser.msie ) {

          // String was a <table>, *may* have spurious <tbody>
          if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 )
            tb = div.firstChild && div.firstChild.childNodes;

          // String was a bare <thead> or <tfoot>
          else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )
            tb = div.childNodes;

          for ( var n = tb.length-1; n >= 0 ; --n ) {
            if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length ) {
              // #1242
              if (jQuery.browser.msie) {
                tb[n].outerHTML="  ";
              } else {
                tb[n].parentNode.removeChild(tb[n]);
              }
            }
          }
        }

        arg = jQuery.makeArray( div.childNodes );
      }

      if ( 0 === arg.length && (!jQuery.nodeName(arg, "form") && !jQuery.nodeName(arg, "select")) )
        return;

      if ( arg[0] == undefined || jQuery.nodeName(arg, "form") || arg.options )
        r.push( arg );
      else
        r = jQuery.merge( r, arg );

    });

    return r;
  },

  attr: function(elem, name, value){
    var fix = jQuery.isXMLDoc(elem) ? {} : jQuery.props;

    // Certain attributes only work when accessed via the old DOM 0 way
    if ( fix[name] ) {
      if ( value != undefined ) elem[fix[name]] = value;
      return elem[fix[name]];

    } else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName(elem, "form") && (name == "action" || name == "method") )
      return elem.getAttributeNode(name).nodeValue;

    // IE elem.getAttribute passes even for style
    else if ( elem.tagName ) {


      if ( value != undefined ) elem.setAttribute( name, value );
      if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) )
        return elem.getAttribute( name, 2 );
      return elem.getAttribute( name );

    // elem is actually elem.style ... set the style
    } else {
      // IE actually uses filters for opacity
      if ( name == "opacity" && jQuery.browser.msie ) {
        if ( value != undefined ) {
          // IE has trouble with opacity if it does not have layout
          // Force it by setting the zoom level
          elem.zoom = 1;

          // Set the alpha filter to set the opacity
          elem.filter = (elem.filter || "").replace(/alpha\([^)]*\)/,"") +
            (parseFloat(value).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
        }

        return elem.filter ?
          (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : "";
      }
      name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
      if ( value != undefined ) elem[name] = value;
      return elem[name];
    }
  },
  trim: function(t){
    return t.replace(/^\s+|\s+$/g, "");
  },

  makeArray: function( a ) {
    var r = [];

    // Need to use typeof to fight Safari childNodes crashes
    if ( typeof a != "array" )
      for ( var i = 0, al = a.length; i < al; i++ )
        r.push( a[i] );
    else
      r = a.slice( 0 );

    return r;
  },

  inArray: function( b, a ) {
    for ( var i = 0, al = a.length; i < al; i++ )
      if ( a[i] == b )
        return i;
    return -1;
  },
  merge: function(first, second) {
    // We have to loop this way because IE & Opera overwrite the length
    // expando of getElementsByTagName
    for ( var i = 0; second[i]; i++ )
      first.push(second[i]);
    return first;
  },
  unique: function(first) {
    var r = [], num = jQuery.mergeNum++;

    for ( var i = 0, fl = first.length; i < fl; i++ )
      if ( num != first[i].mergeNum ) {
        first[i].mergeNum = num;
        r.push(first[i]);
      }

    return r;
  },

  mergeNum: 0,
  grep: function(elems, fn, inv) {
    // If a string is passed in for the function, make a function
    // for it (a handy shortcut)
    if ( typeof fn == "string" )
      fn = new Function("a","i","return " + fn);

    var result = [];

    // Go through the array, only saving the items
    // that pass the validator function
    for ( var i = 0, el = elems.length; i < el; i++ )
      if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
        result.push( elems[i] );

    return result;
  },
  map: function(elems, fn) {
    // If a string is passed in for the function, make a function
    // for it (a handy shortcut)
    if ( typeof fn == "string" )
      fn = new Function("a","return " + fn);

    var result = [];

    // Go through the array, translating each of the items to their
    // new value (or values).
    for ( var i = 0, el = elems.length; i < el; i++ ) {
      var val = fn(elems[i],i);

      if ( val !== null && val != undefined ) {
        if ( val.constructor != Array ) val = [val];
        result = result.concat( val );
      }
    }

    return result;
  }
});

/*
 * Whether the W3C compliant box model is being used.
 *
 * @property
 * @name $.boxModel
 * @type Boolean
 * @cat JavaScript
 */
new function() {
  var b = navigator.userAgent.toLowerCase();

  // Figure out what browser is being used
  jQuery.browser = {
    version: (b.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
    safari: /webkit/.test(b),
    opera: /opera/.test(b),
    msie: /msie/.test(b) && !/opera/.test(b),
    mozilla: /mozilla/.test(b) && !/(compatible|webkit)/.test(b)
  };

  // Check to see if the W3C box model is being used
  jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat";

  jQuery.styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat",

  jQuery.props = {
    "for": "htmlFor",
    "class": "className",
    "float": jQuery.styleFloat,
    cssFloat: jQuery.styleFloat,
    styleFloat: jQuery.styleFloat,
    innerHTML: "innerHTML",
    className: "className",
    value: "value",
    disabled: "disabled",
    checked: "checked",
    readonly: "readOnly",
    selected: "selected",
    maxlength: "maxLength"
  };
};

jQuery.each({
  parent: "a.parentNode",
  parents: "jQuery.parents(a)",
  next: "jQuery.nth(a,2,'nextSibling')",
  prev: "jQuery.nth(a,2,'previousSibling')",
  siblings: "jQuery.sibling(a.parentNode.firstChild,a)",
  children: "jQuery.sibling(a.firstChild)"
}, function(i,n){
  jQuery.fn[ i ] = function(a) {
    var ret = jQuery.map(this,n);
    if ( a && typeof a == "string" )
      ret = jQuery.multiFilter(a,ret);
    return this.pushStack( ret );
  };
});

jQuery.each({
  appendTo: "append",
  prependTo: "prepend",
  insertBefore: "before",
  insertAfter: "after"
}, function(i,n){
  jQuery.fn[ i ] = function(){
    var a = arguments;
    return this.each(function(){
      for ( var j = 0, al = a.length; j < al; j++ )
        jQuery(a[j])[n]( this );
    });
  };
});

jQuery.each( {
  removeAttr: function( key ) {
    jQuery.attr( this, key, "" );
    this.removeAttribute( key );
  },
  addClass: function(c){
    jQuery.className.add(this,c);
  },
  removeClass: function(c){
    jQuery.className.remove(this,c);
  },
  toggleClass: function( c ){
    jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c);
  },
  remove: function(a){
    if ( !a || jQuery.filter( a, [this] ).r.length ) {
      // #1242
      if (location.protocol == 'https:' && jQuery.browser.msie) {
        this.outerHTML="  ";
      } else {
        this.parentNode.removeChild( this );
      }
    }
  },
  empty: function() {
    try {
      while (this.firstChild) {
        // #1242
        if (location.protocol == 'https:' && jQuery.browser.msie) {
          if (typeof(this.firstChild.outerHTML) != "undefined") {
            this.firstChild.outerHTML="  ";
          } else {
            this.firstChild.removeNode(false);
          }
        } else {
          this.removeChild( this.firstChild );
        }
      }
    } catch (e) {
      alert("jQuery.empty " + e.description);
    }
  }
}, function(i,n){
  jQuery.fn[ i ] = function() {
    return this.each( n, arguments );
  };
});

jQuery.each( [ "eq", "lt", "gt", "contains" ], function(i,n){
  jQuery.fn[ n ] = function(num,fn) {
    return this.filter( ":" + n + "(" + num + ")", fn );
  };
});

jQuery.each( [ "height", "width" ], function(i,n){
  jQuery.fn[ n ] = function(h) {
    return h == undefined ?
      ( this.length ? jQuery.css( this[0], n ) : null ) :
      this.css( n, h.constructor == String ? h : h + "px" );
  };
});
jQuery.extend({
  expr: {
    "": "m[2]=='*'||jQuery.nodeName(a,m[2])",
    "#": "a.getAttribute('id')==m[2]",
    ":": {
      // Position Checks
      lt: "i<m[3]-0",
      gt: "i>m[3]-0",
      nth: "m[3]-0==i",
      eq: "m[3]-0==i",
      first: "i==0",
      last: "i==r.length-1",
      even: "i%2==0",
      odd: "i%2",

      // Child Checks
      "first-child": "a.parentNode.getElementsByTagName('*')[0]==a",
      "last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a",
      "only-child": "!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",

      // Parent Checks
      parent: "a.firstChild",
      empty: "!a.firstChild",

      // Text Check
      contains: "(a.textContent||a.innerText||'').indexOf(m[3])>=0",

      // Visibility
      visible: '"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',
      hidden: '"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',

      // Form attributes
      enabled: "!a.disabled",
      disabled: "a.disabled",
      checked: "a.checked",
      selected: "a.selected||jQuery.attr(a,'selected')",

      // Form elements
      text: "'text'==a.type",
      radio: "'radio'==a.type",
      checkbox: "'checkbox'==a.type",
      file: "'file'==a.type",
      password: "'password'==a.type",
      submit: "'submit'==a.type",
      image: "'image'==a.type",
      reset: "'reset'==a.type",
      button: '"button"==a.type||jQuery.nodeName(a,"button")',
      input: "/input|select|textarea|button/i.test(a.nodeName)"
    },
    "[": "jQuery.find(m[2],a).length"
  },

  // The regular expressions that power the parsing engine
  parse: [
    // Match: [@value='test'], [@foo]
    /^\[ *(@)([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,

    // Match: [div], [div p]
    /^(\[)\s*(.*?(\[.*?\])?[^[]*?)\s*\]/,

    // Match: :contains('foo')
    /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,

    // Match: :even, :last-chlid, #id, .class
    new RegExp("^([:.#]*)(" +
      ( jQuery.chars = jQuery.browser.safari && jQuery.browser.version < "3.0.0" ? "\\w" : "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)" ) + "+)")
  ],

  multiFilter: function( expr, elems, not ) {
    var old, cur = [];

    while ( expr && expr != old ) {
      old = expr;
      var f = jQuery.filter( expr, elems, not );
      expr = f.t.replace(/^\s*,\s*/, "" );
      cur = not ? elems = f.r : jQuery.merge( cur, f.r );
    }

    return cur;
  },
  find: function( t, context ) {
    // Quickly handle non-string expressions
    if ( typeof t != "string" )
      return [ t ];

    // Make sure that the context is a DOM Element
    if ( context && !context.nodeType )
      context = null;

    // Set the correct context (if none is provided)
    context = context || document;

    // Handle the common XPath // expression
    if ( !t.indexOf("//") ) {
      context = context.documentElement;
      t = t.substr(2,t.length);

    // And the / root expression
    } else if ( !t.indexOf("/") && !context.ownerDocument ) {
      context = context.documentElement;
      t = t.substr(1,t.length);
      if ( t.indexOf("/") >= 1 )
        t = t.substr(t.indexOf("/"),t.length);
    }

    // Initialize the search
    var ret = [context], done = [], last;

    // Continue while a selector expression exists, and while
    // we're no longer looping upon ourselves
    while ( t && last != t ) {
      var r = [];
      last = t;

      t = jQuery.trim(t).replace( /^\/\//, "" );

      var foundToken = false;

      // An attempt at speeding up child selectors that
      // point to a specific element tag
      var re = new RegExp("^[/>]\\s*(" + jQuery.chars + "+)");
      var m = re.exec(t);

      if ( m ) {
        var nodeName = m[1].toUpperCase();

        // Perform our own iteration and filter
        for ( var i = 0; ret[i]; i++ )
          for ( var c = ret[i].firstChild; c; c = c.nextSibling )
            if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName.toUpperCase()) )
              r.push( c );

        ret = r;
        t = t.replace( re, "" );
        if ( t.indexOf(" ") == 0 ) continue;
        foundToken = true;
      } else {
        re = /^((\/?\.\.)|([>\/+~]))\s*([a-z]*)/i;

        if ( (m = re.exec(t)) != null ) {
          r = [];

          var nodeName = m[4], mergeNum = jQuery.mergeNum++;
          m = m[1];

          for ( var j = 0, rl = ret.length; j < rl; j++ )
            if ( m.indexOf("..") < 0 ) {
              var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
              for ( ; n; n = n.nextSibling )
                if ( n.nodeType == 1 ) {
                  if ( m == "~" && n.mergeNum == mergeNum ) break;

                  if (!nodeName || n.nodeName.toUpperCase() == nodeName.toUpperCase() ) {
                    if ( m == "~" ) n.mergeNum = mergeNum;
                    r.push( n );
                  }

                  if ( m == "+" ) break;
                }
            } else
              r.push( ret[j].parentNode );

          ret = r;

          // And remove the token
          t = jQuery.trim( t.replace( re, "" ) );
          foundToken = true;
        }
      }

      // See if there's still an expression, and that we haven't already
      // matched a token
      if ( t && !foundToken ) {
        // Handle multiple expressions
        if ( !t.indexOf(",") ) {
          // Clean the result set
          if ( context == ret[0] ) ret.shift();

          // Merge the result sets
          done = jQuery.merge( done, ret );

          // Reset the context
          r = ret = [context];

          // Touch up the selector string
          t = " " + t.substr(1,t.length);

        } else {
          // Optomize for the case nodeName#idName
          var re2 = new RegExp("^(" + jQuery.chars + "+)(#)(" + jQuery.chars + "+)");
          var m = re2.exec(t);

          // Re-organize the results, so that they're consistent
          if ( m ) {
             m = [ 0, m[2], m[3], m[1] ];

          } else {
            // Otherwise, do a traditional filter check for
            // ID, class, and element selectors
            re2 = new RegExp("^([#.]?)(" + jQuery.chars + "*)");
            m = re2.exec(t);
          }

          m[2] = m[2].replace(/\\/g, "");

          var elem = ret[ret.length-1];

          // Try to do a global search by ID, where we can
          if ( m[1] == "#" && elem && elem.getElementById ) {
            // Optimization for HTML document case
            var oid = elem.getElementById(m[2]);

            // Do a quick check for the existence of the actual ID attribute
            // to avoid selecting by the name attribute in IE
            // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
            if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
              oid = jQuery('[@id="'+m[2]+'"]', elem)[0];

            // Do a quick check for node name (where applicable) so
            // that div#foo searches will be really fast
            ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
          } else {
            // We need to find all descendant elements
            for ( var i = 0; ret[i]; i++ ) {
              // Grab the tag name being searched for
              var tag = m[1] != "" || m[0] == "" ? "*" : m[2];

              // Handle IE7 being really dumb about <object>s
              if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
                tag = "param";

              r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
            }

            // It's faster to filter by class and be done with it
            if ( m[1] == "." )
              r = jQuery.classFilter( r, m[2] );

            // Same with ID filtering
            if ( m[1] == "#" ) {
              var tmp = [];

              // Try to find the element with the ID
              for ( var i = 0; r[i]; i++ )
                if ( r[i].getAttribute("id") == m[2] ) {
                  tmp = [ r[i] ];
                  break;
                }

              r = tmp;
            }

            ret = r;
          }

          t = t.replace( re2, "" );
        }

      }

      // If a selector string still exists
      if ( t ) {
        // Attempt to filter it
        var val = jQuery.filter(t,r);
        ret = r = val.r;
        t = jQuery.trim(val.t);
      }
    }

    // An error occurred with the selector;
    // just return an empty set instead
    if ( t )
      ret = [];

    // Remove the root context
    if ( ret && context == ret[0] )
      ret.shift();

    // And combine the results
    done = jQuery.merge( done, ret );

    return done;
  },

  classFilter: function(r,m,not){
    m = " " + m + " ";
    var tmp = [];
    for ( var i = 0; r[i]; i++ ) {
      var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
      if ( !not && pass || not && !pass )
        tmp.push( r[i] );
    }
    return tmp;
  },

  filter: function(t,r,not) {
    var last;

    // Look for common filter expressions
    while ( t  && t != last ) {
      last = t;

      var p = jQuery.parse, m;

      for ( var i = 0; p[i]; i++ ) {
        m = p[i].exec( t );

        if ( m ) {
          // Remove what we just matched
          t = t.substring( m[0].length );

          m[2] = m[2].replace(/\\/g, "");
          break;
        }
      }

      if ( !m )
        break;

      // :not() is a special case that can be optimized by
      // keeping it out of the expression list
      if ( m[1] == ":" && m[2] == "not" )
        r = jQuery.filter(m[3], r, true).r;

      // We can get a big speed boost by filtering by class here
      else if ( m[1] == "." )
        r = jQuery.classFilter(r, m[2], not);

      else if ( m[1] == "@" ) {
        var tmp = [], type = m[3];

        for ( var i = 0, rl = r.length; i < rl; i++ ) {
          var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];

          if ( z == null || /href|src/.test(m[2]) )
            z = jQuery.attr(a,m[2]) || '';

          if ( (type == "" && !!z ||
             type == "=" && z == m[5] ||
             type == "!=" && z != m[5] ||
             type == "^=" && z && !z.indexOf(m[5]) ||
             type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
             (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
              tmp.push( a );
        }

        r = tmp;

      // We can get a speed boost by handling nth-child here
      } else if ( m[1] == ":" && m[2] == "nth-child" ) {
        var num = jQuery.mergeNum++, tmp = [],
          test = /(\d*)n\+?(\d*)/.exec(
            m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
            !/\D/.test(m[3]) && "n+" + m[3] || m[3]),
          first = (test[1] || 1) - 0, last = test[2] - 0;

        for ( var i = 0, rl = r.length; i < rl; i++ ) {
          var node = r[i], parentNode = node.parentNode;

          if ( num != parentNode.mergeNum ) {
            var c = 1;

            for ( var n = parentNode.firstChild; n; n = n.nextSibling )
              if ( n.nodeType == 1 )
                n.nodeIndex = c++;

            parentNode.mergeNum = num;
          }

          var add = false;

          if ( first == 1 ) {
            if ( last == 0 || node.nodeIndex == last )
              add = true;
          } else if ( (node.nodeIndex + last) % first == 0 )
            add = true;

          if ( add ^ not )
            tmp.push( node );
        }

        r = tmp;

      // Otherwise, find the expression to execute
      } else {
        var f = jQuery.expr[m[1]];
        if ( typeof f != "string" )
          f = jQuery.expr[m[1]][m[2]];

        // Build a custom macro to enclose it
        eval("f = function(a,i){return " + f + "}");

        // Execute it against the current filter
        r = jQuery.grep( r, f, not );
      }
    }

    // Return an array of filtered elements (r)
    // and the modified expression string (t)
    return { r: r, t: t };
  },
  parents: function( elem ){
    var matched = [];
    var cur = elem.parentNode;
    while ( cur && cur != document ) {
      matched.push( cur );
      cur = cur.parentNode;
    }
    return matched;
  },
  nth: function(cur,result,dir,elem){
    result = result || 1;
    var num = 0;

    for ( ; cur; cur = cur[dir] )
      if ( cur.nodeType == 1 && ++num == result )
        break;

    return cur;
  },
  sibling: function( n, elem ) {
    var r = [];

    for ( ; n; n = n.nextSibling ) {
      if ( n.nodeType == 1 && (!elem || n != elem) )
        r.push( n );
    }

    return r;
  }
});
/*
 * A number of helper functions used for managing events.
 * Many of the ideas behind this code orignated from
 * Dean Edwards' addEvent library.
 */
jQuery.event = {

  // Bind an event to an element
  // Original by Dean Edwards
  add: function(element, type, handler, data) {
    // For whatever reason, IE has trouble passing the window object
    // around, causing it to be cloned in the process
    if ( jQuery.browser.msie && element.setInterval != undefined )
      element = window;

    // Make sure that the function being executed has a unique ID
    if ( !handler.guid )
      handler.guid = this.guid++;

    // if data is passed, bind to handler
    if( data != undefined ) {
          // Create temporary function pointer to original handler
      var fn = handler;

      // Create unique handler function, wrapped around original handler
      handler = function() {
        // Pass arguments and context to original handler
        return fn.apply(this, arguments);
      };

      // Store data in unique handler
      handler.data = data;

      // Set the guid of unique handler to the same of original handler, so it can be removed
      handler.guid = fn.guid;
    }

    // Init the element's event structure
    if (!element.$events)
      element.$events = {};

    if (!element.$handle)
      element.$handle = function() {
        // returned undefined or false
        var val;

        // Handle the second event of a trigger and when
        // an event is called after a page has unloaded
        if ( typeof jQuery == "undefined" || jQuery.event.triggered )
          return val;

        val = jQuery.event.handle.apply(element, arguments);

        return val;
      };

    // Get the current list of functions bound to this event
    var handlers = element.$events[type];

    // Init the event handler queue
    if (!handlers) {
      handlers = element.$events[type] = {};

      // And bind the global event handler to the element
      if (element.addEventListener)
        element.addEventListener(type, element.$handle, false);
      else
        element.attachEvent("on" + type, element.$handle);
    }

    // Add the function to the element's handler list
    handlers[handler.guid] = handler;

    // Remember the function in a global list (for triggering)
    if (!this.global[type])
      this.global[type] = [];
    // Only add the element to the global list once
    if (jQuery.inArray(element, this.global[type]) == -1)
      this.global[type].push( element );
  },

  guid: 1,
  global: {},

  // Detach an event or set of events from an element
  remove: function(element, type, handler) {
    var events = element.$events, ret, index;

    if ( events ) {
      // type is actually an event object here
      if ( type && type.type ) {
        handler = type.handler;
        type = type.type;
      }

      if ( !type ) {
        for ( type in events )
          this.remove( element, type );

      } else if ( events[type] ) {
        // remove the given handler for the given type
        if ( handler )
          delete events[type][handler.guid];

        // remove all handlers for the given type
        else
          for ( handler in element.$events[type] )
            delete events[type][handler];

        // remove generic event handler if no more handlers exist
        for ( ret in events[type] ) break;
        if ( !ret ) {
          if (element.removeEventListener)
            element.removeEventListener(type, element.$handle, false);
          else
            element.detachEvent("on" + type, element.$handle);
          ret = null;
          delete events[type];

          // Remove element from the global event type cache
          while ( this.global[type] && ( (index = jQuery.inArray(element, this.global[type])) >= 0 ) )
            delete this.global[type][index];
        }
      }

      // Remove the expando if it's no longer used
      for ( ret in events ) break;
      if ( !ret )
        element.$handle = element.$events = null;
    }
  },

  trigger: function(type, data, element) {
    // Clone the incoming data, if any
    data = jQuery.makeArray(data || []);

    // Handle a global trigger
    if ( !element )
      jQuery.each( this.global[type] || [], function(){
        jQuery.event.trigger( type, data, this );
      });

    // Handle triggering a single element
    else {
      var val, ret, fn = jQuery.isFunction( element[ type ] || null );

      // Pass along a fake event
      data.unshift( this.fix({ type: type, target: element }) );

      // Trigger the event
      if ( jQuery.isFunction(element.$handle) && (val = element.$handle.apply( element, data )) !== false )
        this.triggered = true;

      if ( fn && val !== false && !jQuery.nodeName(element, 'a') )
        element[ type ]();

      this.triggered = false;
    }
  },

  handle: function(event) {
    // returned undefined or false
    var val;

    // Empty object is for triggered events with no data
    event = jQuery.event.fix( event || window.event || {} );

    var c = this.$events && this.$events[event.type], args = [].slice.call( arguments, 1 );
    args.unshift( event );

    for ( var j in c ) {
      // Pass in a reference to the handler function itself
      // So that we can later remove it
      args[0].handler = c[j];
      args[0].data = c[j].data;

      if ( c[j].apply( this, args ) === false ) {
        event.preventDefault();
        event.stopPropagation();
        val = false;
      }
    }

    // Clean up added properties in IE to prevent memory leak
    if (jQuery.browser.msie)
      event.target = event.preventDefault = event.stopPropagation =
        event.handler = event.data = null;

    return val;
  },

  fix: function(event) {
    // store a copy of the original event object
    // and clone to set read-only properties
    var originalEvent = event;
    event = jQuery.extend({}, originalEvent);

    // add preventDefault and stopPropagation since
    // they will not work on the clone
    event.preventDefault = function() {
      // if preventDefault exists run it on the original event
      if (originalEvent.preventDefault)
        return originalEvent.preventDefault();
      // otherwise set the returnValue property of the original event to false (IE)
      originalEvent.returnValue = false;
    };
    event.stopPropagation = function() {
      // if stopPropagation exists run it on the original event
      if (originalEvent.stopPropagation)
        return originalEvent.stopPropagation();
      // otherwise set the cancelBubble property of the original event to true (IE)
      originalEvent.cancelBubble = true;
    };

    // Fix target property, if necessary
    if ( !event.target && event.srcElement )
      event.target = event.srcElement;

    // check if target is a textnode (safari)
    if (jQuery.browser.safari && event.target.nodeType == 3)
      event.target = originalEvent.target.parentNode;

    // Add relatedTarget, if necessary
    if ( !event.relatedTarget && event.fromElement )
      event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;

    // Calculate pageX/Y if missing and clientX/Y available
    if ( event.pageX == null && event.clientX != null ) {
      var e = document.documentElement, b = document.body;
      event.pageX = event.clientX + (e && e.scrollLeft || b.scrollLeft);
      event.pageY = event.clientY + (e && e.scrollTop || b.scrollTop);
    }

    // Add which for key events
    if ( !event.which && (event.charCode || event.keyCode) )
      event.which = event.charCode || event.keyCode;

    // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
    if ( !event.metaKey && event.ctrlKey )
      event.metaKey = event.ctrlKey;

    // Add which for click: 1 == left; 2 == middle; 3 == right
    // Note: button is not normalized, so don't use it
    if ( !event.which && event.button )
      event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));

    return event;
  }
};

jQuery.fn.extend({
  bind: function( type, data, fn ) {
    return type == "unload" ? this.one(type, data, fn) : this.each(function(){
      jQuery.event.add( this, type, fn || data, fn && data );
    });
  },
  one: function( type, data, fn ) {
    return this.each(function(){
      jQuery.event.add( this, type, function(event) {
        jQuery(this).unbind(event);
        return (fn || data).apply( this, arguments);
      }, fn && data);
    });
  },
  unbind: function( type, fn ) {
    return this.each(function(){
      jQuery.event.remove( this, type, fn );
    });
  },
  trigger: function( type, data ) {
    return this.each(function(){
      jQuery.event.trigger( type, data, this );
    });
  },
  toggle: function() {
    // Save reference to arguments for access in closure
    var a = arguments;

    return this.click(function(e) {
      // Figure out which function to execute
      this.lastToggle = 0 == this.lastToggle ? 1 : 0;

      // Make sure that clicks stop
      e.preventDefault();

      // and execute the function
      return a[this.lastToggle].apply( this, [e] ) || false;
    });
  },
  hover: function(f,g) {

    // A private function for handling mouse 'hovering'
    function handleHover(e) {
      // Check if mouse(over|out) are still within the same parent element
      var p = e.relatedTarget;

      // Traverse up the tree
      while ( p && p != this ) try { p = p.parentNode } catch(e) { p = this; };

      // If we actually just moused on to a sub-element, ignore it
      if ( p == this ) return false;

      // Execute the right function
      return (e.type == "mouseover" ? f : g).apply(this, [e]);
    }

    // Bind the function to the two event listeners
    return this.mouseover(handleHover).mouseout(handleHover);
  },
  ready: function(f) {
    // If the DOM is already ready
    if ( jQuery.isReady )
      // Execute the function immediately
      f.apply( document, [jQuery] );

    // Otherwise, remember the function for later
    else
      // Add the function to the wait list
      jQuery.readyList.push( function() { return f.apply(this, [jQuery]) } );

    return this;
  }
});

jQuery.extend({
  /*
   * All the code that makes DOM Ready work nicely.
   */
  isReady: false,
  readyList: [],

  // Handle when the DOM is ready
  ready: function() {
    // Make sure that the DOM is not already loaded
    if ( !jQuery.isReady ) {
      // Remember that the DOM is ready
      jQuery.isReady = true;

      // If there are functions bound, to execute
      if ( jQuery.readyList ) {
        // Execute all of them
        jQuery.each( jQuery.readyList, function(){
          this.apply( document );
        });

        // Reset the list of functions
        jQuery.readyList = null;
      }
      // Remove event listener to avoid memory leak
      if ( jQuery.browser.mozilla || jQuery.browser.opera )
        document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );

      // Remove script element used by IE hack
      if( !window.frames.length ) // don't remove if frames are present (#1187)
        jQuery(window).load(function(){ jQuery("#__ie_init").remove(); });
    }
  }
});

new function(){

  jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
    "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
    "submit,keydown,keypress,keyup,error").split(","), function(i,o){

    // Handle event binding
    jQuery.fn[o] = function(f){
      return f ? this.bind(o, f) : this.trigger(o);
    };

  });

  // If Mozilla is used
  if ( jQuery.browser.mozilla || jQuery.browser.opera )
    // Use the handy event callback
    document.addEventListener( "DOMContentLoaded", jQuery.ready, false );

  // If IE is used, use the excellent hack by Matthias Miller
  // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
  else if ( jQuery.browser.msie ) {

    // Only works if you document.write() it
    document.write("<scr" + "ipt id=__ie_init defer=true " +
      "src=" + blankPage + "><\/script>");

    // Use the defer script hack
    var script = document.getElementById("__ie_init");

    // script does not exist if jQuery is loaded dynamically
    if ( script )
      script.onreadystatechange = function() {
        if ( this.readyState != "complete" ) return;
        jQuery.ready();
      };

    // Clear from memory
    script = null;

  // If Safari  is used
  } else if ( jQuery.browser.safari )
    // Continually check to see if the document.readyState is valid
    jQuery.safariTimer = setInterval(function(){
      // loaded and complete are both valid states
      if ( document.readyState == "loaded" ||
        document.readyState == "complete" ) {

        // If either one are found, remove the timer
        clearInterval( jQuery.safariTimer );
        jQuery.safariTimer = null;

        // and execute any waiting functions
        jQuery.ready();
      }
    }, 10);

  // A fallback to window.onload, that will always work
  jQuery.event.add( window, "load", jQuery.ready );

};

// Clean up after IE to avoid memory leaks
if (jQuery.browser.msie)
  jQuery(window).one("unload", function() {
    var global = jQuery.event.global;
    for ( var type in global ) {
      var els = global[type], i = els.length;
      if ( i && type != 'unload' )
        do
          els[i-1] && jQuery.event.remove(els[i-1], type);
        while (--i);
    }
  });
jQuery.fn.extend({
  loadIfModified: function( url, params, callback ) {
    this.load( url, params, callback, 1 );
  },
  load: function( url, params, callback, ifModified ) {
    if ( jQuery.isFunction( url ) )
      return this.bind("load", url);

    callback = callback || function(){};

    // Default to a GET request
    var type = "GET";

    // If the second parameter was provided
    if ( params )
      // If it's a function
      if ( jQuery.isFunction( params ) ) {
        // We assume that it's the callback
        callback = params;
        params = null;

      // Otherwise, build a param string
      } else {
        params = jQuery.param( params );
        type = "POST";
      }

    var self = this;

    // Request the remote document
    jQuery.ajax({
      url: url,
      type: type,
      data: params,
      ifModified: ifModified,
      complete: function(res, status){
        if ( status == "success" || !ifModified && status == "notmodified" )
          // Inject the HTML into all the matched elements
          self.attr("innerHTML", res.responseText)
            // Execute all the scripts inside of the newly-injected HTML
            .evalScripts()
            // Execute callback
            .each( callback, [res.responseText, status, res] );
        else
          callback.apply( self, [res.responseText, status, res] );
      }
    });
    return this;
  },
  serialize: function() {
    return jQuery.param( this );
  },
  evalScripts: function() {
    // DDELANGLE : Patch from JQuery bug http://dev.jquery.com/ticket/975
    if(jQuery.browser.mozilla) {
      // Firefox eval's scripts when they get added to the DOM tree,
      // so this isn't necessary here
      // except for popup thick which need bindforms
      if ($(this).text().indexOf("bindForms()") == -1 ) {
        return this;
      }
    }
    //alert("evalScripts " + typeof(this.find("script")) + "-" + $(this).html());
    return this.find("script").each(function(){
      if ( this.src ) {
        //alert("this.src " + this.src);
        jQuery.getScript( this.src );
      } else {
        //alert("ELSE " + this.text || this.textContent || this.innerHTML || "");
        jQuery.globalEval( this.text || this.textContent || this.innerHTML || "" );
      }
    }).end();
  }

});

// Attach a bunch of functions for handling common AJAX events

jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
  jQuery.fn[o] = function(f){
    return this.bind(o, f);
  };
});

jQuery.extend({
  get: function( url, data, callback, type, ifModified ) {
    // shift arguments if data argument was ommited
    if ( jQuery.isFunction( data ) ) {
      callback = data;
      data = null;
    }

    return jQuery.ajax({
      type: "GET",
      url: url,
      data: data,
      success: callback,
      dataType: type,
      ifModified: ifModified
    });
  },
  getIfModified: function( url, data, callback, type ) {
    return jQuery.get(url, data, callback, type, 1);
  },
  getScript: function( url, callback ) {
    return jQuery.get(url, null, callback, "script");
  },
  getJSON: function( url, data, callback ) {
    return jQuery.get(url, data, callback, "json");
  },
  post: function( url, data, callback, type ) {
    if ( jQuery.isFunction( data ) ) {
      callback = data;
      data = {};
    }

    return jQuery.ajax({
      type: "POST",
      url: url,
      data: data,
      success: callback,
      dataType: type
    });
  },
  ajaxTimeout: function( timeout ) {
    jQuery.ajaxSettings.timeout = timeout;
  },
  ajaxSetup: function( settings ) {
    jQuery.extend( jQuery.ajaxSettings, settings );
  },

  ajaxSettings: {
    global: true,
    type: "GET",
    timeout: 0,
    contentType: "application/x-www-form-urlencoded",
    processData: true,
    async: true,
    data: null
  },

  // Last-Modified header cache for next request
  lastModified: {},
  ajax: function( s ) {
    // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
    s = jQuery.extend({}, jQuery.ajaxSettings, s);

    // if data available
    if ( s.data ) {
      // convert data if not already a string
      if (s.processData && typeof s.data != "string")
          s.data = jQuery.param(s.data);
      // append data to url for get requests
      if( s.type.toLowerCase() == "get" ) {
        // "?" + data or "&" + data (in case there are already params)
        s.url += ((s.url.indexOf("?") > -1) ? "&" : "?") + s.data;
        // IE likes to send both get and post data, prevent this
        s.data = null;
      }
    }

    // Watch for a new set of requests
    if ( s.global && ! jQuery.active++ )
      jQuery.event.trigger( "ajaxStart" );

    var requestDone = false;

    // Create the request object; Microsoft failed to properly
    // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
    var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();

    // Open the socket
    xml.open(s.type, s.url, s.async);

    // Set the correct header, if data is being sent
    if ( s.data )
      xml.setRequestHeader("Content-Type", s.contentType);

    // Set the If-Modified-Since header, if ifModified mode.
    if ( s.ifModified )
      xml.setRequestHeader("If-Modified-Since",
        jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );

    // Set header so the called script knows that it's an XMLHttpRequest
    xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");

    // Allow custom headers/mimetypes
    if( s.beforeSend )
      s.beforeSend(xml);

    if ( s.global )
        jQuery.event.trigger("ajaxSend", [xml, s]);

    // Wait for a response to come back
    var onreadystatechange = function(isTimeout){
      // The transfer is complete and the data is available, or the request timed out
      if ( xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
        requestDone = true;

        // clear poll interval
        if (ival) {
          clearInterval(ival);
          ival = null;
        }

        var status;
        try {
          status = jQuery.httpSuccess( xml ) && isTimeout != "timeout" ?
            s.ifModified && jQuery.httpNotModified( xml, s.url ) ? "notmodified" : "success" : "error";
          // Make sure that the request was successful or notmodified
          if ( status != "error" ) {
            // Cache Last-Modified header, if ifModified mode.
            var modRes;
            try {
              modRes = xml.getResponseHeader("Last-Modified");
            } catch(e) {} // swallow exception thrown by FF if header is not available

            if ( s.ifModified && modRes )
              jQuery.lastModified[s.url] = modRes;

            // process the data (runs the xml through httpData regardless of callback)
            var data = jQuery.httpData( xml, s.dataType );

            // If a local callback was specified, fire it and pass it the data
            if ( s.success )
              s.success( data, status );

            // Fire the global callback
            if( s.global )
              jQuery.event.trigger( "ajaxSuccess", [xml, s] );
          } else
            jQuery.handleError(s, xml, status);
        } catch(e) {
          status = "error";
          jQuery.handleError(s, xml, status, e);
        }

        // The request was completed
        if( s.global )
          jQuery.event.trigger( "ajaxComplete", [xml, s] );

        // Handle the global AJAX counter
        if ( s.global && ! --jQuery.active )
          jQuery.event.trigger( "ajaxStop" );

        // Process result
        if ( s.complete )
          s.complete(xml, status);

        // Stop memory leaks
        if(s.async)
          xml = null;
      }
    };

    // don't attach the handler to the request, just poll it instead
    var ival = setInterval(onreadystatechange, 13);

    // Timeout checker
    if ( s.timeout > 0 )
      setTimeout(function(){
        // Check to see if the request is still happening
        if ( xml ) {
          // Cancel the request
          xml.abort();

          if( !requestDone )
            onreadystatechange( "timeout" );
        }
      }, s.timeout);

    // Send the data
    try {
      xml.send(s.data);
    } catch(e) {
      jQuery.handleError(s, xml, null, e);
    }

    // firefox 1.5 doesn't fire statechange for sync requests
    if ( !s.async )
      onreadystatechange();

    // return XMLHttpRequest to allow aborting the request etc.
    return xml;
  },

  handleError: function( s, xml, status, e ) {
    // If a local callback was specified, fire it
    if ( s.error ) s.error( xml, status, e );

    // Fire the global callback
    if ( s.global )
      jQuery.event.trigger( "ajaxError", [xml, s, e] );
  },

  // Counter for holding the number of active queries
  active: 0,

  // Determines if an XMLHttpRequest was successful or not
  httpSuccess: function( r ) {
    try {
      return !r.status && location.protocol == "file:" ||
        ( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
        jQuery.browser.safari && r.status == undefined;
    } catch(e){}
    return false;
  },

  // Determines if an XMLHttpRequest returns NotModified
  httpNotModified: function( xml, url ) {
    try {
      var xmlRes = xml.getResponseHeader("Last-Modified");

      // Firefox always returns 200. check Last-Modified date
      return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
        jQuery.browser.safari && xml.status == undefined;
    } catch(e){}
    return false;
  },

  /* Get the data out of an XMLHttpRequest.
   * Return parsed XML if content-type header is "xml" and type is "xml" or omitted,
   * otherwise return plain text.
   * (String) data - The type of data that you're expecting back,
   * (e.g. "xml", "html", "script")
   */
  httpData: function( r, type ) {
    var ct = r.getResponseHeader("content-type");
    var data = !type && ct && ct.indexOf("xml") >= 0;
    data = type == "xml" || data ? r.responseXML : r.responseText;

    // If the type is "script", eval it in global context
    if ( type == "script" )
      jQuery.globalEval( data );

    // Get the JavaScript object, if JSON is used.
    if ( type == "json" )
      data = eval("(" + data + ")");

    // evaluate scripts within html
    if ( type == "html" )
      jQuery("<div>").html(data).evalScripts();

    return data;
  },

  // Serialize an array of form elements or a set of
  // key/values into a query string
  param: function( a ) {
    var s = [];

    // If an array was passed in, assume that it is an array
    // of form elements
    if ( a.constructor == Array || a.jquery )
      // Serialize the form elements
      jQuery.each( a, function(){
        s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
      });

    // Otherwise, assume that it's an object of key/value pairs
    else
      // Serialize the key/values
      for ( var j in a )
        // If the value is an array then the key names need to be repeated
        if ( a[j] && a[j].constructor == Array )
          jQuery.each( a[j], function(){
            s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
          });
        else
          s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );

    // Return the resulting serialization
    return s.join("&");
  },

  // evalulates a script in global context
  // not reliable for safari
  globalEval: function( data ) {
    if ( window.execScript )
      window.execScript( data );
    else if ( jQuery.browser.safari )
      // safari doesn't provide a synchronous global eval
      window.setTimeout( data, 0 );
    else
      eval.call( window, data );
  }

});
jQuery.fn.extend({

  show: function(speed,callback){
    return speed ?
      this.animate({
        height: "show", width: "show", opacity: "show"
      }, speed, callback) :

      this.filter(":hidden").each(function(){
        this.style.display = this.oldblock ? this.oldblock : "";
        if ( jQuery.css(this,"display") == "none" )
          this.style.display = "block";
      }).end();
  },

  hide: function(speed,callback){
    return speed ?
      this.animate({
        height: "hide", width: "hide", opacity: "hide"
      }, speed, callback) :

      this.filter(":visible").each(function(){
        this.oldblock = this.oldblock || jQuery.css(this,"display");
        if ( this.oldblock == "none" )
          this.oldblock = "block";
        this.style.display = "none";
      }).end();
  },

  // Save the old toggle function
  _toggle: jQuery.fn.toggle,
  toggle: function( fn, fn2 ){
    return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
      this._toggle( fn, fn2 ) :
      fn ?
        this.animate({
          height: "toggle", width: "toggle", opacity: "toggle"
        }, fn, fn2) :
        this.each(function(){
          jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
        });
  },
  slideDown: function(speed,callback){
    return this.animate({height: "show"}, speed, callback);
  },
  slideUp: function(speed,callback){
    return this.animate({height: "hide"}, speed, callback);
  },
  slideToggle: function(speed, callback){
    return this.animate({height: "toggle"}, speed, callback);
  },
  fadeIn: function(speed, callback){
    return this.animate({opacity: "show"}, speed, callback);
  },
  fadeOut: function(speed, callback){
    return this.animate({opacity: "hide"}, speed, callback);
  },
  fadeTo: function(speed,to,callback){
    return this.animate({opacity: to}, speed, callback);
  },
  animate: function( prop, speed, easing, callback ) {
    return this.queue(function(){
      var hidden = jQuery(this).is(":hidden"),
        opt = jQuery.speed(speed, easing, callback),
        self = this;

      for ( var p in prop ) {
        if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
          return jQuery.isFunction(opt.complete) && opt.complete.apply(this);

        if ( p == "height" || p == "width" ) {
          // Store display property
          opt.display = jQuery.css(this, "display");

          // Make sure that nothing sneaks out
          opt.overflow = this.style.overflow;
        }
      }

      if ( opt.overflow != null )
        this.style.overflow = "hidden";

      this.curAnim = jQuery.extend({}, prop);

      jQuery.each( prop, function(name, val){
        var e = new jQuery.fx( self, opt, name );
        if ( val.constructor == Number )
          e.custom( e.cur(), val );
        else
          e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
      });
    });
  },
  queue: function(type,fn){
    if ( !fn ) {
      fn = type;
      type = "fx";
    }

    return this.each(function(){
      if ( !this.queue )
        this.queue = {};

      if ( !this.queue[type] )
        this.queue[type] = [];

      this.queue[type].push( fn );

      if ( this.queue[type].length == 1 )
        fn.apply(this);
    });
  }

});

jQuery.extend({

  speed: function(speed, easing, fn) {
    var opt = speed && speed.constructor == Object ? speed : {
      complete: fn || !fn && easing ||
        jQuery.isFunction( speed ) && speed,
      duration: speed,
      easing: fn && easing || easing && easing.constructor != Function && easing || (jQuery.easing.swing ? "swing" : "linear")
    };

    opt.duration = (opt.duration && opt.duration.constructor == Number ?
      opt.duration :
      { slow: 600, fast: 200 }[opt.duration]) || 400;

    // Queueing
    opt.old = opt.complete;
    opt.complete = function(){
      jQuery.dequeue(this, "fx");
      if ( jQuery.isFunction( opt.old ) )
        opt.old.apply( this );
    };

    return opt;
  },

  easing: {
    linear: function( p, n, firstNum, diff ) {
      return firstNum + diff * p;
    },
    swing: function( p, n, firstNum, diff ) {
      return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
    }
  },

  queue: {},

  dequeue: function(elem,type){
    type = type || "fx";

    if ( elem.queue && elem.queue[type] ) {
      // Remove self
      elem.queue[type].shift();

      // Get next function
      var f = elem.queue[type][0];

      if ( f ) f.apply( elem );
    }
  },

  timers: [],

  /*
   * I originally wrote fx() as a clone of moo.fx and in the process
   * of making it small in size the code became illegible to sane
   * people. You've been warned.
   */

  fx: function( elem, options, prop ){

    var z = this;

    // The styles
    var y = elem.style;

    // Simple function for setting a style value
    z.a = function(){
      if ( options.step )
        options.step.apply( elem, [ z.now ] );

      if ( prop == "opacity" )
        jQuery.attr(y, "opacity", z.now); // Let attr handle opacity
      else {
        y[prop] = parseInt(z.now) + "px";
        y.display = "block"; // Set display property to block for animation
      }
    };

    // Figure out the maximum number to run to
    z.max = function(){
      return parseFloat( jQuery.css(elem,prop) );
    };

    // Get the current size
    z.cur = function(){
      var r = parseFloat( jQuery.curCSS(elem, prop) );
      return r && r > -10000 ? r : z.max();
    };

    // Start an animation from one number to another
    z.custom = function(from,to){
      z.startTime = (new Date()).getTime();
      z.now = from;
      z.a();

      jQuery.timers.push(function(){
        return z.step(from, to);
      });

      if ( jQuery.timers.length == 1 ) {
        var timer = setInterval(function(){
          var timers = jQuery.timers;

          for ( var i = 0; i < timers.length; i++ )
            if ( !timers[i]() )
              timers.splice(i--, 1);

          if ( !timers.length )
            clearInterval( timer );
        }, 13);
      }
    };

    // Simple 'show' function
    z.show = function(){
      if ( !elem.orig ) elem.orig = {};

      // Remember where we started, so that we can go back to it later
      elem.orig[prop] = jQuery.attr( elem.style, prop );

      options.show = true;

      // Begin the animation
      z.custom(0, this.cur());

      // Make sure that we start at a small width/height to avoid any
      // flash of content
      if ( prop != "opacity" )
        y[prop] = "1px";

      // Start by showing the element
      jQuery(elem).show();
    };

    // Simple 'hide' function
    z.hide = function(){
      if ( !elem.orig ) elem.orig = {};

      // Remember where we started, so that we can go back to it later
      elem.orig[prop] = jQuery.attr( elem.style, prop );

      options.hide = true;

      // Begin the animation
      z.custom(this.cur(), 0);
    };

    // Each step of an animation
    z.step = function(firstNum, lastNum){
      var t = (new Date()).getTime();

      if (t > options.duration + z.startTime) {
        z.now = lastNum;
        z.a();

        if (elem.curAnim) elem.curAnim[ prop ] = true;

        var done = true;
        for ( var i in elem.curAnim )
          if ( elem.curAnim[i] !== true )
            done = false;

        if ( done ) {
          if ( options.display != null ) {
            // Reset the overflow
            y.overflow = options.overflow;

            // Reset the display
            y.display = options.display;
            if ( jQuery.css(elem, "display") == "none" )
              y.display = "block";
          }

          // Hide the element if the "hide" operation was done
          if ( options.hide )
            y.display = "none";

          // Reset the properties, if the item has been hidden or shown
          if ( options.hide || options.show )
            for ( var p in elem.curAnim )
              jQuery.attr(y, p, elem.orig[p]);
        }

        // If a callback was provided, execute it
        if ( done && jQuery.isFunction( options.complete ) )
          // Execute the complete function
          options.complete.apply( elem );

        return false;
      } else {
        var n = t - this.startTime;
        // Figure out where in the animation we are and set the number
        var p = n / options.duration;

        // Perform the easing function, defaults to swing
        z.now = jQuery.easing[options.easing](p, n, firstNum, (lastNum-firstNum), options.duration);

        // Perform the next step of the animation
        z.a();
      }

      return true;
    };

  }
});
}
/* --- Constantes / Variables globales --- */

/* id de la div contenant les shutter */
var mainFrame = "#mainframe";

/* id de la div pour un shutter */
var shutter = "#shutter";

/* chemin de l'option 'preview' */
var preview = "/preview";

/* chemin de l'option 'preview' */
var fullscreenKeyword = "/layout-fullscreen/";

/* constantes */
var INIT_LEFT = 200;
var TOTAL_MARGIN = 80;

/* shutterIndex : represente l'id du dernier volet et le nombre de volets */
var shutterIndex = 1;

/* minLevel : represente le niveau du volet ayant le niveau le plus bas */
var minLevel = 1;

/* valeur de vitesse et de type d'animation */
var effectDuration = 1500;
var slideEffect = "easeout";

/* constante : nombre max de niveau */
var MAX_LEVEL = 8;

var currentContext = "";

/* valeur fixe de la marge d'un shutter (utilisé pour les flashs) */
var customLeftMargin = "";

var shutterTargeted;

var myUrl;
var myUrlLevel;

var INITIAL_SHUTTER_WIDTH = 710;
var _generatedWidth = 990;

var controllerDebug = false;

/* used for pane only */
var replaceId = null;

/* ------------------------ */
/* -private- writeDebug --- */
/* ------------------------ */
function writeDebug(msg) {
    if (controllerDebug) {
      console.debug(msg);
    }
}

/* -------------------------- */
/* -private-- JSController --- */
/* -------------------------- */

function JSController(url, addToLeft, isShutter, alignLeft) {

  /* #1512 (curseur défilement reste malgré changement de page) */
  $("div.cursor_scroll").remove();

  /* #982 (autocompletion pour tous les champs Pays) */
  $("div.ac_results").hide();

  customLeftMargin = "";
  shutterTargeted = 0;

  var sharpPosition = url.indexOf('#/' + lang ,0) + ('#/' + lang).length;
  var urlTop = "#";
  var levelDiff;
  var urlSplit;

  /* Cas si le lien n'est pas un shutter */
  if (!isShutter) {
    document.location = url;
  /* Cas où le # est present (en début de chaine) */
  /* On supprime le '#/{lang}' en debut et on remplace '.html' par '/' */
  } else if (sharpPosition > 0) {
    myUrl = url.substring(sharpPosition, url.length).replace(/\.html/,'/');
    /* Le niveau de l'url ne tient pas compte de parametres ('_') et du dernier '/' */
    myUrlLevel = returnLevel(myUrl);

    /* si la nouvelle URL a un niveau inférieur on le stocke */
    if (minLevel < myUrlLevel) {
      minLevel = myUrlLevel;
    }

    var noAnimation = false;
    if (addToLeft == true) {
      levelDiff = "ADD_LEFT";
    } else if (addToLeft == false && addToLeft != null) {
      levelDiff = "ADD_RIGHT";
    } else if (addToLeft == "new") {
      levelDiff = "NEW";
    } else if (addToLeft == "replace_left") {
      levelDiff = "REPLACE_LEFT";
      noAnimation = true;
    } else if (addToLeft == "replace_right") {
      levelDiff = "REPLACE_RIGHT";
      noAnimation = true;
    } else {
      levelDiff = compareLevelUrl(context,myUrl);
    }

    /* #1498 exception des volets de la fiche produit */
    /* --> url contient _ispanel=true ou _pane=XXX */
    /* cas 1 : pas de volet ouvert --> ajout a droite de la fiche produit */
    /* cas 2 : un volet a deja été ouvert --> remplacement du volet courant */

    replaceId = null;
    if (levelDiff == "ADD_LEFT" || levelDiff == "ADD_RIGHT") {
      writeDebug("context: " + context);
      writeDebug("myUrl: " + myUrl);

      if (myUrl.indexOf('_ispanel=true') > -1 || myUrl.indexOf('_pane=') > -1) {
        writeDebug("Exception volet");
        if (context.indexOf('_ispanel=true') > -1 || context.indexOf('_pane=') > -1) {
          writeDebug("cas 2");
          levelDiff = "REPLACE";
          replaceId = shutterIndex;
        } else {
          writeDebug("cas 1");
        }
      }

    }

    writeDebug("levelDiff: " + levelDiff);

    /* context is not usable because the context is updated before the animation is played */
    currentContext = context;

    switch (levelDiff) {
      case "ADD_LEFT":
        addShutter(myUrl, true, alignLeft);
        break;

      case "ADD_RIGHT":
        addShutter(myUrl, false, alignLeft);
        break;

      case "NEW":
        cleanShutter(myUrl);
        break;

      case "REPLACE":
        replaceShutter(myUrl, myUrlLevel, 0, noAnimation, replaceId, alignLeft);
        break;

      case "REPLACE_LEFT":
        replaceShutter(myUrl, myUrlLevel, -1, noAnimation);
        break;

      case "REPLACE_RIGHT":
        replaceShutter(myUrl, myUrlLevel, 1, noAnimation);
        break;

      default:
        writeDebug("CAS NON GéRé: '" + levelDiff + "'");
        break;
    }

    /* Mise a jour du contexte */
    context = myUrl;

    shutterIndex = shutterTargeted;
  }
}

/* ----------------------------- */
/* -private- compareLevelUrl --- */
/* ----------------------------- */
function compareLevelUrl(old_url, new_url) {
   /* suppression des eventuels parametres en fin d'URL (_...) */
   oldUrl = old_url.replace(/_.*$/, '').replace(/\/$/,'');
   newUrl = new_url.replace(/_.*$/, '').replace(/\/$/,'');

   var commonLevel = 0;
   var continueLoop = true;
   var returnVal = "";
   var nl = returnLevel(newUrl);
   var ol = returnLevel(oldUrl);
   var nbPlaceNeeded;
   var tOldUrl = oldUrl.split("/");
   var tNewUrl = newUrl.split("/");

   /* suppression du premier element (vide) */
   tOldUrl.shift();
   tNewUrl.shift();

   /* calcul du nombre de niveaux communs entre les 2 URL */
   while (commonLevel < tOldUrl.length && continueLoop) {
     if (tOldUrl[commonLevel] == tNewUrl[commonLevel]) {
       commonLevel++;
     } else {
       continueLoop = false;
     }
   }

   /* implicite: !(commonLevel>0) si les 2 URL sont completement différentes -> on supprime tout les volets (NEW) */
   returnVal = "NEW";
   if (commonLevel > 0) {
      /* (max(ol,nl)-commonLevel <= 1) la différence entre le niveau courant et le nombre de niveau en commun entre les 2 URL doit etre egal ou inférieur a 1
         (ie. /a/a1/a11 et /a/b1/b11 -> 3 - 1 = 2 NOK)
         (ie. /a/a1/a11 et /a/a1/a12 -> 3 - 2 = 1  OK)
         (ie. /a/a1/a11 et /a/b1/    -> 3 - 1 = 2 NOK)
         (ie. /a/a1/a11 et /a/a1/    -> 3 - 2 = 1  OK)
         (ie. /a/a1/    et /a/b1/b12 -> 3 - 1 = 2 NOK)
         (ie. /a/a1/    et /a/a1/a12 -> 3 - 2 = 1  OK) */
      if (Math.max(ol,nl) - commonLevel <= 1) {

        /* les niveaux sont equivalents, on remplace le contenu du volet */
        if (ol == nl) {
          if (shutterExist(newUrl)) {
            returnVal = "REPLACE";
          } else {
            returnVal = "NEW";
          }
        } else {

          /* calcul du nombre de places nécessaires : 0 si le volet existe deja sinon 1 */
          nbPlaceNeeded = 1;
          if (shutterExist(newUrl)) {
            nbPlaceNeeded = 0;
          }

          /* il doit toujours rester une place libre (ou 0 si le volet existe deja) : le nombre de place libre est determiné en fonction du niveau le plus bas
          ie. a niveau min 4 et de nombre de shutter 2, on a 2 places pour les volets disponibles */
          if (minLevel - shutterIndex >= nbPlaceNeeded) {
            /* le niveau de l'ancienne URL est inférieur à la nouvelle (ie. /a/a1 -> /a) */
            if (ol == nl + 1) {
              if (getShutterIndexForLevel(nl) != 0 && !shutterExist(new_url)) {
                returnVal = "REPLACE_LEFT";
              } else {
                returnVal = "ADD_LEFT";
              }
            }
            /* le niveau de l'ancienne URL est supérieur à la nouvelle (ie. /a -> /a/a1) */
            else if (ol == nl - 1) {
              if (getShutterIndexForLevel(nl) != 0 && !shutterExist(new_url)) {
                returnVal = "REPLACE_RIGHT";
              } else {
                returnVal = "ADD_RIGHT";
              }
            }
          }
        }
      }
   }

   return returnVal;
}

/* ------------------------- */
/* -private- returnLevel --- */
/* ------------------------- */
function returnLevel(url) {
  /* suppression des parametres de l'url (_...) et du dernier */
  var _url = url.replace(/_.*$/, '').replace(/\/$/,'');
  return _url.split("/").length - 1;
}

/* ------------------------ */
/* -private- addShutter --- */
/* ------------------------ */
function addShutter(url, add_to_left, align_to_left) {
  // #1801 : special case for tint page
  var tintSpecialCase = context.lastIndexOf("_pane=tint") == context.length - "_pane=tint".length;
  tintSpecialCase = tintSpecialCase && returnLevel(context) == returnLevel(url);

  if (!shutterExist(url) && !tintSpecialCase ) {

    /* le shutter n'existe pas, on en crée un nouveau */
    var emptyShutter = getNewShutter(++shutterIndex);
    shutterTargeted = shutterIndex;
    if (add_to_left) {
      $(mainFrame).prepend(emptyShutter);
      $(mainFrame).css({left: INIT_LEFT - TOTAL_MARGIN - INITIAL_SHUTTER_WIDTH});
      /*insertion a gauche : suppression du volet a droite */
      ajaxCall(url, shutterIndex, "moveShutter()");
    } else {
      $(mainFrame).append(emptyShutter);
      /* insertion a droite on doit lancer l'animation de décalage la div "mainframe" vers la gauche */
      ajaxCall(url, shutterIndex, "addShutterAnimation(1," + align_to_left + ")");
    }

  } else {

    if (add_to_left) {
      if (tintSpecialCase) {
        var shutterList = getShutterList();
        shutterTargeted = parseInt($(shutterList[shutterList.length-2]).find(".shutter-url").attr("title"));
      } else {
        shutterTargeted = shutterId(url);
      }
      addShutterAnimation(-1, align_to_left);
    } else {
      shutterTargeted = shutterIndex;
      addShutterAnimation(1, align_to_left);
    }

  }
}

/* --------------------------------- */
/* -private- addShutterAnimation --- */
/* --------------------------------- */
function addShutterAnimation(aDirection, alignToLeft) {
  customLeftMargin = getMargin(shutterTargeted);

  /* alignement du volet courant sur la gauche du navigateur */
  if (alignToLeft) {
    moveShutter();
  } else {
    var documentWidth = _generatedWidth;
    var shutterList = getShutterList();
    var widthNextToLastShutter = $(shutterList[shutterList.length-2]).width() + getShutterPadding(shutterList[shutterList.length-2]);
    var widthLastShutter = $(shutterList[shutterList.length-1]).width() + getShutterPadding(shutterList[shutterList.length-1]);

    /* alignement du volet courant sur la droite du naviagteur ou sinon à la droite du dernir volet  */
    if (INIT_LEFT + widthNextToLastShutter + widthLastShutter > documentWidth) {
      if (aDirection == 1) {
        moveShutter(documentWidth - getTotalWidth(), false);
      } else {
        moveShutter();
      }
    }
  }
}

/* -------------------------- */
/* -private- cleanShutter --- */
/* -------------------------- */
function cleanShutter(url) {
  shutterIndex = 1;
  shutterTargeted = 1;
  minLevel = returnLevel(url);
  ajaxCall(url, shutterIndex, "cleanShutterAnimation()", true);
}

/* ----------------------------------- */
/* -private- cleanShutterAnimation --- */
/* ----------------------------------- */
function cleanShutterAnimation() {
  $(mainFrame).css({left: getMargin(shutterIndex)});
}

/* ---------------------------- */
/* -private- replaceShutter --- */
/* ---------------------------- */
/* direction: 0 - REPLACE
             -1 - REPLACE_LEFT
              1 - REPLACE_RIGHT */
function replaceShutter(url, urlLevel, direction, noAnimation, index, alignLeft) {
  writeDebug("replaceShutter: " + url + " noAnimation: " + noAnimation);

  /* idx can be set manually (used in tint page) */
  var idx = index;
  if (idx == null) {
    idx = getShutterIndexForLevel(urlLevel + direction);
    if (idx == 0) {
      idx = 1;
    }
  }

  shutterTargeted = idx;

  if (noAnimation) {
    ajaxCall(url, idx, "");
  } else {
    if (alignLeft == null || alignLeft == true) {
      ajaxCall(url, idx, "replaceShutterAnimation()");
    } else {
      ajaxCall(url, idx, "addShutterAnimation(1, " + alignLeft + ")");
    }

  }
}

/* ------------------------------------- */
/* -private- replaceShutterAnimation --- */
/* ------------------------------------- */
function replaceShutterAnimation() {
  moveShutter();
}

/* -------------------------------- */
/* -public- closeCurrentShutter --- */
/* -------------------------------- */
function closeCurrentShutter() {
  history.back();
}

/* ------------------------- */
/* -private- moveShutter --- */
/* ------------------------- */
function moveShutter() {
  var mainFrameShift = 0;
  var mainFrameLeft = parseInt($(mainFrame).css("left").replace(/px/,''));

  if(arguments.length == 0) {
    /* pas d'argument : mode aligné à gauche */
    var currentId = 0;
    getShutterList().each( function() {
      currentId = parseInt($(this).attr("id").replace(/shutter/,''));
      /* on additionne les marges et les tailles des shutters précedant le shutter courant, pour obtenir le deplacement total */
      if (currentId != shutterTargeted) {
        mainFrameShift -= parseInt($(this).width());
        mainFrameShift -= getShutterPadding(this);
      } else {
        /* on additionne la marge de gauche du shutter courant et on met fin à la boucle */
        mainFrameShift += getMargin(shutterTargeted);
        return false;
      }
    });

    writeDebug("mainFrameLeft: " + mainFrameLeft);
    writeDebug("mainFrameShift: " + mainFrameShift);
    if(mainFrameLeft <= mainFrameShift) {
      removeShutter();
    }
  } else {
    /* argument 1 (taille) : mode libre */
    mainFrameShift = parseInt(arguments[0]);
    if(parseInt(arguments[0]) > 0) {
      /* argument 1 (boolean) : bloquage de la suppression */
      remove = true;
      if (arguments.length > 1) {
        if (arguments[1] == false) {
          remove = false;
        }
      }
      if (remove) {
        removeShutter();
      }
    }
  }

  if (mainFrameLeft != mainFrameShift) {
    $(mainFrame).animate({left: mainFrameShift}, effectDuration, slideEffect);
  }
}

/* ---------------------- */
/* -private- ajaxCall --- */
/* ---------------------- */
function ajaxCall(url, sIndex, aFunction, cleanBeforeInsert) {
  url = url.replace(/</ ," ")
  url = url.replace(/script>/ ," ")
  var isPreview = preview;
  var previewIndex = url.indexOf(preview);
  if (previewIndex > -1) {
    /* removing keyword preview from url */
    url = url.substr(0,previewIndex) + url.substr(previewIndex + preview.length, url.length);
  } else {
    isPreview = "";
  }

  /* moving jsessionid at first call */
  var jSessionID = "";
  if (appContext.indexOf(";jsessionid=") > -1) {
    jSessionID = appContext.substr(appContext.indexOf(";jsessionid="), appContext.length);
    appContext = appContext.substr(0, appContext.indexOf(";jsessionid="));
  }

  var beginUrl = location.protocol + "//" + location.host + appContext + isPreview;
  var endUrl = appSite + "/" + lang + url.replace(/_/,"?") + jSessionID;
  var ajaxHttpsUrl = beginUrl + "/layout-https" + endUrl;
  
  if (ajaxHttpsUrl.indexOf("?") > -1) {
	  ajaxHttpsUrl += "&host=" + location.host;
  } else {
	  ajaxHttpsUrl += "?host=" + location.host;
  }
  
  $.get(
    ajaxHttpsUrl,
    "",
    function(data, textStatus) {
      var ajaxUrl;
      /* no redirect */
      if (data == "null") {
        var ajaxUrl = beginUrl + "/layout-shutter" + endUrl;
         $.ajax({
          type: "GET",
          url: ajaxUrl,
          dataType: "html",
          success: function(data, textStatus) {
            if (cleanBeforeInsert != null && cleanBeforeInsert) {
              $(mainFrame).html(getNewShutter(shutterIndex));
            }
            $(shutter + sIndex).toggleClass("setBackground");
            var divInfos = "<div class='shutter-url' title='" + sIndex + "'>" + url + "</div>";
            if(jQuery.browser.mozilla) {
              $(shutter + sIndex).html(data + divInfos);
            } else {
              $(shutter + sIndex).html(data + divInfos).evalScripts();
            }
            eval(aFunction + ";");
          }
        });
      /* redirect */
      } else {
    	var newUrl = data.replace('/layout-https','');
    	var hostPosition = newUrl.indexOf("host=");
    	newUrl = newUrl.substr(0, hostPosition-1);
        redirectHash(newUrl);
      }
    }
  );

}

/* -------------------------- */
/* -private- shutterExist --- */
/* -------------------------- */
function shutterExist(text) {
  return shutterId(text) != 0;
}

/* ----------------------- */
/* -private- shutterId --- */
/* ----------------------- */
function shutterId(text) {
  var id = 0;
  $(".shutter-url").each( function () {
    if($(this).text() == text) {
      id = parseInt($(this).attr("title"));
    }
  });
  writeDebug("shutterId(" + text + "): " + id);
  return id;
}

/* --------------------------- */
/* -private- getNewShutter --- */
/* --------------------------- */
function getNewShutter(index) {
  return '<div id="shutter' + index + '" class="shutter"></div>';
}

/* ----------------------- */
/* -private- getMargin --- */
/* ----------------------- */
function getMargin(index) {
  var margin = INIT_LEFT;
  var customMargin = $("#shutter" + index + " input[@name=customLeftMargin]").val();
  if (customMargin != null) {
    margin = customMargin;
  }
  return parseInt(margin);
}

/* --------------------------- */
/* -private- removeShutter --- */
/* --------------------------- */

function removeShutter() {
  writeDebug("removeShutter: removing shutter number " + shutterTargeted);

  /* removing the shutter from the last to the one after the shutter with id index */
  var shutterList = getShutterList();
  var i;
  var currentId = 0;
  var remove = true;
  var temp=0;
  for (i=shutterList.length-1; i>=0; i--) {
    currentId = parseInt($(shutterList[i]).attr("id").replace(/shutter/,''));
    if (currentId == shutterTargeted) {
      remove = false;
    }
    if (remove) {
      /* suppression du volet avec effet de fadeOut */
      $(shutter + currentId).fadeOut(effectDuration, function() {

	//Afin d'éviter les boucles infinies lors d'un window.back trop rapide.
    temp++;
	try {
	 	if (temp <= 5){
	 		$(this).remove();
	 	}
	 }
 	catch (e) {
     	//nothing
     }


      });
    }
  }
}

/* ------------------------------------ */
/* -public-- loadPageWithoutHistory --- */
/* ------------------------------------ */

function loadPageWithoutHistory(url) {
  loadPage(url, false);
}

/* --------------------------------- */
/* -public-- loadPageWithHistory --- */
/* --------------------------------- */

function loadPageWithHistory(url) {
  loadPage(url, true)
}

/* ----------------------- */
/* -private-- loadPage --- */
/* ----------------------- */

function loadPage(url, withHistory) {
  try {

    /* Cas où c'est un mini-site fullscreen */
    if (url.indexOf(fullscreenKeyword) > 0) {
      showPopup(url, screen.availHeight, screen.availWidth);
    } else {

      var brandPath = appContext + appSite + "/";
      var strRedirect = url.substring(url.indexOf(brandPath) + brandPath.length - 1);
      /* replacing the ? by _ (if exists) */
      strRedirect = strRedirect.replace(/\?/, '_');
      if (withHistory) {
        writeDebug("loadPage: currentRel " + currentRel);
        writeDebug("loadPage: strRedirect " + strRedirect);

        if (currentRel == '') {
          currentRel = "align.left shutter.true";
        }

        /* 1498 */
        if (currentRel.indexOf("position.right") > -1) {
          if (strRedirect.indexOf('_ispanel=true') > -1 || strRedirect.indexOf('_pane=') > -1) {
            if (context.indexOf('_ispanel=true') > -1 || context.indexOf('_pane=') > -1) {
              history.back();
            }
          }
        }

      if ("#" + strRedirect == location.hash) {
          JSController("#" + strRedirect, null, true, true);
      } else {
      
	      if(!jQuery.browser.mozilla) {
	        $.historyLoad(strRedirect);
	      } else {
	        location.hash = "#" + strRedirect;
	      }
        }
      } else {
        JSController("#" + strRedirect, null, true, true);
      }

    }

  } catch(e) {
    alert("Error in loadPage(" + url + "," + withHistory + "): " + e);
  }
}

/* ---------------------------- */
/* -private-- getTotalWidth --- */
/* ---------------------------- */
function getTotalWidth() {
  var totalWidth = 0;

  getShutterList().each( function () {
    totalWidth += parseInt($(this).width());
    totalWidth += getShutterPadding(this);
  });

  writeDebug("getTotalWidth: " + totalWidth)
  return totalWidth;
}

/* ----------------------------- */
/* -private-- getShutterList --- */
/* ----------------------------- */
function getShutterList() {
  return $(mainFrame + " .shutter");
}

/* -------------------------------------- */
/* -private-- getShutterIndexForLevel --- */
/* -------------------------------------- */
function getShutterIndexForLevel(level) {
  var index = 0;
   $(".shutter-url").each( function() {
    writeDebug("getShutterIndexForLevel: " + $(this).text());
    if ( returnLevel($(this).text()) == level) {
      index = parseInt($(this).attr("title"));
    }
  });
  return index;
}

/* -------------------------------- */
/* -private-- getShutterPadding --- */
/* -------------------------------- */
function getShutterPadding(shutter) {
  var padding = TOTAL_MARGIN;
  try {
    padding = parseInt($(shutter).css("padding-left").replace(/px/,'')) + parseInt($(shutter).css("padding-right").replace(/px/,''));
  } catch (e) {
    /* nothing */
  }
  return padding;

}

function refreshPage() {
  var url = "/" + lang + $("#shutter" + shutterIndex + " .shutter-url").text();
  JSController("#" + url, null, true, true);
}/* value of the attribute 'rel' of the last clicked link */
var currentRel = "";

/* array containing the historic of parameters for the function JSController */
var controllerParam = new Array();

/* idxCP : index for controllerParam */
var idxCP = 0;

function pageload(hash) {
  writeDebug("pageload(" + hash + ")");

  var add_left = null;
  var align_left = true;
  var is_shutter = true;
  var nav = "";

  if (hash && hash.indexOf("TB_inline") == -1) {
    if (currentRel != "") {
      /* 1. currentRel is not empty : user has clicked on a link */
      if (currentRel.indexOf("position.left") > -1) {
        add_left = true;
      }
      if (currentRel.indexOf("position.right") > -1) {
        add_left = false;
      }
      if (currentRel.indexOf("position.new") > -1) {
        add_left = "new";
      }
      if (currentRel.indexOf("position.replace_left") > -1) {
        add_left = "replace_left";
      }
      if (currentRel.indexOf("position.replace_right") > -1) {
        add_left = "replace_right";
      }
      if (currentRel.indexOf("align.left") > -1) {
        align_left = true;
      }
      if (currentRel.indexOf("align.right") > -1) {
        align_left = false;
      }
      if (currentRel.indexOf("shutter.false") > -1) {
        is_shutter = false;
      }
      controllerParam[idxCP] = new Array(add_left, align_left, is_shutter, hash);

      idxCP++;

    } else if (idxCP > 0) {

      /* 2. user has pressed back or following button, detecting which buttons has been pressed */
      nav = detectNavigationButton(hash, idxCP);

      if (nav == "back") {
        idxCP--;
      }

      if (nav == "new") {
          add_left = "new";
          align_left = true;
          is_shutter = true;
      } else {
        if (controllerParam[idxCP][0] == null) {
          add_left = null;
        } else {
          /* if user has clicked on "back" */
          /* add_left can be a boolean or a string */
          if (typeof(controllerParam[idxCP][0]) == 'boolean') {
            if (nav == "back") {
              add_left = !controllerParam[idxCP][0];
            } else {
              add_left = controllerParam[idxCP][0];
            }
          } else {
            add_left = null;
          }
        }
        align_left = controllerParam[idxCP][1];
        is_shutter = controllerParam[idxCP][2];
      }

      if (nav == "forward") {
        idxCP++;
      }

      /* Resetting the parameters */
      if (nav == "new") {
        idxCP = 0;
        controllerParam = new Array();
      }
    } else {
      /* 3. No history yet, this is the first user come */
      controllerParam[idxCP] = new Array(add_left, align_left, is_shutter, hash);

      /*alert("Autre: [add,align,shutter,hash] " + controllerParam[idxCP]);*/

      idxCP++;
    }
    JSController("#" + hash, add_left, is_shutter, align_left);
    /* cleaning the current rel */
    currentRel = "";
  }
}

function detectNavigationButton(hash,position) {
  var idx;
  var buttonClicked = "";
  for(idx=0; idx<controllerParam.length && buttonClicked == ""; idx++) {
    if (controllerParam[idx][3] == hash) {
      if (idx < position) {
        buttonClicked = "back";
      } else {
        buttonClicked = "forward";
      }
    }
  }
  /* the URL entered is not in the history : emptying the shutters and creating new one */
  if (buttonClicked == "") {
    buttonClicked = "new"
  }

  return buttonClicked;
}

function bindLinks() {
  /* set onlick event for buttons */
  $("a").each(function(){
    if (this.rel.indexOf("controller") > -1 && (($(this).attr("class")) ? $(this).attr("class") : "").indexOf("thickbox") < 0) {
      /* remove the keyword 'controller' from rel */
      this.rel = this.rel.replace(/controller/, '');
      $(this).bind("click",function(){
        currentRel = this.rel;
        loadPageWithHistory(this.href);
        return false;
      });
    }
  });
}


/* Used to redirect the url when there are no hash (#) */
/* splitting the url with the home url */
function redirectHash(url) {
  if (rootUrl != '' && rootUrl != '#') {
	  var href = getHref(url);
	  
	  if (href != null){
		  if (href.indexOf(location.href) == 0 && $.browser.msie) {
		      //special case for IE when base Url called
		      currentRel = "align.left shutter.true";
		      $.historyLoad(href.split("#")[1]);
		    } else {
		      location.href = href;
		  }
	  }
  }
}

function getHref(url) {
	  var hash;
	  var currentUrl;
	  if (url == null) {
	    hash = location.hash;
	    
	    currentUrl = document.location.href.replace(/#/, '');
	  } else {
	    hash = '';
	    currentUrl = url;
	  }
	  
	  if (hash.length <= 1) {
	    var href = currentUrl.substr(0, currentUrl.indexOf(appContext + appSite + "/") ) + baseUrl.substr(0, baseUrl.length - 1) + ".html#";

	    if (currentUrl.indexOf(baseUrl.substr(0,baseUrl.length - 1) + ".html") > -1 || currentUrl.indexOf(baseUrl) > -1) {
	      currentUrl = rootUrl;
	    }

	    var indexLang = currentUrl.lastIndexOf("/" + lang + "/");
	    if (isPreview == "true" && currentUrl.substr(indexLang,currentUrl.length).indexOf(codePreview) == -1 ) {
	      href += "/" + lang + codePreview + currentUrl.substr(indexLang+lang.length+1 ,currentUrl.length);
	    } else {
	      href += currentUrl.substr(indexLang,currentUrl.length);
	    }
	    return href.replace(/\?/, '_');
	  }  
}
/**
 * Loops over all forms in document and prepare them for being AJAX submited
 * if they can be. A form can be AJAX submited if it has the css class "ajaxForm".
 * this method is to be invoked when
 *   - document is ready
 *   - ajax is complete
 */
function bindForms() {

  // For each form in document
  $("form").each( function() {
    // gets class attribute of form tag
    var currClass = $(this).attr("class");
    // if class attribute exists
    if(currClass) {
      if( currClass.indexOf("ajaxForm") > -1 ) {

        // removes ajaxForm class for not binding anymore
        $(this).toggleClass("ajaxForm");


        // Inits var callback to false
        var callBack = false;
        if(this.elements["callBack"]) {           // If form has input named callBack
          callBack = this.elements["callBack"].value;
        }

        // retrieves form action
        var formAction = $(this).attr("action");
        if (formAction) {
          // adding parameter ajax=true
          formAction = formAction + ((formAction.indexOf("?") > -1) ? "&" : "?") + "ajax=true";
          // changes form action
          $(this).attr("action", formAction);

          // overriding form submit event
          $(this).submit( function() {
            try {
              var thisForm = $(this);

              toggleFormInput(thisForm, false);

              // submits in AJAX
              var options = {
                  success:    function(xmlReturn) {
                      eval(callBack + "(xmlReturn)" );
                      toggleFormInput(thisForm, true);
                  }
              };

              $(this).ajaxSubmit(options);
            } catch(e) {
              // if error occurs
              writeError("[submit] " + e.description);
            }
            // return false to prevent standard submit
            return false;
          } );
        }
      }
    }
  } );
}

/**
 * Activate/deactivate the submission input.
 */
function toggleFormInput(el, show) {
  /* #1557: only for login form */
  if (el.attr("id") == "loginForm" || el.attr("id") == "contactForm" || el.attr("id") == "newsletterForm") {
    if (show) {
      el.find("input[@type=submit]").removeAttr("disabled");
    } else {
      el.find("input[@type=submit]").attr("disabled", true);
    }
  }
}



/**
 * To keep compatibility with old way
 */
function ajaxFormSubmit(form, callBack) {
  $(form).ajaxSubmit(eval(callBack));
}


/**
 * Login form call back
 */
function callBackLogin(xmlReturn) {
   try {






     var goOn = true;

 	$("#loginError div.modal p").remove();
 	var errors = $("#loginError div.modal").html();
        $("error", xmlReturn).each(function() {
          goOn = false;
          errors = errors + "<p>" + $(this).text() + "</p>" ;
        });
        if(goOn) {
          /* refreshing the menu */
          refreshNav();
          $("redirect", xmlReturn).each(function() {
            loadPageWithHistory($(this).text());
          });
        } else {
          //errors = "<a href='#' class='modal-close' onclick='tb_remove();return false'>" + common_close_link + "</a>" + errors;
          $("#loginError div.modal").html(errors);
          var url = '#TB_inline?height=200&width=250&inlineId=loginError&modal=true';
          tb_show('Error',url);
        }
     } catch(e) {
        writeError("[account-login]" + e.description);
     }
}

/**
 * Login form call back
 */
function callBackReserve(xmlReturn) {

  $("redirect", xmlReturn).each(function() {
    var strRedirect = $(this).text();
    strRedirect = strRedirect + "?DISPLAY=RESERVE";
    $("PRODUCTS", xmlReturn).each(function() {
        strRedirect = strRedirect + "&PRODUCTS="+$(this).text();
      });
    loadPageWithHistory(strRedirect);
  });
}

function callBackSendReserve(xmlReturn) {

  $("redirect", xmlReturn).each(function() {
      loadPageWithoutHistory($(this).text() + "?DISPLAY=SENDRESERVE");
  });
}



/**
 *
 */
function submitServicesForm() {
	ajaxFormSubmit($("#tunnel-save-services"), callBackTunnelServices);
	return false;
}

/**
 * Services call back function
 */
function callBackTunnelServices(xmlReturn) {
  try {
    var goOn = true;

    if ($("refresh", xmlReturn).text().replace(/\n/g,"") == "true") {
      refreshPage();
    }

    $("#errorframe p").remove();
    if (typeof($("address", xmlReturn).attr('code')) == 'undefined') {
      $("error", xmlReturn).each(function() {
        goOn = false;
        $("<p>" + $(this).text() + "</p>").appendTo($("#errorframe div.modal"));
        //on enleve la div qui empeche le double click sur le bouton valider (qui cache le bouton valider)
        $(".avoiddoubleclick").hide()
      });
    }

    if ($("address", xmlReturn).attr('code') == 'notadded') {
      goOn = false;
      $("<p>" + error_creatingAddress + "</p>").appendTo($("#errorframe div.modal"));
    }

    if (goOn) {
      $("redirect", xmlReturn).each(function() {
        currentRel = "align.left shutter.true position.right";
        loadPageWithHistory($(this).text());
      });
      $("input[@name=redirect]").val($("input[@name=redirectForReview]").val());
    } else {
      tb_show('Error', '#TB_inline?height=320&width=300&inlineId=errorframe&modal=true');
    }
  } catch(e) {
    writeError("[shipping-service]" + e.description);
  }
}

function submitCheckSamplesForm() {
  ajaxFormSubmit($("#tunnel-check-samples"), callBackCheckSamplesForm);
  return false;
}

/**
 * Services call back function
 */
function callBackCheckSamplesForm(xmlReturn) {
  try {
	if($("issamples", xmlReturn).text().replace(/\n/g,"") == 0) {
		tb_show('','#TB_inline?height=150&width=235&inlineId=samplesMessage&modal=true');

		$("#TB_ajaxContent .message a").click( function () {
	        $("#TB_ajaxContent").hide();
	        setTimeout('$("#TB_ajaxContent").show();', 1000);
        });

		$("#TB_ajaxContent .message a").each( function () {
	        tb_init($(this));
        });
	} else {
		$("redirect", xmlReturn).each(function() {
		      	currentRel = "align.left shutter.true position.right";
		      	loadPageWithHistory($(this).text());
		});
	}
  } catch(e) {
    writeError("[check-samples]" + e.description);
  }
}



/**
 * Basket call back
 */
function returnFromBasket(xmlReturn) {
      try {
        var str="";
        $("#caddieMessage p").remove();

        $("error", xmlReturn).each(function() {
          $("<p>" + $(this).text() + "</p>").appendTo($("#caddieMessage div.modal"));
        });

        $("message", xmlReturn).each(function() {
          $("<p>" + $(this).text() + "</p>").appendTo($("#caddieMessage div.modal"));
        });

        $("nbItemsInCart", xmlReturn).each(function() {
          updateArticle($(this).text().replace(/\n/g,""));
        });

        loadSmartProfile({sp_id: $("#spStat input[@name=catId]").val(), sp_type: $("#spStat input[@name=catType]").val(), sp_added: $("#spStat input[@name=catId]").val(), sp_quantity: $("#quantity").val()});
        tb_show('', '#TB_inline?height=200&width=300&inlineId=caddieMessage&modal=true');
      } catch(e) {
        writeError("[returnFromBasket]" + e.description);
      }
}
function returnFromBasketAfterAddingSelection(xmlReturn) {
    try {
    	
      var str="";
      $("#SelectioncaddieMessage p").remove();

      $("error", xmlReturn).each(function() {
        $("<p>" + $(this).text() + "</p>").appendTo($("#SelectioncaddieMessage div.modal"));
      });

      $("message", xmlReturn).each(function() {
        $("<p>" + $(this).text() + "</p>").appendTo($("#SelectioncaddieMessage div.modal"));
      });

      $("nbItemsInCart", xmlReturn).each(function() {
        updateArticle($(this).text().replace(/\n/g,""));
      });

      //loadSmartProfile({sp_id: $("#spStat input[@name=catId]").val(), sp_type: $("#spStat input[@name=catType]").val(), sp_added: $("#spStat input[@name=catId]").val(), sp_quantity: $("#quantity").val()});
      tb_show('', '#TB_inline?height=200&width=300&inlineId=SelectioncaddieMessage&modal=true');
      setTimeout("stylePopup()",10); 

    } catch(e) {
      writeError("[returnFromBasket]" + e.description);
    }
}
function stylePopup(){
	  $("#TB_window").css({padding:"20px 0px 15px 15px"});
}
function bindThickbox() {
  //pass where to apply thickbox
  $('a.thickbox, area.thickbox, input.thickbox').each(
    function() {
      if(($(this).attr("href"))) {
        if($(this).attr("href").indexOf("/layout-shutter") < 0 ) {
          var brandPath = appContext + appSite + "/";
          var idx = $(this).attr("href").indexOf(brandPath);
          if( idx >= 0) {
            var newHref = $(this).attr("href").substr(0, idx + brandPath.length - 1);
            newHref += "/layout-shutter" + $(this).attr("href").substr(idx + brandPath.length - 1);
            $(this).attr("href", newHref);
          }
        }
      }
      if ($(this).attr("class").indexOf("TBbinded") == -1) {
        tb_init($(this));
        $(this).toggleClass("TBbinded");
      }
    }
  );
}

/* JS Functions for tunnel-modify-caddie-product */
function resultProductModified(xmlReturn) {
  try {
    var hasErrors=false;
    $("error ", xmlReturn).each(function() {
      alert($(this).text());
      hasErrors = true;
    });
    if (!hasErrors) {
		/* rechargement de la page */
	    refreshPage();
		refreshNav();
		setTimeout("tb_remove()", 200);
    }
  } catch(e) {
    writeError("resultProductModified: " + e.description);
  }
}

/* JS Functions for caddie-list */
function resultProductDeleted(xmlReturn) {
  try {
    var goOn=true;

    $("formId", xmlReturn).each(function() {
      formId = $(this).text().replace(/\n/g,'');
    });

    $("#errorframe p").remove();
    $("error", xmlReturn).each(function() {
      goOn = false;
      $("<p>" + $(this).text() + "</p>").appendTo($("#errorframe div.modal"));
    });

    if (goOn) {
	    refreshNav();
	    refreshPage();
	} else {
		tb_show('Error', '#TB_inline?height=200&width=300&inlineId=errorframe&modal=true');
	}
  } catch(e) {
    writeError("[resultProductDeleted]" + e.description);
  }
}

/**
 *
 */
function submitDeleteProduct(productId) {
  var selected = '';
  var selected_price = 0;
  var newTotalTTC = 0;
  var text = '';
  var selected_price = $('input[@name=discard_price_'+productId+']').val();
  var totalTTC = document.forms.frm_discard_selection.elements['totalTTC'];
  var freeShippingThreshold = document.forms.frm_discard_selection.elements['freeShippingThreshold'];
  var realShippingPrice = document.forms.frm_discard_selection.elements['realShippingPrice'];
  var shippingPrice = document.forms.frm_discard_selection.elements['shippingPrice'];
  var shippingPage = document.forms.frm_discard_selection.elements['shippingPage'];

  newTotalTTC = parseFloat(totalTTC.value) - selected_price;
  if(newTotalTTC < parseFloat(freeShippingThreshold.value)
      && parseFloat(freeShippingThreshold.value) != -1
      && parseFloat(totalTTC.value) > 0
      && parseFloat(shippingPrice.value) == 0) {
    text = "removefromcartfreeshippinglost";
  } else {
    text = "removefromcart";
  }
  //If there is no  product select, displays an alert, otherwise submit the form
    tb_show('', $("#confirmUrl").val() + "?height=160&width=235&text=" + text + "&modal=true&formID=frm_discard_selection&callback=resultProductDeleted");
}

function callBackDisplayVariant(xmlReturn) {
	var packshotContainer = $("input[@name=packshotContainer]").val();
	var imgLoadingContainer = $("input[@name=imgLoadingContainer]").val();
	var descriptionContainer = $("input[@name=descriptionContainer]").val();
	var titleContainer = $("input[@name=titleContainer]").val();
	var priceContainer = $("input[@name=priceContainer]").val();
	var design = $("input[@name=design]").val() || null;
	var priceLine = $("input[@name=priceLine]").val() || null;
	var submitButton = $("input[@name=submitButton]").val() || null;
	var isEcom = $("input[@name=isEcom]").val() || null;
	
	var price = $("price", xmlReturn).text().replace(/\n/g,'');
	var devise = $("devise", xmlReturn).text().replace(/\n/g,'');
	var error = $("error", xmlReturn).text().replace(/\n/g,'');

	if (devise == 'null' && priceLine != null && submitButton != null) {
		$("#" + submitButton).hide();
		$("#" + priceContainer).html($("error", xmlReturn).text());
	} else {
		$("#" + submitButton).show();
		$("#" + priceContainer).html(devise);
	}
	if(design != 'amasie'){
		var img = new Image();
		if($("#" + packshotContainer + " img").length){
			var l = $("#" + packshotContainer + " img").width() || $("#" + packshotContainer + " img").attr("width") || "";
			var h = $("#" + packshotContainer + " img").height() || $("#" + packshotContainer + " img").attr("height") || "";
		}
		$("#" + packshotContainer).empty();

		$(img).load(function () {
			$(img).addClass("png-noscale");
			$(img).attr("width",l);
			$(img).attr("height",h);
			$("#" + packshotContainer).append(this);
			$("#" + imgLoadingContainer).fadeOut("fast", function() {
				$("#" + packshotContainer).fadeIn();
			});

		}).attr({
	          src: $("packshot", xmlReturn).text().replace(/\n/g,''),
	          title: $("productTitle", xmlReturn).text().replace(/\n/g,'')+" "+$("productSubTitle", xmlReturn).text().replace(/\n/g,''),
	          alt: $("productTitle", xmlReturn).text().replace(/\n/g,'')+" "+$("productSubTitle", xmlReturn).text().replace(/\n/g,'')
	    }).error(function () {
	      // notify the user that the image could not be loaded
			$("#" + imgLoadingContainer).fadeOut("fast", function() {
				$("#" + packshotContainer).fadeIn();
			});	

			return false;
	    });
		
		
		if(isEcom && error == "error.outofstock")
		{
			$("#postForm").hide();
			$("#outOfStock").show();
			$("#variantSelector").attr("class","priceContainer tableborder");
		}
		else if (isEcom){
			$("#postForm").show();
			$("#outOfStock").hide();
			$("#variantSelector").attr("class","priceContainer tableborder1");
		}
		
	}
    $("input[@name=pcid]").val($("pcid", xmlReturn).text().replace(/\n/g,''));
    $("input[@name=sku]").val($("sku", xmlReturn).text().replace(/\n/g,''));
    $("#" + descriptionContainer).html($("description", xmlReturn).text().replace(/\n/g,''));
    $("#" + titleContainer).text($("title", xmlReturn).text().replace(/\n/g,''));
    // re-initialiser le scroll
    $(".highlights p").css("margin-top","0px");
    var id= $(".highlights").attr("id").split("hLights")[1];
    initScroll(id);
}

function callBackDisplayVariantSelection(xmlReturn) {
	var tintNbIdContainer = $("tintNbIdContainer", xmlReturn).text().replace(/\n/g,'');
	var packshotContainer = $("packshotContainer", xmlReturn).text().replace(/\n/g,'');
	var pcidContainer = $("pcidContainer", xmlReturn).text().replace(/\n/g,'');
	var imgLoadingContainer = $("input[@name=imgLoadingContainer]").val();
	var priceContainer = $("priceContainer", xmlReturn).text().replace(/\n/g,'');
	var ppuContainer = $("ppuContainer", xmlReturn).text().replace(/\n/g,'');
	var TotalProductsPrices = $("#selectionTotalPrice").text();
	var beforeTotalPrice = $("currentPrice", xmlReturn).text().replace(/\n/g,'');
	var currentTotal = $("total", xmlReturn).text().replace(/\n/g,'');
	var TotalProductsPricesContainer = $("TotalProductsPricesContainer", xmlReturn).text().replace(/\n/g,'');
	var price = $("price", xmlReturn).text().replace(/\n/g,'');
	var ppu = $("ppu", xmlReturn).text().replace(/\n/g,'');
	currentTotalNew = $("#selectionTotalPrice").html();
	var digitTT = currentTotalNew.replace(',','.');
	
	var calcNewtotal = (parseFloat(digitTT) - parseFloat(beforeTotalPrice) + parseFloat(price));
	$("input[@name=" + pcidContainer + "]").val($("pcid", xmlReturn).text().replace(/\n/g,''));

	var price = parseFloat(price).toFixed(2);
	price = price.toString();
	price = price.replace('.',',');
	//mise à jour du prix produit
	$("#" + priceContainer).text( price);
	$("#" + ppuContainer).text( ppu);
	var total = 0;
	var submitFormItemsId = $('div .bottom_modif_qte form input[@name=pcid]').val();
	var reg=new RegExp("[ , ]", "g");
	var arrayItemsList = submitFormItemsId.split(reg);
	var newItemId =$("pcid", xmlReturn).text();
	var addNewItem = "";
	
	//boucle pour récuperer le prix des produits
	for (i = 0; i<arrayItemsList.length; i++){
		if ($("#productPrice"+(i +1 )).html()){
			var priceTemp = parseFloat($("#productPrice"+( i + 1 )).html().replace(',','.'));
			if(priceTemp){
				total = total + priceTemp;	
				if("pcidContainer"+ (i+1) == pcidContainer){
					arrayItemsList[i] = trim(newItemId);
				}
			}
		}
	}
	
	for (var i=0; i<arrayItemsList.length; i++) {
		var coma ="";
		if(addNewItem != "") coma = ",";
		addNewItem = addNewItem + coma+ arrayItemsList[i];
		
	}
	$('div .bottom_modif_qte form input[@name=pcid]').val(addNewItem)
	//traitement pour l affichage
	var strNewtotal = total.toFixed(2);
	strNewtotal = strNewtotal.toString();
	strNewtotal = strNewtotal.replace('.',',');
	
	$("#selectionTotalPrice").text(strNewtotal);
	//réinitialise les variables pour recalculer le total
	strNewtotal = null;
	total = null;


	var img = new Image();
		var l = 180;
		var h = 219;

	$("#" + packshotContainer).empty();

	$(img).load(function () {
		$(img).addClass("png");
		$("#" + packshotContainer).append(this);
			$(img).attr("width",l);
			$("#" + imgLoadingContainer).fadeOut("fast", function() {
			$(img).attr("height",h);
			$("#" + packshotContainer).fadeIn();
		});
	})
	.attr({
	  width : l,
	  height : h,
      src: $("packshot", xmlReturn).text().replace(/\n/g,''),
      title: $("productTitle", xmlReturn).text().replace(/\n/g,'')+" "+$("productSubTitle", xmlReturn).text().replace(/\n/g,''),
      alt: $("productTitle", xmlReturn).text().replace(/\n/g,'')+" "+$("productSubTitle", xmlReturn).text().replace(/\n/g,'')
    })
    .error(function () {
      // notify the user that the image could not be loaded
		$("#" + imgLoadingContainer).fadeOut("fast", function() {
			$("#" + packshotContainer).fadeIn();
		});
		return false;
    });

}
function trim (myString){
	return myString.replace(/^\s+/g,'').replace(/\s+$/g,'');
}
function callBackTunnelDisplayAddress(xmlReturn) {
	var addressId = $("addressId", xmlReturn).text().replace(/\n/g,'');
	var addressType = $("addressType", xmlReturn).text().replace(/\n/g,'');
	$("#addressFullname-"+addressType).text($("addressFullName", xmlReturn).text().replace(/\n/g,''));
	$("#addressLine1-"+addressType).text($("addressLine1", xmlReturn).text().replace(/\n/g,''));
	$("#addressLine2-"+addressType).text($("addressLine2", xmlReturn).text().replace(/\n/g,''));
	$("#addressZipCity-"+addressType).text($("addressZipcode", xmlReturn).text().replace(/\n/g,'')+" "+$("addressCity", xmlReturn).text().replace(/\n/g,''));
	$("#addressCountry-"+addressType).text($("addressCountry", xmlReturn).text().replace(/\n/g,''));
	if(addressType == 1) {
		$("input[@name=shippingAddressId]").val(addressId);
	}
	if(addressType == 2) {
		$("input[@name=billingAddressId]").val(addressId);
	}
}

/**
 * Order review call back
 */
function callBackRecHistory(xmlReturn) {

  try {
    var goOn = true;
    $("error", xmlReturn).each(function() {
      goOn = false;
    });

    if (goOn) {

    $("redirect", xmlReturn).each(function() {
      loadPageWithHistory($(this).text());
    });

    }
  }
  catch(e) {
    writeError("[callBackRecHistory]" + e.description);
  }
}

/**
 * Order review call back
 */
function callBackForm(xmlReturn) {

  try {
    var goOn = true;
    var error = "";
    $("#errorframe p").remove();
    $("error", xmlReturn).each(function() {
      goOn = false;
      $("<p>" + $(this).text() + "</p>").appendTo($("#errorframe div.modal"));
    });

    if (goOn) {

      $("redirect", xmlReturn).each(function() {
        loadPageWithHistory($(this).text());
      });

    } else {
      tb_show('Error', '#TB_inline?height=200&width=300&inlineId=errorframe&modal=true');
    }
  }
  catch(e) {
    writeError("[callBackForm]" + e.description);
  }
}

function submitPaymentByPhone() {
  $("#acceptLegalTerms").val("false");
  $("#isClickToCall").val("true");
  ajaxFormSubmit($("#tunnel-recap-payment"), callBackPaymentByPhone);
}

function submitInPaymentByPhone(estara_id) {
  $("#acceptLegalTerms").val("false");
  $("#isClickToCall").val("true");
  $("input[@type=submit]").css("visibility", "hidden");
  webVoicePop("Template=" + estara_id);
}

function callBackPaymentByPhone(xmlReturn) {
  try {
    var goOn = true;
    var error = "";
    $("#errorframe p").remove();
    $("error", xmlReturn).each(function() {
      $("<p>" + $(this).text() + "</p>").appendTo($("#errorframe div.modal"));
      goOn = false;
    });

    if (goOn) {
      $("input[@type=submit]").css("visibility", "hidden");
      webVoicePop("Template=" + $("input[@name=estara_id]").val());
    } else {
      tb_show('Error', '#TB_inline?height=200&width=300&inlineId=errorframe&modal=true');
    }
  }
  catch(e) {
    writeError("[callBackPaymentByPhone] " + e.description);
  }
}

/**
 * Order payment call back
 */
function callBackPaymentForm(xmlReturn) {

  try {
    var goOn = true;
    var error = "";;
    $("#paymentMessage p").remove("");
    $("error", xmlReturn).each(function() {
      goOn = false;
      error += "<p>" + $(this).text() + "</p>";
    });

    if (goOn) {
      tb_remove();

      /* refreshing the menu */
      refreshNav();

      $("redirect", xmlReturn).each(function() {
        loadPageWithoutHistory($(this).text());
      });

    } else {
      $("#paymentMessage").append(error);
      tb_show('Error', '#TB_inline?height=200&width=300&inlineId=paymentMessage&modal=true');
    }
  }
  catch(e) {
    writeError("[callBackPaymentForm]" + e.description);
  }
}

/**
 * Order payment call back
 */
function callBackContactForm(xmlReturn) {

  try {
    var goOn = true;
    var message = "";;
    $("#contactMessage p").remove();
    $("#errorcontactMessage p").remove();

    $("error", xmlReturn).each(function() {
      goOn = false;
      message += "<p>" + $(this).text() + "</p>";
    });

    $("message", xmlReturn).each(function() {
      message += "<p>" + $(this).text() + "</p>";
    });


    if (goOn) {
      $("#contactMessage").append(message);
      tb_show('', '#TB_inline?height=200&width=300&inlineId=contactMessage&modal=true');
      $("redirect", xmlReturn).each(function() {
        loadPageWithoutHistory($(this).text());
      });
    } else {
      $("#errorcontactMessage").append(message);
      tb_show('', '#TB_inline?height=200&width=300&inlineId=errorcontactMessage&modal=true');
    }
  }
  catch(e) {
    writeError("[callBackContactForm]" + e.description);
  }
}

function returnFromWl(xmlReturn) {
  try {
    $("#wishlistMessage p").remove();
    $("error", xmlReturn).each(function() {
      $("<p>" + $(this).text() + "</p>").appendTo($("#wishlistMessage div.modal"));
    });
    $("message", xmlReturn).each(function() {
      $("<p>" + $(this).text() + "</p>").appendTo($("#wishlistMessage div.modal"));
      displayAlreadyInWishList();

    });
    tb_show('', '#TB_inline?height=200&width=300&inlineId=wishlistMessage&modal=true');
  } catch(e) {
    writeError("[returnFromWl]" + e.description);
  }
}

function returnFromCaddieWl(xmlReturn) {
  try {
    $("#wishlistMessage p").remove();
    $("error", xmlReturn).each(function() {
      $("<p>" + $(this).text() + "</p>").appendTo($("#wishlistMessage div.modal"));
    });
    $("message", xmlReturn).each(function() {
      $("<p>" + $(this).text() + "</p>").appendTo($("#wishlistMessage div.modal"));
      displayAlreadyInWishList();
    });
    tb_show('', '#TB_inline?height=200&width=300&inlineId=wishlistMessage&modal=true');
  } catch(e) {
    writeError("[returnFromCaddieWl]" + e.description);
  }
}

/*
 * account-registration.jsp
 */
function callBackRegister(xmlReturn) {
   try {
    var goOn = true;
    var errors = "";
    $("#registerError p").remove();
    $("error", xmlReturn).each(function() {
      goOn = false;
      errors = errors + "<p>" + $(this).text() + "</p>";
    });
    if(goOn) {
      //Désactivation du bouton valider pour éviter de créer des doublons de compte.
      $("#createAccount").attr('disabled', 'disabled');
      /* refreshing the menu */
      refreshNav();
       $("redirect", xmlReturn).each(function() {
        loadPageWithoutHistory($(this).text());
       });
    } else {
      $("#registerError").append(errors);
      tb_show('Error','#TB_inline?height=400&width=250&inlineId=registerError&modal=true');
    }
  } catch(e) {
    writeError("[account-login]" + e.description);
  }
}

/*
 * profile.jsp
 */

  function activateFields(name, mode) {
    try {
      var fieldName = "fieldset." + name;

      /* disabling input hidden and putting input in read only */
      if (mode == 'readonly') {
        $(fieldName + " input").attr("readonly", "readonly");
      } else {
        /* showing/hiding address */
        if ($(fieldName).attr("class").indexOf("isFirstAddress") == -1 && $(fieldName).attr("class").indexOf("address") > -1) {
          if ($("fieldset.isFirstAddress").html()) {
            $("fieldset.isFirstAddress ol").hide();
            /* if selectedAdress has been modified, we have to hide cancel button and show modify button */
            if($("fieldset.isFirstAddress").attr("class").indexOf("resume") == -1) {
              $("fieldset.isFirstAddress a.link").each( function() {
                showHideLink($(this));
              });
              $("fieldset.isFirstAddress").toggleClass("resume");
            }
          }
          $("fieldset.isFirstAddress").toggleClass("isFirstAddress");
          $(fieldName + " ol").show();
          $(fieldName).toggleClass("isFirstAddress");
        }
        $(fieldName + " input").removeAttr("readonly");
      }

      showHideSelect(name, mode);
      $(fieldName).toggleClass("resume");
      $(fieldName + " a.link").each(
        function() { showHideLink($(this)); }
      );
    } catch(e) {
      writeError("[activateFields]" + e.description);
    }
  }

  function showHideLink(link) {
    if(link.attr("class") && link.attr("class").indexOf("hidden") == -1) {
      link.hide();
    } else {
      link.show();
    }
    link.toggleClass("hidden");
  }

  function showHideSelect(name, mode) {
    /* hiding select only in readonly mode */
    /* showing select not in readonly mode */
    /* showing / hiding input-select */
    $("fieldset." + name + " input").each(
      function() {
        if ($(this).attr("class")) {
          if ($(this).attr("class").indexOf("unused") > -1 || $(this).attr("class").indexOf("selectbox") > -1) {
            $(this).toggle();
          }
        }
      }
    );
    
    /* showing / hiding non-selectbox select */
	$("fieldset." + name + " select").each(
      function() {
	      if (! $(this).attr("class")) {
	          $(this).toggle();
	        }
	      }
      );
  }


  function resultProfileModified(xmlReturn) {
    try {
      var hasErrors=false;
      var height = "";
      var width = "";
      var divId = "";
      $("#error div.modal p").remove();
      $("error", xmlReturn).each(function() {
        hasErrors = true;
        $("#error div.modal").append("<p>" + $(this).text() + "</p>");
      });
      if (!hasErrors) {
        var addressIdDeleted = $("input[@name=address_to_delete]").val();
        $("fieldset.address" + addressIdDeleted).remove();
        height = "150";
        width = "235";
        divId = "profil";
        refreshNav();
        var oldLogin = $("oldLogin", xmlReturn).text().replace(/\n/g,'');
        var newLogin = $("newLogin", xmlReturn).text().replace(/\n/g,'');
        var addressId = $("addressId", xmlReturn).text().replace(/\n/g,'');
        $("redirect", xmlReturn).each(function() {
          var redirect = $(this).text();
          if (redirect.indexOf("?") > -1) {
            redirect += "&";
          } else {
            redirect += "?";
          }
          loadPageWithoutHistory(redirect +"addressId="+ addressId + "&oldLogin=" + oldLogin + "&newLogin=" + newLogin);
        });
      } else {
        height = "200";
        width = "300";
        divId = "error";
      }
      var url = '#TB_inline?height=' + height + '&width=' + width + '&inlineId=' + divId + '&modal=true';
      tb_show('',url);
    } catch(e) {
      writeError("[resultProfileModified]" + e.description);
    }
  }

  function submitDeleteAddress(id) {
    try {
      $("input[@name=address_to_delete]").val(id);
      ajaxFormSubmit($("#profile-informations"), resultProfileModified);
    } catch(e) {
      writeError("[submitDeleteAddress]" + e.description);
    }
  }

  function closePopup(redirect) {
    //close pop up
    tb_remove();
    loadPageWithoutHistory(redirect);
  }


/*
 * wishlist.jsp
 */

    function callBackSendWl(xmlResponse) {
      var msg = "";
      var hasErrors = false;
      $("#backFromWlError p").remove();
      $("#backFromWlMessage p").remove();

      $("error", xmlResponse).each(function() {
        hasErrors = true;
        $("<p>" + $(this).text() + "</p>").appendTo($("#backFromWlError div.modal"));
      });

      $("message", xmlResponse).each(function() {
        $("<p>" + $(this).text() + "</p>").appendTo($("#backFromWlMessage div.modal"));
      });

      if (!hasErrors) {
        tb_show('','#TB_inline?height=200&amp;width=250&amp;inlineId=backFromWlMessage&amp;modal=true');
        $("#messageSendWl").val("");
        $("#friendEmail").val("");
      } else {
        tb_show('','#TB_inline?height=200&amp;width=250&amp;inlineId=backFromWlError&amp;modal=true');
      }
    }

    function returnFromWlToCart(xmlResponse) {
      var msg = "";
      var hasErrors = false;

      $("#caddieMessage p").remove();

      $("error", xmlResponse).each(function() {
        hasErrors = true;
        $("<p>" + $(this).text() + "</p>").appendTo($("#caddieMessage div.modal"));
      });

      if (hasErrors) {
        tb_show('', '#TB_inline?height=200&width=300&inlineId=caddieMessage&modal=true');
      } else {
        $("caddie", xmlResponse).each(function() {
          updateArticle($(this).text().replace(/\n/g,""));
        });
        $("#addWlToCartButton").hide();
        $("#buyAllList, #addWlToCartDisabledButton").show();
        $("#buyList_" + $("result", xmlResponse).text().replace(/\n/g,'')).show();
      }
    }

    function returnFromOrderHistory(xmlResponse) {
      var msg = "";
      var hasErrors = false;

      $("error", xmlResponse).each(function() {
        hasErrors = true;
        $("<p>" + $(this).text() + "</p>").appendTo($("#caddieMessage div.modal"));
      });

      if (hasErrors) {
        tb_show('', '#TB_inline?height=470&width=500&inlineId=caddieMessage&modal=true');
      } else {

      }
    }

  function clearListCallBack(xmlReturn) {
    var goOn = true;
    var errors = "";
    $("#error div.modal p").remove();
    $("error", xmlReturn).each(function() {
      goOn = false;
      errors = errors + "<p>" + $(this).text() + "</p>";
    });
    if(goOn) {
      var redirect = $("redirect", xmlReturn).text();
      closePopup(redirect);
    } else {
      $("#error div.modal").append(errors);
      //tb_remove();
      var url = '#TB_inline?height=200&width=300&inlineId=error&modal=true';
      tb_show('',url);
    }
  }

  function writeCommentCallBack(xmlReturn) {
    var goOn = true;
    var errors = "";
    $("#error div.modal p").remove();
    $("error", xmlReturn).each(function() {
      goOn = false;
      errors = errors + "<p>" + $(this).text() + "</p>";
    });
    if(goOn) {
      closePopup($("redirect", xmlReturn).text());
    } else {
      $("#error div.modal").append(errors);
      //tb_remove();
      var url = '#TB_inline?height=200&width=300&inlineId=error&modal=true';
      tb_show('',url);
    }
  }


/*
 *
 */
    function bookmarkThis(actionUrl, objectType, id) {
      if (id != null) {
        $.post(
          actionUrl,
          { objectType: objectType, id: id},
          function(xmlReturn) {
            var goOn = true;
            var error = "";
            $("error", xmlReturn).each(function() {
              goOn = false;
              error += "<p>" + $(this).text().replace(/\n/g,'') + "</p>";
            });
            if (!goOn) {
              $("#errorframe").html(error);
              tb_show('Error', '#TB_inline?height=200&width=300&inlineId=errorframe');
            } else {
              $("#notBookmarked").hide();
              $("#bookmarked").show();
            }
          }
        );
      }
    }

/*
 * extranet : orderdetails.jsp
 */
  function callBackForm(xmlReturn) {

    try {
      var goOn = true;
      var error = "";
      $("#errorframe p").remove();
      $("error", xmlReturn).each(function() {
        goOn = false;
        $("<p>" + $(this).text() + "</p>").appendTo($("#errorframe div.modal"));
      });

      if (goOn) {
        tb_remove();
        $("redirect", xmlReturn).each(function() {
          loadPageWithHistory($(this).text() + "&user=" + $("user", xmlReturn).text().replace(/\n/g,'') + "&document=" + $("document", xmlReturn).text().replace(/\n/g,''));
        });

      } else {
        tb_show('Error', '#TB_inline?height=200&width=300&inlineId=errorframe&modal=true');
      }
    }
    catch(e) {
      writeError("[callBackForm]" + e.description);
    }
  }

  /*
   * extranet : customer.jsp
   */
  function listUserCallBack(xmlReturn) {
    try {
      var goOn = true;
      var errors = "";
      var j = 1;
      /* #1309 */
      if (jQuery.browser.msie) {
        $("#searchUserResult tr").hide();
      } else {
        $("#searchUserResult tr").remove();
      }
      $("#errorframe p").remove();
      $("error", xmlReturn).each(function() {
        goOn = false;
        errors = errors + "<p>" + $(this).text().replace(/\n/g,'') + "</p>";
      });
      if(goOn) {
        $("user", xmlReturn).each(function() {
          var result = $(this).text().split("|");
          var i;
          var row;
          if (j%2 == 1) {
            row = "<tr class='exOdd'>";
          } else {
            row = "<tr>";
          }
          for(i=1; i<result.length; i++) {
            if (i == 1) {
              row += "<td><a href='javascript:loginUser(" + result[0] + ")'>" + result[i] + "</a></td>";
            } else {
              row += "<td>" + result[i] + "</td>";
            }
          }

          row += "</tr>";
          $("#searchUserResult").append(row);
          j++;
        });
      } else {
        $("#searchUserResult").append("<tr><td>" + extranet_customer_no_result + "</td></tr>");
        $("#errorframe").append(errors);
        tb_show('', '#TB_inline?height=200&width=300&inlineId=errorframe&modal=true');
      }
    } catch(e) {
      writeError("listUserCallBack: " + e.description);
    }
  }

  function loginUser(id) {
    if (id != null && $("#setSwitchUserAction").val() != null) {
      $.post(
        $("#setSwitchUserAction").val(),
        { id: id},
        function(xmlReturn) {
          var goOn = true;
          var error = "";
          $("#error p").remove();
          $("error", xmlReturn).each(function() {
            goOn = false;
            error += "<p>" + $(this).text().replace(/\n/g,'') + "</p>";
          });
          if (!goOn) {
            $("#error").html(error);
            tb_show('Error', '#TB_inline?height=200&width=300&inlineId=error');
          } else {
            if (id == 0) {
              $("#customerName").html($("message", xmlReturn).text());
              $("#disconnectCustomer").hide();
            } else {
              $("#customerName").html($("name", xmlReturn).text());
              $("#disconnectCustomer").show();
            }
          }
        }
      );
    }
  }

/*
 * extranet : update-document-note-popup.jsp
 */

  function UpdateDocumentNoteCallBack(xmlReturn) {
    var goOn = true;
    var errors = "";
    $("#errorDocumentNote p").remove();
    $("error", xmlReturn).each(function() {
      goOn = false;
      errors = errors + "<p>" + $(this).text().replace(/\n/g,'') + "</p>";
    });
    if(goOn) {
      var row = "<tr>";
      row += "<td>" + $("date", xmlReturn).text() + "</td>";
      row += "<td>" + $("operatorName", xmlReturn).text() + "</td>";
      row += "<td><textarea rows='2' cols='20' readonly='readonly'>" + $("description", xmlReturn).text() + "</textarea></td>";
      row += "</tr>";
      $("#listNotes").append(row);
      $("#noteCount" + $("documentID", xmlReturn).text().replace(/\n/g,'')).text($("documentCount", xmlReturn).text());
    } else {
      $("#errorDocumentNote").append(errors);
      //tb_remove();
      var url = '#TB_inline?height=200&width=300&inlineId=error';
      tb_show('',url);
    }
  }

  /*
   * extranet : cancel-order-popup.jsp
   */

  function cancelDocumentPopupCallBack(xmlReturn) {
    var goOn = true;
    var errors = "";
    $("#errorCancelDocument p").remove();
    $("error", xmlReturn).each(function() {
      tb_remove();
      goOn = false;
      alert($(this).text().replace(/\n/g,''));
      //errors = errors + "<p>" + $(this).text().replace(/\n/g,'') + "</p>";
    });
    if(goOn) {
     $("redirect", xmlReturn).each(function() {
      tb_remove();
      loadPageWithoutHistory($(this).text());
     });
    } /*else {
      $("#errorDocumentNote").append(errors);
      var url = '#TB_inline?height=200&width=300&inlineId=error';
      tb_show('',url);
    }*/
  }

  /*
   * store-locator: search.jsp
   */


  function submitStoreSearch() {
    var countryVal = encodeURIComponent($("#ac-country").val());
    var cityVal = encodeURIComponent($("#ac-city").val());
    var strRedirect = $("#storeForm").attr("action") + "_country=" + countryVal + "&city=" + cityVal;
    
    loadPageWithHistory(strRedirect);
    return false;
  }

  /*
   * store-locator: result.jsp
   */


  function showStores(id, way) {
    var i = 1;
    if (way == "previous") {
      i = -1;
    }
    showStorePane(id, i);
  }

  function showStorePane(id, i) {
    $("#paneright" + id).fadeOut("slow");
    $("#previous" + id).fadeOut("slow");
    $("#next" + id).fadeOut("slow");
    $("#paneleft" + id).fadeOut("slow",
      function() {
        $("#paneleft" + (id + i)).fadeIn("slow");
        $("#paneright" + (id + i)).fadeIn("slow");
        $("#previous" + (id + i)).fadeIn("slow");
        $("#next" + (id + i)).fadeIn("slow");
      }
    );
  }

  function showStoreForm(id) {
    /* hiding links */
    $("table#links").hide();
    /* hiding previous data */
    $("#store-content table").hide();
    $("#store-content div.divbg").hide();
    $("form#" + id).show();
    $("p#foottext").show();
  }

  /*
   * very dior/espace perso : home.jsp
   */

  function showBoudoir() {
    if ($("#boudoir").css("display") == "none") {
      $("#boudoir").show();
    }
    $("#boudoir").css("visibility", "visible");
    $("#boudoir").css("z-index", "1000");
  }
  function hideBoudoir() {
    $("#boudoir").css("visibility", "hidden");
    $("#boudoir").css("z-index", "1");
  }

  /*
   * common
   */

   function disableInput(button) {
     $(button).attr('disabled',true);
   }

   /*
    * tunnel
    */
  function showCaddie(show) {
    /* #1391 le parametre show n'est plus nï¿½cessaire */
    $("div.jScrollPaneContainer div").css("overflow", "hidden");
  }

  /*
   *  forgotton password (tunnel et espace perso)
   */

  function callBackRetrievePassword(xmlReturn) {
    try {
      $("#loginError p").remove();
      $("error", xmlReturn).each(function() {
        $("<p>" + $(this).text() + "</p>").appendTo($("#loginError div.modal"));
      });
      $("message", xmlReturn).each(function() {
        $("<p>" + $(this).text() + "</p>").appendTo($("#loginError div.modal"));
      });
      tb_show('Error','#TB_inline?height=200&amp;width=250&amp;inlineId=loginError&amp;modal=true');
    } catch(e) {
      writeError("[retrieve-password]" + e.description);
    }
  }

  /**
   * Prepares the returned message and display it in the 'message' div...
   */
  function callBackSendEmail(xmlReturn) {
    var msg = "";
    $("error", xmlReturn).each( function() {
      msg += $(this).text() + '<br/>';
    });

    $("message", xmlReturn).each( function() {
      msg += $(this).text() + '<br/>';
    });

    $("#message").html("<p>" + msg + "</p>");
    $("#message").show();
  }

  function callBackProductSendEmail(xmlReturn) {
    var msg = "";
    var error = false;
    $("error", xmlReturn).each( function() {
      msg += $(this).text() + '<br/>';
      error = true;
    });

    $("message", xmlReturn).each( function() {
      msg += $(this).text() + '<br/>';
    });

	if(msg){
	    $("#message").html(msg);
	    $('#aunami_container').hide();
	    $("#message").show();
	    if(error){
		    $("#aunami_container_close").hide();
			$("#aunami_message_close").show();
	    }
		TB_WIDTH = 320;
		TB_HEIGHT = 160;
		$('#TB_ajaxContent').width('');
		$('#TB_ajaxContent').height('');
		tb_position();
		refreshCaptcha();

	}
  }

  function hideErrorMessage(){
	    $('#aunami_container').show();
	    $("#message").hide();

	    $("#aunami_message_close").hide();
	    $("#aunami_container_close").show();

	    TB_WIDTH = 520;
		TB_HEIGHT = 380;
		tb_position();
  }

  /*
   * product-tints.jsp
   */
  var tintArray = new Array();
  function addTint(img, label, color){
      tintArray.push({swatch: img, name: label, color: color});
  }

  function showTint(index){
      $("img#texture").attr("src", tintArray[index].swatch);
      $("span#label").html(tintArray[index].name);
      $("span#color").html(tintArray[index].color);
  }

  function replace_shutter_left(aUrl) {
      var url = aUrl.substr(aUrl.lastIndexOf("/" + lang + "/"),aUrl.length);
      var sharpPosition = url.indexOf('#/' + lang ,0) + ('#/' + lang).length;
      var myUrl = url.substring(sharpPosition, url.length).replace(/\.html/,'/');
      var myUrlLevel = returnLevel(myUrl.replace(/_.*$/, '').replace(/\/$/,''));

      // getting next to last shutter (product page, tint page is the last)
      var shutters = getShutterList();
      var index = 1;
      if (shutters.length > 1) {
        index = $(shutters[shutters.length-2]).attr("id").replace(/shutter/,'');
      }

      replaceShutter(myUrl, myUrlLevel, -1, true, index);
      return false;
  }

  /*
   * newsletter.jsp
   */

   function callBackNewsletterForm(xmlReturn) {
      try {
	    var goOn = true;
	    var msg = "";
	    $("#backFromNewsletterMessage p").remove();

	    $("error", xmlReturn).each(function() {
	      goOn = false;
	      msg = msg + "<p>" + $(this).text() + "</p>";
	    });
	    
	    $("message", xmlReturn).each(function() {
	      msg = msg + "<p>" + $(this).text() + "</p>";
	    });
	    $("#backFromNewsletterMessage").append(msg);
	    if(goOn) {
	       $("redirect", xmlReturn).each(function() {
	         loadPageWithHistory($(this).text());
	       });
	    }
	    if(msg){
	    	tb_show('Error','#TB_inline?height=200&width=250&inlineId=backFromNewsletterMessage&modal=true');
	    }
	  } catch(e) {
	    writeError("[callBackNewsletterForm]" + e.description);
	  }
  }

  function callBackDiscoverToFriend(xmlReturn){
  	try {
	    var goOn = true;
	    var errors = "";
	    var message = "";
	    $("#backFromNewsletterMessage p").remove();
	    $("error", xmlReturn).each(function() {
	      goOn = false;
	      errors = errors + "<p>" + $(this).text() + "</p>";
	    });

	    $("message", xmlReturn).each(function() {
	      message = message + "<p>" + $(this).text() + "</p>";
	    });
	    if(goOn) {
	      /* refreshing the menu */
	       refreshNav();
	       $("redirect", xmlReturn).each(function() {
	        loadPageWithoutHistory($(this).text());
	       });
	       $("#backFromNewsletterMessage").append(message);
	       tb_show('Error','#TB_inline?height=200&width=250&inlineId=backFromNewsletterMessage&modal=true');
	    } else {
	      $("#backFromNewsletterMessage").append(errors);
	      tb_show('Error','#TB_inline?height=200&width=250&inlineId=backFromNewsletterMessage&modal=true');
	   	  refreshCaptcha();
	    }
	  } catch(e) {
	    writeError("[account-login]" + e.description);
	  }
  }

  function refreshCaptcha(){
  		var img = new Image();
		var d = new Date();
		var id = ($('#imgCaptcha2').length == 0)?'':2;
		img.src = $('#imgCaptcha' + id).attr('src').substr(0, $('#imgCaptcha' + id).attr('src').indexOf('?'));
		$("#imgCaptcha" + id).attr('src', img.src + "?conf=conf" + id + "&ts=" + d.getMilliseconds());

  }

  function callBackPersoLogin(xmlReturn) {
    try {
      var goOn = true;
      $("#error div.modal p").remove();
      $("error", xmlReturn).each(function() {
        goOn = false;
        $("#error div.modal").append("<p>" + $(this).text() + "</p>");
      });
      if (goOn) {
        /* refreshing the menu */
        refreshNav();
        $("redirect", xmlReturn).each(function() {
          /* #1470 : problï¿½me de refresh aprï¿½s login */
          var redirect = $(this).text();
          if (redirect.indexOf("?") == -1) {
            redirect += "?refresh=true";
          } else {
            redirect += "&refresh=true";
          }
          loadPageWithoutHistory(redirect);
        });
      } else {
        var url = '#TB_inline?height=200&width=300&inlineId=error&modal=true';
        tb_show('',url);
        $("redirectPerso", xmlReturn).each(function() {
          loadPageWithHistory($(this).text().replace(/\n/g,''));
        });
      }
    } catch(e) {
      writeError("[callBackPersoLogin]" + e.description);
    }
  }

  function callBackPersoSurvey(xmlReturn) {
    $("redirect", xmlReturn).each(function() {
        var redirect = $(this).text();
        loadPageWithoutHistory(redirect);
      });
  }

  function callBackPopupLogin(xmlReturn) {
    try {
      var goOn = true;
      $("#TB_ajaxContent div.modal p.error").remove();
      $("error", xmlReturn).each(function() {
        goOn = false;
        $("#TB_ajaxContent div.modal").append("<p class='error'>" + $(this).text() + "</p>");
      });
      if (goOn) {
        /* refreshing the menu */
        refreshNav();
        /* adding to wishlist */
        $('#addToWl').submit();
      } else {
        var url = '#TB_inline?height=390&width=500&inlineId=error&modal=true';
        tb_show('',url);
      }
    } catch(e) {
      writeError("[callBackPersoLogin]" + e.description);
    }
  }

  /* extranet */

  function callBackExtranet(xmlReturn) {
    try {
      var goOn = true;
      $("#errorframe div.modal p").remove();
      $("error", xmlReturn).each(function() {
        goOn = false;
        $("#errorframe div.modal").append("<p>" + $(this).text() + "</p>");
      });
      if (goOn) {
        location.reload(true);
      } else {
        var url = '#TB_inline?height=200&width=300&inlineId=errorframe&modal=true';
        tb_show('',url);
      }
    } catch(e) {
      writeError("[callBackExtranet]" + e.description);
    }
  }


  /* print functions */
  function printPage(url) {
    showPopup(url, 500, 500);
  }

  function showPopupPage(aUrl, height, width) {
    var indexLang = aUrl.indexOf("/" + lang + "/");
    var layout = "/layout-popup";
    var url = aUrl.substr(0, indexLang) + layout + aUrl.substr(indexLang, aUrl.length);
    showPopup(url, height, width);
  }

  function showPopup(url, height, width) {
    var top=(screen.availHeight-height)/2;
    var left=(screen.availWidth-width)/2;
    window.open(url, "" ,"width=" + width + ",height=" + height + ",left=" + left + ",top=" + top);
  }



/* product-page */
  var isScrolling = false;

  function initScroll(timeStamp) {
    var highlightsID  = 'hLights' + timeStamp;
    var cursorID      = 'cId' + timeStamp;
    var scrollTop     = $('#sTop' + timeStamp);
    var scrollBottom  = $('#sBottom' + timeStamp);
    var highlights    = $('#hLights' + timeStamp);

    if (scrollTop.attr("class") && scrollTop.attr("class").indexOf("binded") == -1) {
      var heightText = 0 ;
      
      $('#' + highlightsID + ' p').each( function(i) {
    	  heightText = heightText  + parseInt($(this).height());
      });
      
      var heightVisible  = parseInt(highlights.height());
      var heightToScroll = parseInt(heightVisible * 3 / 4);
      
      if ( heightText > heightVisible ) {
    	
    	  
        scrollTop.mouseover( function(event) { myFunctionToAdd(event, "up", cursorID, highlightsID, heightToScroll, heightText);} )
                       .mousemove( function(event) { myFunctionToShow(event, cursorID)} )
                       .mouseout ( function(event) { myFunctionToHide(cursorID)} )
                       .toggleClass("binded");

        scrollBottom.mouseover( function(event) { myFunctionToAdd(event, "down", cursorID, highlightsID, heightToScroll, heightText);} )
                          .mousemove( function(event) { myFunctionToShow(event, cursorID)} )
                          .mouseout ( function(event) { myFunctionToHide(cursorID)} );

        highlights.mouseover( function(event) { myFunctionToAdd(event, null, cursorID) } )
                        .mousemove( function(event) { myFunctionToShow(event, cursorID)} )
                        .mouseout ( function(event) { myFunctionToHide(cursorID)} );
      }
    }
  }

  function scrollMe(way, highlightsID, heightToScroll, heightText) {
    var text = $('#' + highlightsID + ' p:first');

    if (!isScrolling) {
      var margin = parseInt(text.css("margin-top").replace("px", ""));

      if (way == 'up') {
        if (margin + heightToScroll < 15) {
          isScrolling = true;
          text.animate({marginTop: margin + heightToScroll}, 500, function() {isScrolling = false;});
        }
      } else if (way == 'down') {    	
        if (margin - heightToScroll > - heightText - 15) {
          isScrolling = true;
          text.animate({marginTop: margin - heightToScroll}, 500, function() {isScrolling = false;});
        }
      }

    }
  }

  function myFunctionToAdd(event, way, cursorID, highlightsID, heightToScroll, heightText) {
    if($('#' + cursorID).size() == 0){
      $("body").append("<div id='" + cursorID + "' class='cursor_scroll' alt='scroll' />");
      $('#' + cursorID).css({
        top: (event.pageY + 11) + 'px',
        left: (event.pageX + 16) + 'px',
        position: 'absolute'
      });
    }
    $('#' + cursorID).show();

    if (way) {
      scrollMe(way, highlightsID, heightToScroll, heightText);
    }
  }

  function myFunctionToHide(cursorID) {
    $('#' + cursorID).hide();
  }

  function myFunctionToShow(event, cursorID) {
    $('#' + cursorID).css({
        top: (event.pageY + 11) + 'px',
        left: (event.pageX + 16) + 'px'
    });
    $('#' + cursorID).show();
  }


  function addToWl(sku) {
    $('#addToWl input').val(sku);
    $('#addToWl').submit();
    $('#addToWl input').val('');
  }

  function limite(zone, max) {
    var max = max || 500;
    if(zone.value.length>=max){
      zone.value=zone.value.substring(0,max);
      zone.scrollTop = zone.scrollHeight;
    }
  }

  /* --- SmartProfile --- */

  function loadSmartProfile(parameters) {
    $.get(
      smart_profile_path,
      parameters,
      function(JSReturn) {
        eval(JSReturn);
      }
    );
  }
  
  function rewriteCustomHeader() {
	var test = $("iframe#custom_header").attr("src");
	$("iframe#custom_header").attr("src", test);
  }	
	
  /* --- Selection popup --- */
  
// gestion du sélecteur de teinte
function updateTintProduct( productId , containerId, capacity) {
	showload();
	var submitForm = $('div #' + containerId).parents("form");
		//var text = $('#' + containerId + " option:selected").text();
	//console.log("productId: " + productId, "containerId=", containerId);
	
	submitForm.submit();
	//$('#variantTintForm').submit();
	
}

function writeError(message) {
    if (window.console && window.console.error) {
        console.error(message);
    }
}/*
 * jQuery Easing v1.1 - http://gsgd.co.uk/sandbox/jquery.easing.php
 *
 * Uses the built in easing capabilities added in jQuery 1.1
 * to offer multiple easing options
 *
 * Copyright (c) 2007 George Smith
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 */

jQuery.easing = {
	easein: function(x, t, b, c, d) {
		return c*(t/=d)*t + b; // in
	},
	easeinout: function(x, t, b, c, d) {
		if (t < d/2) return 2*c*t*t/(d*d) + b;
		var ts = t - d/2;
		return -2*c*ts*ts/(d*d) + 2*c*ts/d + c/2 + b;		
	},
	easeout: function(x, t, b, c, d) {
		return -c*t*t/(d*d) + 2*c*t/d + b;
	},
	expoin: function(x, t, b, c, d) {
		var flip = 1;
		if (c < 0) {
			flip *= -1;
			c *= -1;
		}
		return flip * (Math.exp(Math.log(c)/d * t)) + b;		
	},
	expoout: function(x, t, b, c, d) {
		var flip = 1;
		if (c < 0) {
			flip *= -1;
			c *= -1;
		}
		return flip * (-Math.exp(-Math.log(c)/d * (t-d)) + c + 1) + b;
	},
	expoinout: function(x, t, b, c, d) {
		var flip = 1;
		if (c < 0) {
			flip *= -1;
			c *= -1;
		}
		if (t < d/2) return flip * (Math.exp(Math.log(c/2)/(d/2) * t)) + b;
		return flip * (-Math.exp(-2*Math.log(c/2)/d * (t-d)) + c + 1) + b;
	},
	bouncein: function(x, t, b, c, d) {
		return c - jQuery.easing['bounceout'](x, d-t, 0, c, d) + b;
	},
	bounceout: function(x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	bounceinout: function(x, t, b, c, d) {
		if (t < d/2) return jQuery.easing['bouncein'] (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing['bounceout'] (x, t*2-d,0, c, d) * .5 + c*.5 + b;
	},
	elasin: function(x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	elasout: function(x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	elasinout: function(x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	backin: function(x, t, b, c, d) {
		var s=1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	backout: function(x, t, b, c, d) {
		var s=1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	backinout: function(x, t, b, c, d) {
		var s=1.70158;
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	linear: function(x, t, b, c, d) {
		return c*t/d + b; //linear
	}
};/*
 * jQuery form plugin
 * @requires jQuery v1.1 or later
 *
 * Examples at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id$
 * Version: 1.0.2  Jul-18-2007
 */
 (function($) {
/**
 * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX.
 *
 * ajaxSubmit accepts a single argument which can be either a success callback function
 * or an options Object.  If a function is provided it will be invoked upon successful
 * completion of the submit and will be passed the response from the server.
 * If an options Object is provided, the following attributes are supported:
 *
 *  target:   Identifies the element(s) in the page to be updated with the server response.
 *            This value may be specified as a jQuery selection string, a jQuery object,
 *            or a DOM element.
 *            default value: null
 *
 *  url:      URL to which the form data will be submitted.
 *            default value: value of form's 'action' attribute
 *
 *  type:     The method in which the form data should be submitted, 'GET' or 'POST'.
 *            default value: value of form's 'method' attribute (or 'GET' if none found)
 *
 *  beforeSubmit:  Callback method to be invoked before the form is submitted.
 *            default value: null
 *
 *  success:  Callback method to be invoked after the form has been successfully submitted
 *            and the response has been returned from the server
 *            default value: null
 *
 *  dataType: Expected dataType of the response.  One of: null, 'xml', 'script', or 'json'
 *            default value: null
 *
 *  semantic: Boolean flag indicating whether data must be submitted in semantic order (slower).
 *            default value: false
 *
 *  resetForm: Boolean flag indicating whether the form should be reset if the submit is successful
 *
 *  clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful
 *
 *
 * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for
 * validating the form data.  If the 'beforeSubmit' callback returns false then the form will
 * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data
 * in array format, the jQuery object, and the options object passed into ajaxSubmit.
 * The form data array takes the following form:
 *
 *     [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * If a 'success' callback method is provided it is invoked after the response has been returned
 * from the server.  It is passed the responseText or responseXML value (depending on dataType).
 * See jQuery.ajax for further details.
 *
 *
 * The dataType option provides a means for specifying how the server response should be handled.
 * This maps directly to the jQuery.httpData method.  The following values are supported:
 *
 *      'xml':    if dataType == 'xml' the server response is treated as XML and the 'success'
 *                   callback method, if specified, will be passed the responseXML value
 *      'json':   if dataType == 'json' the server response will be evaluted and passed to
 *                   the 'success' callback, if specified
 *      'script': if dataType == 'script' the server response is evaluated in the global context
 *
 *
 * Note that it does not make sense to use both the 'target' and 'dataType' options.  If both
 * are provided the target will be ignored.
 *
 * The semantic argument can be used to force form serialization in semantic order.
 * This is normally true anyway, unless the form contains input elements of type='image'.
 * If your form must be submitted with name/value pairs in semantic order and your form
 * contains an input of type='image" then pass true for this arg, otherwise pass false
 * (or nothing) to avoid the overhead for this logic.
 *
 *
 * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this:
 *
 * $("#form-id").submit(function() {
 *     $(this).ajaxSubmit(options);
 *     return false; // cancel conventional submit
 * });
 *
 * When using ajaxForm(), however, this is done for you.
 *
 * @example
 * $('#myForm').ajaxSubmit(function(data) {
 *     alert('Form submit succeeded! Server returned: ' + data);
 * });
 * @desc Submit form and alert server response
 *
 *
 * @example
 * var options = {
 *     target: '#myTargetDiv'
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Submit form and update page element with server response
 *
 *
 * @example
 * var options = {
 *     success: function(responseText) {
 *         alert(responseText);
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Submit form and alert the server response
 *
 *
 * @example
 * var options = {
 *     beforeSubmit: function(formArray, jqForm) {
 *         if (formArray.length == 0) {
 *             alert('Please enter data.');
 *             return false;
 *         }
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Pre-submit validation which aborts the submit operation if form data is empty
 *
 *
 * @example
 * var options = {
 *     url: myJsonUrl.php,
 *     dataType: 'json',
 *     success: function(data) {
 *        // 'data' is an object representing the the evaluated json data
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc json data returned and evaluated
 *
 *
 * @example
 * var options = {
 *     url: myXmlUrl.php,
 *     dataType: 'xml',
 *     success: function(responseXML) {
 *        // responseXML is XML document object
 *        var data = $('myElement', responseXML).text();
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc XML data returned from server
 *
 *
 * @example
 * var options = {
 *     resetForm: true
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc submit form and reset it if successful
 *
 * @example
 * $('#myForm).submit(function() {
 *    $(this).ajaxSubmit();
 *    return false;
 * });
 * @desc Bind form's submit event to use ajaxSubmit
 *
 *
 * @name ajaxSubmit
 * @type jQuery
 * @param options  object literal containing options which control the form submission process
 * @cat Plugins/Form
 * @return jQuery
 */
$.fn.ajaxSubmit = function(options) {
    if (typeof options == 'function')
        options = { success: options };

    options = $.extend({
        url:  this.attr('action') || window.location,
        type: this.attr('method') || 'GET'
    }, options || {});

    var a = this.formToArray(options.semantic);

    // give pre-submit callback an opportunity to abort the submit
    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;

    // fire vetoable 'validate' event
    var veto = {};
    $.event.trigger('form.submit.validate', [a, this, options, veto]);
    if (veto.veto)
        return this;

    var q = $.param(a);//.replace(/%20/g,'+');

    if (options.type.toUpperCase() == 'GET') {
        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
        options.data = null;  // data is null for 'get'
    }
    else
        options.data = q; // data is the query string for 'post'

    var $form = this, callbacks = [];
    if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
    if (options.clearForm) callbacks.push(function() { $form.clearForm(); });

    // perform a load on the target only if dataType is not provided
    if (!options.dataType && options.target) {
        var oldSuccess = options.success;// || function(){};
        callbacks.push(function(data, status) {
            $(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, [data, status]);
        });
    }
    else if (options.success)
        callbacks.push(options.success);

    options.success = function(data, status) {
        for (var i=0, max=callbacks.length; i < max; i++)
            callbacks[i](data, status);
    };

    // are there files to upload?
    var files = $('input:file', this).fieldValue();
    var found = false;
    for (var j=0; j < files.length; j++)
        if (files[j])
            found = true;

    if (options.iframe || found) { // options.iframe allows user to force iframe mode
        fileUpload();
    } else {
      /* #1285 (Espace perso authentification) */
      if (jQuery.browser.msie && navigator.appVersion.indexOf("MSIE 6.0") > -1 && location.protocol == 'https:') {
        $.ajax({async: false, url: baseXmlUrl, type: "POST"});
        $.ajax(options);
      } else {
        $.ajax(options);
      }
    }

    // fire 'notify' event
    $.event.trigger('form.submit.notify', [this, options]);
    return this;


    // private function for handling file uploads (hat tip to YAHOO!)
    function fileUpload() {
        var form = $form[0];
        var opts = $.extend({}, $.ajaxSettings, options);

        var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++;
        var $io = $('<iframe id="' + id + '" src="' + blankPage + '" name="' + id + '" />');
        var io = $io[0];
        var op8 = $.browser.opera && window.opera.version() < 9;
        if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';
        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

        var xhr = { // mock object
            responseText: null,
            responseXML: null,
            status: 0,
            statusText: 'n/a',
            getAllResponseHeaders: function() {},
            getResponseHeader: function() {},
            setRequestHeader: function() {}
        };

        var g = opts.global;
        // trigger ajax global events so that activity/block indicators work like normal
        if (g && ! $.active++) $.event.trigger("ajaxStart");
        if (g) $.event.trigger("ajaxSend", [xhr, opts]);

        var cbInvoked = 0;
        var timedOut = 0;

        // take a breath so that pending repaints get some cpu time before the upload starts
        setTimeout(function() {
            $io.appendTo('body');
            // jQuery's event binding doesn't work for iframe events in IE
            io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);

            // make sure form attrs are set
            var encAttr = form.encoding ? 'encoding' : 'enctype';
            var t = $form.attr('target');
            $form.attr({
                target:   id,
                method:  'POST',
                encAttr: 'multipart/form-data',
                action:   opts.url
            });

            // support timout
            if (opts.timeout)
                setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

            form.submit();
            $form.attr('target', t); // reset target
        }, 10);

        function cb() {
            if (cbInvoked++) return;

            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);

            var ok = true;
            try {
                if (timedOut) throw 'timeout';
                // extract the server response from the iframe
                var data, doc;
                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
                xhr.responseText = doc.body ? doc.body.innerHTML : null;
                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;

                if (opts.dataType == 'json' || opts.dataType == 'script') {
                    var ta = doc.getElementsByTagName('textarea')[0];
                    data = ta ? ta.value : xhr.responseText;
                    if (opts.dataType == 'json')
                        eval("data = " + data);
                    else
                        $.globalEval(data);
                }
                else if (opts.dataType == 'xml') {
                    data = xhr.responseXML;
                    if (!data && xhr.responseText != null)
                        data = toXml(xhr.responseText);
                }
                else {
                    data = xhr.responseText;
                }
            }
            catch(e){
                ok = false;
                $.handleError(opts, xhr, 'error', e);
            }

            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
            if (ok) {
                opts.success(data, 'success');
                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
            }
            if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
            if (g && ! --$.active) $.event.trigger("ajaxStop");
            if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

            // clean up
            setTimeout(function() {
                $io.remove();
                xhr.responseXML = null;
            }, 100);
        };

        function toXml(s, doc) {
            if (window.ActiveXObject) {
                doc = new ActiveXObject('Microsoft.XMLDOM');
                doc.async = 'false';
                doc.loadXML(s);
            }
            else
                doc = (new DOMParser()).parseFromString(s, 'text/xml');
            return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
        };
    };
};
$.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *    is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *    used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * Note that for accurate x/y coordinates of image submit elements in all browsers
 * you need to also use the "dimensions" plugin (this method will auto-detect its presence).
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.  See ajaxSubmit for a full description of the options argument.
 *
 *
 * @example
 * var options = {
 *     target: '#myTargetDiv'
 * };
 * $('#myForm').ajaxSForm(options);
 * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response
 *       when the form is submitted.
 *
 *
 * @example
 * var options = {
 *     success: function(responseText) {
 *         alert(responseText);
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Bind form's submit event so that server response is alerted after the form is submitted.
 *
 *
 * @example
 * var options = {
 *     beforeSubmit: function(formArray, jqForm) {
 *         if (formArray.length == 0) {
 *             alert('Please enter data.');
 *             return false;
 *         }
 *     }
 * };
 * $('#myForm').ajaxSubmit(options);
 * @desc Bind form's submit event so that pre-submit callback is invoked before the form
 *       is submitted.
 *
 *
 * @name   ajaxForm
 * @param  options  object literal containing options which control the form submission process
 * @return jQuery
 * @cat    Plugins/Form
 * @type   jQuery
 */
$.fn.ajaxForm = function(options) {
    return this.ajaxFormUnbind().submit(submitHandler).each(function() {
        // store options in hash
        this.formPluginId = $.fn.ajaxForm.counter++;
        $.fn.ajaxForm.optionHash[this.formPluginId] = options;
        $(":submit,input:image", this).click(clickHandler);
    });
};

$.fn.ajaxForm.counter = 1;
$.fn.ajaxForm.optionHash = {};

function clickHandler(e) {
    var $form = this.form;
    $form.clk = this;
    if (this.type == 'image') {
        if (e.offsetX != undefined) {
            $form.clk_x = e.offsetX;
            $form.clk_y = e.offsetY;
        } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
            var offset = $(this).offset();
            $form.clk_x = e.pageX - offset.left;
            $form.clk_y = e.pageY - offset.top;
        } else {
            $form.clk_x = e.pageX - this.offsetLeft;
            $form.clk_y = e.pageY - this.offsetTop;
        }
    }
    // clear form vars
    setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);
};

function submitHandler() {
    // retrieve options from hash
    var id = this.formPluginId;
    var options = $.fn.ajaxForm.optionHash[id];
    $(this).ajaxSubmit(options);
    return false;
};

/**
 * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
 *
 * @name   ajaxFormUnbind
 * @return jQuery
 * @cat    Plugins/Form
 * @type   jQuery
 */
$.fn.ajaxFormUnbind = function() {
    this.unbind('submit', submitHandler);
    return this.each(function() {
        $(":submit,input:image", this).unbind('click', clickHandler);
    });

};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 *
 * The semantic argument can be used to force form serialization in semantic order.
 * This is normally true anyway, unless the form contains input elements of type='image'.
 * If your form must be submitted with name/value pairs in semantic order and your form
 * contains an input of type='image" then pass true for this arg, otherwise pass false
 * (or nothing) to avoid the overhead for this logic.
 *
 * @example var data = $("#myForm").formToArray();
 * $.post( "myscript.cgi", data );
 * @desc Collect all the data from a form and submit it to the server.
 *
 * @name formToArray
 * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
 * @type Array<Object>
 * @cat Plugins/Form
 */
$.fn.formToArray = function(semantic) {
    var a = [];
    if (this.length == 0) return a;

    var form = this[0];
    var els = semantic ? form.getElementsByTagName('*') : form.elements;
    if (!els) return a;
    for(var i=0, max=els.length; i < max; i++) {
        var el = els[i];
        var n = el.name;
        if (!n) continue;

        if (semantic && form.clk && el.type == "image") {
            // handle image inputs on the fly when semantic == true
            if(!el.disabled && form.clk == el)
                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
            continue;
        }

        var v = $.fieldValue(el, true);
        if (v && v.constructor == Array) {
            for(var j=0, jmax=v.length; j < jmax; j++)
                a.push({name: n, value: v[j]});
        }
        else if (v !== null && typeof v != 'undefined')
            a.push({name: n, value: v});
    }

    if (!semantic && form.clk) {
        // input type=='image' are not found in elements array! handle them here
        var inputs = form.getElementsByTagName("input");
        for(var i=0, max=inputs.length; i < max; i++) {
            var input = inputs[i];
            var n = input.name;
            if(n && !input.disabled && input.type == "image" && form.clk == input)
                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
        }
    }
    return a;
};


/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 *
 * The semantic argument can be used to force form serialization in semantic order.
 * If your form must be submitted with name/value pairs in semantic order then pass
 * true for this arg, otherwise pass false (or nothing) to avoid the overhead for
 * this logic (which can be significant for very large forms).
 *
 * @example var data = $("#myForm").formSerialize();
 * $.ajax('POST', "myscript.cgi", data);
 * @desc Collect all the data from a form into a single string
 *
 * @name formSerialize
 * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
 * @type String
 * @cat Plugins/Form
 */
$.fn.formSerialize = function(semantic) {
    //hand off to jQuery.param for proper encoding
    return $.param(this.formToArray(semantic));
};


/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 *
 * The successful argument controls whether or not serialization is limited to
 * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.
 *
 * @example var data = $("input").formSerialize();
 * @desc Collect the data from all successful input elements into a query string
 *
 * @example var data = $(":radio").formSerialize();
 * @desc Collect the data from all successful radio input elements into a query string
 *
 * @example var data = $("#myForm :checkbox").formSerialize();
 * @desc Collect the data from all successful checkbox input elements in myForm into a query string
 *
 * @example var data = $("#myForm :checkbox").formSerialize(false);
 * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string
 *
 * @example var data = $(":input").formSerialize();
 * @desc Collect the data from all successful input, select, textarea and button elements into a query string
 *
 * @name fieldSerialize
 * @param successful true if only successful controls should be serialized (default is true)
 * @type String
 * @cat Plugins/Form
 */
$.fn.fieldSerialize = function(successful) {
    var a = [];
    this.each(function() {
        var n = this.name;
        if (!n) return;
        var v = $.fieldValue(this, successful);
        if (v && v.constructor == Array) {
            for (var i=0,max=v.length; i < max; i++)
                a.push({name: n, value: v[i]});
        }
        else if (v !== null && typeof v != 'undefined')
            a.push({name: this.name, value: v});
    });
    //hand off to jQuery.param for proper encoding
    return $.param(a);
};


/**
 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
 *
 *  <form><fieldset>
 *      <input name="A" type="text" />
 *      <input name="A" type="text" />
 *      <input name="B" type="checkbox" value="B1" />
 *      <input name="B" type="checkbox" value="B2"/>
 *      <input name="C" type="radio" value="C1" />
 *      <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be determined the
 *       array will be empty, otherwise it will contain one or more values.
 *
 * @example var data = $("#myPasswordElement").fieldValue();
 * alert(data[0]);
 * @desc Alerts the current value of the myPasswordElement element
 *
 * @example var data = $("#myForm :input").fieldValue();
 * @desc Get the value(s) of the form elements in myForm
 *
 * @example var data = $("#myForm :checkbox").fieldValue();
 * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object.
 *
 * @example var data = $("#mySingleSelect").fieldValue();
 * @desc Get the value(s) of the select control
 *
 * @example var data = $(':text').fieldValue();
 * @desc Get the value(s) of the text input or textarea elements
 *
 * @example var data = $("#myMultiSelect").fieldValue();
 * @desc Get the values for the select-multiple control
 *
 * @name fieldValue
 * @param Boolean successful true if only the values for successful controls should be returned (default is true)
 * @type Array<String>
 * @cat Plugins/Form
 */
$.fn.fieldValue = function(successful) {
    for (var val=[], i=0, max=this.length; i < max; i++) {
        var el = this[i];
        var v = $.fieldValue(el, successful);
        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
            continue;
        v.constructor == Array ? $.merge(val, v) : val.push(v);
    }
    return val;
};

/**
 * Returns the value of the field element.
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If the given element is not
 * successful and the successful arg is not false then the returned value will be null.
 *
 * Note: If the successful flag is true (default) but the element is not successful, the return will be null
 * Note: The value returned for a successful select-multiple element will always be an array.
 * Note: If the element has no value the return value will be undefined.
 *
 * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]);
 * @desc Gets the current value of the myPasswordElement element
 *
 * @name fieldValue
 * @param Element el The DOM element for which the value will be returned
 * @param Boolean successful true if value returned must be for a successful controls (default is true)
 * @type String or Array<String> or null or undefined
 * @cat Plugins/Form
 */
$.fieldValue = function(el, successful) {
    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
    if (typeof successful == 'undefined') successful = true;

    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
        (t == 'checkbox' || t == 'radio') && !el.checked ||
        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
        tag == 'select' && el.selectedIndex == -1))
            return null;

    if (tag == 'select') {
        var index = el.selectedIndex;
        if (index < 0) return null;
        var a = [], ops = el.options;
        var one = (t == 'select-one');
        var max = (one ? index+1 : ops.length);
        for(var i=(one ? index : 0); i < max; i++) {
            var op = ops[i];
            if (op.selected) {
                // extra pain for IE...
                var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
                if (one) return v;
                a.push(v);
            }
        }
        return a;
    }
    return el.value;
};


/**
 * Clears the form data.  Takes the following actions on the form's input fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 *
 * @example $('form').clearForm();
 * @desc Clears all forms on the page.
 *
 * @name clearForm
 * @type jQuery
 * @cat Plugins/Form
 */
$.fn.clearForm = function() {
    return this.each(function() {
        $('input,select,textarea', this).clearFields();
    });
};

/**
 * Clears the selected form elements.  Takes the following actions on the matched elements:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 *
 * @example $('.myInputs').clearFields();
 * @desc Clears all inputs with class myInputs
 *
 * @name clearFields
 * @type jQuery
 * @cat Plugins/Form
 */
$.fn.clearFields = $.fn.clearInputs = function() {
    return this.each(function() {
        var t = this.type, tag = this.tagName.toLowerCase();
        if (t == 'text' || t == 'password' || tag == 'textarea')
            this.value = '';
        else if (t == 'checkbox' || t == 'radio')
            this.checked = false;
        else if (tag == 'select')
            this.selectedIndex = -1;
    });
};


/**
 * Resets the form data.  Causes all form elements to be reset to their original value.
 *
 * @example $('form').resetForm();
 * @desc Resets all forms on the page.
 *
 * @name resetForm
 * @type jQuery
 * @cat Plugins/Form
 */
$.fn.resetForm = function() {
    return this.each(function() {
        // guard against an input with the name of 'reset'
        // note that IE reports the reset function as an 'object'
        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
            this.reset();
    });
};

})(jQuery);
// gaTracker: jQuery Google Analytics Integration
// A quicker, automated way to embed Google Analytics.
// (c)2007 Jason Huck/Core Five Creative
//
// Requires jQuery 1.2.x or higher (for cross-domain $.getScript)
//
// Usage:
// 
// Only a tracking code is required:
// $.gaTracker('UA-XXXXX-XX');
// 
// ...but other options can be specified:
// $.gaTracker(
//		'UA-XXXXX-XX',
//		{
//			external:	'/external/',
//			mailto:		'/mailto/',
//			download:	'/downloads/',
//			extensions:	[
//				'pdf','doc','xls','csv','jpg','gif', 'mp3',
//				'swf','txt','ppt','zip','gz','dmg','xml'		
//			]
//		}
//	);
//
// TODO: more testing, delay after $.getScript for Safari


(function($){
	$.gaTracker = function(code, opts){
		opts = jQuery.extend({
			external:	'/external/',
			mailto:		'/mailtos/',
			download:	'/downloads/',
			extensions: [
					'pdf','doc','xls','csv','jpg','gif', 'mp3',
					'swf','txt','ppt','zip','gz','dmg','xml'		
			]	
		}, opts);
		
		// Returns the given URL prefixed if it is:
		//		a) a link to an external site
		//		b) a mailto link
		//		c) a downloadable file
		// ...otherwise returns an empty string.
		function decorateLink(u){
			var trackingURL = '';
			
			if(u.indexOf('://') == -1 && u.indexOf('mailto:') != 0){
				// no protocol or mailto - internal link - check extension
				var ext = u.split('.')[u.split('.').length - 1];			
				var exts = opts.extensions;
				
				for(i = 0; i < exts.length; i++){
					if(ext == exts[i]){
						trackingURL = opts.download + u;
						break;
					}
				}				
			} else {
				if(u.indexOf('mailto:') == 0){
					// mailto link - decorate
					trackingURL = opts.mailto + u.substring(7);					
				} else {
					// complete URL - check domain
					var regex = /([^:\/]+)*(?::\/\/)*([^:\/]+)(:[0-9]+)*\/?/i;
					var linkparts = regex.exec(u);
					var urlparts = regex.exec(location.href);					
					if(linkparts[2] != urlparts[2]) trackingURL = opts.external + u;
				}
			}
			
			return trackingURL;			
		}
		
		// add tracking code to the current page
		function addTracking(){
			_uacct = code;
			urchinTracker();
		
			// examine every link in the page
			$('a').each(function(){
				var u = $(this).attr('href');
				
				if(typeof(u) != 'undefined'){
					var newLink = decorateLink(u);

					// if it needs to be tracked manually,
					// bind a click event to call GA with
					// the decorated/prefixed link
					if(newLink.length){
						$(this).click(function(){
							urchinTracker(newLink);
						});
					}
				}				
			});
		}
		
		// include the external GA script in try/catch to play nice
		function initGA(){
			try{
				// determine whether to include the normal or SSL version
				var gaURL = (location.href.indexOf('https') == 0 ? 'https://ssl' : 'http://www');
				gaURL += '.google-analytics.com/urchin.js';
		
				// include the script
				//$.getScript(gaURL, function(){
					addTracking();
				//});
			} catch(err) {
				// log any failure
				console.log('Failed to load Google Analytics:' + err);
			}
		}
		
		initGA();
	}
})(jQuery);
/*
 * Thickbox 3 - One Box To Rule Them All.
 * By Cody Lindley (http://www.codylindley.com)
 * Copyright (c) 2007 cody lindley
 * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
*/

/*var tb_pathToImage = "images/loadingAnimation.gif";*/

/*!!!!!!!!!!!!!!!!! edit below this line at your own risk !!!!!!!!!!!!!!!!!!!!!!!*/

//on page load call tb_init
$(document).ready(function(){
  tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox
  imgLoader = new Image();// preload image
  imgLoader.src = tb_pathToImage;
});

//add thickbox to href & area elements that have a class of .thickbox
function tb_init(domChunk){
  $(domChunk).click(function(){
  var t = this.title || this.name || null;
  var a = this.href || this.alt;
  var g = this.rel || false;
  tb_show(t,a,g);
  this.blur();
  return false;
  });
}

function tb_show(caption, url, imageGroup) {//function called when the user clicks on a thickbox link

  try {
    if (typeof document.body.style.maxHeight === "undefined") {//if IE 6
      $("body","html").css({height: "100%", width: "100%"});
      $("html").css("overflow","hidden");
      if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6
        // GSR : problem with IE
        $("body").append("<iframe id='TB_HideSelect' src='" + blankPage + "'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>");
        $("#TB_overlay").click(tb_remove);
      }
    }else{//all others
      if(document.getElementById("TB_overlay") === null){
        $("body").append("<div id='TB_overlay'></div><div id='TB_window'>");
        $("#TB_overlay").click(tb_remove);
      }
    }

    if(caption===null){caption="";}
    $("body").append("<div id='TB_load'><img src='"+imgLoader.src+"' /></div>");//add loader to the page
    $('#TB_load').show();//show loader

    var baseURL;
     if(url.indexOf("?")!==-1){ //ff there is a query string involved
      baseURL = url.substr(0, url.indexOf("?"));
     }else{
         baseURL = url;
     }

     var urlString = /\.jpg|\.jpeg|\.png|\.gif|\.bmp/g;
     var urlType = baseURL.toLowerCase().match(urlString);

    if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images

      TB_PrevCaption = "";
      TB_PrevURL = "";
      TB_PrevHTML = "";
      TB_NextCaption = "";
      TB_NextURL = "";
      TB_NextHTML = "";
      TB_imageCount = "";
      TB_FoundURL = false;
      if(imageGroup){
        TB_TempArray = $("a[@rel="+imageGroup+"]").get();
        for (TB_Counter = 0; ((TB_Counter < TB_TempArray.length) && (TB_NextHTML === "")); TB_Counter++) {
          var urlTypeTemp = TB_TempArray[TB_Counter].href.toLowerCase().match(urlString);
            if (!(TB_TempArray[TB_Counter].href == url)) {
              if (TB_FoundURL) {
                TB_NextCaption = TB_TempArray[TB_Counter].title;
                TB_NextURL = TB_TempArray[TB_Counter].href;
                TB_NextHTML = "<span id='TB_next'>&nbsp;&nbsp;<a href='#'>Next &gt;</a></span>";
              } else {
                TB_PrevCaption = TB_TempArray[TB_Counter].title;
                TB_PrevURL = TB_TempArray[TB_Counter].href;
                TB_PrevHTML = "<span id='TB_prev'>&nbsp;&nbsp;<a href='#'>&lt; Prev</a></span>";
              }
            } else {
              TB_FoundURL = true;
              TB_imageCount = "Image " + (TB_Counter + 1) +" of "+ (TB_TempArray.length);
            }
        }
      }

      imgPreloader = new Image();
      imgPreloader.onload = function(){
      imgPreloader.onload = null;

      // Resizing large images - orginal by Christian Montoya edited by me.
      var pagesize = tb_getPageSize();
      var x = pagesize[0] - 150;
      var y = pagesize[1] - 150;
      var imageWidth = imgPreloader.width;
      var imageHeight = imgPreloader.height;
      if (imageWidth > x) {
        imageHeight = imageHeight * (x / imageWidth);
        imageWidth = x;
        if (imageHeight > y) {
          imageWidth = imageWidth * (y / imageHeight);
          imageHeight = y;
        }
      } else if (imageHeight > y) {
        imageWidth = imageWidth * (y / imageHeight);
        imageHeight = y;
        if (imageWidth > x) {
          imageHeight = imageHeight * (x / imageWidth);
          imageWidth = x;
        }
      }
      // End Resizing

      TB_WIDTH = imageWidth + 30;
      TB_HEIGHT = imageHeight + 60;
      $("#TB_window").append("<a href='' id='TB_ImageOff' title='Close'><img id='TB_Image' src='"+url+"' width='"+imageWidth+"' height='"+imageHeight+"' alt='"+caption+"'/></a>" + "<div id='TB_caption'>"+caption+"<div id='TB_secondLine'>" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "</div></div><div id='TB_closeWindow'><a href='#' id='TB_closeWindowButton' title='Close'>close</a> or Esc Key</div>");

      $("#TB_closeWindowButton").click(tb_remove);

      if (!(TB_PrevHTML === "")) {
        function goPrev(){
          if($(document).unbind("click",goPrev)){$(document).unbind("click",goPrev);}
          $("#TB_window").remove();
          $("body").append("<div id='TB_window'></div>");
          tb_show(TB_PrevCaption, TB_PrevURL, imageGroup);
          return false;
        }
        $("#TB_prev").click(goPrev);
      }

      if (!(TB_NextHTML === "")) {
        function goNext(){
          $("#TB_window").remove();
          $("body").append("<div id='TB_window'></div>");
          tb_show(TB_NextCaption, TB_NextURL, imageGroup);
          return false;
        }
        $("#TB_next").click(goNext);

      }

      document.onkeydown = function(e){
        if (e == null) { // ie
          keycode = event.keyCode;
        } else { // mozilla
          keycode = e.which;
        }
        if(keycode == 27){ // close
          tb_remove();
        } else if(keycode == 190){ // display previous image
          if(!(TB_NextHTML == "")){
            document.onkeydown = "";
            goNext();
          }
        } else if(keycode == 188){ // display next image
          if(!(TB_PrevHTML == "")){
            document.onkeydown = "";
            goPrev();
          }
        }
      };

      tb_position();
      $("#TB_load").remove();
      $("#TB_ImageOff").click(tb_remove);
      $("#TB_window").css({display:"block"}); //for safari using css instead of show
      };

      imgPreloader.src = url;
    }else{//code to show html pages

      var queryString = url.replace(/^[^\?]+\??/,'');
      var params = tb_parseQuery( queryString );

      TB_WIDTH = (params['width']*1) + 30 || 630; //defaults to 630 if no paramaters were added to URL
      TB_HEIGHT = (params['height']*1) + 40 || 440; //defaults to 440 if no paramaters were added to URL
      ajaxContentW = TB_WIDTH - 30;
      ajaxContentH = TB_HEIGHT - 45;

      if(url.indexOf('TB_iframe') != -1){
          urlNoQuery = url.split('TB_');
          $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Close'>close</a> or Esc Key</div></div><iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;' onload='tb_showIframe()'> </iframe>");
        }else{
          if($("#TB_window").css("display") != "block"){
            if(params['modal'] != "true"){
            $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'>close</a> or Esc Key</div></div><div id='TB_ajaxContent' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px'></div>");
            }else{
            $("#TB_overlay").unbind();
            $("#TB_window").append("<div id='TB_ajaxContent' class='TB_modal' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px;'></div>");
            }
          }else{
            $("#TB_ajaxContent")[0].style.width = ajaxContentW +"px";
            $("#TB_ajaxContent")[0].style.height = ajaxContentH +"px";
            $("#TB_ajaxContent")[0].scrollTop = 0;
            $("#TB_ajaxWindowTitle").html(caption);
          }
      }

      $("#TB_closeWindowButton").click(tb_remove);

        if(url.indexOf('TB_inline') != -1){
          $("#TB_ajaxContent").html($('#' + params['inlineId']).html());
          tb_position();
          $("#TB_load").remove();
          $("#TB_window").css({display:"block"});
        }else if(url.indexOf('TB_iframe') != -1){
          tb_position();
          if(frames['TB_iframeContent'] === undefined){//be nice to safari
            $("#TB_load").remove();
            $("#TB_window").css({display:"block"});
            $(document).keyup( function(e){ var key = e.keyCode; if(key == 27){tb_remove();}});
          }
        }else{
          $("#TB_ajaxContent").load(url += "&random=" + (new Date().getTime()),function(){//to do a post change this load method
            tb_position();
            $("#TB_load").remove();
            tb_init("#TB_ajaxContent a.thickbox");
            $("#TB_window").css({display:"block"});
          });
        }

    }

    if(!params['modal']){
      document.onkeyup = function(e){
        if (e == null) { // ie
          keycode = event.keyCode;
        } else { // mozilla
          keycode = e.which;
        }
        if(keycode == 27){ // close
          tb_remove();
        }
      };
    }

  } catch(e) {
    //nothing here
  }
}

//helper functions below
function tb_showIframe(){
  $("#TB_load").remove();
  $("#TB_window").css({display:"block"});
}

function tb_remove() {
   $("#TB_imageOff").unbind("click");
  $("#TB_overlay").unbind("click");
  $("#TB_closeWindowButton").unbind("click");
  $("#TB_window").fadeOut("fast",function(){$('#TB_window,#TB_overlay,#TB_HideSelect').remove();});
  $("#TB_load").remove();
  if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
    $("body","html").css({height: "auto", width: "auto"});
    $("html").css("overflow","");
  }
  document.onkeydown = "";
  return false;
}

function tb_position() {
$("#TB_window").css({marginLeft: '-' + parseInt((TB_WIDTH / 2),10) + 'px', width: TB_WIDTH + 'px'});
  if ( !(jQuery.browser.msie && typeof XMLHttpRequest == 'function')) { // take away IE6
    $("#TB_window").css({marginTop: '-' + parseInt((TB_HEIGHT / 2),10) + 'px'});
  }
}

function tb_parseQuery ( query ) {
   var Params = {};
   if ( ! query ) {return Params;}// return empty object
   var Pairs = query.split(/[;&]/);
   for ( var i = 0; i < Pairs.length; i++ ) {
      var KeyVal = Pairs[i].split('=');
      if ( ! KeyVal || KeyVal.length != 2 ) {continue;}
      var key = unescape( KeyVal[0] );
      var val = unescape( KeyVal[1] );
      val = val.replace(/\+/g, ' ');
      Params[key] = val;
   }
   return Params;
}

function tb_getPageSize(){
  var de = document.documentElement;
  var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
  var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
  arrayPageSize = [w,h];
  return arrayPageSize;
}
/*
 * jQuery history plugin
 *
 * Copyright (c) 2006 Taku Sano (Mikage Sawatari)
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Modified by Lincoln Cooper to add Safari support and only call the callback once during initialization
 * for msie when no initial hash supplied.
 */


jQuery.extend({
  historyCurrentHash: undefined,

  historyCallback: undefined,

  historyInit: function(callback){
    jQuery.historyCallback = callback;
    var current_hash = location.hash;

    jQuery.historyCurrentHash = current_hash;
    if(jQuery.browser.msie) {
      // To stop the callback firing twice during initilization if no hash present
      if (jQuery.historyCurrentHash == '') {
      jQuery.historyCurrentHash = '#';
    }

      // add hidden iframe for IE
      $("body").prepend('<iframe id="jQuery_history" style="display: none;" src="' + blankPage + '"></iframe>'); /* GSR */
      var ihistory = $("#jQuery_history")[0];
      if (typeof(ihistory) != 'undefined') { /* GSR */
        var iframe = ihistory.contentWindow.document;
        iframe.open();
        iframe.close();
        iframe.location.hash = current_hash;
      }
    }
    else if ($.browser.safari) {
      // etablish back/forward stacks
      jQuery.historyBackStack = [];
      jQuery.historyBackStack.length = history.length;
      jQuery.historyForwardStack = [];

      jQuery.isFirst = true;
    }
    jQuery.historyCallback(current_hash.replace(/^#/, ''));
    setInterval(jQuery.historyCheck, 100);
  },

  historyAddHistory: function(hash) {
    // This makes the looping function do something
    jQuery.historyBackStack.push(hash);

    jQuery.historyForwardStack.length = 0; // clear forwardStack (true click occured)
    this.isFirst = true;
  },

  historyCheck: function(){
    if(jQuery.browser.msie) {
      // On IE, check for location.hash of iframe
      try { 
	      var ihistory = $("#jQuery_history")[0];
	      var iframe = ihistory.contentDocument || ihistory.contentWindow.document;
	      var current_hash = iframe.location.hash;
	      if(current_hash != jQuery.historyCurrentHash) {
	        // enter when back button is pushed
	
	        location.hash = current_hash;
	        jQuery.historyCurrentHash = current_hash;
	        jQuery.historyCallback(current_hash.replace(/^#/, ''));
	      }
	  } catch (e) {
    	 // sometimes the call of ihistory.contentDocument crashes
      }
    } else if ($.browser.safari) {
      if (!jQuery.dontCheck) {
        var historyDelta = history.length - jQuery.historyBackStack.length;

        if (historyDelta) { // back or forward button has been pushed
          jQuery.isFirst = false;
          if (historyDelta < 0) { // back button has been pushed
            // move items to forward stack
            for (var i = 0; i < Math.abs(historyDelta); i++) jQuery.historyForwardStack.unshift(jQuery.historyBackStack.pop());
          } else { // forward button has been pushed
            // move items to back stack
            for (var i = 0; i < historyDelta; i++) jQuery.historyBackStack.push(jQuery.historyForwardStack.shift());
          }
          var cachedHash = jQuery.historyBackStack[jQuery.historyBackStack.length - 1];
          if (cachedHash != undefined) {
            jQuery.historyCurrentHash = location.hash;
            jQuery.historyCallback(cachedHash);
          }
        } else if (jQuery.historyBackStack[jQuery.historyBackStack.length - 1] == undefined && !jQuery.isFirst) {
          // back button has been pushed to beginning and URL already pointed to hash (e.g. a bookmark)
          // document.URL doesn't change in Safari
          if (document.URL.indexOf('#') >= 0) {
            jQuery.historyCallback(document.URL.split('#')[1]);
          } else {
            var current_hash = location.hash;
            jQuery.historyCallback('');
          }
          jQuery.isFirst = true;
        }
      }
    } else {
      // otherwise, check for location.hash
      var current_hash = location.hash;
      if(current_hash != jQuery.historyCurrentHash) {
        jQuery.historyCurrentHash = current_hash;
        jQuery.historyCallback(current_hash.replace(/^#/, ''));
      }
    }
  },
  historyLoad: function(hash){
    var newhash;

    if (jQuery.browser.safari) {
      newhash = hash;
    }
    else {
      newhash = '#' + hash;
      location.hash = newhash;
    }
    jQuery.historyCurrentHash = newhash;

    if(jQuery.browser.msie) {
      var ihistory = $("#jQuery_history")[0];
      var iframe = ihistory.contentWindow.document;
      iframe.open();
      iframe.close();
      iframe.location.hash = newhash;
      jQuery.historyCallback(hash);
    }
    else if (jQuery.browser.safari) {
      jQuery.dontCheck = true;
      // Manually keep track of the history values for Safari
      this.historyAddHistory(hash);

      // Wait a while before allowing checking so that Safari has time to update the "history" object
      // correctly (otherwise the check loop would detect a false change in hash).
      var fn = function() {jQuery.dontCheck = false;};
      window.setTimeout(fn, 200);
      jQuery.historyCallback(hash);
      // N.B. "location.hash=" must be the last line of code for Safari as execution stops afterwards.
      //      By explicitly using the "location.hash" command (instead of using a variable set to "location.hash") the
      //      URL in the browser and the "history" object are both updated correctly.
      location.hash = newhash;
    }
    else {
      jQuery.historyCallback(hash);
    }
  }
});


jQuery.autocomplete = function(input, options) {
  // Create a link to self
  var me = this;
 
  // Create jQuery object for input element
  var $input = $(input).attr("autocomplete", "off");

  // Apply inputClass if necessary
  if (options.inputClass) {
    $input.addClass(options.inputClass);
  }

  // Create results
  var results = document.createElement("div");

  // Create jQuery object for results
  // var $results = $(results);
  var $results = $(results).hide().addClass(options.resultsClass).css("position", "absolute");
  if( options.width > 0 ) {
    $results.css("width", options.width);
  }

  // Add to body element
  $("body").append(results);

  input.autocompleter = me;

  var timeout = null;
  var prev = "";
  var active = -1;
  var cache = {};
  var keyb = false;
  var hasFocus = false;
  var lastKeyPressCode = null;
  var mouseDownOnSelect = false;
  var hidingResults = false;

  // flush cache
  function flushCache(){
    cache = {};
    cache.data = {};
    cache.length = 0;
  };

  // flush cache
  flushCache();

  // if there is a data array supplied
  if( options.data != null ){
    var sFirstChar = "", stMatchSets = {}, row = [];

    // no url was specified, we need to adjust the cache length to make sure it fits the local data store
    if( typeof options.url != "string" ) {
      options.cacheLength = 1;
    }

    // loop through the array and create a lookup structure
    for( var i=0; i < options.data.length; i++ ){
      // if row is a string, make an array otherwise just reference the array
      row = ((typeof options.data[i] == "string") ? [options.data[i]] : options.data[i]);

      // if the length is zero, don't add to list
      if( row[0].length > 0 ){
        // get the first character
        sFirstChar = row[0].substring(0, 1).toLowerCase();
        // if no lookup array for this character exists, look it up now
        if( !stMatchSets[sFirstChar] ) stMatchSets[sFirstChar] = [];
        // if the match is a string
        stMatchSets[sFirstChar].push(row);
      }
    }

    // add the data items to the cache
    for( var k in stMatchSets ) {
      // increase the cache size
      options.cacheLength++;
      // add to the cache
      addToCache(k, stMatchSets[k]);
    }
  }

  $input
  .keydown(function(e) {
    // track last key pressed
    lastKeyPressCode = e.keyCode;
    
    switch(e.keyCode) {
      case 38: // up
        e.preventDefault();
        moveSelect(-1);
        break;
      case 40: // down
        e.preventDefault();
        moveSelect(1);
        break;
      case 9:  // tab
      case 13: // return
        if( selectCurrent() ){
          // make sure to blur off the current field
          $input.get(0).blur();
          e.preventDefault();
        }
        break;
      default:
        active = -1;
        if (timeout) clearTimeout(timeout);
        
        timeout = setTimeout(function(){onChange();}, options.delay);
        break;
    }
  })
  .focus(function(){
    // track whether the field has focus, we shouldn't process any results if the field no longer has focus
    hasFocus = true;
  })
  .blur(function() {
    // track whether the field has focus
    hasFocus = false;
    if (!mouseDownOnSelect) {
      hideResults();
    }
  });

  hideResultsNow();

  function onChange() {
	  
    // ignore if the following keys are pressed: [del] [shift] [capslock]
    if( lastKeyPressCode == 46 || (lastKeyPressCode > 8 && lastKeyPressCode < 32) ) return $results.hide();
    var v = $input.val();
    //modif FG / ticket #2309 supression de ce controle inutile, bloquant pour la completion des regions de 2 pays different sur la meme lettre. (ex: france -> region=a puis japon -> region=a) 
    //if (v == prev) return;
    prev = v;
    if (v.length >= options.minChars) {
      $input.addClass(options.loadingClass);
      requestData(v);
    } else {
      $input.removeClass(options.loadingClass);
      $results.hide();
    }
  };

   function moveSelect(step) {
	   
    var lis = $("li", results);
    if (!lis) return;

    active += step;

    if (active < 0) {
      active = 0;
    } else if (active >= lis.size()) {
      active = lis.size() - 1;
    }

    lis.removeClass("ac_over");

    $(lis[active]).addClass("ac_over");

    // Weird behaviour in IE
    // if (lis[active] && lis[active].scrollIntoView) {
    // 	lis[active].scrollIntoView(false);
    // }

  };

  function selectCurrent() {
	  
    var li = $("li.ac_over", results)[0];
    if (!li) {
      var $li = $("li", results);
      if (options.selectOnly) {
        if ($li.length == 1) li = $li[0];
      } else if (options.selectFirst) {
        li = $li[0];
      }
    }
    if (li) {
      selectItem(li);
      return true;
    } else {
      return false;
    }
  };

  function selectItem(li) {
	  
    if (!li) {
      li = document.createElement("li");
      li.extra = [];
      li.selectValue = "";
    }
    var v = $.trim(li.selectValue ? li.selectValue : li.innerHTML);
    input.lastSelected = v;
    prev = v;
    $results.html("");
    $input.val(v);
    hideResultsNow();
    if (options.onItemSelect) {
      setTimeout(function() { options.onItemSelect(li) }, 1);
    }
  };

  // selects a portion of the input string
  function createSelection(start, end){
	  
    // get a reference to the input element
    var field = $input.get(0);
    if( field.createTextRange ){
      var selRange = field.createTextRange();
      selRange.collapse(true);
      selRange.moveStart("character", start);
      selRange.moveEnd("character", end);
      selRange.select();
    } else if( field.setSelectionRange ){
      field.setSelectionRange(start, end);
    } else {
      if( field.selectionStart ){
        field.selectionStart = start;
        field.selectionEnd = end;
      }
    }
    field.focus();
  };

  // fills in the input box w/the first match (assumed to be the best match)
  function autoFill(sValue){
	  
    // if the last user key pressed was backspace, don't autofill
    if( lastKeyPressCode != 8 ){
      // fill in the value (keep the case the user has typed)
      $input.val($input.val() + sValue.substring(prev.length));
      // select the portion of the value not typed by the user (so the next character will erase)
      createSelection(prev.length, sValue.length);
    }
  };

  function showResults() {
	  
    // get the position of the input field right now (in case the DOM is shifted)
    var pos = findPos(input);
    // either use the specified width, or autocalculate based on form element
    var iWidth = (options.width > 0) ? options.width : $input.width();
    // reposition
    $results.css({
      width: parseInt(iWidth) + "px",
      top: (pos.y + input.offsetHeight) + "px",
      left: pos.x + "px"
    }).show();
  };

  function hideResults() {
	  
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(hideResultsNow, 200);
  };

  function hideResultsNow() {
	  
    if (hidingResults) {
      return;
    }
    hidingResults = true;

    if (timeout) {
      clearTimeout(timeout);
    }

    var v = $input.removeClass(options.loadingClass).val();

    if ($results.is(":visible")) {
      $results.hide();
    }

    if (options.mustMatch) {
      if (!input.lastSelected || input.lastSelected != v) {
        selectItem(null);
      }
    }

    hidingResults = false;
  };

  function receiveData(q, data) {
	  
    if (data) {
      $input.removeClass(options.loadingClass);
      results.innerHTML = "";

      // if the field no longer has focus or if there are no matches, do not display the drop down
      if( !hasFocus || data.length == 0 ) return hideResultsNow();

      if ($.browser.msie) {
        // we put a styled iframe behind the calendar so HTML SELECT elements don't show through
        $results.append('<iframe src="' + blankPage + '"/>');
      }
      results.appendChild(dataToDom(data));
      // autofill in the complete box w/the first match as long as the user hasn't entered in more data
      if( options.autoFill && ($input.val().toLowerCase() == q.toLowerCase()) ) autoFill(data[0][0]);
      showResults();
    } else {
      hideResultsNow();
    }
  };

  function parseData(data) {
	  
    if (!data) return null;
    var parsed = [];
    var rows = data.split(options.lineSeparator);
    for (var i=0; i < rows.length; i++) {
      var row = $.trim(rows[i]);
      if (row) {
        parsed[parsed.length] = row.split(options.cellSeparator);
      }
    }
    return parsed;
  };

  function dataToDom(data) {
	  
    var ul = document.createElement("ul");
    var num = data.length;

    // limited results to a max number
    if( (options.maxItemsToShow > 0) && (options.maxItemsToShow < num) ) num = options.maxItemsToShow;

    for (var i=0; i < num; i++) {
      var row = data[i];
      if (!row) continue;
      var li = document.createElement("li");
      if (options.formatItem) {
        li.innerHTML = options.formatItem(row, i, num);
        li.selectValue = row[0];
      } else {
        li.innerHTML = row[0];
        li.selectValue = row[0];
      }
      var extra = null;
      if (row.length > 1) {
        extra = [];
        for (var j=1; j < row.length; j++) {
          extra[extra.length] = row[j];
        }
      }
      li.extra = extra;
      ul.appendChild(li);

      $(li).hover(
        function() { $("li", ul).removeClass("ac_over"); $(this).addClass("ac_over"); active = $("li", ul).indexOf($(this).get(0)); },
        function() { $(this).removeClass("ac_over"); }
      ).click(function(e) {
        e.preventDefault();
        e.stopPropagation();
        selectItem(this)
      });

    }
    $(ul).mousedown(function() {
      mouseDownOnSelect = true;
    }).mouseup(function() {
      mouseDownOnSelect = false;
    });
    return ul;
  };

  function requestData(q) {
	  
    if (!options.matchCase) q = q.toLowerCase();
    var data = options.cacheLength ? loadFromCache(q) : null;
    // recieve the cached data
    if (data) {
      receiveData(q, data);
    // if an AJAX url has been supplied, try loading the data now
    } else if( (typeof options.url == "string") && (options.url.length > 0) ){
      $.get(makeUrl(q), function(data) {
        data = parseData(data);
        addToCache(q, data);
        receiveData(q, data);
      });
    // if there's been no data found, remove the loading class
    } else {
      $input.removeClass(options.loadingClass);
    }
  };

  function makeUrl(q) {
	  
    var sep = options.url.indexOf('?') == -1 ? '?' : '&';
    var url = options.url + sep + "q=" + encodeURI(q);
    for (var i in options.extraParams) {
      /* modif GSR : ajout de l'eval */
      url += "&" + i + "=" + encodeURI(eval(options.extraParams[i]));
      //url += "&" + i + "=" + encodeURI(options.extraParams[i]);
    }
    return url;
  };

  function loadFromCache(q) {
	  
    if (!q) return null;
    if (cache.data[q]) return cache.data[q];
    if (options.matchSubset) {
      for (var i = q.length - 1; i >= options.minChars; i--) {
        var qs = q.substr(0, i);
        var c = cache.data[qs];
        if (c) {
          var csub = [];
          for (var j = 0; j < c.length; j++) {
            var x = c[j];
            var x0 = x[0];
            if (matchSubset(x0, q)) {
              csub[csub.length] = x;
            }
          }
          return csub;
        }
      }
    }
    return null;
  };

  function matchSubset(s, sub) {
	  
    if (!options.matchCase) s = s.toLowerCase();
    var i = s.indexOf(sub);
    if (i == -1) return false;
    return i == 0 || options.matchContains;
  };

  this.flushCache = function() {
    flushCache();
  };

  this.setExtraParams = function(p) {
    options.extraParams = p;
  };

  this.findValue = function(){
    var q = $input.val();

    if (!options.matchCase) q = q.toLowerCase();
    var data = options.cacheLength ? loadFromCache(q) : null;
    if (data) {
      findValueCallback(q, data);
    } else if( (typeof options.url == "string") && (options.url.length > 0) ){
      $.get(makeUrl(q), function(data) {
        data = parseData(data)
        addToCache(q, data);
        findValueCallback(q, data);
      });
    } else {
      // no matches
      findValueCallback(q, null);
    }
  }

  function findValueCallback(q, data){
	  
    if (data) $input.removeClass(options.loadingClass);

    var num = (data) ? data.length : 0;
    var li = null;

    for (var i=0; i < num; i++) {
      var row = data[i];

      if( row[0].toLowerCase() == q.toLowerCase() ){
        li = document.createElement("li");
        if (options.formatItem) {
          li.innerHTML = options.formatItem(row, i, num);
          li.selectValue = row[0];
        } else {
          li.innerHTML = row[0];
          li.selectValue = row[0];
        }
        var extra = null;
        if( row.length > 1 ){
          extra = [];
          for (var j=1; j < row.length; j++) {
            extra[extra.length] = row[j];
          }
        }
        li.extra = extra;
      }
    }

    if( options.onFindValue ) setTimeout(function() { options.onFindValue(li) }, 1);
  }

  function addToCache(q, data) {
	  
    if (!data || !q || !options.cacheLength) return;
    if (!cache.length || cache.length > options.cacheLength) {
      flushCache();
      cache.length++;
    } else if (!cache[q]) {
      cache.length++;
    }
    cache.data[q] = data;
  };

  function findPos(obj) {
	  
    var curleft = obj.offsetLeft || 0;
    var curtop = obj.offsetTop || 0;
    while (obj = obj.offsetParent) {
      curleft += obj.offsetLeft
      curtop += obj.offsetTop
    }
    return {x:curleft,y:curtop};
  }
}

jQuery.fn.autocomplete = function(url, options, data) {
  // Make sure options exists
  options = options || {};
  // Set url as option
  options.url = url;
  // set some bulk local data
  options.data = ((typeof data == "object") && (data.constructor == Array)) ? data : null;

  // Set default values for required options
  options.inputClass = options.inputClass || "ac_input";
  options.resultsClass = options.resultsClass || "ac_results";
  options.lineSeparator = options.lineSeparator || "\n";
  options.cellSeparator = options.cellSeparator || "|";
  options.minChars = options.minChars || 1;
  options.delay = options.delay || 400;
  options.matchCase = options.matchCase || 0;
  options.matchSubset = options.matchSubset || 1;
  options.matchContains = options.matchContains || 0;
  options.cacheLength = options.cacheLength || 1;
  options.mustMatch = options.mustMatch || 0;
  options.extraParams = options.extraParams || {};
  options.loadingClass = options.loadingClass || "ac_loading";
  options.selectFirst = options.selectFirst || false;
  options.selectOnly = options.selectOnly || false;
  options.maxItemsToShow = options.maxItemsToShow || -1;
  options.autoFill = options.autoFill || false;
  options.width = parseInt(options.width, 10) || 0;

  this.each(function() {
    var input = this;
    new jQuery.autocomplete(input, options);
  });

  // Don't break the chain
  return this;
}

jQuery.fn.autocompleteArray = function(data, options) {
  return this.autocomplete(null, options, data);
}

jQuery.fn.indexOf = function(e){
  for( var i=0; i<this.length; i++ ){
    if( this[i] == e ) return i;
  }
  return -1;
};
  function closeNav() {
    try {
      var nav;
      if($.browser.msie) {
        nav = window.navFlash;
      } else {
        nav = window.document.navFlash;
      }
      if (nav != null) {
        // function closeNav must be defined
        if (typeof(nav.closeNav) != 'undefined') {
          nav.closeNav();
        }
      }
    } catch(e) {
      if (window.console && window.console.error) {
          console.error("error from flash: " + e);
          console.error(arguments);
      }
    }

  }

  // Fonction de login dans espace perso
  // @param oLogin : un objet contenant le login o.login et le password o.password
  // @return oPerso : un objet contenant les infos perso

  function sendID(oLogin) {
    var oPerso = {erreur: 1, articles: 0};
    
    var method = "POST";
    var goOn = true;
    var error = "";
    var modeConnected = "";
    var login;
    var password;
    if (oLogin == null) {
      modeConnected="&connected=1";
      login = "";
      password = "";
      method = "GET";
    } else {
      login = oLogin.login;
      password = oLogin.password;
    }

    var xmlReturn;

    /* username desactivated for FF 1.5: #1497 */
    /* if site is not ecommerce and has no personal space, this is useless #2376 */
    if (navigator.userAgent.indexOf("Firefox/1.5") > -1 || !isPerso && !isEcommerce) {
       goOn = false;
    } else {
      // Interrogation de la base et renvoie de l'objet r
      xmlReturn = $.ajax(
        {
          type: method,
          url: connect_path + ((connect_path.indexOf("?") > -1) ? "&" : "?") + "ajax=true&mode=menu" + modeConnected,
          data: "login=" + login + "&password=" + password,
          async: false
        }
      ).responseXML;
      
      var nbItem = $("caddie", xmlReturn).text().replace(/\n/g,'')
      // detecting if response is empty (work on FF and IE)
      goOn = nbItem != "";
      $("error", xmlReturn).each(function() {
          goOn = false;
       });
    }

    if (goOn) {
      oPerso.erreur = 0;
      oPerso.prenom = $("firstname", xmlReturn).text().replace(/\n/g,'');
      oPerso.nom = $("lastname", xmlReturn).text().replace(/\n/g,'');
      oPerso.vip = new Boolean(  parseInt($("isvip", xmlReturn).text().replace(/\n/g,'')) ).valueOf();
      oPerso.articles = nbItem;
    } else {
      /* cart quantity desactivated for FF 1.5: #1497 */
      if (navigator.userAgent.indexOf("Firefox/1.5") == -1 && nbItem != "") {
        oPerso.articles = nbItem;
      }
    }
	    
    return oPerso;
  }

  // Fonction d'ouverture d'une nouvelle fenï¿½tre dans le navigateur
  // @param tabTarget : un tableau contenant les paramï¿½tres de la nouvelle fenï¿½tre
  //					  ces paramï¿½tres sont passï¿½s dans le noeud <target> du lien dans le xml
  function sendTarget(tabTarget) {
    //nothing
  }

  // Fonction d'ouverture d'un nouveau template en arriï¿½re plan de la navigation
  // @param tabLink : un tableau contenant les paramï¿½tres du nouveau template
  //					ces paramï¿½tres sont passï¿½s dans le noeud <link> du lien dans le xml
  function sendLink(tabLink) {
	  
	if (tabLink.indexOf("___") != -1 ) {
		
		var params = tabLink.split("___");
	  
		if (translate_url_path) {
		
			var url = $.ajax(
			  {
			    type: "GET",
			    url: translate_url_path,
			    data: "type=" + params[1] + "&id=" + params[2],
			    async: false
			  }
			).responseText;
			
			url = url.replace("\n", "");
			
		} else {
	      if (window.console && window.console.error) {
	          console.error("translate_url_path is not defined");
	      }
		}

	} else {
	    var url = tabLink;
	}

    var indexPopup = tabLink.indexOf(' POPUP');

    if (tabLink == 'back' || tabLink == 'BACK') {
      history.back();
    } else {

      if (indexPopup > -1) {
        var indexLang = url.indexOf("/" + lang + "/");

        // thickbox
        if (tabLink.indexOf(' SMALL') > -1) {
          url = url.substr(0, indexLang) + "/layout-shutter" + url.substr(indexLang, url.length);
          tb_show('', url + '?height=270&width=430&inlineId=caddieMessage&modal=true&fromId=' + nfrontActiveObjectID + '&fromType=' + nfrontActiveObjectType);
	      $("#TB_window").addClass("TB_dioruniverse_window");
	      $("#TB_ajaxContent").addClass("TB_dioruniverse_ajaxContent");
        // normal popup
        } else{
          showPopupPage(url, 440, 480);
        }
      } else if (tabLink.indexOf("http") == 0 ) {
        showPopup(url, screen.availHeight, screen.availWidth);
      }
      else {
        loadPageWithHistory(url);
      }
      var hash = url.substr(url.lastIndexOf("/" + lang + "/"),url.length);
      // 1093: Dï¿½sactivation de l'envoi des informations au clic vers Smart Profile 
      // sp_clic('N', document.title, location.hash.replace(/#/,''), hash);

    }
  }


  function sendLinkHidden(tabLink) {
    hideBoudoir();
    sendLink(tabLink);
  }

  // Fonction de crï¿½ation d'un nouveau compte
  // perso_path initialisï¿½ dans meta.jsp
  function createNewCount() {
    sendLink(perso_path + "_step=register");
  }

  // Fonction de renvoie du password
  // @param id : l'id de la personne
  function sendPassword(email) {
    var goOn = true;
    var message = ""
    // Interrogation de la base et renvoie de l'objet r
    var xmlReturn = $.ajax(
      {
        type: "POST",
        //mail_account_info : defined in meta.jsp
        url: mail_account_info + "?ajax=true",
        data: "email=" + email,
        async: false
      }
    ).responseXML;

    message = $("error", xmlReturn).text().replace(/\n/g,'');
    if (message == "") {
      message = $("text", xmlReturn).text().replace(/\n/g,'');
    }
    return message;
  }

  // Fonction permettant d'updater le nombre d'article dans le panier de l'utilisateur
  // @param n : le nouveau nombre d'article
  function updateArticle(n){
    try {
      var nav;
      if($.browser.msie) {
        nav = window.navFlash;
      } else {
        nav = window.document.navFlash;
      }
      if (nav != null) {

        // function updateArticle must be defined
        if (typeof(nav.updateArticle) != 'undefined') {

          // when there are more than one flash on the site, nav is an array
          if (typeof(nav.length) == "undefined") {
            nav.updateArticle(n);
          } else {
            //looping on all flash, trying to find updateArticle
            for(i=0;i<nav.length;i++) {
              try {
                nav[i].updateArticle(n);
              } catch(e) {
                //alert(e);
              }
            }
          }

        }
      }
    } catch(e) {
      alert("updateArticle: " + e);
    }
  }

  function redimDiv(width){
    $("#conteneur").width(width + "px");
  }

  /* function for flash */
  function navFlash_DoFSCommand(command, args) {
    evalCommand(command, args);
  }

  function slideshowFlash_DoFSCommand(command, args) {
    evalCommand(command, args);
  }

  function homeBodycareFlash_DoFSCommand(command, args) {
    evalCommand(command, args);
  }

  function homeParfumFlash_DoFSCommand(command, args) {
    evalCommand(command, args);
  }

  function franchiseFlash_DoFSCommand(command, args) {
    evalCommand(command, args);
  }


  function evalCommand(command, args) {

    try {
      if (args != '') {
        eval(command + "('" + args + "')");
      } else {
        eval(command + "()");
      }
    } catch (e) {
      if (window.console && window.console.error) {
          console.error("error from flash: " + e);
          console.error(arguments);
      }
    }

  }


  function disconnect() {
    $.get(disconnect_path,
      function() {
       //forcing refresh, changing url with parameter disc
       var url = appContext + appSite + location.hash.replace(/#/,'').replace(/_$/,'');
       loadPageWithoutHistory(url);
      }
    );
  }

  function openPopId() {
    sendLink(perso_path);
  }

  function refreshNav() {
    var nav = getNavObject();
    if (nav != null) {
      // when there are more than one flash on the site, nav is an array
      if (typeof(nav.length) == "undefined") {
        if (nav.connect) {
          nav.connect(sendID());
        }
      } else {
        //looping on all flash, trying to find updateArticle
        for(i=0;i<nav.length;i++) {
          try {
            if (nav.connect) {
              nav.connect(sendID());
            }
          } catch(e) {
            //alert(e);
          }
        }
      }
    }
  }
  
  function forceFoldMenu(iterator){
	var nav = getNavObject();
	var iterator = iterator;
		
	try {	
		if (nav != null && typeof(nav) != 'undefined'){
			if ((typeof(nav.foldMenu) == 'function' && (isFolded.valueOf() ))){
				foldMenu(true);
			}else{
				foldMenu(false);
			}
		}
	} catch(e) {
		
		if ((nav == null || !nav.foldMenu) && iterator < 100){
			nav = getNavObject();
			iterator++;
			setTimeout("forceFoldMenu(" + iterator + ")", 1000);
			
		}
		
		if (window.console && window.console.error) {
			  console.log("error force foldmenu menu.js: "+ e );
		}
	}
  }

  function foldMenu(fold){
	  var nav = getNavObject();
	  try {
	    if (nav != null) {
	      // when there are more than one flash on the site, nav is an array
	      if (typeof(nav.length) == "undefined") {
	          nav.foldMenu(fold);
	      } else {
	        //looping on all flash
	        for(i=0;i<nav.length;i++) {
	          try {
	            if (nav.connect) {
	              nav.foldMenu(fold);
	            }
	          } catch(e) {
	            alert(e);
	          }
	        }
	      }
	    }
	  }catch(e) {
		  if ( nav.foldMenu == 'undefined' || !nav.foldMenu () ){
				nav = getNavObject();
				setTimeout("forceFoldMenu()", 1000);
			}
		  if (window.console && window.console.error) {
			  console.log("error foldMenu : "+ e );
		  }
      }
  }

 function getNavObject(){
	 if($.browser.msie) {
	    return window.navFlash;
	 } else {
	    return window.document.navFlash;
	 }
  }/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-08-17 13:14:11 -0500 (Fri, 17 Aug 2007) $
 * $Rev: 2759 $
 *
 * Version: 1.1.2
 *
 * Requires: jQuery 1.1.3+
 */

(function($){

// store a copy of the core height and width methods
var height = $.fn.height,
    width  = $.fn.width;

var logDimentions = function() {
    if (window.console && window.console.error) {
        console.error("error from dimensions.js");
        console.error(arguments);
    }
  };

$.fn.extend({
   /**
   * If used on document, returns the document's height (innerHeight).
   * If used on window, returns the viewport's (window) height.
   * See core docs on height() to see what happens when used on an element.
   *
   * @example $("#testdiv").height()
   * @result 200
   *
   * @example $(document).height()
   * @result 800
   *
   * @example $(window).height()
   * @result 400
   *
   * @name height
   * @type Number
   * @cat Plugins/Dimensions
   */
  height: function() {
	try {
	    if ( !this[0] ) error();
	    if ( this[0] == window )
	      if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
	        return self.innerHeight - (($(document).height() > self.innerHeight) ? getScrollbarWidth() : 0);
	      else if ( $.browser.safari )
	        return self.innerHeight;
	      else
	                return $.boxModel && document.documentElement.clientHeight || document.body.clientHeight;
	
	    if ( this[0] == document )
	      return Math.max( ($.boxModel && document.documentElement.scrollHeight || document.body.scrollHeight), document.body.offsetHeight );
	
	    return height.apply(this, arguments);
	} catch(e) {
		logDimentions(e, "height", arguments);
	}
  },

  /**
   * If used on document, returns the document's width (innerWidth).
   * If used on window, returns the viewport's (window) width.
   * See core docs on width() to see what happens when used on an element.
   *
   * @example $("#testdiv").width()
   * @result 200
   *
   * @example $(document).width()
   * @result 800
   *
   * @example $(window).width()
   * @result 400
   *
   * @name width
   * @type Number
   * @cat Plugins/Dimensions
   */
  width: function() {
	try {
	    if (!this[0]) error();
	    if ( this[0] == window )
	      if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
	        return self.innerWidth - (($(document).width() > self.innerWidth) ? getScrollbarWidth() : 0);
	      else if ( $.browser.safari )
	        return self.innerWidth;
	      else
	                return $.boxModel && document.documentElement.clientWidth || document.body.clientWidth;
	
	    if ( this[0] == document )
	      if ($.browser.mozilla) {
	        // mozilla reports scrollWidth and offsetWidth as the same
	        var scrollLeft = self.pageXOffset;
	        self.scrollTo(99999999, self.pageYOffset);
	        var scrollWidth = self.pageXOffset;
	        self.scrollTo(scrollLeft, self.pageYOffset);
	        return document.body.offsetWidth + scrollWidth;
	      }
	      else
	        return Math.max( (($.boxModel && !$.browser.safari) && document.documentElement.scrollWidth || document.body.scrollWidth), document.body.offsetWidth );
	
	    return width.apply(this, arguments);
	} catch(e) {
		logDimentions(e, "width", arguments);
	}
  },

  /**
   * Gets the inner height (excludes the border and includes the padding) for the first matched element.
   * If used on document, returns the document's height (innerHeight).
   * If used on window, returns the viewport's (window) height.
   *
   * @example $("#testdiv").innerHeight()
   * @result 210
   *
   * @name innerHeight
   * @type Number
   * @cat Plugins/Dimensions
   */
  innerHeight: function() {
	try {
	    if (!this[0]) error();
	    return this[0] == window || this[0] == document ?
	      this.height() :
	      this.is(':visible') ?
	        this[0].offsetHeight - num(this, 'borderTopWidth') - num(this, 'borderBottomWidth') :
	        this.height() + num(this, 'paddingTop') + num(this, 'paddingBottom');
	} catch(e) {
		logDimentions(e, "innerHeight", arguments);
	}
  },

  /**
   * Gets the inner width (excludes the border and includes the padding) for the first matched element.
   * If used on document, returns the document's width (innerWidth).
   * If used on window, returns the viewport's (window) width.
   *
   * @example $("#testdiv").innerWidth()
   * @result 210
   *
   * @name innerWidth
   * @type Number
   * @cat Plugins/Dimensions
   */
  innerWidth: function() {
	try {
	    if (!this[0]) error();
	    return this[0] == window || this[0] == document ?
	      this.width() :
	      this.is(':visible') ?
	        this[0].offsetWidth - num(this, 'borderLeftWidth') - num(this, 'borderRightWidth') :
	        this.width() + num(this, 'paddingLeft') + num(this, 'paddingRight');
	} catch(e) {
		logDimentions(e, "innerWidth", arguments);
	}
  },

  /**
   * Gets the outer height (includes the border and padding) for the first matched element.
   * If used on document, returns the document's height (innerHeight).
   * If used on window, returns the viewport's (window) height.
   *
   * The margin can be included in the calculation by passing an options map with margin
   * set to true.
   *
   * @example $("#testdiv").outerHeight()
   * @result 220
   *
   * @example $("#testdiv").outerHeight({ margin: true })
   * @result 240
   *
   * @name outerHeight
   * @type Number
   * @param Map options Optional settings to configure the way the outer height is calculated.
   * @cat Plugins/Dimensions
   */
  outerHeight: function(options) {
	try {
	    if (!this[0]) error();
	    options = $.extend({ margin: false }, options || {});
	    return this[0] == window || this[0] == document ?
	      this.height() :
	      this.is(':visible') ?
	        this[0].offsetHeight + (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0) :
	        this.height()
	          + num(this,'borderTopWidth') + num(this, 'borderBottomWidth')
	          + num(this, 'paddingTop') + num(this, 'paddingBottom')
	          + (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0);
	} catch(e) {
		logDimentions(e, "outerHeight", arguments);
	}
  },

  /**
   * Gets the outer width (including the border and padding) for the first matched element.
   * If used on document, returns the document's width (innerWidth).
   * If used on window, returns the viewport's (window) width.
   *
   * The margin can be included in the calculation by passing an options map with margin
   * set to true.
   *
   * @example $("#testdiv").outerWidth()
   * @result 1000
   *
   * @example $("#testdiv").outerWidth({ margin: true })
   * @result 1020
   *
   * @name outerHeight
   * @type Number
   * @param Map options Optional settings to configure the way the outer width is calculated.
   * @cat Plugins/Dimensions
   */
  outerWidth: function(options) {
	try {
	    if (!this[0]) error();
	    options = $.extend({ margin: false }, options || {});
	    return this[0] == window || this[0] == document ?
	      this.width() :
	      this.is(':visible') ?
	        this[0].offsetWidth + (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0) :
	        this.width()
	          + num(this, 'borderLeftWidth') + num(this, 'borderRightWidth')
	          + num(this, 'paddingLeft') + num(this, 'paddingRight')
	          + (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0);
	} catch(e) {
		logDimentions(e, "outerWidth", arguments);
	}
  },

  /**
   * Gets how many pixels the user has scrolled to the right (scrollLeft).
   * Works on containers with overflow: auto and window/document.
   *
   * @example $(window).scrollLeft()
   * @result 100
   *
   * @example $(document).scrollLeft()
   * @result 100
   *
   * @example $("#testdiv").scrollLeft()
   * @result 100
   *
   * @name scrollLeft
   * @type Number
   * @cat Plugins/Dimensions
   */
  /**
   * Sets the scrollLeft property for each element and continues the chain.
   * Works on containers with overflow: auto and window/document.
   *
   * @example $(window).scrollLeft(100).scrollLeft()
   * @result 100
   *
   * @example $(document).scrollLeft(100).scrollLeft()
   * @result 100
   *
   * @example $("#testdiv").scrollLeft(100).scrollLeft()
   * @result 100
   *
   * @name scrollLeft
   * @param Number value A positive number representing the desired scrollLeft.
   * @type jQuery
   * @cat Plugins/Dimensions
   */
  scrollLeft: function(val) {
	try {
	    if (!this[0]) error();
	    if ( val != undefined )
	      // set the scroll left
	      return this.each(function() {
	        if (this == window || this == document)
	          window.scrollTo( val, $(window).scrollTop() );
	        else
	          this.scrollLeft = val;
	      });
	
	    // return the scroll left offest in pixels
	    if ( this[0] == window || this[0] == document )
	      return self.pageXOffset ||
	        $.boxModel && document.documentElement.scrollLeft ||
	        document.body.scrollLeft;
	
	    return this[0].scrollLeft;
	} catch(e) {
		logDimentions(e, "scrollLeft", arguments);
	}
  },

  /**
   * Gets how many pixels the user has scrolled to the bottom (scrollTop).
   * Works on containers with overflow: auto and window/document.
   *
   * @example $(window).scrollTop()
   * @result 100
   *
   * @example $(document).scrollTop()
   * @result 100
   *
   * @example $("#testdiv").scrollTop()
   * @result 100
   *
   * @name scrollTop
   * @type Number
   * @cat Plugins/Dimensions
   */
  /**
   * Sets the scrollTop property for each element and continues the chain.
   * Works on containers with overflow: auto and window/document.
   *
   * @example $(window).scrollTop(100).scrollTop()
   * @result 100
   *
   * @example $(document).scrollTop(100).scrollTop()
   * @result 100
   *
   * @example $("#testdiv").scrollTop(100).scrollTop()
   * @result 100
   *
   * @name scrollTop
   * @param Number value A positive number representing the desired scrollTop.
   * @type jQuery
   * @cat Plugins/Dimensions
   */
  scrollTop: function(val) {
	try {
	    if (!this[0]) error();
	    if ( val != undefined )
	      // set the scroll top
	      return this.each(function() {
	        if (this == window || this == document)
	          window.scrollTo( $(window).scrollLeft(), val );
	        else
	          this.scrollTop = val;
	      });
	
	    // return the scroll top offset in pixels
	    if ( this[0] == window || this[0] == document )
	      return self.pageYOffset ||
	        $.boxModel && document.documentElement.scrollTop ||
	        document.body.scrollTop;
	
	    return this[0].scrollTop;
	} catch(e) {
		logDimentions(e, "scrollTop", arguments);
	}
  },

  /**
   * Gets the top and left positioned offset in pixels.
   * The positioned offset is the offset between a positioned
   * parent and the element itself.
   *
   * For accurate calculations make sure to use pixel values for margins, borders and padding.
   *
   * @example $("#testdiv").position()
   * @result { top: 100, left: 100 }
   *
   * @example var position = {};
   * $("#testdiv").position(position)
   * @result position = { top: 100, left: 100 }
   *
   * @name position
   * @param Object returnObject Optional An object to store the return value in, so as not to break the chain. If passed in the
   *                            chain will not be broken and the result will be assigned to this object.
   * @type Object
   * @cat Plugins/Dimensions
   */
  position: function(returnObject) {
	return this.offset({ margin: false, scroll: false, relativeTo: this.offsetParent() }, returnObject);
  },

  /**
   * Gets the location of the element in pixels from the top left corner of the viewport.
   * The offset method takes an optional map of key value pairs to configure the way
   * the offset is calculated. Here are the different options.
   *
   * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
   * (Boolean) border - Should the border of the element be included in the calculations? False by default.
   * (Boolean) padding - Should the padding of the element be included in the calculations? False by default.
   * (Boolean) scroll - Should the scroll offsets of the parent elements be included in the calculations? True by default.
   *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
   *                    properties to the returned object, scrollTop and scrollLeft.
   * (Boolean) lite - When true it will use the offsetLite method instead of the full-blown, slower offset method. False by default.
   *                  Only use this when margins, borders and padding calculations don't matter.
   * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
   *                             It will retreive the offset relative to this parent element. By default it is the body element.
   *
   * Also an object can be passed as the second paramater to
   * catch the value of the return and continue the chain.
   *
   * For accurate calculations make sure to use pixel values for margins, borders and padding.
   *
   * Known issues:
   *  - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari
   *    Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden
   *
   * @example $("#testdiv").offset()
   * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }
   *
   * @example $("#testdiv").offset({ scroll: false })
   * @result { top: 90, left: 90 }
   *
   * @example var offset = {}
   * $("#testdiv").offset({ scroll: false }, offset)
   * @result offset = { top: 90, left: 90 }
   *
   * @name offset
   * @param Map options Optional settings to configure the way the offset is calculated.
   * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
   *                            chain will not be broken and the result will be assigned to this object.
   * @type Object
   * @cat Plugins/Dimensions
   */
  offset: function(options, returnObject) {
	try {
	    if (!this[0]) error();
	    var x = 0, y = 0, sl = 0, st = 0,
	        elem = this[0], parent = this[0], op, parPos, elemPos = $.css(elem, 'position'),
	        mo = $.browser.mozilla, ie = $.browser.msie, oa = $.browser.opera,
	        sf = $.browser.safari, sf3 = $.browser.safari && parseInt($.browser.version) > 520,
	        absparent = false, relparent = false,
	        options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false, relativeTo: document.body }, options || {});
	
	    // Use offsetLite if lite option is true
	    if (options.lite) return this.offsetLite(options, returnObject);
	    // Get the HTMLElement if relativeTo is a jquery collection
	    if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
	
	    if (elem.tagName == 'BODY') {
	      // Safari 2 is the only one to get offsetLeft and offsetTop properties of the body "correct"
	      // Except they all mess up when the body is positioned absolute or relative
	      x = elem.offsetLeft;
	      y = elem.offsetTop;
	      // Mozilla ignores margin and subtracts border from body element
	      if (mo) {
	        x += num(elem, 'marginLeft') + (num(elem, 'borderLeftWidth')*2);
	        y += num(elem, 'marginTop')  + (num(elem, 'borderTopWidth') *2);
	      } else
	      // Opera ignores margin
	      if (oa) {
	        x += num(elem, 'marginLeft');
	        y += num(elem, 'marginTop');
	      } else
	      // IE does not add the border in Standards Mode
	      if ((ie && jQuery.boxModel)) {
	        x += num(elem, 'borderLeftWidth');
	        y += num(elem, 'borderTopWidth');
	      } else
	      // Safari 3 doesn't not include border or margin
	      if (sf3) {
	        x += num(elem, 'marginLeft') + num(elem, 'borderLeftWidth');
	        y += num(elem, 'marginTop')  + num(elem, 'borderTopWidth');
	      }
	    } else {
	      do {
	        parPos = $.css(parent, 'position');
	
	        x += parent.offsetLeft;
	        y += parent.offsetTop;
	
	        // Mozilla and IE do not add the border
	        // Mozilla adds the border for table cells
	        if ((mo && !parent.tagName.match(/^t[d|h]$/i)) || ie || sf3) {
	          // add borders to offset
	          x += num(parent, 'borderLeftWidth');
	          y += num(parent, 'borderTopWidth');
	
	          // Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
	          if (mo && parPos == 'absolute') absparent = true;
	          // IE does not include the border on the body if an element is position static and without an absolute or relative parent
	          if (ie && parPos == 'relative') relparent = true;
	        }
	
	        op = parent.offsetParent || document.body;
	        if (options.scroll || mo) {
	          do {
	            if (options.scroll) {
	              // get scroll offsets
	              sl += parent.scrollLeft;
	              st += parent.scrollTop;
	            }
	
	            // Opera sometimes incorrectly reports scroll offset for elements with display set to table-row or inline
	            if (oa && ($.css(parent, 'display') || '').match(/table-row|inline/)) {
	              sl = sl - ((parent.scrollLeft == parent.offsetLeft) ? parent.scrollLeft : 0);
	              st = st - ((parent.scrollTop == parent.offsetTop) ? parent.scrollTop : 0);
	            }
	
	            // Mozilla does not add the border for a parent that has overflow set to anything but visible
	            if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
	              x += num(parent, 'borderLeftWidth');
	              y += num(parent, 'borderTopWidth');
	            }
	
	            parent = parent.parentNode;
	          } while (parent != op);
	        }
	        parent = op;
	
	        // exit the loop if we are at the relativeTo option but not if it is the body or html tag
	        if (parent == options.relativeTo && !(parent.tagName == 'BODY' || parent.tagName == 'HTML'))  {
	          // Mozilla does not add the border for a parent that has overflow set to anything but visible
	          if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
	            x += num(parent, 'borderLeftWidth');
	            y += num(parent, 'borderTopWidth');
	          }
	          // Safari 2 and opera includes border on positioned parents
	          if ( ((sf && !sf3) || oa) && parPos != 'static' ) {
	            x -= num(op, 'borderLeftWidth');
	            y -= num(op, 'borderTopWidth');
	          }
	          break;
	        }
	        if (parent.tagName == 'BODY' || parent.tagName == 'HTML') {
	          // Safari 2 and IE Standards Mode doesn't add the body margin for elments positioned with static or relative
	          if (((sf && !sf3) || (ie && $.boxModel)) && elemPos != 'absolute' && elemPos != 'fixed') {
	            x += num(parent, 'marginLeft');
	            y += num(parent, 'marginTop');
	          }
	          // Safari 3 does not include the border on body
	          // Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
	          // IE does not include the border on the body if an element is positioned static and without an absolute or relative parent
	          if ( sf3 || (mo && !absparent && elemPos != 'fixed') ||
	               (ie && elemPos == 'static' && !relparent) ) {
	            x += num(parent, 'borderLeftWidth');
	            y += num(parent, 'borderTopWidth');
	          }
	          break; // Exit the loop
	        }
	      } while (parent);
	    }
	
	    var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);
	
	    if (returnObject) { $.extend(returnObject, returnValue); return this; }
	    else              { return returnValue; }
	} catch(e) {
		logDimentions(e, "offset", arguments);
	}
  },

  /**
   * Gets the location of the element in pixels from the top left corner of the viewport.
   * This method is much faster than offset but not as accurate when borders and margins are
   * on the element and/or its parents. This method can be invoked
   * by setting the lite option to true in the offset method.
   * The offsetLite method takes an optional map of key value pairs to configure the way
   * the offset is calculated. Here are the different options.
   *
   * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
   * (Boolean) border - Should the border of the element be included in the calculations? False by default.
   * (Boolean) padding - Should the padding of the element be included in the calcuations? False by default.
   * (Boolean) scroll - Sould the scroll offsets of the parent elements be included int he calculations? True by default.
   *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
   *                    properties to the returned object, scrollTop and scrollLeft.
   * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
   *                             It will retreive the offset relative to this parent element. By default it is the body element.
   *
   * @name offsetLite
   * @param Map options Optional settings to configure the way the offset is calculated.
   * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
   *                            chain will not be broken and the result will be assigned to this object.
   * @type Object
   * @cat Plugins/Dimensions
   */
  offsetLite: function(options, returnObject) {
	try {
	    if (!this[0]) error();
	    var x = 0, y = 0, sl = 0, st = 0, parent = this[0], offsetParent,
	        options = $.extend({ margin: true, border: false, padding: false, scroll: true, relativeTo: document.body }, options || {});
	
	    // Get the HTMLElement if relativeTo is a jquery collection
	    if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
	
	    do {
	      x += parent.offsetLeft;
	      y += parent.offsetTop;
	
	      offsetParent = parent.offsetParent || document.body;
	      if (options.scroll) {
	        // get scroll offsets
	        do {
	          sl += parent.scrollLeft;
	          st += parent.scrollTop;
	          parent = parent.parentNode;
	        } while(parent != offsetParent);
	      }
	      parent = offsetParent;
	    } while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML' && parent != options.relativeTo);
	
	    var returnValue = handleOffsetReturn(this[0], options, x, y, sl, st);
	
	    if (returnObject) { $.extend(returnObject, returnValue); return this; }
	    else              { return returnValue; }
	} catch(e) {
		logDimentions(e, "offsetLite", arguments);
	}
  },

  /**
   * Returns a jQuery collection with the positioned parent of
   * the first matched element. This is the first parent of
   * the element that has position (as in relative or absolute).
   *
   * @name offsetParent
   * @type jQuery
   * @cat Plugins/Dimensions
   */
  offsetParent: function() {
	try {
	    if (!this[0]) error();
	    var offsetParent = this[0].offsetParent;
	    while ( offsetParent && (offsetParent.tagName != 'BODY' && $.css(offsetParent, 'position') == 'static') )
	      offsetParent = offsetParent.offsetParent;
	    return $(offsetParent);
	} catch(e) {
		logDimentions(e, "offsetParent", arguments);
	}
  }
});

/**
 * Throws an error message when no elements are in the jQuery collection
 * @private
 */
var error = function() {
  throw "Dimensions: jQuery collection is empty";
};

/**
 * Handles converting a CSS Style into an Integer.
 * @private
 */
var num = function(el, prop) {
  return parseInt($.css(el.jquery?el[0]:el,prop))||0;
};

/**
 * Handles the return value of the offset and offsetLite methods.
 * @private
 */
var handleOffsetReturn = function(elem, options, x, y, sl, st) {
  if ( !options.margin ) {
    x -= num(elem, 'marginLeft');
    y -= num(elem, 'marginTop');
  }

  // Safari and Opera do not add the border for the element
  if ( options.border && (($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
    x += num(elem, 'borderLeftWidth');
    y += num(elem, 'borderTopWidth');
  } else if ( !options.border && !(($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
    x -= num(elem, 'borderLeftWidth');
    y -= num(elem, 'borderTopWidth');
  }

  if ( options.padding ) {
    x += num(elem, 'paddingLeft');
    y += num(elem, 'paddingTop');
  }

  // do not include scroll offset on the element ... opera sometimes reports scroll offset as actual offset
  if ( options.scroll && (!$.browser.opera || elem.offsetLeft != elem.scrollLeft && elem.offsetTop != elem.scrollLeft) ) {
    sl -= elem.scrollLeft;
    st -= elem.scrollTop;
  }

  return options.scroll ? { top: y - st, left: x - sl, scrollTop:  st, scrollLeft: sl }
                        : { top: y, left: x };
};

/**
 * Gets the width of the OS scrollbar
 * @private
 */
var scrollbarWidth = 0;
var getScrollbarWidth = function() {
  if (!scrollbarWidth) {
    var testEl = $('<div>')
        .css({
          width: 100,
          height: 100,
          overflow: 'auto',
          position: 'absolute',
          top: -1000,
          left: -1000
        })
        .appendTo('body');
    scrollbarWidth = 100 - testEl
      .append('<div>')
      .find('div')
        .css({
          width: '100%',
          height: 200
        })
        .width();
    testEl.remove();
  }
  return scrollbarWidth;
};

})(jQuery);/* Copyright (c) 2006 Kelvin Luck (kelvin AT kelvinluck DOT com || http://www.kelvinluck.com)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * 
 * See http://kelvinluck.com/assets/jquery/jScrollPane/
 * $Id: jScrollPane.js 1567 2007-03-23 01:34:29Z kelvin $
 */

/**
 * Replace the vertical scroll bars on any matched elements with a fancy
 * styleable (via CSS) version. With JS disabled the elements will
 * gracefully degrade to the browsers own implementation of overflow:auto.
 * If the mousewheel plugin has been included on the page then the scrollable areas will also
 * respond to the mouse wheel.
 *
 * @example jQuery(".scroll-pane").jScrollPane();
 *
 * @name jScrollPane
 * @type jQuery
 * @param Object	settings	hash with options, described below.
 *								scrollbarWidth	-	The width of the generated scrollbar in pixels
 *								scrollbarMargin	-	The amount of space to leave on the side of the scrollbar in pixels
 *								wheelSpeed		-	The speed the pane will scroll in response to the mouse wheel in pixels
 *								showArrows		-	Whether to display arrows for the user to scroll with
 *								arrowSize		-	The height of the arrow buttons if showArrows=true
 *								animateTo		-	Whether to animate when calling scrollTo and scrollBy
 *								dragMinHeight	-	The minimum height to allow the drag bar to be
 *								dragMaxHeight	-	The maximum height to allow the drag bar to be
 * @return jQuery
 * @cat Plugins/jScrollPane
 * @author Kelvin Luck (kelvin AT kelvinluck DOT com || http://www.kelvinluck.com)
 */
jQuery.jScrollPane = {
	active : []
};
jQuery.fn.jScrollPane = function(settings)
{
	settings = jQuery.extend(
		{
			scrollbarWidth : 10,
			scrollbarMargin : 5,
			wheelSpeed : 18,
			showArrows : false,
			arrowSize : undefined,
			animateTo : false,
			dragMinHeight : 1,
			dragMaxHeight : 99999
		}, settings
	);
	return this.each(
		function()
		{
			var $this = jQuery(this);
			
			if (jQuery(this).parent().is('.jScrollPaneContainer')) {
				var $c = jQuery(this).parent();
				var paneWidth = $c.innerWidth();
				var paneHeight = $c.outerHeight();
				var trackHeight = paneHeight;
				if ($c.unmousewheel) {
					$c.unmousewheel();
				}
				jQuery('>.jScrollPaneTrack, >.jScrollArrowUp, >.jScrollArrowDown', $c).remove();
				$this.css({'top':0});
			} else {
				this.originalPadding = $this.css('paddingTop') + ' ' + $this.css('paddingRight') + ' ' + $this.css('paddingBottom') + ' ' + $this.css('paddingLeft');
				this.originalSidePaddingTotal = (parseInt($this.css('paddingLeft')) || 0) + (parseInt($this.css('paddingRight')) || 0);
				var paneWidth = $this.innerWidth();
				var paneHeight = $this.innerHeight();
				var trackHeight = paneHeight;
				$this.wrap(
					jQuery('<div>').attr(
						{'className':'jScrollPaneContainer'}
					).css(
						{
							'height':paneHeight+'px', 
							'width':paneWidth+'px'
						}
					)
				);
			}
			var p = this.originalSidePaddingTotal;
			$this.css(
				{
					'height':'auto',
					'width':paneWidth - settings.scrollbarWidth - settings.scrollbarMargin - p + 'px',
					'paddingRight':settings.scrollbarMargin + 'px'
				}
			);
			var contentHeight = $this.outerHeight();
			var percentInView = paneHeight / contentHeight;

			if (percentInView < .98) {
				var $container = $this.parent();
				$container.append(
					jQuery('<div>').attr({'className':'jScrollPaneTrack'}).css({'width':settings.scrollbarWidth+'px'}).append(
						jQuery('<div>').attr({'className':'jScrollPaneDrag'}).css({'width':settings.scrollbarWidth+'px'}).append(
							jQuery('<div>').attr({'className':'jScrollPaneDragTop'}).css({'width':settings.scrollbarWidth+'px'}),
							jQuery('<div>').attr({'className':'jScrollPaneDragBottom'}).css({'width':settings.scrollbarWidth+'px'})
						)
					)
				);
				
				var $track = jQuery('>.jScrollPaneTrack', $container);
				var $drag = jQuery('>.jScrollPaneTrack .jScrollPaneDrag', $container);
				
				if (settings.showArrows) {
					
					var currentArrowButton;
					var currentArrowDirection;
					var currentArrowInterval;
					var currentArrowInc;
					var whileArrowButtonDown = function()
					{
						if (currentArrowInc > 4 || currentArrowInc%4==0) {
							positionDrag(dragPosition + currentArrowDirection * mouseWheelMultiplier);
						}
						currentArrowInc ++;
					};
					var onArrowMouseUp = function(event)
					{
						jQuery('body').unbind('mouseup', onArrowMouseUp);
						currentArrowButton.removeClass('jScrollActiveArrowButton');
						clearInterval(currentArrowInterval);
						alert($(event.target));
						//currentArrowButton.parent().removeClass('jScrollArrowUpClicked jScrollArrowDownClicked');
					};
					var onArrowMouseDown = function() {
						alert(direction);
						//currentArrowButton = $(this);
						jQuery('body').bind('mouseup', onArrowMouseUp);
						currentArrowButton.addClass('jScrollActiveArrowButton');
						currentArrowInc = 0;
						whileArrowButtonDown();
						currentArrowInterval = setInterval(whileArrowButtonDown, 100);
					};
					$container
						.append(
							jQuery('<a>')
								.attr({'href':'javascript:;', 'className':'jScrollArrowUp'})
								.css({'width':settings.scrollbarWidth+'px'})
								.html('Scroll up')
								.bind('mousedown', function()
								{
									currentArrowButton = $(this);
									currentArrowDirection = -1;
									onArrowMouseDown();
									this.blur();
									return false;
								}),
							jQuery('<a>')
								.attr({'href':'javascript:;', 'className':'jScrollArrowDown'})
								.css({'width':settings.scrollbarWidth+'px'})
								.html('Scroll down')
								.bind('mousedown', function()
								{
									currentArrowButton = $(this);
									currentArrowDirection = 1;
									onArrowMouseDown();
									this.blur();
									return false;
								})
						);
					if (settings.arrowSize) {
						trackHeight = paneHeight - settings.arrowSize - settings.arrowSize;
						$track
							.css({'height': trackHeight+'px', top:settings.arrowSize+'px'})
					} else {
						var topArrowHeight = jQuery('>.jScrollArrowUp', $container).height();
						trackHeight = paneHeight - topArrowHeight - jQuery('>.jScrollArrowDown', $container).height();
						$track
							.css({'height': trackHeight+'px', top:topArrowHeight+'px'})
					}
				}
				
				var $pane = jQuery(this).css({'position':'absolute', 'overflow':'visible'});
				
				var currentOffset;
				var maxY;
				var mouseWheelMultiplier;
				// store this in a seperate variable so we can keep track more accurately than just updating the css property..
				var dragPosition = 0;
				var dragMiddle = percentInView*paneHeight/2;
				
				// pos function borrowed from tooltip plugin and adapted...
				var getPos = function (event, c) {
					var p = c == 'X' ? 'Left' : 'Top';
					return event['page' + c] || (event['client' + c] + (document.documentElement['scroll' + p] || document.body['scroll' + p])) || 0;
				};
				
				var ignoreNativeDrag = function() {	return false; };
				
				var initDrag = function()
				{
					ceaseAnimation();
					currentOffset = $drag.offset(false);
					currentOffset.top -= dragPosition;
					maxY = trackHeight - $drag[0].offsetHeight;
					mouseWheelMultiplier = 2 * settings.wheelSpeed * maxY / contentHeight;
				};
				
				var onStartDrag = function(event)
				{
					initDrag();
					dragMiddle = getPos(event, 'Y') - dragPosition - currentOffset.top;
					jQuery('body').bind('mouseup', onStopDrag).bind('mousemove', updateScroll);
					if (jQuery.browser.msie) {
						jQuery('body').bind('dragstart', ignoreNativeDrag).bind('selectstart', ignoreNativeDrag);
					}
					return false;
				};
				var onStopDrag = function()
				{
					jQuery('body').unbind('mouseup', onStopDrag).unbind('mousemove', updateScroll);
					dragMiddle = percentInView*paneHeight/2;
					if (jQuery.browser.msie) {
						jQuery('body').unbind('dragstart', ignoreNativeDrag).unbind('selectstart', ignoreNativeDrag);
					}
				};
				var positionDrag = function(destY)
				{
					destY = destY < 0 ? 0 : (destY > maxY ? maxY : destY);
					dragPosition = destY;
					$drag.css({'top':destY+'px'});
					var p = destY / maxY;
					$pane.css({'top':((paneHeight-contentHeight)*p) + 'px'});
				};
				var updateScroll = function(e)
				{
					positionDrag(getPos(e, 'Y') - currentOffset.top - dragMiddle);
				};
				
				var dragH = Math.max(Math.min(percentInView*paneHeight, settings.dragMaxHeight), settings.dragMinHeight);
				$drag.css(
					{'height':dragH+'px'}
				).bind('mousedown', onStartDrag);
				
				var trackScrollInterval;
				var trackScrollInc;
				var trackScrollMousePos;
				var doTrackScroll = function()
				{
					if (trackScrollInc > 8 || trackScrollInc%4==0) {
						positionDrag((dragPosition - ((dragPosition - trackScrollMousePos) / 2)));
					}
					trackScrollInc ++;
				};
				var onStopTrackClick = function()
				{
					clearInterval(trackScrollInterval);
					jQuery('body').unbind('mouseup', onStopTrackClick).unbind('mousemove', onTrackMouseMove);
				};
				var onTrackMouseMove = function(event)
				{
					trackScrollMousePos = getPos(event, 'Y') - currentOffset.top - dragMiddle;
				};
				var onTrackClick = function(event)
				{
					initDrag();
					onTrackMouseMove(event);
					trackScrollInc = 0;
					jQuery('body').bind('mouseup', onStopTrackClick).bind('mousemove', onTrackMouseMove);
					trackScrollInterval = setInterval(doTrackScroll, 100);
					doTrackScroll();
				};
				
				$track.bind('mousedown', onTrackClick);
				
				// if the mousewheel plugin has been included then also react to the mousewheel
				if ($container.mousewheel) {
					$container.mousewheel(
						function (event, delta) {
							initDrag();
							ceaseAnimation();
							var d = dragPosition;
							positionDrag(dragPosition - delta * mouseWheelMultiplier);
							var dragOccured = d != dragPosition;
							return !dragOccured;
						},
						false
					);					
				}
				var _animateToPosition;
				var _animateToInterval;
				function animateToPosition()
				{
					var diff = (_animateToPosition - dragPosition) / 3;
					if (diff > 1 || diff < -1) {
						positionDrag(dragPosition + diff);
					} else {
						positionDrag(_animateToPosition);
						ceaseAnimation();
					}
				}
				var ceaseAnimation = function()
				{
					if (_animateToInterval) {
						clearInterval(_animateToInterval);
						delete _animateToPosition;
					}
				};
				var scrollTo = function(pos)
				{
					ceaseAnimation();
					var destDragPosition = -pos/(paneHeight-contentHeight) * maxY;
					if (settings.animateTo) {
						_animateToPosition = destDragPosition;
						_animateToInterval = setInterval(animateToPosition, 100);
					} else {
						positionDrag(destDragPosition);
					}
				};
				$this[0].scrollTo = scrollTo;
				
				$this[0].scrollBy = function(delta)
				{
					var currentPos = -parseInt($pane.css('top')) || 0;
					scrollTo(currentPos + delta);
				};
				
				initDrag();
				
				jQuery.jScrollPane.active.push($this[0]);

			} else {
				$this.css(
					{
						'height':paneHeight+'px',
						'width':paneWidth-this.originalSidePaddingTotal+'px',
						'padding':this.originalPadding
					}
				);
				// remove from active list?
			}
		}
	)
};

// clean up the scrollTo expandos
jQuery(window)
	.bind('unload', function() {
		var els = jQuery.jScrollPane.active; 
		for (var i=0; i<els.length; i++) {
			els[i].scrollTo = els[i].scrollBy = null;
		}
	}
);// le scrollbar personnalise

	$(function()
		{
			$('.lista').jScrollPane({scrollbarWidth:10, scrollbarMargin:10});
		});
/* Copyright (c) 2006 Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * $LastChangedDate: 2007-03-06 20:55:27 +0000 (Tue, 06 Mar 2007) $
 * $Rev: 1497 $
 */

(function($) {

$.fn.extend({
	/**
	 * Apply the mousewheel event to the elements in the jQuery object.
	 * The handler function should be prepared to take the event object
	 * and a param called 'delta'. The 'delta' param is a number
	 * either > 0 or < 0. > 0 = up and < 0 = down.
	 *
	 * @example $("p").mousewheel(function(event, delta){
	 *   if (delta > 0)
	 *     // do something on mousewheel scroll up
	 *   else if (delta < 0)
	 *     //do something on mousewheel scroll down
	 * });
	 *
	 * @name mousewheel
	 * @type jQuery
	 * @param Function handler A function to call when onmousewheel fires. Should take two params: event and delta.
	 * @cat Plugins/Mousewheel
	 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
	 */
	mousewheel: function(f) {
		if (!f.guid) f.guid = $.event.guid++;
		if (!$.event._mwCache) $.event._mwCache = [];
		
		return this.each( function() {
			if (this._mwHandlers) return this._mwHandlers.push(f);
			else this._mwHandlers = [];
			
			this._mwHandlers.push(f);
			
			var s = this;
			
			this._mwHandler = function(e) {
				e = $.event.fix(e || window.event);
				var delta = 0, returnValue = true;
				
				if (e.wheelDelta)  delta = e.wheelDelta/120;
				if (e.detail)      delta = -e.detail/3;
				if (window.opera)  delta = -e.wheelDelta;
				
				for (var i=0; i<s._mwHandlers.length; i++)
					if (s._mwHandlers[i])
						if ( s._mwHandlers[i].call(s, e, delta) === false ) {
							returnValue = false;
							e.preventDefault();
							e.stopPropagation();
						}
				
				return returnValue;
			};
			
			if (this.addEventListener)
				if ($.browser.mozilla) this.addEventListener('DOMMouseScroll', this._mwHandler, false);
				else                   this.addEventListener('mousewheel',     this._mwHandler, false);
			else
				$.event.add(this, 'mousewheel', this._mwHandler);
			
			$.event._mwCache.push( $(this) );
		});
	},
	
	/**
	 * This method removes one or all applied mousewheel events from the elements.
	 * You can remove a single handler function by passing it as the first param.
	 * If you do not pass anything, it will remove all handlers.
	 *
	 * @name unmousewheel
	 * @param Function handler The handler function to remove from the mousewheel event.
	 * @type jQuery
	 * @cat Plugins/Mousewheel
	 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
	 */
	unmousewheel: function(f) {
		return this.each( function() {
			if ( f && this._mwHandlers ) {
				for (var i=0; i<this._mwHandlers.length; i++)
					if (this._mwHandlers[i] && this._mwHandlers[i].guid == f.guid)
						delete this._mwHandlers[i];
			} else {
				if (this.addEventListener)
					if ($.browser.mozilla) this.removeEventListener('DOMMouseScroll', this._mwHandler, false);
					else                   this.removeEventListener('mousewheel',     this._mwHandler, false);
				else
					$.event.remove(this, 'mousewheel', this._mwHandler);
					
				this._mwHandlers = this._mwHandler = null;
			}
		});
	}
});

// clean-up
$(window)
	.bind('unload', function() {
		var els = $.event._mwCache || [];
		for (var i=0; i<els.length; i++)
			els[i].unmousewheel();
	});
	
})(jQuery);/*
 * jQuery selectbox plugin
 *
 * Copyright (c) 2007 Sadri Sahraoui (brainfault.com)
 * Licensed under the GPL license:
 *   http://www.gnu.org/licenses/gpl.html
 *
 * The code is inspired from Autocomplete plugin (http://www.dyve.net/jquery/?autocomplete)
 *
 * Revision: $Id$
 * Version: 0.3
 */
jQuery.fn.extend({
  selectbox: function(options) {
    return this.each(function() {
      new jQuery.SelectBox(this, options);
    });
  }
});

jQuery.SelectBox = function(selectobj, options) {

  var opt = options || {};
  opt.inputClass = opt.inputClass || "selectbox";
  opt.containerClass = opt.containerClass || "selectbox-wrapper";
  opt.hoverClass = opt.hoverClass || "selected";
  opt.debug = opt.debug || false;
  //opt.debug = true;

  var elm_id = selectobj.id;
  var active = -1;
  var inFocus = false;
  var hasfocus = 0;
  
  //jquery object for select element
  var $select = $(selectobj);
  //jquery input object
  var $input = setupInput(opt);
  // jquery container object
  var $container = setupContainer(opt);

  // hide select and append newly created elements
  $select.hide().before($container).before($input);

  init();
  $input
  .click(function(){
    if (!inFocus) {
      $container.toggle();
    }
  })
  .focus(function(){
     if ($container.not(':visible')) {
       inFocus = true;
       $container.show();
     }
  })
  .keydown(function(event) {
    switch(event.keyCode) {
      case 38: // up
        event.preventDefault();
        moveSelect(-1);
        break;
      case 40: // down
        event.preventDefault();
        moveSelect(1);
        break;
      //case 9:  // tab
      case 13: // return
        event.preventDefault(); // seems not working in mac !
        setCurrent();
        hideMe();
        break;
    }
  })
  .blur(function() {
    if ($container.is(':visible') && hasfocus > 0 ) {
      if(opt.debug) alert('container visible and has focus')
    } else {
      hideMe();
    }
  });


  function hideMe() {
    hasfocus = 0;
    $container.hide();
  }

  function init() {
    $container.append(getSelectOptions()).hide();
    /* GSR : under FF, input width is 0, so the width will be automatic */
    /*if(!jQuery.browser.mozilla) {
      var width = $input.width();
      if (width==0) width = $input.css("width").split("px")[0]; // dans les fenêtres modal, width est nulle, on s'appuie alors sur la css.
      $container.width(width);
    }*/
  }

  function setupContainer(options) {
    var container = document.createElement("div");
    $container = $(container);
    $container.attr('id', elm_id+'_container');
    $container.addClass(options.containerClass);

    return $container;
  }

  function setupInput(options) {
    var input = document.createElement("input");
    var $input = $(input);
    $input.attr("id", elm_id+"_input");
    $input.attr("type", "text");
    $input.addClass(options.inputClass);
    $input.attr("autocomplete", "off");
    $input.attr("readonly", "readonly");
    $input.attr("tabIndex", $select.attr("tabindex")); // "I" capital is important for ie

    return $input;
  }

  function moveSelect(step) {
    var lis = $("li", $container);
    if (!lis) return;

    active += step;

    if (active < 0) {
      active = 0;
    } else if (active >= lis.size()) {
      active = lis.size() - 1;
    }

    lis.removeClass(opt.hoverClass);

    $(lis[active]).addClass(opt.hoverClass);
  }

  function setCurrent() {
    var li = $("li."+opt.hoverClass, $container).get(0);
    var el = li.id;
    $select.val(el);
    $input.val($(li).children().html().replace(/\n/g,' '));
    return true;
  }

  // select value
  function getCurrentSelected() {
    return $select.val();
  }

  // input value
  function getCurrentValue() {
    return $input.val();
  }

  function getSelectOptions() {
    var select_options = new Array();
    var ul = document.createElement('ul');
    $select.children('option').each(function() {
      var li = document.createElement('li');
      li.setAttribute('id', $(this).val());
      /* GSR */
      li.innerHTML = "<a onmouseover='$(this).toggleClass(\"over\")' onmouseout='$(this).toggleClass(\"over\")'>" + $(this).html() + "</a>";
      if ($(this).is(':selected')) {
        $input.val($(this).html().replace(/\n/g,' '));
        $(li).addClass(opt.hoverClass);
      }
      ul.appendChild(li);
      $(li)
      .mouseover(function(event) {
        hasfocus = 1;
        if (opt.debug) alert('out on (mouseover) : '+this.id);
        jQuery('li', $container).removeClass(opt.hoverClass);
        jQuery(event.target, $container).addClass(opt.hoverClass);
      })
      .mouseout(function(event) {
        hasfocus = -1;
        if (opt.debug) alert('out on (mouseout) : '+this.id);
        jQuery(event.target, $container).removeClass(opt.hoverClass);
      })
      .click(function(event) {
        if (opt.debug) alert('click on (click) :'+this.id);
        $(this).addClass(opt.hoverClass);
        setCurrent();
        hideMe();
      });
    });
    return ul;
  }

};/*
 * DOMcollapse
 * Version 3.0
 * released 06.12.2005
 * Not for commercial reselling or use, unless consent given by the author
 * Check for updates on http://onlinetools.org and http://wait-till-i.com
 *
*/

dc={
  triggerElements:'h3', 	// elements to trigger the effect
  parentElementId:null,	// ID of the parent element (keep null if none)
  uniqueCollapse:true,	// is set to true only one element can be open at a time

  // CSS class names
  trigger:'trigger',
  triggeropen:'expanded',
  hideClass:'hide',
  showClass:'show',

  // pictures and text alternatives
  closedPic:closedPicPath,
  closedAlt:'expand section',
  openPic:openPicPath,
  openAlt:'collapse section',

  IMGwidth:'7',
  IMGheight:'7',

  /* Doesn't work with Safari
    hoverClass:'hover',
  */

  init:function(e){
    var temp;
    if(!document.getElementById || !document.createTextNode){return;}
    if(!dc.parentElementId){
      temp=document.getElementsByTagName(dc.triggerElements);
    } else if(document.getElementById(dc.parentElementId)){
      temp=document.getElementById(dc.parentElementId).getElementsByTagName(dc.triggerElements);
    }else{
      return;
    }
    dc.tempLink=document.createElement('a');
    dc.tempLink.setAttribute('href','#');
    dc.tempLink.setAttribute('width','7px');
    dc.tempLink.appendChild(document.createElement('img'));
    for(var i=0;i<temp.length;i++){
      /* GSR : #292 */
      if (temp[i].innerHTML.indexOf(dc.openAlt) == -1 && temp[i].innerHTML.indexOf(dc.closedAlt) == -1) {
        if(dc.cssjs('check',temp[i],dc.trigger) || dc.cssjs('check',temp[i],dc.triggeropen)){
          dc.makeTrigger(temp[i],e);
        }
      }
    }
  },
  makeTrigger:function(o,e){
    var tl=dc.tempLink.cloneNode(true);
    var tohide=o.nextSibling;
    while(tohide.nodeType!=1)
    {
      tohide=tohide.nextSibling;
    }
    o.tohide=tohide;
    if(!dc.cssjs('check',o,dc.triggeropen)){
      dc.cssjs('add',tohide,dc.hideClass);
      tl.getElementsByTagName('img')[0].setAttribute('src',dc.closedPic);
    tl.getElementsByTagName('img')[0].setAttribute('width',dc.IMGwidth);
    tl.getElementsByTagName('img')[0].setAttribute('height',dc.IMGheight);
      tl.getElementsByTagName('img')[0].setAttribute('alt',dc.closedAlt);
      //o.setAttribute('title',dc.closedAlt);
    }else{
      dc.cssjs('add',tohide,dc.showClass);
      tl.getElementsByTagName('img')[0].setAttribute('src',dc.openPic);
    tl.getElementsByTagName('img')[0].setAttribute('width',dc.IMGwidth);
    tl.getElementsByTagName('img')[0].setAttribute('height',dc.IMGheight);
      tl.getElementsByTagName('img')[0].setAttribute('alt',dc.openAlt);
      //o.setAttribute('title',dc.openAlt);
      dc.currentOpen=o;
    }
    dc.addEvent(o,'click',dc.addCollapse,false);
    /* Doesn't work with Safari
    dc.addEvent(o,'mouseover',dc.hover,false);
    dc.addEvent(o,'mouseout',dc.hover,false);
    */
    o.insertBefore(tl,o.firstChild);
    dc.addEvent(tl,'click',dc.addCollapse,false);
    // Safari hacks
    tl.onclick=function(){return false;}
    o.onclick=function(){return false;}
  },
  /* Doesn't work with Safari
  hover:function(e){
    var o=dc.getTarget(e);
    var action=dc.cssjs('check',o,dc.hoverClass)?'remove':'add';
    dc.cssjs(action,o,dc.hoverClass)
  },
  */
  addCollapse:function(e){
    var action,pic;
    // hack to fix safari's redraw bug
    // as mentioned on http://en.wikipedia.org/wiki/Wikipedia:Browser_notes#Mac_OS_X
    if (self.screenTop && self.screenX){
      window.resizeTo(self.outerWidth + 1, self.outerHeight);
      window.resizeTo(self.outerWidth - 1, self.outerHeight);
    }
    if(dc.uniqueCollapse && dc.currentOpen){
      dc.currentOpen.getElementsByTagName('img')[0].setAttribute('src',dc.closedPic);
      dc.currentOpen.getElementsByTagName('img')[0].setAttribute('width',dc.IMGwidth);
      dc.currentOpen.getElementsByTagName('img')[0].setAttribute('height',dc.IMGheight);
      dc.currentOpen.getElementsByTagName('img')[0].setAttribute('alt',dc.closedAlt);
      //dc.currentOpen.setAttribute('title',dc.closedAlt);
      dc.cssjs('swap',dc.currentOpen.tohide,dc.showClass,dc.hideClass);
      dc.cssjs('remove',dc.currentOpen,dc.triggeropen);
      dc.cssjs('add',dc.currentOpen,dc.trigger);
    }
    var o=dc.getTarget(e);
    if(o.tohide){
      if(dc.cssjs('check',o.tohide,dc.hideClass)){
        o.getElementsByTagName('img')[0].setAttribute('src',dc.openPic);
        o.getElementsByTagName('img')[0].setAttribute('width',dc.IMGwidth);
        o.getElementsByTagName('img')[0].setAttribute('height',dc.IMGheight);
        o.getElementsByTagName('img')[0].setAttribute('alt',dc.openAlt);
        //o.setAttribute('title',dc.openAlt);
        dc.cssjs('swap',o.tohide,dc.hideClass,dc.showClass);
        dc.cssjs('add',o,dc.triggeropen);
        dc.cssjs('remove',o,dc.trigger);
      }else{
        o.getElementsByTagName('img')[0].setAttribute('src',dc.closedPic);
        o.getElementsByTagName('img')[0].setAttribute('width',dc.IMGwidth);
        o.getElementsByTagName('img')[0].setAttribute('height',dc.IMGheight);
        o.getElementsByTagName('img')[0].setAttribute('alt',dc.closedAlt);
        //o.setAttribute('title',dc.closedAlt);
        dc.cssjs('swap',o.tohide,dc.showClass,dc.hideClass);
        dc.cssjs('remove',o,dc.triggeropen);
        dc.cssjs('add',o,dc.trigger);
      }
      dc.currentOpen=o;
      dc.cancelClick(e);
      //document.getElementById('debug').innerHTML=o.tohide.className;
    }
    else{
      dc.cancelClick(e);
    }
  },
  /* helper methods */
  getTarget:function(e){
    var target = window.event ? window.event.srcElement : e ? e.target : null;
    if (!target){return false;}
    while(!target.tohide && target.nodeName.toLowerCase()!='body')
    {
      target=target.parentNode;
    }
    // if (target.nodeName.toLowerCase() != 'a'){target = target.parentNode;} Safari fix not needed here
    return target;
  },
  cancelClick:function(e){
    if (window.event){
      window.event.cancelBubble = true;
      window.event.returnValue = false;
      return;
    }
    if (e){
      e.stopPropagation();
      e.preventDefault();
    }
  },
  addEvent: function(elm, evType, fn, useCapture){
    if (elm.addEventListener)
    {
      elm.addEventListener(evType, fn, useCapture);
      return true;
    } else if (elm.attachEvent) {
      var r = elm.attachEvent('on' + evType, fn);
      return r;
    } else {
      elm['on' + evType] = fn;
    }
  },
  cssjs:function(a,o,c1,c2){
    switch (a){
      case 'swap':
        o.className=!dc.cssjs('check',o,c1)?o.className.replace(c2,c1):o.className.replace(c1,c2);
      break;
      case 'add':
        if(!dc.cssjs('check',o,c1)){o.className+=o.className?' '+c1:c1;}
      break;
      case 'remove':
        var rep=o.className.match(' '+c1)?' '+c1:c1;
        o.className=o.className.replace(rep,'');
      break;
      case 'check':
        return new RegExp("(^|\\s)" + c1 + "(\\s|$)").test(o.className)
      break;
    }
  }
}
dc.addEvent(window, 'load', dc.init, false);
/*
 * jQuery tintPicker
 *	inspirÃ© de jQuery selectbox plugin .

 */

jQuery.fn.extend({
  tintpicker: function(options) {
    return this.each(function() {
      new jQuery.TintPicker(this, options);
    });
  }
});

jQuery.TintPicker = function(selectobj, options) {
	// les option sont partagÃ©es par toutes les instances de l'objet, attention notamment Ã  la propriÃ©tÃ© containerOffset
	var opt = options || {};
	opt.tintWidth = opt.tintWidth || "10";
	opt.tintHeight = opt.tintHeight || "10";
	opt.tintPickerId = opt.tintPickerId || "tintPicker";
	opt.index = selectobj.id.split("tint")[1];
	opt.debug = opt.debug || false;
	opt.pickerClass = opt.pickerClass || "tintPicker";
	opt.mainLabelClass = opt.mainLabelClass || "tintMainLabel";
	opt.callBack = opt.callBack;
	opt.safeZone = opt.safeZone || 0; // zone en pixel placÃ©e en dÃ©but et fin de scroll pour ne pas gÃªner la consultation du premier et dernier item en cas de scroll

    if(opt.debug) console.log('--TintPicker');
	if(opt.debug && opt.index=="") {
		alert('tintPicker :: selectobj.id doit commencer par "tint"');
	}

	//jquery object for select element
	var $select = $(selectobj);
	var inFocus = false;
	var hasfocus = 0;
	// jquery container object
	var $container = setupPicker(opt,$select);
	var $mainLabel = setupMainLabel(opt,$select);
	var $wrapper = $container.children("div");
	$select.hide().before($container).before($mainLabel);
	updateMainLabel();
	var hauteurWrapper = $wrapper.height();
	var hauteurContainer = $container.height();
	var containerYOffset = $container.offset().top;// il faut recalculer Ã  chaque fois Ã  cause de la mise en place
	var y; // position Y de la souris sur la page
	var ymouse;
	var margin;

	// affinage du rendu de la palette
	if (hauteurWrapper > hauteurContainer) { // besoin de scroll interne
		// ï¿½vï¿½nement sur le container pour scroll
		$container.mousemove(function(e){
			containerYOffset = $container.offset().top;// il faut recalculer Ã  chaque fois Ã  cause de la mise en place
			// laisser une marge haute et basse avant de dÃ©clencher pour permettre la lecture du premier et dernier Ã©lÃ©ment
			y = e.pageY;
			ymouse = (y - containerYOffset);
			if(ymouse <= 2){
				$wrapper.css("margin-top", 0);
			}else if ( ymouse > opt.safeZone && ymouse <= (hauteurContainer-opt.safeZone)) { // on ne travaille que dans la zone dÃ©finie
		      	margin = -Math.round([(ymouse - opt.safeZone)*(hauteurWrapper - hauteurContainer)]/[hauteurContainer-(2*opt.safeZone)]);
		      	$wrapper.css("margin-top", margin);
			}
		});
	} else {
		// recadre la palette globale au contenu pour Ã©viter les lignes vides
		$container.height(hauteurWrapper);
	}

	//$("#out"+opt.index).html($container.attr('id') + ", hw: " +hauteurWrapper+ "> hc: " + hauteurContainer + ", marge :"+margin);


	// click sur le lien pour afficher le selecteur
	$("#"+$container.attr('id') + " a").click(function () {
		$('div #'+ $container.attr('id') + " a.activ").attr("class","");
		$(this).attr("class","activ");
		if(opt.debug)console.log("This: "+$(this).attr("id"));
		var aId = $(this).attr("id");
		var currentProductId = aId.substring(12,18);
		if(opt.debug)console.log("currentproductid: "+currentProductId);
		var formNbId = $('div #' + $container.attr('id')).parents("form").attr("id");
		$("form#" + formNbId + " input[@name=pcid]").val( currentProductId );
		opt.index =  selectobj.id.split("tint")[1];
		if(opt.debug)console.log("opt.index : "+opt.index );
		$('select#tint' + opt.index + ' option').removeAttr('selected');
		//Note : Firebug doesn't show the result of the following line
		$('select#tint' + opt.index + ' option[@value=' + aId.substr(12,aId.length) + ']').attr('selected','selected');
		hideMe();
		updateMainLabel();
		eval( opt.callBack + "(\"" + aId.substr(12,aId.length) + "\",\"" + $select.attr("id") + "\")");

		return false;
	})
	.mouseover(function(event) {
        hasfocus = 1;
    })
    .mouseout(function(event) {
        hasfocus = -1;
    });
	// important de masquer le container Ã  la fin pour bien rÃ©cupÃ©rer les hauteurs de contenu
	$container.hide();

  function hideMe() {
	if(opt.debug) console.log('--hideMe');
    hasfocus = 0;
    $container.hide();
  }

	// met en place la combo fake
	function setupMainLabel(options,select) {
		if(opt.debug) console.log('--setupMainLabel');
	    var mainLabel = document.createElement("a");
	    $select = select;
	    var $mainLabel = $(mainLabel);
	    $mainLabel.attr("id", $select.attr("id") +'_'+opt.index);
	    $mainLabel.attr("href", "javascript:;");
	    $mainLabel.append("<img alt=\"\"  />" +  "<span></span>");
	    $mainLabel.addClass(options.mainLabelClass);

	    $mainLabel.mouseup(function() {
		    if (!inFocus) {
		      $container.toggle();
		    }
		})
		.focus(function(){
		     if ($container.not(':visible')) {
		       inFocus = true;
		       $container.show();
		     }
  		})
  		.blur(function() {
		    if ($container.is(':visible') && hasfocus > 0 ) {
		      //if(opt.debug) alert('container visible and has focus')
		    } else {
		      hideMe();
		    }
 		});
	    return $mainLabel;
  	}

	function updateMainLabel(){
		if(opt.debug) console.log('--updateMainLabel');
		$mainLabelImg = $mainLabel.children("img");		
		$mainLabelImg.attr('src',$select.children("option:selected").attr("id"));
		if(opt.debug) console.log("$select.children  : "+$select.children("option:selected").attr("id"));
		if(opt.debug)  console.log("xxxx"+$mainLabelImg.attr('src',$select.children("option:selected").attr("id")));
		$mainLabelImg.attr('width',options.tintWidth);
		$mainLabelImg.attr('height',options.tintHeight);
		var tintStr = $select.children("option:selected span").html();
	    var tintCode = tintStr.substr(tintStr.length - 3,tintStr.length);
		$mainLabel.children("span").html(" NÂ°" + tintCode+$select.children("option").html());
	}





	// met en place la palette de couleurs <c:set var="timeStamp"><%=String.valueOf(System.currentTimeMillis()) %></c:set>
  function setupPicker(options,select) {
	if(opt.debug) console.log('--setupPicker');
    var container = document.createElement("div");
    $container = $(container);
    $container.attr('id', opt.tintPickerId +'_'+opt.index);
    $container.addClass(options.pickerClass);


	var wrapper = document.createElement("div");
	$wrapper = $(wrapper);
	$wrapper.attr('id', opt.tintPickerId +'_'+opt.index+'_wrapper');

	$select = select;
	var output="";
	var clazz="";
    $select.children('option').each(function() {
	    if ($(this).is(':selected')) {
	      	clazz="activ";
	    } else {
	      	clazz="";
	    }
      output += "<a href=\"javascript:;\" id=\"" + $select.attr("id") + "Item" + this.value  + "\" class=\""+clazz+"\" title=\""+$(this).html()+"\"><img src=\"" + $(this).attr("id") + "\" width=\""+options.tintWidth+"\" height=\""+options.tintHeight+"\" /><span>" + $(this).html() + "</span></a>";
    });

	$wrapper.append(output);
	$container.append($wrapper);
    return $container;
  }

  function showPicker() {
	if(opt.debug) console.log('--showPicker');
  	$container.show();
  }


};/**
 * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
 *
 * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */
if(typeof deconcept == "undefined") var deconcept = new Object();
if(typeof deconcept.util == "undefined") deconcept.util = new Object();
if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object();
deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) {
  if (!document.getElementById) { return; }
  this.DETECT_KEY = detectKey ? detectKey : 'detectflash';
  this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY);
  this.params = new Object();
  this.variables = new Object();
  this.attributes = new Array();
  if(swf) { this.setAttribute('swf', swf); }
  if(id) { this.setAttribute('id', id); }
  if(w) { this.setAttribute('width', w); }
  if(h) { this.setAttribute('height', h); }
  if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); }
  this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion();
  if (!window.opera && document.all && this.installedVer.major > 7) {
    // only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE
    deconcept.SWFObject.doPrepUnload = true;
  }
  if(c) { this.addParam('bgcolor', c); }
  var q = quality ? quality : 'high';
  this.addParam('quality', q);
  this.setAttribute('useExpressInstall', false);
  this.setAttribute('doExpressInstall', false);
  var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location;
  this.setAttribute('xiRedirectUrl', xir);
  this.setAttribute('redirectUrl', '');
  if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); }
}
deconcept.SWFObject.prototype = {
  useExpressInstall: function(path) {
    this.xiSWFPath = !path ? "expressinstall.swf" : path;
    this.setAttribute('useExpressInstall', true);
  },
  setAttribute: function(name, value){
    this.attributes[name] = value;
  },
  getAttribute: function(name){
    return this.attributes[name];
  },
  addParam: function(name, value){
    this.params[name] = value;
  },
  getParams: function(){
    return this.params;
  },
  addVariable: function(name, value){
    this.variables[name] = value;
  },
  getVariable: function(name){
    return this.variables[name];
  },
  getVariables: function(){
    return this.variables;
  },
  getVariablePairs: function(){
    var variablePairs = new Array();
    var key;
    var variables = this.getVariables();
    for(key in variables){
      variablePairs[variablePairs.length] = key +"="+ variables[key];
    }
    return variablePairs;
  },
  getSWFHTML: function() {
    var swfNode = "";
    if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture
      if (this.getAttribute("doExpressInstall")) {
        this.addVariable("MMplayerType", "PlugIn");
        this.setAttribute('swf', this.xiSWFPath);
      }
      swfNode = '<embed type="application/x-shockwave-flash" src="'+ this.getAttribute('swf') +'" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'"';
      swfNode += ' id="'+ this.getAttribute('id') +'" name="'+ this.getAttribute('id') +'" ';
      var params = this.getParams();
       for(var key in params){ swfNode += [key] +'="'+ params[key] +'" '; }
      var pairs = this.getVariablePairs().join("&");
       if (pairs.length > 0){ swfNode += 'flashvars="'+ pairs +'"'; }
      swfNode += '/>';
    } else { // PC IE
      if (this.getAttribute("doExpressInstall")) {
        this.addVariable("MMplayerType", "ActiveX");
        this.setAttribute('swf', this.xiSWFPath);
      }
      swfNode = '<object id="'+ this.getAttribute('id') +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'">';
      swfNode += '<param name="movie" value="'+ this.getAttribute('swf') +'" />';
      var params = this.getParams();
      for(var key in params) {
       swfNode += '<param name="'+ key +'" value="'+ params[key] +'" />';
      }
      var pairs = this.getVariablePairs().join("&");
      if(pairs.length > 0) {swfNode += '<param name="flashvars" value="'+ pairs +'" />';}
      swfNode += "</object>";
    }
    return swfNode;
  },
  write: function(elementId){
    if(this.getAttribute('useExpressInstall')) {
      // check to see if we need to do an express install
      var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]);
      if (this.installedVer.versionIsValid(expressInstallReqVer) && !this.installedVer.versionIsValid(this.getAttribute('version'))) {
        this.setAttribute('doExpressInstall', true);
        this.addVariable("MMredirectURL", escape(this.getAttribute('xiRedirectUrl')));
        document.title = document.title.slice(0, 47) + " - Flash Player Installation";
        this.addVariable("MMdoctitle", document.title);
      }
    }
    if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){
      var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId;
      /*** MODIF GSR ---------------------------- ***/
      /*** TEST ADDED WHEN BOJECT ID IS NOT FOUND ***/
	    	/*** #2390: Ensure the flash is not loaded twice! ***/ 
	      if (n != null && n.getElementsByTagName('embed').length == 0 && n.getElementsByTagName('Object').length == 0) {	    	
	        n.innerHTML = this.getSWFHTML();	        
        return true;
      }
      /*** -------------------------------------- ***/
    }else{
      if(this.getAttribute('redirectUrl') != "") {
        document.location.replace(this.getAttribute('redirectUrl'));
      }
    }
    return false;
  }
}

/* ---- detection functions ---- */
deconcept.SWFObjectUtil.getPlayerVersion = function(){
  var PlayerVersion = new deconcept.PlayerVersion([0,0,0]);
  if(navigator.plugins && navigator.mimeTypes.length){
    var x = navigator.plugins["Shockwave Flash"];
    if(x && x.description) {
      PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
    }
  }else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE
    var axo = 1;
    var counter = 3;
    while(axo) {
      try {
        counter++;
        axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter);
//				document.write("player v: "+ counter);
        PlayerVersion = new deconcept.PlayerVersion([counter,0,0]);
      } catch (e) {
        axo = null;
      }
    }
  } else { // Win IE (non mobile)
    // do minor version lookup in IE, but avoid fp6 crashing issues
    // see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
    try{
      var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
    }catch(e){
      try {
        var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
        PlayerVersion = new deconcept.PlayerVersion([6,0,21]);
        axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code)
      } catch(e) {
        if (PlayerVersion.major == 6) {
          return PlayerVersion;
        }
      }
      try {
        axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
      } catch(e) {}
    }
    if (axo != null) {
      PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
    }
  }
  return PlayerVersion;
}
deconcept.PlayerVersion = function(arrVersion){
  this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0;
  this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0;
  this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0;
}
deconcept.PlayerVersion.prototype.versionIsValid = function(fv){
  if(this.major < fv.major) return false;
  if(this.major > fv.major) return true;
  if(this.minor < fv.minor) return false;
  if(this.minor > fv.minor) return true;
  if(this.rev < fv.rev) return false;
  return true;
}
/* ---- get value of query string param ---- */
deconcept.util = {
  getRequestParameter: function(param) {
    var q = document.location.search || document.location.hash;
    if (param == null) { return q; }
    if(q) {
      var pairs = q.substring(1).split("&");
      for (var i=0; i < pairs.length; i++) {
        if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
          return pairs[i].substring((pairs[i].indexOf("=")+1));
        }
      }
    }
    return "";
  }
}
/* fix for video streaming bug */
deconcept.SWFObjectUtil.cleanupSWFs = function() {
  var objects = document.getElementsByTagName("OBJECT");
  for (var i = objects.length - 1; i >= 0; i--) {
    objects[i].style.display = 'none';
    for (var x in objects[i]) {
      if (typeof objects[i][x] == 'function') {
        objects[i][x] = function(){};
      }
    }
  }
}
// fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/
if (deconcept.SWFObject.doPrepUnload) {
  if (!deconcept.unloadSet) {
    deconcept.SWFObjectUtil.prepUnload = function() {
      __flash_unloadHandler = function(){};
      __flash_savedUnloadHandler = function(){};
      window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs);
    }
    window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload);
    deconcept.unloadSet = true;
  }
}
/* add document.getElementById if needed (mobile IE < 5) */
if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }}

/* add some aliases for ease of use/backwards compatibility */
var getQueryParamValue = deconcept.util.getRequestParameter;
var FlashObject = deconcept.SWFObject; // for legacy support
var SWFObject = deconcept.SWFObject;
/* Pour les stats */

function sp_tracker(sp,ci)
{var smartParam = "";for(var i=0;i<sp.length;i++) smartParam += sp[i];document.cookie = 'sp=1; expires=Sunday, 02-Feb-2020 20:20:20 GMT';
if (ci!="") smartParam += "&_ci=" +ci;
if (window.screen) { res = screen.width + "x" + screen.height; col = screen.colorDepth;} else {res ="n/a"; col="n/a";}
ctz=(new Date()).getTimezoneOffset();smartParam += "&_cr=" + Math.round (Math.random()*1000000000000000);
var flashversion = deconcept.SWFObjectUtil.getPlayerVersion();
if (flashversion["major"] > 0) _fv=flashversion['major'] +"."+ flashversion['minor'] +"."+ flashversion['rev']; else _fv="-1";
smartParam += "&_fv=" + escape(_fv);
smartParam += "&_dom=" + escape(window.location.protocol+"//"+window.location.hostname);
smartParam += "&_ref=" + escape(document.referrer.substring(0,254));
smartParam += "&_res=" + escape(res) + "&_col=" + escape(col);
smartParam += "&_tz=" + Math.round(((ctz==(new Date(20010101)).getTimezoneOffset())?ctz:(ctz+60))/-60);
smartParam += "&_ck=" + (document.cookie.indexOf('sp=1') >= 0);
smartImageF=new Image();smartImageF.src=location.protocol+"//ws2.smartp.com/sp_tracker.cfm"+smartParam;}
var sp_t=1;/* Pour les clics */
function sp_send(sp)
{var clicParam = "";for(var i=0;i<sp.length;i++) clicParam += sp[i];document.cookie = 'spc=1; expires=Sunday, 02-Feb-2020 20:20:20 GMT';
clicParam += "&_cr=" + Math.round (Math.random()*1000000000000000);clicParam += "&_ck=" + (document.cookie.indexOf('spc=1') >= 0);
clicImage=new Image();clicImage.src=location.protocol+"//ws2.smartp.com/sp_tracker.cfm"+clicParam;
}