/**
 * ==> jquery listen
 */
/**
 * jQuery.Listen
 * Copyright (c) 2007-2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Dual licensed under MIT and GPL.
 * Date: 3/7/2008
 *
 * ==>  Form Plugin */
/*
 * jQuery Form Plugin
 * version: 2.12 (06/07/2008)
 * @requires jQuery v1.2.2 or later
 *
 * Examples and documentation 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: base.js 9953 2009-11-04 15:32:20Z andy $
 */
(function($) {

/*
    Usage Note:  
    -----------
    Do not use both ajaxSubmit and ajaxForm on the same form.  These
    functions are intended to be exclusive.  Use ajaxSubmit if you want
    to bind your own submit handler to the form.  For example,

    $(document).ready(function() {
        $('#myForm').bind('submit', function() {
            $(this).ajaxSubmit({
                target: '#output'
            });
            return false; // <-- important!
        });
    });

    Use ajaxForm when you want the plugin to manage all the event binding
    for you.  For example,

    $(document).ready(function() {
        $('#myForm').ajaxForm({
            target: '#output'
        });
    });
        
    When using ajaxForm, the ajaxSubmit function will be invoked for you
    at the appropriate time.  
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting 
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
    if (!this.length) {
        log('ajaxSubmit: skipping submit process - no element selected');
        return this;
    }

    if (typeof options == 'function')
        options = { success: options };

    options = $.extend({
        url:  this.attr('action') || window.location.toString(),
        type: this.attr('method') || 'GET'
    }, options || {});

    // hook for manipulating the form data before it is extracted;
    // convenient for use with rich editors like tinyMCE or FCKEditor
    var veto = {};
    this.trigger('form-pre-serialize', [this, options, veto]);
    if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
        return this;
   }

    var a = this.formToArray(options.semantic);
    if (options.data) {
        options.extraData = options.data;
        for (var n in options.data)
            a.push( { name: n, value: options.data[n] } );
    }

    // give pre-submit callback an opportunity to abort the submit
    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
        log('ajaxSubmit: submit aborted via beforeSubmit callback');
        return this;
    }    

    // fire vetoable 'validate' event
    this.trigger('form-submit-validate', [a, this, options, veto]);
    if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
        return this;
    }    

    var q = $.param(a);

    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) {
            $(options.target).html(data).each(oldSuccess, arguments);
        });
    }
    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, $form);
    };

    // 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;

    // options.iframe allows user to force iframe mode
   if (options.iframe || found) { 
       // hack to fix Safari hang (thanks to Tim Molendijk for this)
       // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
       if ($.browser.safari && options.closeKeepAlive)
           $.get(options.closeKeepAlive, fileUpload);
       else
           fileUpload();
       }
   else
       $.ajax(options);

    // fire 'notify' event
    this.trigger('form-submit-notify', [this, options]);
    return this;


    // private function for handling file uploads (hat tip to YAHOO!)
    function fileUpload() {
        var form = $form[0];
        
        if ($(':input[name=submit]', form).length) {
            alert('Error: Form elements must not be named "submit".');
            return;
        }
        
        var opts = $.extend({}, $.ajaxSettings, options);

        var id = 'jqFormIO' + (new Date().getTime());
        var $io = $('<iframe id="' + id + '" name="' + id + '" />');
        var io = $io[0];

        if ($.browser.msie || $.browser.opera) 
            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;

        // add submitting element to data if we know it
        var sub = form.clk;
        if (sub) {
            var n = sub.name;
            if (n && !sub.disabled) {
                options.extraData = options.extraData || {};
                options.extraData[n] = sub.value;
                if (sub.type == "image") {
                    options.extraData[name+'.x'] = form.clk_x;
                    options.extraData[name+'.y'] = form.clk_y;
                }
            }
        }
        
        // take a breath so that pending repaints get some cpu time before the upload starts
        setTimeout(function() {
            // make sure form attrs are set
            var t = $form.attr('target'), a = $form.attr('action');
            $form.attr({
                target:   id,
                encoding: 'multipart/form-data',
                enctype:  'multipart/form-data',
                method:   'POST',
                action:   opts.url
            });

            // support timout
            if (opts.timeout)
                setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

            // add "extra" data to form if provided in options
            var extraInputs = [];
            try {
                if (options.extraData)
                    for (var n in options.extraData)
                        extraInputs.push(
                            $('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
                                .appendTo(form)[0]);
            
                // add iframe to doc and submit the form
                $io.appendTo('body');
                io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
                form.submit();
            }
            finally {
                // reset attrs and remove "extra" input elements
                $form.attr('action', a);
                t ? $form.attr('target', t) : $form.removeAttr('target');
                $(extraInputs).remove();
            }
        }, 10);

        function cb() {
            if (cbInvoked++) return;
            
            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);

            var operaHack = 0;
            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;
                
                if (doc.body == null && !operaHack && $.browser.opera) {
                    // In Opera 9.2.x the iframe DOM is not always traversable when
                    // the onload callback fires so we give Opera 100ms to right itself
                    operaHack = 1;
                    cbInvoked--;
                    setTimeout(cb, 100);
                    return;
                }
                
                xhr.responseText = doc.body ? doc.body.innerHTML : null;
                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
                xhr.getResponseHeader = function(header){
                    var headers = {'content-type': opts.dataType};
                    return headers[header];
                };

                if (opts.dataType == 'json' || opts.dataType == 'script') {
                    var ta = doc.getElementsByTagName('textarea')[0];
                    xhr.responseText = ta ? ta.value : xhr.responseText;
                }
                else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
                    xhr.responseXML = toXml(xhr.responseText);
                }
                data = $.httpData(xhr, opts.dataType);
            }
            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;
        };
    };
};

/**
 * 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.
 *
 * 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.
 */ 
$.fn.ajaxForm = function(options) {
    return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
        $(this).ajaxSubmit(options);
        return false;
    }).each(function() {
        // store options in hash
        $(":submit,input:image", this).bind('click.form-plugin',function(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);
        });
    });
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
    this.unbind('submit.form-plugin');
    return this.each(function() {
        $(":submit,input:image", this).unbind('click.form-plugin');
    });

};

/**
 * 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.
 */
$.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
 */
$.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
 */
$.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.
 */
$.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.
 */
$.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
 */
$.fn.clearForm = function() {
    return this.each(function() {
        $('input,select,textarea', this).clearFields();
    });
};

/**
 * Clears the selected form elements.
 */
$.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.
 */
$.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();
    });
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) { 
    if (b == undefined) b = true;
    return this.each(function() { 
        this.disabled = !b 
    });
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.select = function(select) {
    if (select == undefined) select = true;
    return this.each(function() { 
        var t = this.type;
        if (t == 'checkbox' || t == 'radio')
            this.checked = select;
        else if (this.tagName.toLowerCase() == 'option') {
            var $sel = $(this).parent('select');
            if (select && $sel[0] && $sel[0].type == 'select-one') {
                // deselect all other options
                $sel.find('option').select(false);
            }
            this.selected = select;
        }
    });
};

// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
    if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
        window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
};

})(jQuery);



/* ==>  Thickbox */
/*
 * Thickbox 3.1 - 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
*/

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

//add thickbox to href & area elements that have a class of .thickbox
function tb_init(domChunk){
  //console.log("init thickbox");
  $(domChunk).css('visibility', 'visible');
  $(domChunk).unbind('click').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
        $("body").append("<iframe id='TB_HideSelect'></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'></div>");
        $("#TB_overlay").click(tb_remove);
      }
    }
    
    if(tb_detectMacXFF()){
      $("#TB_overlay").addClass("TB_overlayMacFFBGHack");//use png overlay so hide flash
    }else{
      $("#TB_overlay").addClass("TB_overlayBG");//use background and opacity
    }
    
    if(caption===null){caption="";}
    $("body").append("<div id='TB_load'><img src='/images/loadingAnimation/arrows_white.gif' /></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$/;
     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='Schlie&szlig;en'>Schlie&szlig;en</a></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      
  
      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
      
      //modifications
      if(TB_HEIGHT > $(window).height()){
        TB_HEIGHT = $(window).height()-50;
      }
      
      if(TB_WIDTH > $(window).width()){       
        TB_WIDTH = $(window).width()-30;
        console.log(TB_WIDTH);
      }
      
      ajaxContentW = TB_WIDTH - 30;
      ajaxContentH = TB_HEIGHT - 45;
      
      if (url.indexOf('TB_iframe') != -1) {// either iframe or ajax window    
        urlNoQuery = url.split('TB_');
        $("#TB_iframeContent").remove();
        if (params['modal'] != "true") {//iframe no modal
          $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>" + caption + "</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Schlie&szlig;en'>Schlie&szlig;en</a></div></div><iframe frameborder='0' hspace='0' src='" + urlNoQuery[0] + "' id='TB_iframeContent' name='TB_iframeContent" + Math.round(Math.random() * 1000) + "' onload='tb_showIframe()' style='width:" + (ajaxContentW + 29) + "px;height:" + (ajaxContentH + 17) + "px;' > </iframe>");
        }
        else {//iframe modal
          //patch
          $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>" + caption + "</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Schlie&szlig;en'>Schlie&szlig;en</a></div></div><iframe frameborder='0' hspace='0' src='" + urlNoQuery[0] + "' id='TB_iframeContent' name='TB_iframeContent" + Math.round(Math.random() * 1000) + "' onload='tb_showIframe()' style='width:" + (ajaxContentW + 29) + "px;height:" + (ajaxContentH + 17) + "px;' > </iframe>");
          $("#TB_overlay").unbind();
          $("#TB_window").append("<iframe frameborder='0' hspace='0' src='" + urlNoQuery[0] + "' id='TB_iframeContent' name='TB_iframeContent" + Math.round(Math.random() * 1000) + "' onload='tb_showIframe()' style='width:" + (ajaxContentW + 29) + "px;height:" + (ajaxContentH + 17) + "px;'> </iframe>");
        }
      }
      
      else {// not an iframe, ajax
        if ($("#TB_window").css("display") != "block") {
          if (params['modal'] != "true") {//ajax no modal
            $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>" + caption + "</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'>Schlie&szlig;en</a></div></div><div id='TB_ajaxContent' style='width:" + ajaxContentW + "px;height:" + ajaxContentH + "px'></div>");
          }
          else {//ajax modal
            $("#TB_overlay").unbind();
            //$("#TB_window").append("<div id='TB_ajaxContent' class='TB_modal' style='width:" + ajaxContentW + "px;height:" + ajaxContentH + "px;'></div>");
            //patch
            $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>" + caption + "</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'>Schlie&szlig;en</a></div></div><div id='TB_ajaxContent' style='width:" + ajaxContentW + "px;height:" + ajaxContentH + "px'></div>");
          }
        }
        
        else {//this means the window is already up, we are just loading new content via ajax
          console.log("already up!");
          $("#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").append($('#' + params['inlineId']).children());
          $("#TB_window").unload(function () {
            $('#' + params['inlineId']).append( $("#TB_ajaxContent").children() ); // move elements back when you're finished
          });
          tb_position();
          $("#TB_load").remove();
          $("#TB_window").css({display:"block"}); 
        }else if(url.indexOf('TB_iframe') != -1){
          tb_position();
          if($.browser.safari){//safari needs help because it will not fire iframe onload
            $("#TB_load").remove();
            $("#TB_window").css({display:"block"});
          }
        }else{
          //patch, this shoud only be used if browser is IE
          if($.browser.msie && $.browser.version < 7.0){
            url = sixGroups.attachUrlParam(url, {name: 'random', value: (new Date().getTime())});
          }         
         $.ajax(
            {url: url,
            dataType: 'html',
            //beforeSubmit: function(){},
            success: function(data){
              //console.log(data);
              $('#TB_ajaxContent').append(data);
              tb_position();
              $("#TB_load").remove();
              tb_init("#TB_ajaxContent a.thickbox");
              $("#TB_window").css({display:"block"});
              setTimeout("sixGroups.Tracking.track();", 100);
            },
            error : function(xhr, str, obj){
              console.error(str);
              tb_remove();
            }
            
            }
          );
          
          
        }
      
    }
    
    if(params && params.modal){
    }

    else{
      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
    console.error(e);
  }
}

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

function tb_remove() {
  $("#TB_imageOff").unbind("click");
  $("#TB_closeWindowButton").unbind("click");
  $("#TB_window").fadeOut("fast",function(){$('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().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 = "";
  document.onkeyup = "";
  return false;
}

function tb_position() {
$("#TB_window").css({marginLeft: '-' + parseInt((TB_WIDTH / 2),10) + 'px', width: TB_WIDTH + 'px'});
  if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // 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;
}

function tb_detectMacXFF() {
  var userAgent = navigator.userAgent.toLowerCase();
  if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) {
    return true;
  }
}





/* ==>  Dimensions */
/* 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: 2009-11-04 16:32:20 +0100 (Mi, 04 Nov 2009) $
 * $Rev: 9953 $
 *
 * Version: 1.2
 *
 * Requires: jQuery 1.2+
 */

(function($){
  
$.dimensions = {
  version: '1.2'
};

// Create innerHeight, innerWidth, outerHeight and outerWidth methods
$.each( [ 'Height', 'Width' ], function(i, name){
  
  // innerHeight and innerWidth
  $.fn[ 'inner' + name ] = function() {
    if (!this[0]) return;
    
    var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
        borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
    
    return this.is(':visible') ? this[0]['client' + name] : num( this, name.toLowerCase() ) + num(this, 'padding' + torl) + num(this, 'padding' + borr);
  };
  
  // outerHeight and outerWidth
  $.fn[ 'outer' + name ] = function(options) {
    if (!this[0]) return;
    
    var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
        borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
    
    options = $.extend({ margin: false }, options || {});
    
    var val = this.is(':visible') ? 
        this[0]['offset' + name] : 
        num( this, name.toLowerCase() )
          + num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
          + num(this, 'padding' + torl) + num(this, 'padding' + borr);
    
    return val + (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
  };
});

// Create scrollLeft and scrollTop methods
$.each( ['Left', 'Top'], function(i, name) {
  $.fn[ 'scroll' + name ] = function(val) {
    if (!this[0]) return;
    
    return val != undefined ?
    
      // Set the scroll offset
      this.each(function() {
        this == window || this == document ?
          window.scrollTo( 
            name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
            name == 'Top'  ? val : $(window)[ 'scrollTop'  ]()
          ) :
          this[ 'scroll' + name ] = val;
      }) :
      
      // Return the scroll offset
      this[0] == window || this[0] == document ?
        self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
          $.boxModel && document.documentElement[ 'scroll' + name ] ||
          document.body[ 'scroll' + name ] :
        this[0][ 'scroll' + name ];
  };
});

$.fn.extend({
  position: function() {
    var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;
    
    if (elem) {
      // Get *real* offsetParent
      offsetParent = this.offsetParent();
      
      // Get correct offsets
      offset       = this.offset();
      parentOffset = offsetParent.offset();
      
      // Subtract element margins
      offset.top  -= num(elem, 'marginTop');
      offset.left -= num(elem, 'marginLeft');
      
      // Add offsetParent borders
      parentOffset.top  += num(offsetParent, 'borderTopWidth');
      parentOffset.left += num(offsetParent, 'borderLeftWidth');
      
      // Subtract the two offsets
      results = {
        top:  offset.top  - parentOffset.top,
        left: offset.left - parentOffset.left
      };
    }
    
    return results;
  },
  
  offsetParent: function() {
    var offsetParent = this[0].offsetParent;
    while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
      offsetParent = offsetParent.offsetParent;
    return $(offsetParent);
  }
});

function num(el, prop) {
  return parseInt($.curCSS(el.jquery?el[0]:el,prop,true))||0;
};

})(jQuery);


/* ==  Cookie */
/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

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

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


/* ==> Color animations */
/*
 * jQuery Color Animations
 * Copyright 2007 John Resig
 * Released under the MIT and GPL licenses.
 */

(function(jQuery){

  // We override the animation for all of these color styles
  jQuery.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
    jQuery.fx.step[attr] = function(fx){
      if ( fx.state == 0 ) {
        fx.start = getColor( fx.elem, attr );
        fx.end = getRGB( fx.end );
      }

      fx.elem.style[attr] = "rgb(" + [
        Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
        Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
        Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
      ].join(",") + ")";
    }
  });

  // Color Conversion functions from highlightFade
  // By Blair Mitchelmore
  // http://jquery.offput.ca/highlightFade/

  // Parse strings looking for color tuples [255,255,255]
  function getRGB(color) {
    var result;

    // Check if we're already dealing with an array of colors
    if ( color && color.constructor == Array && color.length == 3 )
      return color;

    // Look for rgb(num,num,num)
    if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
      return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];

    // Look for rgb(num%,num%,num%)
    if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
      return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];

    // Look for #a0b1c2
    if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
      return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];

    // Look for #fff
    if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
      return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];

    // Otherwise, we're most likely dealing with a named color
    return colors[jQuery.trim(color).toLowerCase()];
  }
  
  function getColor(elem, attr) {
    var color;

    do {
      color = jQuery.curCSS(elem, attr);

      // Keep going until we find an element that has color, or we hit the body
      if ( color != '' && color != 'transparent' || jQuery.nodeName(elem, "body") )
        break; 

      attr = "backgroundColor";
    } while ( elem = elem.parentNode );

    return getRGB(color);
  };
  
  // Some named colors to work with
  // From Interface by Stefan Petre
  // http://interface.eyecon.ro/

  var colors = {
    aqua:[0,255,255],
    azure:[240,255,255],
    beige:[245,245,220],
    black:[0,0,0],
    blue:[0,0,255],
    brown:[165,42,42],
    cyan:[0,255,255],
    darkblue:[0,0,139],
    darkcyan:[0,139,139],
    darkgrey:[169,169,169],
    darkgreen:[0,100,0],
    darkkhaki:[189,183,107],
    darkmagenta:[139,0,139],
    darkolivegreen:[85,107,47],
    darkorange:[255,140,0],
    darkorchid:[153,50,204],
    darkred:[139,0,0],
    darksalmon:[233,150,122],
    darkviolet:[148,0,211],
    fuchsia:[255,0,255],
    gold:[255,215,0],
    green:[0,128,0],
    indigo:[75,0,130],
    khaki:[240,230,140],
    lightblue:[173,216,230],
    lightcyan:[224,255,255],
    lightgreen:[144,238,144],
    lightgrey:[211,211,211],
    lightpink:[255,182,193],
    lightyellow:[255,255,224],
    lime:[0,255,0],
    magenta:[255,0,255],
    maroon:[128,0,0],
    navy:[0,0,128],
    olive:[128,128,0],
    orange:[255,165,0],
    pink:[255,192,203],
    purple:[128,0,128],
    violet:[128,0,128],
    red:[255,0,0],
    silver:[192,192,192],
    white:[255,255,255],
    yellow:[255,255,0]
  };
  
})(jQuery);






/* ==> easing */
/*OT
 * jQuery Easing v1.1.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.extend({
  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
    }
  }
});


/**
 * 
 * 
 * blockUI
 * 
 * 
 */
/*
 * jQuery blockUI plugin
 * Version 2.11 (12/13/2008)
 * @requires jQuery v1.2.3 or later
 *
 * Examples at: http://malsup.com/jquery/block/
 * Copyright (c) 2007-2008 M. Alsup
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Thanks to Amir-Hossein Sobhi for some excellent contributions!
 */

;(function($) {

if (/1\.(0|1|2)\.(0|1|2)/.test($.fn.jquery) || /^1.1/.test($.fn.jquery)) {
    alert('blockUI requires jQuery v1.2.3 or later!  You are using v' + $.fn.jquery);
    return;
}

// global $ methods for blocking/unblocking the entire page
$.blockUI   = function(opts) { install(window, opts); };
$.unblockUI = function(opts) { remove(window, opts); };

// plugin method for blocking element content
$.fn.block = function(opts) {
    return this.each(function() {
        if ($.css(this,'position') == 'static')
            this.style.position = 'relative';
        if ($.browser.msie) 
            this.style.zoom = 1; // force 'hasLayout'
        install(this, opts);
    });
};

// plugin method for unblocking element content
$.fn.unblock = function(opts) {
    return this.each(function() {
        remove(this, opts);
    });
};

$.blockUI.version = 2.11; // 2nd generation blocking at no extra cost!

// override these in your code to change the default behavior and style
$.blockUI.defaults = {
    // message displayed when blocking (use null for no message)
    message:  '<h1>Please wait...</h1>',
    
    // styles for the message when blocking; if you wish to disable
    // these and use an external stylesheet then do this in your code:
    // $.blockUI.defaults.css = {};
    css: { 
        padding:        0,
        margin:         0,
        width:          '30%', 
        top:            '40%', 
        left:           '35%', 
        textAlign:      'center', 
        color:          '#000', 
        border:         '3px solid #aaa',
        backgroundColor:'#fff',
        cursor:         'wait'
    },
    
    // styles for the overlay
    overlayCSS:  { 
        backgroundColor:'#000', 
        opacity:        '0.6' 
    },
    
    // z-index for the blocking overlay
    baseZ: 1000,
    
    // set these to true to have the message automatically centered
    centerX: true, // <-- only effects element blocking (page block controlled via css above)
    centerY: true,
    
    // allow body element to be stetched in ie6; this makes blocking look better
    // on "short" pages.  disable if you wish to prevent changes to the body height
    allowBodyStretch: true,
    
    // be default blockUI will supress tab navigation from leaving blocking content;
    constrainTabKey: true,
    
    // fadeOut time in millis; set to 0 to disable fadeout on unblock
    fadeOut:  400,
    
    // if true, focus will be placed in the first available input field when
    // page blocking
    focusInput: true,
    
    // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
    applyPlatformOpacityRules: true,
    
    // callback method invoked when unblocking has completed; the callback is
    // passed the element that has been unblocked (which is the window object for page
    // blocks) and the options that were passed to the unblock call:
    //     onUnblock(element, options)
    onUnblock: null,
    
    // don't ask (if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493)
    quirksmodeOffsetHack: 4
};

// private data and functions follow...

var ie6 = $.browser.msie && /MSIE 6.0/.test(navigator.userAgent);
var pageBlock = null;
var pageBlockEls = [];

function install(el, opts) {
    var full = (el == window);
    var msg = opts && opts.message !== undefined ? opts.message : undefined;
    opts = $.extend({}, $.blockUI.defaults, opts || {});
    opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
    var css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
    msg = msg === undefined ? opts.message : msg;

    // remove the current block (if there is one)
    if (full && pageBlock) 
        remove(window, {fadeOut:0}); 
    
    // if an existing element is being used as the blocking content then we capture
    // its current place in the DOM (and current display style) so we can restore
    // it when we unblock
    if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
        var node = msg.jquery ? msg[0] : msg;
        var data = {};
        $(el).data('blockUI.history', data);
        data.el = node;
        data.parent = node.parentNode;
        data.display = node.style.display;
        data.position = node.style.position;
        data.parent.removeChild(node);
    }
    
    var z = opts.baseZ;
    
    // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
    // layer1 is the iframe layer which is used to supress bleed through of underlying content
    // layer2 is the overlay layer which has opacity and a wait cursor
    // layer3 is the message content that is displayed while blocking
    
    var lyr1 = ($.browser.msie) ? $('<iframe class="blockUI" style="z-index:'+ z++ +';border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="javascript:false;"></iframe>')
                                : $('<div class="blockUI" style="display:none"></div>');
    var lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ z++ +';cursor:wait;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
    var lyr3 = full ? $('<div class="blockUI blockMsg blockPage" style="z-index:'+z+';position:fixed"></div>')
                    : $('<div class="blockUI blockMsg blockElement" style="z-index:'+z+';display:none;position:absolute"></div>');

    // if we have a message, style it
    if (msg) 
        lyr3.css(css);

    // style the overlay
    if (!opts.applyPlatformOpacityRules || !($.browser.mozilla && /Linux/.test(navigator.platform))) 
        lyr2.css(opts.overlayCSS);
    lyr2.css('position', full ? 'fixed' : 'absolute');
    
    // make iframe layer transparent in IE
    if ($.browser.msie) 
        lyr1.css('opacity','0.0');

    $([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
    
    // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
    var expr = $.browser.msie && (!$.boxModel || $('object,embed', full ? null : el).length > 0);
    if (ie6 || expr) {
        // give body 100% height
        if (full && opts.allowBodyStretch && $.boxModel)
            $('html,body').css('height','100%');

        // fix ie6 issue when blocked element has a border width
        if ((ie6 || !$.boxModel) && !full) {
            var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
            var fixT = t ? '(0 - '+t+')' : 0;
            var fixL = l ? '(0 - '+l+')' : 0;
        }

        // simulate fixed position
        $.each([lyr1,lyr2,lyr3], function(i,o) {
            var s = o[0].style;
            s.position = 'absolute';
            if (i < 2) {
                full ? s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"')
                     : s.setExpression('height','this.parentNode.offsetHeight + "px"');
                full ? s.setExpression('width','jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"')
                     : s.setExpression('width','this.parentNode.offsetWidth + "px"');
                if (fixL) s.setExpression('left', fixL);
                if (fixT) s.setExpression('top', fixT);
            }
            else if (opts.centerY) {
                if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
                s.marginTop = 0;
            }
        });
    }
    
    // show the message
    lyr3.append(msg).show();
    if (msg && (msg.jquery || msg.nodeType))
        $(msg).show();

    // bind key and mouse events
    bind(1, el, opts);
        
    if (full) {
        pageBlock = lyr3[0];
        pageBlockEls = $(':input:enabled:visible',pageBlock);
        if (opts.focusInput)
            setTimeout(focus, 20);
    }
    else
        center(lyr3[0], opts.centerX, opts.centerY);
};

// remove the block
function remove(el, opts) {
    var full = el == window;
    var data = $(el).data('blockUI.history');
    opts = $.extend({}, $.blockUI.defaults, opts || {});
    bind(0, el, opts); // unbind events
    var els = full ? $('body').children().filter('.blockUI') : $('.blockUI', el);
    
    if (full) 
        pageBlock = pageBlockEls = null;

    if (opts.fadeOut) {
        els.fadeOut(opts.fadeOut);
        setTimeout(function() { reset(els,data,opts,el); }, opts.fadeOut);
    }
    else
        reset(els, data, opts, el);
};

// move blocking element back into the DOM where it started
function reset(els,data,opts,el) {
    els.each(function(i,o) {
        // remove via DOM calls so we don't lose event handlers
        if (this.parentNode) 
            this.parentNode.removeChild(this);
    });

    if (data && data.el) {
        data.el.style.display = data.display;
        data.el.style.position = data.position;
        data.parent.appendChild(data.el);
        $(data.el).removeData('blockUI.history');
    }

    if (typeof opts.onUnblock == 'function')
        opts.onUnblock(el,opts);
};

// bind/unbind the handler
function bind(b, el, opts) {
    var full = el == window, $el = $(el);
    
    // don't bother unbinding if there is nothing to unbind
    if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) 
        return;
    if (!full) 
        $el.data('blockUI.isBlocked', b);
        
    // bind anchors and inputs for mouse and key events
    var events = 'mousedown mouseup keydown keypress';
    b ? $(document).bind(events, opts, handler) : $(document).unbind(events, handler);

// former impl...
//    var $e = $('a,:input');
//    b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
};

// event handler to suppress keyboard/mouse events when blocking
function handler(e) {
    // allow tab navigation (conditionally)
    if (e.keyCode && e.keyCode == 9) {
        if (pageBlock && e.data.constrainTabKey) {
            var els = pageBlockEls;
            var fwd = !e.shiftKey && e.target == els[els.length-1];
            var back = e.shiftKey && e.target == els[0];
            if (fwd || back) {
                setTimeout(function(){focus(back)},10);
                return false;
            }
        }
    }
    // allow events within the message content
    if ($(e.target).parents('div.blockMsg').length > 0)
        return true;
        
    // allow events for content that is not being blocked
    return $(e.target).parents().children().filter('div.blockUI').length == 0;
};

function focus(back) {
    if (!pageBlockEls) 
        return;
    var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
    if (e) 
        e.focus();
};

function center(el, x, y) {
    var p = el.parentNode, s = el.style;
    var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
    var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
    if (x) s.left = l > 0 ? (l+'px') : '0';
    if (y) s.top  = t > 0 ? (t+'px') : '0';
};

function sz(el, p) { 
    return parseInt($.css(el,p))||0; 
};

})(jQuery);


/**
 * inArray func
 * @param {Object} value
 */
Array.prototype.inArray = function (value) {
  //js 1.6
  if(typeof this.indexOf != 'undefined'){
    return this.indexOf(value) > -1 ? true : false;
  }
  //ie
  else{
    var i;
    for (i=0; i < this.length; i++) {
      if (this[i] === value) {
        return true;
      }
    }
    return false;    
  }
};

/**
 * ==> jQuery smart modal plugin (http://www.oneblackbear.com/smartmodal/index.html)
 * @param {Object} params
 */
jQuery.fn.extend({
  modal: function(params){
    var jQ = jQuery;
    var params=params;
    var urlParams;
    var settings = {
      
    }
    return this.each(function(){
      jQ(this).click(function(){
        var trig = jQ(this);
        
        /*if(this.href){
          urlParams = parseQueryString(this.href);         
        }
        if(this.title){
          
        }*/
        
        ie6=jQ.browser.msie&&(jQ.browser.version == "6.0")
        if(!jQ('#modal_overlay').length){ //only add the div if its not there already
          jQ("body").append('<div id="modal_overlay"></div>');
        }
        jQ("#modal_overlay").css({height:'100%',width:'100%',position:'fixed',left:0,top:0,'z-index':1000,opacity:50/100});
        
        if(!jQ('#modal_content').length){ //only add the div if its not there already
          jQ("body").append('<div id="modal_content"></div>');
        }
        
        c = "<div class='modal_close' id='modal_closeButton'><p>x</p></div>";
        c += '<div class="modal_inner">';
        if(trig.attr("rel")){ //if rel exists use the rel as id for target container
          div_id = jQ('#'+trig.attr('rel'));
          div_class = jQ('.'+trig.attr('rel'));  
          //remove the content and attach it to this layer
          
          if(div_id.length){
            //c = c + div_id.html();
            //c = $(div_id).clone(true);
            //jQ(div_id).empty();
          }
          else if(div_class.length){
            //c = c + div_class.html();
            //jQ(div_class).empty();
          }
        }
        
        else if(trig.attr('href')){ //if it has a href but no rel then insert the href as image src
          if(trig.attr('title')){ //if it has a title tag, use it
            title = trig.attr('title');
            c = c +"<h3 class='modal_title'>"+title+"</h3><img src='"+trig.attr('href')+"' alt='"+title+"' />"; //make the content
          }else{
            c = c+"<img src='"+trig.attr('href')+"' alt='modal' />"; //no title tag
          }
        }
        
        else{ //if no rel or no href then use the content inside the trigger
          c = c + trig.html();
        }
        
        c += '</div>';
        //set content
        jQ("#modal_content").html(c);
        
        //now clone the node
        if (div_id.length) {
          jQ(div_id).appendTo('#modal_content .modal_inner').show();
        }
        
        //if style info has been passed in then apply that as well as defaults
        if(params && params['modal_styles']){
          styling = params['modal_styles'];
          jQ("#modal_content").css(styling);
        }
        jQ("#modal_content").css({display:"block", zIndex:1001});
        
        //position in center
        var height =  jQ("#modal_content").height();
        var width = jQ("#modal_content").width();
        jQ("#modal_content").css({marginLeft: '-' + parseInt((width / 2),10) + 'px', width: width + 'px'});
        /*if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // take away IE6
          $("#TB_window").css({marginTop: '-' + parseInt((TB_HEIGHT / 2),10) + 'px'});
        } */
        
        
        
        //on load stuff     
        jQ("#modal_content").load(function(){
          o = jQ("#modal_overlay");
          w = jQ("#modal_content");
          w.css({width:$(this).css("width"), height:$(this).css("height") });
          if(ie6) {
            $('html,body').css({height:'100%',width:'100%'});
            i=$('<iframe src="javascript:false;document.write(\'\');" class="overlay"></iframe>').css({opacity:0});
            o.html('<p style="width:100%;height:100%"/>').prepend(i)
            o = o.css({position:'absolute'})[0];
            for(var y in {Top:1,Left:1}) o.style.setExpression(y.toLowerCase(),"(_=(document.documentElement.scroll"+y+" || document.body.scroll"+y+"))+'px'");
          }         
        });
        
        //if show param is been passed then eval it
        if(params && params.show){
          params.show();
        }
        
        //close modals      
        jQ("#modal_overlay, .modal_close").click(function(){
          console.log('idcls', div_id, div_class);
          //put content back into wrapper div
          if(div_id.length){
            c = c + div_id.html();
            jQ(div_id).appendTo('body').hide();
            //jQ(div_id).html(jQ("#modal_content div.modal_inner").html()).hide();
          }
          else if(div_class.length){
            c = c + div_class.html();           
            jQ(div_class).appendTo('body').hide();
          }          
          
          jQ("#modal_content").remove();
          jQ("#modal_overlay").remove();
          if(params && params.hide){ //hide param
            params.hide();
          }
        });
        return false;
      });
    });
  }
});



/*
 * jQuery clueTip plugin
 * Version 0.9.8  (05/22/2008)
 * @requires jQuery v1.1.4+
 * @requires Dimensions plugin (for jQuery versions < 1.2.5)
 *
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */
;(function($) { 
/*
 * @name clueTip
 * @type jQuery
 * @cat Plugins/tooltip
 * @return jQuery
 * @author Karl Swedberg
 *
 * @credit Inspired by Cody Lindley's jTip (http://www.codylindley.com)
 * @credit Thanks to the following people for their many and varied contributions:
      Shelane Enos, Glen Lipka, Hector Santos, Torben Schreiter, Dan G. Switzer, Jörn Zaefferer 
 * @credit Thanks to Jonathan Chaffer, as always, for help with the hard parts. :-)
 */

 /**
 * 
 * Displays a highly customizable tooltip when the user hovers (default) or clicks (optional) the matched element. 
 * By default, the clueTip plugin loads a page indicated by the "rel" attribute via ajax and displays its contents.
 * If a "title" attribute is specified, its value is used as the clueTip's heading.
 * The attribute to be used for both the body and the heading of the clueTip is user-configurable. 
 * Optionally, the clueTip's body can display content from an element on the same page.
 * * Just indicate the element's id (e.g. "#some-id") in the rel attribute.
 * Optionally, the clueTip's body can display content from the title attribute, when a delimiter is indicated. 
 * * The string before the first instance of the delimiter is set as the clueTip's heading.
 * * All subsequent strings are wrapped in separate DIVs and placed in the clueTip's body.
 * The clueTip plugin allows for many, many more options. Pleasee see the examples and the option descriptions below...
 * 
 * 
 * @example $('#tip).cluetip();
 * @desc This is the most basic clueTip. It displays a 275px-wide clueTip on mouseover of the element with an ID of "tip." On mouseout of the element, the clueTip is hidden.
 *
 *
 * @example $('a.clue').cluetip({
 *  hoverClass: 'highlight',
 *  sticky: true,
 *  closePosition: 'bottom',
 *  closeText: '<img src="cross.png" alt="close" />',
 *  truncate: 60,
 *  ajaxSettings: {
 *    type: 'POST'
 *  }
 * });
 * @desc Displays a clueTip on mouseover of all <a> elements with class="clue". The hovered element gets a class of "highlight" added to it (so that it can be styled appropriately. This is esp. useful for non-anchor elements.). The clueTip is "sticky," which means that it will not be hidden until the user either clicks on its "close" text/graphic or displays another clueTip. The "close" text/graphic is set to diplay at the bottom of the clueTip (default is top) and display an image rather than the default "Close" text. Moreover, the body of the clueTip is truncated to the first 60 characters, which are followed by an ellipsis (...). Finally, the clueTip retrieves the content using POST rather than the $.ajax method's default "GET."
 * 
 * More examples can be found at http://plugins.learningjquery.com/cluetip/demo/
 * 
 * Full list of options/settings can be found at the bottom of this file and at http://plugins.learningjquery.com/cluetip/
 */

  var $cluetip, $cluetipInner, $cluetipOuter, $cluetipTitle, $cluetipArrows, $dropShadow, imgCount;
  $.fn.cluetip = function(js, options) {
    if (typeof js == 'object') {
      options = js;
      js = null;
    }
		//console.info(options);
    return this.each(function(index) {
      var $this = $(this);      
      
      // support metadata plugin (v1.0 and 2.0)
      var opts = $.extend(false, {}, $.fn.cluetip.defaults, options || {}, $.metadata ? $this.metadata() : $.meta ? $this.data() : {});

      // start out with no contents (for ajax activation)
      var cluetipContents = false;
      var cluezIndex = parseInt(opts.cluezIndex, 10)-1;
      var isActive = false, closeOnDelay = 0;

      // create the cluetip divs
      if (!$('#cluetip').length) {
        $cluetipInner = $('<div id="cluetip-inner"></div>');
        $cluetipTitle = $('<h3 id="cluetip-title"></h3>');        
        $cluetipOuter = $('<div id="cluetip-outer"></div>').append($cluetipInner).prepend($cluetipTitle);
        $cluetip = $('<div id="cluetip"></div>').css({zIndex: opts.cluezIndex})
        .append($cluetipOuter).append('<div id="cluetip-extra"></div>')[insertionType](insertionElement).hide();
        $('<div id="cluetip-waitimage"></div>').css({position: 'absolute', zIndex: cluezIndex-1})
        .insertBefore('#cluetip').hide();
        $cluetip.css({position: 'absolute', zIndex: cluezIndex});
        $cluetipOuter.css({position: 'relative', zIndex: cluezIndex+1});
        $cluetipArrows = $('<div id="cluetip-arrows" class="cluetip-arrows"></div>').css({zIndex: cluezIndex+1}).appendTo('#cluetip');
      }
      var dropShadowSteps = (opts.dropShadow) ? +opts.dropShadowSteps : 0;
      if (!$dropShadow) {
        $dropShadow = $([]);
        for (var i=0; i < dropShadowSteps; i++) {
          $dropShadow = $dropShadow.add($('<div></div>').css({zIndex: cluezIndex-i-1, opacity:.1, top: 1+i, left: 1+i}));
        };
        $dropShadow.css({position: 'absolute', backgroundColor: '#000'})
        .prependTo($cluetip);
      }
      try{
        var tipAttribute = $this.attr(opts.attribute), ctClass = opts.cluetipClass;
        if (!tipAttribute && !opts.splitTitle && !js) return true;
        // if hideLocal is set to true, on DOM ready hide the local content that will be displayed in the clueTip      
        if (opts.local && opts.hideLocal) { $(tipAttribute + ':first').hide(); }
        var tOffset = parseInt(opts.topOffset, 10), lOffset = parseInt(opts.leftOffset, 10);
        // vertical measurement variables
        var tipHeight, wHeight;
        var defHeight = isNaN(parseInt(opts.height, 10)) ? 'auto' : (/\D/g).test(opts.height) ? opts.height : opts.height + 'px';
        var sTop, linkTop, posY, tipY, mouseY, baseline;
        // horizontal measurement variables
        var tipInnerWidth = isNaN(parseInt(opts.width, 10)) ? 275 : parseInt(opts.width, 10);
        var tipWidth = tipInnerWidth + (parseInt($cluetip.css('paddingLeft'))||0) + (parseInt($cluetip.css('paddingRight'))||0) + dropShadowSteps;
        var linkWidth = this.offsetWidth;
        var linkLeft, posX, tipX, mouseX, winWidth;
              
        // parse the title
        var tipParts;
        var tipTitle = (opts.attribute != 'title') ? $this.attr(opts.titleAttribute) : '';
        if (opts.splitTitle) {
          if(tipTitle == undefined) {tipTitle = '';}
          tipParts = tipTitle.split(opts.splitTitle);
          tipTitle = tipParts.shift();
        }
        var localContent;        
      }
      catch(e){
        console.warn(e);
      }

/***************************************      
* ACTIVATION
****************************************/
    
//activate clueTip
    var activate = function(event) {
      if (!opts.onActivate($this)) {
        return false;
      }
      isActive = true;
      $cluetip.removeClass().css({width: tipInnerWidth});
      if (tipAttribute == $this.attr('href')) {
        $this.css('cursor', opts.cursor);
      }
      $this.attr('title','');
      if (opts.hoverClass) {
        $this.addClass(opts.hoverClass);
      }
      linkTop = posY = $this.offset().top;
      linkLeft = $this.offset().left;
      mouseX = event.pageX;
      mouseY = event.pageY;
      if ($this[0].tagName.toLowerCase() != 'area') {
        sTop = $(document).scrollTop();
        winWidth = $(window).width();
      }
// position clueTip horizontally
      if (opts.positionBy == 'fixed') {
        posX = linkWidth + linkLeft + lOffset;
        $cluetip.css({left: posX});
      } else {
        posX = (linkWidth > linkLeft && linkLeft > tipWidth)
          || linkLeft + linkWidth + tipWidth + lOffset > winWidth 
          ? linkLeft - tipWidth - lOffset 
          : linkWidth + linkLeft + lOffset;
        if ($this[0].tagName.toLowerCase() == 'area' || opts.positionBy == 'mouse' || linkWidth + tipWidth > winWidth) { // position by mouse
          if (mouseX + 20 + tipWidth > winWidth) {  
            $cluetip.addClass(' cluetip-' + ctClass);
            posX = (mouseX - tipWidth - lOffset) >= 0 ? mouseX - tipWidth - lOffset - parseInt($cluetip.css('marginLeft'),10) + parseInt($cluetipInner.css('marginRight'),10) :  mouseX - (tipWidth/2);
          } else {
            posX = mouseX + lOffset;
          }
        }
        var pY = posX < 0 ? event.pageY + tOffset : event.pageY;
        $cluetip.css({left: (posX > 0 && opts.positionBy != 'bottomTop') ? posX : (mouseX + (tipWidth/2) > winWidth) ? winWidth/2 - tipWidth/2 : Math.max(mouseX - (tipWidth/2),0)});
      }
        wHeight = $(window).height();

/***************************************
* load a string from cluetip method's first argument
***************************************/
      if (js) {
        $cluetipInner.html(js);
        cluetipShow(pY);
      }
/***************************************
* load the title attribute only (or user-selected attribute). 
* clueTip title is the string before the first delimiter
* subsequent delimiters place clueTip body text on separate lines
***************************************/

      else if (tipParts) {
        var tpl = tipParts.length;
        for (var i=0; i < tpl; i++){
          if (i == 0) {
            $cluetipInner.html(tipParts[i]);
          } else { 
            $cluetipInner.append('<div class="split-body">' + tipParts[i] + '</div>');
          }            
        };
        cluetipShow(pY);
      }
/***************************************
* load external file via ajax          
***************************************/

      else if (!opts.local && tipAttribute.indexOf('#') != 0) {
        if (cluetipContents && opts.ajaxCache) {
          $cluetipInner.html(cluetipContents);
          cluetipShow(pY);
        }
        else {
          var ajaxSettings = opts.ajaxSettings;
          ajaxSettings.url = tipAttribute;
          ajaxSettings.beforeSend = function() {
            $cluetipOuter.children().empty();
            if (opts.waitImage) {
              $('#cluetip-waitimage')
              .css({top: mouseY+20, left: mouseX+20})
              .show();
            }
          };
         ajaxSettings.error = function() {
            if (isActive) {
              $cluetipInner.html('<i>sorry, the contents could not be loaded</i>');
            }
          };
          ajaxSettings.success = function(data) {
            cluetipContents = opts.ajaxProcess(data);
            if (isActive) {
              $cluetipInner.html(cluetipContents);
            }
          };
          ajaxSettings.complete = function() {
            imgCount = $('#cluetip-inner img').length;
            if (imgCount && !$.browser.opera) {
              $('#cluetip-inner img').load(function() {
                imgCount--;
                if (imgCount<1) {
                  $('#cluetip-waitimage').hide();
                  if (isActive) cluetipShow(pY);
                }
              }); 
            } else {
              $('#cluetip-waitimage').hide();
              if (isActive) cluetipShow(pY);    
            } 
          };
          $.ajax(ajaxSettings);
        }

/***************************************
* load an element from the same page
***************************************/
      } else if (opts.local){
        var $localContent = $(tipAttribute + ':first');
        var localCluetip = $.fn.wrapInner ? $localContent.wrapInner('<div></div>').children().clone(true) : $localContent.html();
        $.fn.wrapInner ? $cluetipInner.empty().append(localCluetip) : $cluetipInner.html(localCluetip);
        cluetipShow(pY);
      }
    };

// get dimensions and options for cluetip and prepare it to be shown
    var cluetipShow = function(bpY) {
      $cluetip.addClass('cluetip-' + ctClass);
      
      if (opts.truncate) { 
        var $truncloaded = $cluetipInner.text().slice(0,opts.truncate) + '...';
        $cluetipInner.html($truncloaded);
      }
      function doNothing() {}; //empty function
      tipTitle ? $cluetipTitle.show().html(tipTitle) : (opts.showTitle) ? $cluetipTitle.show().html('&nbsp;') : $cluetipTitle.hide();
      if (opts.sticky) {
        var $closeLink = $('<div id="cluetip-close"><a href="#" title="close">' + opts.closeText + '</a></div>');
        (opts.closePosition == 'bottom') ? $closeLink.appendTo($cluetipInner) : (opts.closePosition == 'title') ? $closeLink.prependTo($cluetipTitle) : $closeLink.prependTo($cluetipInner);
        $closeLink.click(function() {
          cluetipClose();
          return false;
        });
        if (opts.mouseOutClose) {
          if ($.fn.hoverIntent && opts.hoverIntent) { 
            $cluetip.hoverIntent({
              over: doNothing, 
              timeout: opts.hoverIntent.timeout,  
              out: function() { $closeLink.trigger('click'); }
            });
          } else {
            $cluetip.hover(doNothing, 
            function() {$closeLink.trigger('click'); });
          }
        } else {
          $cluetip.unbind('mouseout');
        }
      }
// now that content is loaded, finish the positioning 
      var direction = '';
      $cluetipOuter.css({overflow: defHeight == 'auto' ? 'visible' : 'auto', height: defHeight});
      tipHeight = defHeight == 'auto' ? Math.max($cluetip.outerHeight(),$cluetip.height()) : parseInt(defHeight,10);   
      tipY = posY;
      baseline = sTop + wHeight;
      if (opts.positionBy == 'fixed') {
        tipY = posY - opts.dropShadowSteps + tOffset;
      } else if ( (posX < mouseX && Math.max(posX, 0) + tipWidth > mouseX) || opts.positionBy == 'bottomTop') {
        if (posY + tipHeight + tOffset > baseline && mouseY - sTop > tipHeight + tOffset) { 
          tipY = mouseY - tipHeight - tOffset;
          direction = 'top';
        } else { 
          tipY = mouseY + tOffset;
          direction = 'bottom';
        }
      } else if ( posY + tipHeight + tOffset > baseline ) {
        tipY = (tipHeight >= wHeight) ? sTop : baseline - tipHeight - tOffset;
      } else if ($this.css('display') == 'block' || $this[0].tagName.toLowerCase() == 'area' || opts.positionBy == "mouse") {
        tipY = bpY - tOffset;
      } else {
        tipY = posY - opts.dropShadowSteps;
      }
      if (direction == '') {
        posX < linkLeft ? direction = 'left' : direction = 'right';
      }
      $cluetip.css({top: tipY + 'px'}).removeClass().addClass('clue-' + direction + '-' + ctClass).addClass(' cluetip-' + ctClass);
      if (opts.arrows) { // set up arrow positioning to align with element
        var bgY = (posY - tipY - opts.dropShadowSteps);
        $cluetipArrows.css({top: (/(left|right)/.test(direction) && posX >=0 && bgY > 0) ? bgY + 'px' : /(left|right)/.test(direction) ? 0 : ''}).show();
      } else {
        $cluetipArrows.hide();
      }

// (first hide, then) ***SHOW THE CLUETIP***
      $dropShadow.hide();
      $cluetip.hide()[opts.fx.open](opts.fx.open != 'show' && opts.fx.openSpeed);
      if (opts.dropShadow) $dropShadow.css({height: tipHeight, width: tipInnerWidth}).show();
      if ($.fn.bgiframe) { $cluetip.bgiframe(); }
      // trigger the optional onShow function
      if (opts.delayedClose > 0) {
        closeOnDelay = setTimeout(cluetipClose, opts.delayedClose);
      }
      opts.onShow($cluetip, $cluetipInner);
      
    };

/***************************************
   =INACTIVATION
-------------------------------------- */
    var inactivate = function() {
      isActive = false;
      $('#cluetip-waitimage').hide();
      if (!opts.sticky || (/click|toggle/).test(opts.activation) ) {
        cluetipClose();
clearTimeout(closeOnDelay);        
      };
      if (opts.hoverClass) {
        $this.removeClass(opts.hoverClass);
      }
      $('.cluetip-clicked').removeClass('cluetip-clicked');
    };
// close cluetip and reset some things
    var cluetipClose = function() {
      $cluetipOuter 
      .parent().hide().removeClass().end()
      .children().empty();
      if (tipTitle) {
        $this.attr(opts.titleAttribute, tipTitle);
      }
      $this.css('cursor','');
      if (opts.arrows) $cluetipArrows.css({top: ''});
    };

/***************************************
   =BIND EVENTS
-------------------------------------- */
  // activate by click
      if ( (/click|toggle/).test(opts.activation) ) {
        $this.click(function(event) {
          if ($cluetip.is(':hidden') || !$this.is('.cluetip-clicked')) {
            activate(event);
            $('.cluetip-clicked').removeClass('cluetip-clicked');
            $this.addClass('cluetip-clicked');

          } else {
            inactivate(event);

          }
          this.blur();
          return false;
        });
  // activate by focus; inactivate by blur    
      } else if (opts.activation == 'focus') {
        $this.focus(function(event) {
          activate(event);
        });
        $this.blur(function(event) {
          inactivate(event);
        });
  // activate by hover
    // clicking is returned false if cluetip url is same as href url
      } else {
        $this.click(function() {
          if ($this.attr('href') && $this.attr('href') == tipAttribute && !opts.clickThrough) {
            return false;
          }
        });
        //set up mouse tracking
        var mouseTracks = function(evt) {
          if (opts.tracking == true) {
            var trackX = posX - evt.pageX;
            var trackY = tipY ? tipY - evt.pageY : posY - evt.pageY;
            $this.mousemove(function(evt) {
              $cluetip.css({left: evt.pageX + trackX, top: evt.pageY + trackY });
            });
          }
        };
        if ($.fn.hoverIntent && opts.hoverIntent) {
          $this.mouseover(function() {$this.attr('title',''); })
          .hoverIntent({
            sensitivity: opts.hoverIntent.sensitivity,
            interval: opts.hoverIntent.interval,  
            over: function(event) {
              activate(event);
              mouseTracks(event);
            }, 
            timeout: opts.hoverIntent.timeout,  
            out: function(event) {inactivate(event); $this.unbind('mousemove');}
          });           
        } else {
          $this.hover(function(event) {
            activate(event);
            mouseTracks(event);
          }, function(event) {
            inactivate(event);
            $this.unbind('mousemove');
          });
        }
      }
    });
  };
  
/*
 * options for clueTip
 *
 * each one can be explicitly overridden by changing its value. 
 * for example: $.fn.cluetip.defaults.width = 200; 
 * would change the default width for all clueTips to 200. 
 *
 * each one can also be overridden by passing an options map to the cluetip method.
 * for example: $('a.example').cluetip({width: 200}); 
 * would change the default width to 200 for clueTips invoked by a link with class of "example"
 *
 */
  
  $.fn.cluetip.defaults = {  // set up default options
    width:            350,      // The width of the clueTip
    height:           'auto',   // The height of the clueTip
    cluezIndex:       97,       // Sets the z-index style property of the clueTip
    positionBy:       'auto',   // Sets the type of positioning: 'auto', 'mouse','bottomTop', 'fixed'
    topOffset:        10,       // Number of px to offset clueTip from top of invoking element
    leftOffset:       10,       // Number of px to offset clueTip from left of invoking element
    local:            true,    // Whether to use content from the same page for the clueTip's body
    hideLocal:        true,     // If local option is set to true, this determines whether local content
                                // to be shown in clueTip should be hidden at its original location
    attribute:        'rel',    // the attribute to be used for fetching the clueTip's body content
    titleAttribute:   'title',  // the attribute to be used for fetching the clueTip's title
    splitTitle:       '',       // A character used to split the title attribute into the clueTip title and divs
                                // within the clueTip body. more info below [6]
    showTitle:        true,     // show title bar of the clueTip, even if title attribute not set
    cluetipClass:     'default',// class added to outermost clueTip div in the form of 'cluetip-' + clueTipClass.
    hoverClass:       '',       // class applied to the invoking element onmouseover and removed onmouseout
    waitImage:        false,     // whether to show a "loading" img, which is set in jquery.cluetip.css
    cursor:           'help',
    arrows:           false,    // if true, displays arrow on appropriate side of clueTip
    dropShadow:       false,     // set to false if you don't want the drop-shadow effect on the clueTip
    dropShadowSteps:  6,        // adjusts the size of the drop shadow
    sticky:           false,    // keep visible until manually closed
    mouseOutClose:    false,    // close when clueTip is moused out
    activation:       'hover',  // set to 'click' to force user to click to show clueTip
                                // set to 'focus' to show on focus of a form element and hide on blur
    clickThrough:     false,    // if true, and activation is not 'click', then clicking on link will take user to the link's href,
                                // even if href and tipAttribute are equal
    tracking:         false,    // if true, clueTip will track mouse movement (experimental)
    delayedClose:     0,        // close clueTip on a timed delay (experimental)
    closePosition:    'top',    // location of close text for sticky cluetips; can be 'top' or 'bottom' or 'title'
    closeText:        'Close',  // text (or HTML) to to be clicked to close sticky clueTips
    truncate:         0,        // number of characters to truncate clueTip's contents. if 0, no truncation occurs

    // effect and speed for opening clueTips
    fx: {             
                      open:       'show', // can be 'show' or 'slideDown' or 'fadeIn'
                      openSpeed:  ''
    },     

    // settings for when hoverIntent plugin is used             
    hoverIntent: {    
                      sensitivity:  3,
                      interval:     50,
                      timeout:      0
    },

    // function to run just before clueTip is shown.           
    onActivate:       function(e) {return true;},

    // function to run just after clueTip is shown.
    onShow:           function(ct, c){},
    
    // whether to cache results of ajax request to avoid unnecessary hits to server    
    ajaxCache:        true,  

    // process data retrieved via xhr before it's displayed
    ajaxProcess:      function(data) {
                        data = data.replace(/<s(cript|tyle)(.|\s)*?\/s(cript|tyle)>/g, '').replace(/<(link|title)(.|\s)*?\/(link|title)>/g,'');
                        return data;
    },                

    // can pass in standard $.ajax() parameters, not including error, complete, success, and url
    ajaxSettings: {   
                      dataType: 'html'
    },
    debug: false
  };


/*
 * Global defaults for clueTips. Apply to all calls to the clueTip plugin.
 *
 * @example $.cluetip.setup({
 *   insertionType: 'prependTo',
 *   insertionElement: '#container'
 * });
 * 
 * @property
 * @name $.cluetip.setup
 * @type Map
 * @cat Plugins/tooltip
 * @option String insertionType: Default is 'appendTo'. Determines the method to be used for inserting the clueTip into the DOM. Permitted values are 'appendTo', 'prependTo', 'insertBefore', and 'insertAfter'
 * @option String insertionElement: Default is 'body'. Determines which element in the DOM the plugin will reference when inserting the clueTip.
 *
 */
   
  var insertionType = 'appendTo', insertionElement = 'body';
  $.cluetip = {};
  $.cluetip.setup = function(options) {
    if (options && options.insertionType && (options.insertionType).match(/appendTo|prependTo|insertBefore|insertAfter/)) {
      insertionType = options.insertionType;
    }
    if (options && options.insertionElement) {
      insertionElement = options.insertionElement;
    }
  };
  
})(jQuery);





/* jQuery elementReady plugin
 * Version 0.6
 * Copyright (C) 2007-08 Bennett McElwee.
 * Licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License (http://creativecommons.org/licenses/by-sa/3.0/)
 * Permissions beyond the scope of this license may be available at http://www.thunderguy.com/semicolon/.
 */

/*
  IMPLEMENTATION NOTES
  There may be race conditions. The most likely could occur if check() is
  called while a previous invocation of check() is still running. This could
  cause a callback to be called more than once, or not at all. Less likely is
  for elementReady() to be called concurrently with check() (with similar
  effects) or with itself (which could cause an interval to run forever).
  None of these are likely to occur. In fact I don't think they are possible
  at all except on IE. -- Bennett McElwee, August 2007
*/
(function($) {

/**
 * While a page is loading, call a given callback function as soon as a specific
 * element (with a specific ID) is loaded into the DOM, even before the full DOM
 * has been loaded. Executes the function within the context of the element. This
 * means that when the passed-in function is executed, the 'this' keyword points
 * to the specific DOM element.
 *
 * The function returns 'this', so you can chain multiple calls to
 * elementReady(). (Not that there's much benefit in doing that.)
 *
 * One argument is passed to the callback: a reference to the jQuery function.
 * You can name this argument $ and therefore use the $ alias even in
 * noConflict mode.
 *
 * If the element has not been found by the time the DOM is fully loaded, then
 * the function will not be called.
 *
 * The function works by polling the DOM at short intervals. By default it polls
 * every 23 milliseconds, but you can change this by setting
 * $.elementReady.interval_ms to whatever value you like.
 * Don't bother changing this unless you really know what you're doing.
 *
 * @example
 * $.elementReady('powerpic', function(){
 *     this.src = 'powered-by-jquery.png';
 * });
 * @desc Change the source of a specific image as soon as it is loaded into the
 * DOM (before the whole DOM is loaded).
 *
 * @example
 * $.elementReady('header', function(){
 *     $(this).addClass('fancy');
 * });
 * @desc If you want to have the jQuery object instead of the regular DOM
 * element, use the $(this) function.
 *
 * @example
 * $.elementReady('first',  function(){ $(this).fancify(); })
 *  .elementReady('second', function(){ $(this).fancify(); });
 * @desc Chain multiple calls to $.elementReady().
 *
 * @example
 * jQuery.noConflict();
 * jQuery.elementReady('header', function($){
 *     $(this).addClass('fancy');
 * });
 * @desc Use the '$' alias within your callback, even in noConflict mode.
 *
 * @example
 * $.elementReady.interval_ms = 100;
 * @desc Change the polling interval to 100ms. This only works if $.elementReady()
 * has not yet been called.
 *
 * @name   $.elementReady
 * @type   jQuery
 * @param  String   id  string ID of the element to wait for
 * @param  Function fn  function to call when the element is ready
 * @return jQuery
 * @cat    Plugins/Event
 * @author Bennett McElwee
 */
var interval = null;
var checklist = [];

$.elementReady = function(id, fn) {
  checklist.push({id: id, fn: fn});
  if (!interval) {
    interval = setInterval(check, $.elementReady.interval_ms);
  }
  return this;
};

// Plugin settings
$.elementReady.interval_ms = 23; // polling interval in ms

// Private function
function check() {
  var docReady = $.isReady; // check doc ready first; thus ensure that check is made at least once _after_ doc is ready
  for (var i = checklist.length - 1; 0 <= i; --i) {
    var el = document.getElementById(checklist[i].id);
    if (el) {
      var fn = checklist[i].fn; // first remove from checklist, then call function
      checklist[i] = checklist[checklist.length - 1];
      checklist.pop();
      fn.apply(el, [$]);
    }
  }
  if (docReady) {
    clearInterval(interval);
    interval = null;
  }
};

})(jQuery);




/*
 * Lightweight RTE - jQuery Plugin
 * Copyright (c) 2009 Andrey Gayvoronsky - http://www.gayvoronsky.com
 */
jQuery.fn.rte = function(options) {
  var editors = new Array();
  $(this).each( function() {
    editors.push(new lwRTE (this, options));
  });  
  return editors;
}


var lwRTE = function (textarea, options) {
  var testUrl = 'test';
  this.css_url  = options.css;
  this.css_class  = options.frame_class;
  this.base_url = options.base_url;
  this.width    = options.width || '100%';
  this.height   = options.height || 350;
  
  //edit by as: make it possible to have the controls below the frame
  this.controls_position = options.controls_position || 'top';
  this.culture = options.culture || 'en_US';
	
  this.allowSourceMode = options.allowSourceMode || false;
  this.events = options.events || {};
  this.labels = options.labels || typeof toolbarLabels != 'undefined' ? toolbarLabels : {}; 
  

  this.iframe   = null;
  this.iframe_doc = null;
  this.textarea = null;
  this.event    = null;
  this.range    = null;
  this.toolbars = {rte: '', html : ''};
  
  //mod by AS: make it possible to switch source editing off
  this.controls = {
    rte: {},
    html: {}
  };
  
  if(this.allowSourceMode){
    this.controls = {
      rte: {disable: {hint: 'Source editor'}}, 
      html: {enable: {hint: 'Visual editor'}}
   };    
  }

  $.extend(this.controls.rte, options.controls_rte);
  $.extend(this.controls.html, options.controls_html);

  if(document.designMode || document.contentEditable) {
    $(textarea).wrap($('<div></div>').addClass('rte-zone').width(this.width));
    this.textarea = textarea;
    this.enable_design_mode();
    console.info('iframe doc', $(this.iframe_doc));    
  } 
}


lwRTE.prototype.editor_cmd = function(command, args) {
  this.iframe.contentWindow.focus();
  try {
    console.log(command, false, args);
    this.iframe_doc.execCommand(command, false, args);
  } catch(e) {
    console.log(e)
  }
  this.iframe.contentWindow.focus();
}

lwRTE.prototype.get_toolbar = function() {
  var editor = (this.iframe) ? $(this.iframe) : $(this.textarea);
  
  //modifcation by as to make bottom pos work
  if(this.controls_position !== 'bottom'){
    return (editor.prev().hasClass('rte-toolbar')) ? editor.prev() : null;
  }
  
  else{
    return (editor.next().hasClass('rte-toolbar')) ? editor.next() : null;
  }  
}

lwRTE.prototype.activate_toolbar = function(editor, tb){
  var old_tb = this.get_toolbar();
  
  if (old_tb) 
    old_tb.remove();
  /*
   * fix by as: make it possible to position at bottom
   *
   */
  if (this.controls_position !== 'bottom'){ 
    $(editor).before($(tb).clone(true));
  }
  else{
    $(editor).after($(tb).clone(true));
  }
}
  
lwRTE.prototype.enable_design_mode = function() {
  var self = this;

  // need to be created this way
  self.iframe = document.createElement("iframe");
  self.iframe.frameBorder = 0;
  self.iframe.frameMargin = 0;
  self.iframe.framePadding = 0;
  self.iframe.width = '100%';
  self.iframe.height = self.height || '100%';

  if($(self.textarea).attr('class'))
    self.iframe.className = $(self.textarea).attr('class');

  //mod by as: thwe frame should not have the same id
  if($(self.textarea).attr('id')){
    self.iframe.id = $(self.textarea).attr('id');
  }
  else{//no id specified, use a random id  
    self.iframe.id = $(self.textarea).attr('name');
  }
    
  
  if($(self.textarea).attr('name'))
    self.iframe.title = $(self.textarea).attr('name');

  var content = $(self.textarea).val();

  //this is ok, as long as we remove the element, there shold not be a problem
  $(self.textarea).hide().after(self.iframe).remove();
  self.textarea = null;

  var css = (self.css_url) ? "<link type='text/css' rel='stylesheet' href='" + self.css_url + "' />" : '';
  var base = (self.base_url) ? "<base href='" + self.base_url + "' />" : '';
  var style = (self.css_class) ? "class='" + self.css_class + "'" : '';

  // Mozilla need this to display caret
  if($.trim(content) == '')
    content = '<br>';

  var doc = '<html><head>' + base + css + '</head><body id="rte-body">' + content + '</body></html>';

  self.iframe_doc = self.iframe.contentWindow.document;

  try {
    self.iframe_doc.designMode = 'on';
  } catch ( e ) {
    // Will fail on Gecko if the editor is placed in an hidden container element
    // The design mode will be set ones the editor is focused
    $(self.iframe_doc).focus(function() { self.iframe_doc.designMode(); } );
  }

  self.iframe_doc.open();
  self.iframe_doc.write(doc);
  self.iframe_doc.close();

  if(!self.toolbars.rte)
    self.toolbars.rte = self.create_toolbar(self.controls.rte);

  self.activate_toolbar(self.iframe, self.toolbars.rte);

  //convert back to textarea, if the form is submitted
  $(self.iframe).parents('form').submit( 
      function() { self.disable_design_mode(true); }
  );

  //store the current selectiion if there is one?
  $(self.iframe_doc).mouseup(function(event) { 
    if(self.iframe_doc.selection)
      self.range = self.iframe_doc.selection.createRange();  //store to restore later(IE fix)

    self.set_selected_controls( (event.target) ? event.target : event.srcElement, self.controls.rte); 
  });

  //not quite sure what this does yet
  $(self.iframe_doc).keyup(
    function(event) { 
      self.set_selected_controls( self.get_selected_element(), self.controls.rte);    
     }
  );

  // Mozilla CSS styling off--> why?
  if(!$.browser.msie){
    self.editor_cmd('styleWithCSS', false);    
  }
  
  if(typeof self.events.click != 'undefined'){
    window.console.log('click defined');
    //$(self.iframe_doc).trigger('focus'); //fix for ie/safari
    try{
      $(self.iframe_doc).click(function(){
        try{
         self.events.click();
        }           
        catch(e){
          console.error(e);
          alert('exception! '+e);
        }
      });  
    }
    catch(e){
      console.error(e);
      alert(e);
    }            
  }
  
  
  if(typeof self.events.keyup != 'undefined'){
    //$(self.iframe_doc).trigger('focus'); //fix for ie/safari
    $(self.iframe_doc).keyup(function(){           
       self.events.keyup();          
    });        
  }
  
  if (typeof self.events.blur != 'undefined') {
    $(self.iframe_doc).blur(function(){            
        self.events.blur();
    });
  }
    
  //mod by as: apply listeners
  /* $(self.iframe_doc).focus(
      function(){
        console.log('focus');
        $(this).keyup(function(){          
          if(self.onKeyup){
            self.onKeyup();
          }
        });
      }
     );
     
      $(self.iframe_doc).blur(
        function(){
        console.log('blur');
        $(this).unbind('keyup');
      }
      );*/
     
     //doesnt work :(
     /*$.each(self.events, function(eventKey){
      console.info(eventKey, this);
      func = this;
       $(self.iframe_doc).bind(eventKey, function(){
         func();        
       });
     });*/
    
    
      /*console.log('!!!bind!');
      if(self.events.keyup){
        $(self.iframe_doc).keyup(function(){          
           self.events.keyup();          
        });        
      }
      
      */
      
      
      /*if(self.events.focus){
        $(self.iframe_doc).unbind('focus').focus(function(){
          alert('!focus');
          self.events.focus();
        });
      } */
   
     
      /* $(self.iframe_doc).unbind('blur').blur(
        function(){
        console.log('!blur');
        
          self.events.blur();
        }
        //$(self.iframe_doc).unbind('focus');
      }); */
  
}
    
lwRTE.prototype.disable_design_mode = function(submit) {
  var self = this;
  
  //returns a hidden input field or a textarea to pass the data 
  self.textarea = (submit) ? $('<input type="hidden" />').get(0) : $('<textarea></textarea>').width('100%').height(self.height).get(0);
  
  //mod by as: remove old instances (e.g. still existing if form is sumitted via ajax)
  console.info( $(':input'), $(':input').filter('#'+self.iframe.id));
  $(':input').filter("#"+self.iframe.id).remove();
  

  if(self.iframe.className)
    self.textarea.className = self.iframe.className;

  if(self.iframe.id)
    self.textarea.id = self.iframe.id;
    
  if(self.iframe.title)
    self.textarea.name = self.iframe.title;
  
  $(self.textarea).val($('body', self.iframe_doc).html());
  
  //edit by AS: remove single br
  if($(self.textarea).val() == '<br>' || $(self.textarea).val() == '<br/>') {
    $(self.textarea).val(''); 
  }
  console.info('val now:', $(self.textarea).val());
  
  //edit by AS: this is a problem on ajax submit, the element can only be addedm if not already there 
  $(self.iframe).before(self.textarea);

  if(!self.toolbars.html)
    self.toolbars.html  = self.create_toolbar(self.controls.html);

  if(submit != true) {
    $(self.iframe).remove();
    self.iframe = null;
    self.activate_toolbar(self.textarea, self.toolbars.html);
  }
}
    
lwRTE.prototype.toolbar_click = function(obj, control) {
  var fn = control.exec;

  $('.rte-panel', this.get_toolbar()).remove();

  if(fn)
    fn.apply(this);
  else if(this.iframe && control.command) {
    var args = control.args;

    if(obj.tagName.toUpperCase() == 'SELECT') {
      args = obj.options[obj.selectedIndex].value;

      if(args.length <= 0)
        return;
    }

    this.editor_cmd(control.command, args);
  }
}
  
lwRTE.prototype.create_toolbar = function(controls) {
  var self = this;
  var tb = $("<div></div>").addClass('rte-toolbar').width('100%').append($("<ul></ul>")).append($("<div></div>").addClass('clear'));
  var obj, li, linkText, title;
  
  
  for (var key in controls){
    if(controls[key].separator) {
      li = $("<li></li>").addClass('separator');
    } else {
      if(controls[key].select) {
        obj = $(controls[key].select)
          .change( function(e) {
            self.event = e;
            self.toolbar_click(this, controls[this.className]); 
            return false;
          });
      } else {
        //console.log('creating:', i18n(key, self.culture, toolbarLabels), '| ', key, '| ', self.culture,  '| ', toolbarLabels);
        linkText = typeof controls[key].linkText == 'undefined' ? '' : i18n(controls[key].linkText, self.culture, self.labels);
        title = typeof controls[key].hint != 'undefined' ? controls[key].hint : i18n(key, self.culture, self.labels);
        				
        obj = $("<a href='#'>"+linkText+"</a>")
          //kollidiert mit <li> title und tooltip
					//.attr('title', title)
          .attr('rel', key)
          .click( function(e) {
            self.event = e;
            self.toolbar_click(this, controls[this.rel]); 
            return false;
          })
      }

      li = $("<li title=\"" + title + "\" class=\"" + (controls[key].liClass) + "\"></li>").append(obj.addClass(key));
    }

    $("ul",tb).append(li);
  }

  $('.enable', tb).click(function() {
    self.enable_design_mode();
    return false; 
  });

  $('.disable', tb).click(function() {
    self.disable_design_mode();
    return false; 
  });

  return tb.get(0);
}

lwRTE.prototype.create_panel = function(obj){
  var self = this;
  var ie6 = jQuery.browser.msie&&(jQuery.browser.version == "6.0");
  var tb = self.get_toolbar();
  var tbArea = $(tb).parent('.rte-zone');
  var panel = jQuery('.rte-panel', tbArea);
  
  //create new panel for thsi rte area if not already there
  if(panel.length < 1){
    //panel = $('<div></div>').hide().addClass('rte-panel');
    jQuery(tbArea).append('<div class="rte-panel"><div class="rte-panel-title">'
      +obj.title+'<a class="rte-close" href="#">X</a></div><div class="rte-panel-content">'
      +obj.content+'</div></div>'
    );
    //append($("<a class='close' href='#'>X</a>")
    //.click( function() { panel.remove(); return false; }))
    panel = jQuery('.rte-panel', tbArea)[0];
    //console.info('new panel', panel);
  }
  else{
    //console.info('panel exists', panel);
    jQuery('.rte-panel-title', panel[0]).html(obj.title+'<a class="rte-close" href="#">X</a>');
    jQuery('.rte-panel-content', panel[0]).html(obj.content);    
  }
  console.info('zone', tbArea, 'panel', panel);
  
  //TODO: ie6 flash/selector fix
   //on load stuff     
        /*jQ("#modal_content").load(function(){
          o = jQ("#modal_overlay");
          w = jQ("#modal_content");
          w.css({width:$(this).css("width"), height:$(this).css("height") });
          if(ie6) {
            $('html,body').css({height:'100%',width:'100%'});
            i=$('<iframe src="javascript:false;document.write(\'\');" class="overlay"></iframe>').css({opacity:0});
            o.html('<p style="width:100%;height:100%"/>').prepend(i)
            o = o.css({position:'absolute'})[0];
            for(var y in {Top:1,Left:1}) o.style.setExpression(y.toLowerCase(),"(_=(document.documentElement.scroll"+y+" || document.body.scroll"+y+"))+'px'");
          }         
        });*/
  
  //translucent overlay
  //only add the div if its not there already
  if(!jQuery('#rtePanelOverlay').length){ 
    jQuery("body").append('<div id="rtePanelOverlay"></div>');
  }
  jQuery('#rtePanelOverlay').show();
        
  /*if(!jQuery('.rtePanel', tbArea).length){ //only add the div if its not there already
    jQuery(tbArea).append('<div class="rte-panel"><div class="rte-panel-title">'
      +obj.title+'<a class='rte-close' href='#'>X</a></div><div class="rte-panel-content">'
      +obj.content+'</div></div>'
    );
  }*/
	
	//console.info('width',jQuery(panel).width());
  
   //position in center
  var height =  jQuery(panel).height();
  var width = jQuery(panel).width()+100;
  jQuery(panel).css({marginLeft: '-' + parseInt((width / 2),10) + 'px', width: width + 'px'});
  
  //drag and drop
  /*jQuery(panel).mousedown( function() { drag = true; return false; })
    .mouseup( function() { drag = false; return false; })
    .mousemove( 
      function(e) {
        if(drag && event) {
          left -= event.pageX - e.pageX;
          top -=  event.pageY - e.pageY;
          panel.css( {left: left, top: top} ); 
        }

        event = e;
        return false;
      } 
    )*/
  
  //close overlay
  jQuery("#rtePanelOverlay, .rte-close").click(function(){    
    jQuery(panel).hide();   
    jQuery('#rtePanelOverlay').hide(); 
    if(obj.onClose){
      obj.onClose(panel);
    }
    /*if(params && params.hide){ //hide param
      params.hide();
    }*/
    return false;
  });
      
  return panel;
}

/*lwRTE.prototype.create_panel = function(title, width) {
  var self = this;
  var tb = self.get_toolbar();
  if(!tb)
    return false;

    //mod by as, do not attach it to the toolbar , this will leed to stupid css overwrites
  //$('.rte-panel', tb).remove();
  $('.rte-panel').remove();
  
  
  var drag, event;
  var left = self.event.pageX;
  var top = self.event.pageY;
  
  //mod by as: we could hook hin our own custom panel here
  
  var panel = $('<div></div>').hide().addClass('rte-panel').css({left: left, top: top});
  $('<div></div>')
    .addClass('rte-panel-title')
    .html(title)
    .append($("<a class='close' href='#'>X</a>")
    .click( function() { panel.remove(); return false; }))
    //.appendTo(panel);
    
   
    
    .mousedown( function() { drag = true; return false; })
    .mouseup( function() { drag = false; return false; })
    .mousemove( 
      function(e) {
        if(drag && event) {
          left -= event.pageX - e.pageX;
          top -=  event.pageY - e.pageY;
          panel.css( {left: left, top: top} ); 
        }

        event = e;
        return false;
      } 
    )
    .appendTo(panel);

  if(width)
    panel.width(width);

  //tb.append(panel);
  //mod py as: attach it to the area, not to the toolbar
  $('.rte-zone').append(panel);  
    
  return panel;
}*/

lwRTE.prototype.get_content = function() {
  return (this.iframe) ? $('body', this.iframe_doc).html() : $(this.textarea).val();
}

lwRTE.prototype.set_content = function(content) {
  (this.iframe) ? $('body', this.iframe_doc).html(content) : $(this.textarea).val(content);
}

lwRTE.prototype.set_selected_controls = function(node, controls) {
  var toolbar = this.get_toolbar();

  if(!toolbar)
    return false;
    
  var key, i_node, obj, control, tag, i, value;

  for (key in controls) {
    control = controls[key];
    obj = $('.' + key, toolbar);

    obj.removeClass('active');

    if(!control.tags)
      continue;

    i_node = node;
    do {
      if(i_node.nodeType != 1)
        continue;

      tag = i_node.nodeName.toLowerCase();
      if($.inArray(tag, control.tags) < 0 )
        continue;

      if(control.select) {
        obj = obj.get(0);
        if(obj.tagName.toUpperCase() == 'SELECT') {
          obj.selectedIndex = 0;

          for(i = 0; i < obj.options.length; i++) {
            value = obj.options[i].value;
            if(value && ((control.arg_cmp && control.arg_cmp(i_node, value)) || tag == value)) {
              obj.selectedIndex = i;
              break;
            }
          }
        }
      } else
          obj.addClass('active');
    }  while(i_node = i_node.parentNode)
  }
    
  return true;
}

lwRTE.prototype.get_selected_element = function () {
  var node, selection, range;
  var iframe_win  = this.iframe.contentWindow;
  
  if (iframe_win.getSelection) {
    try {
      selection = iframe_win.getSelection();
      range = selection.getRangeAt(0);
      node = range.commonAncestorContainer;
    } catch(e){
      return false;
    }
  } else {
    try {
      selection = iframe_win.document.selection;
      range = selection.createRange();
      node = range.parentElement();
    } catch (e) {
      return false;
    }
  }

  return node;
}

lwRTE.prototype.get_selection_range = function() {
  var rng = null;
  var iframe_window = this.iframe.contentWindow;
  this.iframe.focus();
  
  if(iframe_window.getSelection) {
    rng = iframe_window.getSelection().getRangeAt(0);
    if($.browser.opera) { //v9.63 tested only
      var s = rng.startContainer;
      if(s.nodeType === Node.TEXT_NODE)
        rng.setStartBefore(s.parentNode);
    }
  } else {
    this.range.select(); //Restore selection, if IE lost focus.
    rng = this.iframe_doc.selection.createRange();
  }

  return rng;
}

lwRTE.prototype.get_selected_text = function() {
  var iframe_win = this.iframe.contentWindow;

  if(iframe_win.getSelection) 
    return iframe_win.getSelection().toString();

  this.range.select(); //Restore selection, if IE lost focus.
  return iframe_win.document.selection.createRange().text;
};

lwRTE.prototype.get_selected_html = function() {
  var html = null;
  var iframe_window = this.iframe.contentWindow;
  var rng = this.get_selection_range();

  if(rng) {
    if(iframe_window.getSelection) {
      var e = document.createElement('div');
      e.appendChild(rng.cloneContents());
      html = e.innerHTML;   
    } else {
      html = rng.htmlText;
    }
  }

  return html;
};

/**
 * replaces the selected text with the passed html
 * @param {Object} html
 */  
lwRTE.prototype.selection_replace_with = function(html) {
  var rng = this.get_selection_range();
  var iframe_window = this.iframe.contentWindow;

  if(!rng)
    return;
  
  this.editor_cmd('removeFormat'); // we must remove formating or we will get empty format tags!

  if(iframe_window.getSelection) {
    rng.deleteContents();
    rng.insertNode(rng.createContextualFragment(html));
    this.editor_cmd('delete');
  } else {
    this.editor_cmd('delete');
    rng.pasteHTML(html);
  }
}

lwRTE.prototype.focus = function(){
  try {
    this.iframe.contentWindow.focus();
  }
  catch(e){
    $(this.textarea).focus();
  }
};

/**
* Faviconize (http://www.babylon-design.com/share/faviconize/)
* A jQuery plugin for displaying a favicon on an external link.
* 
* Version 1.0
* March 4th, 2008
*
* Author : Samuel Le Morvan (http://www.babylon-design.com/)
* 
* Inspired by:
* Ask the CSS Guy (http://www.askthecssguy.com/2006/12/hyperlink_cues_with_favicons.html)
* 
*
**/
(function($){
	$.fn.faviconize = function(e) {
		
		var e = $.extend({position:'before', linkable:false, exceptions: new Array(), afterFaviconize:null}, e);
		 
		function faviconizePlace(a, h) {
			switch(e.position) {
				case "before" : a.before(h+'&nbsp;'); break;
				case "after" : a.after('&nbsp;'+h); break;
				default :  break;
			}
			
			if(e.afterFaviconize !== null){
			 e.afterFaviconize(a);
			}
		}
		
		$(this).each(function() {
			var a = $(this);
			var r = a.attr("href").match(/http:\/\/[a-z0-9.-]*(\/)?/i);
			var r = r[0] + ((r[1] == null) ? "/" : "");
			if(r) {
				if($.grep(e.exceptions, function(x) {x = (x.match(/\/$/) == null) ? x+"/" : x; return (x == r);}).length == 0) {
					var f = r + 'favicon.ico';
					var i = new Image(); $(i).attr("src", f);
					var h = '<img src="'+f+'" alt="'+ ((e.linkable) ? a.text() : '') +'" '+ ((e.className) ? 'class="'+e.className+'"' : '') +' />';
					h = (e.linkable) ? '<a href="'+a.attr("href")+'">'+h+'</a>' : h;
					$(i).load(function() {faviconizePlace(a, h);});
					$(i).error(function() {if(e.defaultImage) {faviconizePlace(a, h.replace(/src="(.*?)"/i, 'src="'+e.defaultImage+'"')); }});
				}
			}
		});
	}
})(jQuery);




/*******

 *** Anchor Slider by Cedric Dugas   ***
 *** Http://www.position-absolute.com ***
 
 Never have an anchor jumping your content, slide it.

 Don't forget to put an id to your anchor !
 You can use and modify this script for any project you want, but please leave this comment as credit.
 
*****/
(function($){     
jQuery.fn.anchorAnimate = function(settings) {

 settings = jQuery.extend({
     speed : 1100,
     callback : function(elem){}
 }, settings);
 
 
 return this.each(function(){     
     var caller = this
     $(caller).unbind('click').click(function (event) {
         event.preventDefault();                  
         var locationHref = window.location.href
         var elementClick = $(caller).attr("href");
         var destination = $(elementClick).offset().top;
         
         $("html:not(:animated),body:not(:animated)").animate(
           {scrollTop: destination}, 
           settings.speed, 
           function() {
             var re = new RegExp('#.*');
             var hash = $(caller).attr("href").match(re);
             window.location.hash = hash;
             console.log('anchor:', hash);
           }
         );         
         settings.callback(caller);
         return false;     
     })
 })
}
})(jQuery);