if (typeof Jx !== 'undefined') {
    Jx.Splitter.Snap.implement({
        initialize: function(snap, element, splitter, events) {
            this.snap = snap;
            this.element = element;
            var jxl = element.retrieve('jxLayout');
            jxl.addEvent('sizeChange', this.sizeChange.bind(this));
            this.splitter = splitter;
            this.layout = splitter.options.layout; 
            var jxo = jxl.options;
            var size = this.element.getContentBoxSize();
            if (this.layout == 'vertical') {
                this.originalSize = size.height;
                this.minimumSize = jxo.snapHeight ? jxo.snapHeight : 0;
            } else {
                this.originalSize = size.width;
                this.minimumSize = jxo.snapHeight ? jxo.snapHeight : 0;
            }
            events.each(function(eventName) {
                snap.addEvent(eventName, this.toggleElement.bind(this));
            }, this);
        }
    });
}

    sprintfWrapper = {
    
        init: function() {
     
    		if (typeof arguments == "undefined") { return null; }
    		if (arguments.length < 1) { return null; }
    		if (typeof arguments[0] != "string") { return null; }
    		if (typeof RegExp == "undefined") { return null; }
     
    		var string = arguments[0];
    		var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
    		var matches = new Array();
    		var strings = new Array();
    		var convCount = 0;
    		var stringPosStart = 0;
    		var stringPosEnd = 0;
    		var matchPosEnd = 0;
    		var newString = '';
    		var match = null;
     
    		while (match = exp.exec(string)) {
    			if (match[9]) { convCount += 1; }
     
    			stringPosStart = matchPosEnd;
    			stringPosEnd = exp.lastIndex - match[0].length;
    			strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
     
    			matchPosEnd = exp.lastIndex;
    			matches[matches.length] = {
    				match: match[0],
    				left: match[3] ? true : false,
    				sign: match[4] || '',
    				pad: match[5] || ' ',
    				min: match[6] || 0,
    				precision: match[8],
    				code: match[9] || '%',
    				negative: parseInt(arguments[convCount]) < 0 ? true : false,
    				argument: String(arguments[convCount])
    			};
    		}
    		strings[strings.length] = string.substring(matchPosEnd);
     
    		if (matches.length == 0) { return string; }
    		if ((arguments.length - 1) < convCount) { return null; }
     
    		var code = null;
    		var match = null;
    		var i = null;
     
    		for (i=0; i<matches.length; i++) {
     
    			if (matches[i].code == '%') { substitution = '%' }
    			else if (matches[i].code == 'b') {
    				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
    				substitution = sprintfWrapper.convert(matches[i], true);
    			}
    			else if (matches[i].code == 'c') {
    				matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
    				substitution = sprintfWrapper.convert(matches[i], true);
    			}
    			else if (matches[i].code == 'd') {
    				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
    				substitution = sprintfWrapper.convert(matches[i]);
    			}
    			else if (matches[i].code == 'f') {
    				matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
    				substitution = sprintfWrapper.convert(matches[i]);
    			}
    			else if (matches[i].code == 'o') {
    				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
    				substitution = sprintfWrapper.convert(matches[i]);
    			}
    			else if (matches[i].code == 's') {
    				matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
    				substitution = sprintfWrapper.convert(matches[i], true);
    			}
    			else if (matches[i].code == 'x') {
    				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
    				substitution = sprintfWrapper.convert(matches[i]);
    			}
    			else if (matches[i].code == 'X') {
    				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
    				substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
    			}
    			else {
    				substitution = matches[i].match;
    			}
     
    			newString += strings[i];
    			newString += substitution;
     
    		}
    		newString += strings[i];
     
    		return newString;
     
    	},    
    
    	convert: function(match, nosign){
    		if (nosign) {
    			match.sign = '';
    		} else {
    			match.sign = match.negative ? '-' : match.sign;
    		}
    		var l = match.min - match.argument.length + 1 - match.sign.length;
    		var pad = new Array(1 < 0 ? 0 : l).join(match.pad);
    		if (!match.left) {
    			if (match.pad == "0" || nosign) {
    				return match.sign + pad + match.argument;
    			} else {
    				return pad + match.sign + match.argument;
    			}
    		} else {
    			if (match.pad == "0" || nosign) {
    				return match.sign + match.argument + pad.replace(/0/g, ' ');
    			} else {
    				return match.sign + match.argument + pad;
    			}
    		}
    	}
    }
     
    sprintf = sprintfWrapper.init;




dbug = {};

dbug.startStamp = new Date();
dbug.lastStamp = dbug.startStamp;


dbug.log = function() {
    if (window.console) {
        Array.unshift(arguments, new Date() - dbug.lastStamp);
        console.log.apply(console, arguments );
        dbug.lastStamp = new Date();
    }
}
/**
 * Class: Mx
 * Mx is a global singleton object that contains the entire Mx library
 * within it.  All Mx functions, attributes and classes are accessed
 * through the global Mx object.  Mx should not create any other
 * global variables, if you discover that it does then please report
 * it as a bug
 *
 * License: 
 * Copyright (c) 2008, Daniel Barth.
 * 
 * This file is licensed under an MIT style license
 */

if (typeof Mx === 'undefined') {
    var Mx = {};
    (function() {
        var source = $$('script[src$=mxlib.js]').shift();
        if (source) {
            var u = new URI(source.src);
            Mx.Base =  u.get('scheme')+ "://" + u.get('host') + u.get('directory');
        }
    })();    
} 


if (typeof document.id === 'undefined') {
    document.id = $;
}

Class.Mutators.Delegates = function(self,flag) {
    var delegate = function(method, target) {
        this[method] = target[method].bind(target, arguments);
        //this[method] = target.bind(target, arguments);
        //if (typeof target == 'array') {
        //    this[method] = target[tgtMethod].bind(target, arguments);
        //}
        //else {
        //
        //}
    }
    if ($defined(flag)){
        self.delegateMethod = delegate.bind(self);
        return self;
    }
    else {   
        this.implement({'delegateMethod':delegate});
    }
};

Mx.Css = new Class({
    
    Implements: [Options],
    
    options: {
        group: 'default'    
    },
    
    initialize: function() {
        this.setOptions(arguments[1]||{});
        var dxSource = $$('script[src$=mxlib.js]').shift();
        if (dxSource) {
            this.href = new URI(dxSource.src).get('directory')+arguments[0];
            this.domObj = new Element('link',{
                'href': this.href,
                'type': 'text/css',
                'media': 'screen',
                'rel': 'stylesheet'
            }).inject( dxSource, 'before');
            this.domObj.store('group',this.options.group);
        }
    },
    
    enable: function() {
        $$('link').each(function(link) {
            if (link.getAttribute('rel').indexOf("style") != -1 && link.retrieve('group') == this.options.group) {
                link.disabled = link.getAttribute('href').indexOf(this.href) != -1 ? true : false;
            }
        });
        window.fireEvent('stylesheetChanged');
    },
    
    disable: function() {
        this.domObj.disable = true;
        window.fireEvent('stylesheetChanged');
    }
    
});  

Mx.defaultStyleSheet = new Mx.Css("css/mxlib.css");

Element.implement({

    isVisible: function(){
        return (this.offsetWidth > 0 || this.offsetHeight > 0);
    },
    
    enableOverflow: function() {
        if (!this.retrieve('mx:overflow')){
            this.store('mx:overflow',this.getStyle('overflow'));
        }
        this.setStyle("overflow","auto");
    },
    
    disableOverflow: function() {
       if (!this.retrieve('mx:overflow')){
           this.store('mx:overflow',this.getStyle('overflow'));
       }       
       this.setStyle("overflow","hidden");
    },
    
    restoreOverflow: function() {
       if (this.retrieve('mx:overflow')){
           this.setStyle("overflow",this.retrieve('mx:overflow'));
       }    
    }
});

Function.implement({
	bindWithDelay: function(delay, bind, args){
		return this.create({bind: bind, arguments: args, delay: delay});
	}    
});

String.implement({
    left: function(n) {
        if (n > 0) {
            return this.substr(0,n);
        }
        else {
            return this.substr(0,this.length+n);
        }
    }
});

String.implement({
    toElement: function() {
      var tagInfo = this.match(/<(\S*)([^>]*)>(.*)\<\/\1>/);
      if(tagInfo) {
        var tag = tagInfo[1],
            attributes = "{" + tagInfo[2].replace(/(\S*)=(['"\\]?)([^'"\\]*)\2\s?/g, "\"$1\":\"$3\",").left(-1) + "}", /*#'\'"*/
            html = tagInfo[3];
        return new Element(tag, JSON.decode(attributes)).set('html',html);
      } else return new Element("div").setHTML(this);
    },
    toElements: function() {
      var tags = this.match(/\<(\S*)\>([^<>]*)\<\/\1>/g), elements = [];
      if(tags) {
        for(var i = 0; i < tags.length; i++) {
          var element = tags[i].toElement();
          if(element) elements.push(element);
        }
        return elements;
      } else return [this.toElement()];
    },
    injectBefore: function(element) {
      this.toElements().each(function(item) {
        item.injectBefore(element);
      });
    },
    injectAfter: function(element) {
      this.toElements().each(function(item) {
        item.injectAfter(element);
      });
    },
    injectInside: function(element) {
      this.toElements().each(function(item) {
        item.injectInside(element);
      });
    },
    injectTop: function(element) {
      this.toElements().each(function(item) {
        item.injectTop(element);
      });
    }
});
 
Element.implement({
    appendTopHTML: function(html) {
      this.setHTML(html + this.innerHTML);
    },
    appendHTML: function(html) {
      this.setHTML(this.innerHTML + html);
    }
});


Element.implement({
    bindEvents: function(target, namespace, args) {
        var elements = this.getElements("[evt]");
        if (this.get('evt')) {
            elements.push(this);
        }
        elements.each(function(e) {
            e.get('evt').split(',').each(function(evt) {
                var method = 'on'+namespace.capitalize()+evt.camelCase().capitalize();
                if (target[method]) {
                    args = $splat(args); args.push(e);
                    e.addEvent(evt,target[method].bind(target,args));
                    e.removeAttribute('evt');
                }
            });
        });
        return this;
    }
});

Array.implement({
    
    /**
     * Method: swap
     * swaps 2 elements of an array
     * 
     * Parameters:
     * a - the first position to swap
     * b - the second position to swap
     */
    'swap': function(a,b){
        var temp;
        temp = this[a];
        this[a] = this[b];
        this[b] = temp;
    }
    
});

Element.implement({
	empty_: function(){
	    if (Browser.Engine.Trident) {
    		$A(this.childNodes).each(function(node){
	    		Element.destroy(node);
	    	});
	    }
	    else {
	        this.innerHTML = '';
	    }
		return this;
	}
});

Function.implement({
	wait: function(delay, bind, args) {
		var self = this; 
		var options = {bind: bind, delay: delay, arguments: args};
		$clear(self.timer);
			var args = options.arguments;
			args = (args != undefined) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0);
			//if (options.event) args = [event || window.event].extend(args);
			var returns = function(){
				return self.apply(options.bind || null, args);
			};
			self.timer = setTimeout(returns, options.delay);
			return self.timer;
	}

});

(function() {

    var after = function(context, element){
		if (!element.parentNode) return;
		var next = element.nextSibling;
		(next) ? element.parentNode.insertBefore(context, next) : element.parentNode.appendChild(context);
	};

    var substitute = function(node,object) {
        var txt = node.nodeValue;
        var results = node.nodeValue.match((/\\?\{([^{}]+)\}/g));
        if (results != null) {
            var tempNode = document.createElement('div');        
		    results.each(function(match) {
    		    tempNode.appendChild(  document.createTextNode ( txt.substring(0,txt.indexOf(match)) ) );
	    	    var name = match.slice(1,match.length-1);
	    	    if (object[name]) {
	    	        tempNode.appendChild( document.id(object[name]) );
	    	    }
	    	    tempNode.appendChild(  document.createTextNode ( txt.substring(txt.indexOf(match)+match.length) ) );
	    	    txt = txt.substring(txt.indexOf(match)+match.length);
	    	});

    		for (var i = tempNode.childNodes.length - 1 ; i >= 0 ; i--) {
                after(tempNode.childNodes[i],node);
	    	}
	    	node.parentNode.removeChild(node);
    		tempNode = null;
        }
    }

    var fn = function(struct,object) {
    	if ($type(struct) == "element") {
			if (struct.nodeType == 3) {
                substitute(struct,0);
			}
			else if (struct.nodeType == 8) {
			
			}			
			else {
				fn(struct.childNodes,object);
			}			
    	}
    	else if ($type(struct) == "collection") {
    		for (var i = 0; i < struct.length; i++) {
    			var e = struct[i];
				if (e.nodeType == 3) {
					substitute(e,object)
				}
    			else if (e.nodeType == 8) {
    			
    			}				
			    else {
    				fn(e,object);
	    		}					
    		}
    	}
    }
    
    Element.implement({
        substitute: function(object) {
            object = $merge(object);
            for (var i in object) {
                if (typeof object[i] == "string") {
                    object[i] = document.createTextNode(object[i]);
                }
            }
            fn(this,object);
            return this; 
        }            
    });

})();

(function() {
    /* Use this function with caution, because it can slow down your application dramatically */
    Element.Events.render = {
        onAdd: function() {
            var returns = function() {
                if (this.isVisible()) {
                    $clear(this.$timer);
                    this.$timer = null;
                    this.fireEvent('render');
                }
            }.bind(this);        
            this.$timer = setInterval(returns, 100);
        }
    };
})();

Element.implement({
    setRuntimeStyle: function() {
        var oStyle = this.get('oStyle');
        if (!oStyle) {
            this.store('oStyle',this.style.cssText);
        }
        this.setStyle.apply(this,arguments);   
    },
    
    clearRuntimeStyle: function() {
        var oStyle = this.retrieve('oStyle');
        if (oStyle) {
            this.style.cssText = oStyle;
            this.eliminate('oStyle');
        }
    }
});

IframeShim.implement({
	makeShim: function(){
		if(this.options.browsers){
			var zIndex = this.element.getStyle('zIndex').toInt();

			if (!zIndex){
				var pos = this.element.getStyle('position');
				if (pos == 'static' || !pos) this.element.setStyle('position', 'relative');
				this.element.setStyle('zIndex', zIndex || 1);
			}
			zIndex = ($chk(this.options.zIndex) && zIndex > this.options.zIndex) ? this.options.zIndex : zIndex - 1;
			if (zIndex < 0) zIndex = 1;
			this.shim = new Element('iframe', {
				//src: (window.location.protocol == 'https') ? '://0' : 'javascript:void(0)',
				src: '',
				scrolling: 'no',
				frameborder: 0,
				styles: {
					zIndex: zIndex,
					position: 'absolute',
					border: 'none',
					filter: 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'
				},
				'class': this.options.className
			}).store('IframeShim', this);
			var inject = (function(){
				this.shim.inject(this.element, 'after');
				this[this.options.display ? 'show' : 'hide']();
				this.fireEvent('inject');
			}).bind(this);
			if (Browser.Engine.trident && !IframeShim.ready) {
			    window.addEvent('domready', inject);
			}
			else inject();
		} else {
			this.position = this.hide = this.show = this.dispose = $lambda(this);
		}
	}
});

IframeShim.ready = false;


var Blanket = new Class({

	Implements: [Options, Events, Class.Occlude],

	options: {
		className: 'Blanket',
		display: false,
		zIndex: null,
		margin: 0,
		offset: {x: 0, y: 0},
		browsers: true || (Browser.Engine.trident4 || (Browser.Engine.gecko && !Browser.Engine.gecko19 && Browser.Platform.mac))
	},

	property: 'Blanket',

	initialize: function(element, options){
		this.element = $(element);
		if (this.occlude()) return this.occluded;
		this.setOptions(options);
		return this;
	},

	makeModal: function(){
		if(this.options.browsers){
			var zIndex = this.element.getStyle('zIndex').toInt();
			if (!zIndex){
				var pos = this.element.getStyle('position');
				if (pos == 'static' || !pos) this.element.setStyle('position', 'relative');
				this.element.setStyle('zIndex', zIndex || 1);
			}
			zIndex = ($chk(this.options.zIndex) && zIndex > this.options.zIndex) ? this.options.zIndex : zIndex - 1;
			if (zIndex < 0) zIndex = 1;
            this.blanket = new Element('div',{
                'class': this.options.className,
                styles:{
                    display:'none',
                    zIndex: zIndex,
                    position: 'absolute',
                    opacity: 0.8,
                    left: 0,
                    top: 0
                }
            }).store('Blanket',this);
            this.blanket.resize = (function() {
                var ss = $(document.body).getScrollSize();
                this.setStyles({
                    width: ss.x,
                    height: ss.y
                });
            }).bind(this.blanket);
            //this.options.parent.adopt(this.blanket);
            window.addEvent('resize', this.blanket.resize);
            			
			var inject = (function(){
				this.blanket.inject(this.element, 'after');
				this[this.options.display ? 'show' : 'hide']();
				this.fireEvent('inject');
			}).bind(this);
			if (Browser.Engine.trident && !IframeShim.ready) window.addEvent('load', inject);
			else inject();
		} else {
			this.position = this.hide = this.show = this.dispose = $lambda(this);
		}
	},

	hide: function(){
		if (this.blanket) this.blanket.setStyle('display', 'none');
		return this;
	},

	show: function(){
	    if (!this.blanket) {
	        this.makeModal();
        }
		if (this.blanket) {
		    this.blanket.resize();
		    this.blanket.setStyle('display', 'block');
		}
		//return this.position();
	},

	dispose: function(){
		if (this.shim) this.shim.dispose();
		return this;
	},

	destroy: function(){
		if (this.blanket) this.blanket.destroy();
		return this;
	}

});

Mx.Object = new Class({
	
    Implements: [Options, Events],
	
    Family: "Mx.Object",
	
	initialize: function(options){
        this.setOptions(options);
    }

});
if (typeof Jx != 'undefined') {

(function() { 

    var containerCount = 0;

    Mx.Container = new Class({
    
    	Extends: Mx.Object,

    	domObj: null,
    	
    	contentObj: null,
    	
    	options: {
    	    height: null,
    	    width: null,
    	    'class': null,
    	    display: true
    	},
    	
    	resizeStack: 0,
    	
        initialize: function(options){
    		this.parent(options);
    		
            //initialize the container
            this.domObj = new Element('div',{
                styles: {
                    overflow: 'hidden',
                    display: this.options.display ? 'block' : 'none'
                },
                id: this.getId()
            });
            
            if (this.options['class']) {
                this.domObj.addClass(this.options['class']);
            }
    
            var l = new Jx.Layout(this.domObj, $merge({
                onSizeChange: function() {
            	    this.resizeStack++;
            	    (function() {
            	        this.resizeStack--;
            	        if (this.resizeStack === 0) {
                            this.onSizeChange();
                        }
                    }).delay(10,this);            
                }.bind(this),
                height: this.options.height,
                width: this.options.width
            },this.options.layoutOptions || {}));
    
            if (this.options.parent) {
                this.addTo(this.options.parent);
            }
    
            if (this.options.width||this.options.height) {
                l.resize();
            }
            

            this.domObj.store('mxo',this);
            //this.position();
    
    	},	
    	
    	setContent: function(mixed, element) {
    	    element = element || this.contentObj || this.domObj;
    	    if ($type(mixed) == "string") {
    	        element.empty().set('html',mixed);
    	    }
    	    else if (mixed.toElement) {
    	        element.empty().adopt(mixed.toElement());
    	    }
    	},
    	
    	getLayout: function() {
    	    return this.domObj.retrieve('jxLayout');
    	},
    	
    	onSizeChange: function() {
    	},
    	
        /**
         * Method: position
         * positions an element relative to another element
         * based on the provided options.  Positioning rules are
         * a string with two space-separated values.  The first value
         * references the parent element and the second value references
         * the thing being positioned.  In general, multiple rules can be
         * considered by passing an array of rules to the horizontal and
         * vertical options.  The position method will attempt to position
         * the element in relation to the relative element using the rules
         * specified in the options.  If the element does not fit in the
         * viewport using the rule, then the next rule is attempted.  If
         * all rules fail, the last rule is used and element may extend
         * outside the viewport.  Horizontal and vertical rules are
         * processed independently.
         *
         * Horizontal Positioning:
         * Horizontal values are 'left', 'center', 'right', and numeric values.
         * Some common rules are:
         * o 'left left' is interpreted as aligning the left
         * edge of the element to be positioned with the left edge of the
         * reference element.  
         * o 'right right' aligns the two right edges.  
         * o 'right left' aligns the left edge of the element to the right of
         * the reference element.  
         * o 'left right' aligns the right edge of the element to the left
         * edge of the reference element.
         *
         * Vertical Positioning:
         * Vertical values are 'top', 'center', 'bottom', and numeric values.
         * Some common rules are:
         * o 'top top' is interpreted as aligning the top
         * edge of the element to be positioned with the top edge of the
         * reference element.  
         * o 'bottom bottom' aligns the two bottom edges.  
         * o 'bottom top' aligns the top edge of the element to the bottom of
         * the reference element.  
         * o 'top bottom' aligns the bottom edge of the element to the top
         * edge of the reference element.
         * 
         * Parameters:
         * element - the element to position
         * relative - the element to position relative to
         * options - the positioning options, see list below.
         *
         * Options:
         * horizontal - the horizontal positioning rule to use to position the 
         *    element.  Valid values are 'left', 'center', 'right', and a numeric
         *    value.  The default value is 'center center'.
         * vertical - the vertical positioning rule to use to position the 
         *    element.  Valid values are 'top', 'center', 'bottom', and a numeric
         *    value.  The default value is 'center center'.
         * offsets - an object containing numeric pixel offset values for the object
         *    being positioned as top, right, bottom and left properties.
         */
        position: function(options) {
            options = options || {};
            var element = this.domObj;
            var relative = document.id(options.relative || this.options.parent || document.body);
            var hor = $splat(options.horizontal || ['center center']);
            var ver = $splat(options.vertical || ['center center']);
            var offsets = $merge({top:0,right:0,bottom:0,left:0}, options.offsets || {});
            
            var coords = relative.getCoordinates(); //top, left, width, height
            var page;
            var scroll;
            if (!document.id(element.parentNode) || element.parentNode ==  document.body) {
                page = Jx.getPageDimensions();
                scroll = document.id(document.body).getScroll();
            } else {
                page = document.id(element.parentNode).getContentBoxSize(); //width, height
                scroll = document.id(element.parentNode).getScroll();
            }
            if (relative == document.body) {
                // adjust coords for the scroll offsets to make the object
                // appear in the right part of the page.
                coords.left += scroll.x;
                coords.top += scroll.y;            
            } else if (element.parentNode == relative) {
                // if the element is opening *inside* its relative, we want
                // it to position correctly within it so top/left becomes
                // the reference system.
                coords.left = 0;
                coords.top = 0;
            }
            var size = element.getMarginBoxSize(); //width, height
            var left;
            var right;
            var top;
            var bottom;
            var n;
            if (!hor.some(function(opt) {
                var parts = opt.split(' ');
                if (parts.length != 2) {
                    return false;
                }
                if (!isNaN(parseInt(parts[0],10))) {
                    n = parseInt(parts[0],10);
                    if (n>=0) {
                        left = n;                    
                    } else {
                        left = coords.left + coords.width + n;
                    }
                } else {
                    switch(parts[0]) {
                        case 'right':
                            left = coords.left + coords.width;
                            break;
                        case 'center':
                            left = coords.left + Math.round(coords.width/2);
                            break;
                        case 'left':
                        default:
                            left = coords.left;
                            break;
                    }                
                }
                if (!isNaN(parseInt(parts[1],10))) {
                    n = parseInt(parts[1],10);
                    if (n<0) {
                        right = left + n;
                        left = right - size.width;
                    } else {
                        left += n;
                        right = left + size.width;
                    }
                    right = coords.left + coords.width + parseInt(parts[1],10);
                    left = right - size.width;
                } else {
                    switch(parts[1]) {
                        case 'left':
                            left -= offsets.left;
                            right = left + size.width;
                            break;
                        case 'right':
                            left += offsets.right;
                            right = left;
                            left = left - size.width;
                            break;
                        case 'center':
                        default:
                            left = left - Math.round(size.width/2);
                            right = left + size.width;
                            break;
                    }                
                }
                return (left >= scroll.x && right <= scroll.x + page.width);
            })) {
                // all failed, snap the last position onto the page as best
                // we can - can't do anything if the element is wider than the
                // space available.
                if (right > page.width) {
                    left = scroll.x + page.width - size.width;
                }
                if (left < 0) {
                    left = 0;
                }
            }
            element.setStyle('left', left);
            
            if (!ver.some(function(opt) {
                    var parts = opt.split(' ');
                    if (parts.length != 2) {
                        return false;
                    }
                    if (!isNaN(parseInt(parts[0],10))) {
                        top = parseInt(parts[0],10);
                    } else {
                        switch(parts[0]) {
                            case 'bottom':
                                top = coords.top + coords.height;
                                break;
                            case 'center':
                                top = coords.top + Math.round(coords.height/2);
                                break;
                            case 'top':
                            default:
                                top = coords.top;
                                break;
                        }
                    }
                    if (!isNaN(parseInt(parts[1],10))) {
                        var n = parseInt(parts[1],10);
                        if (n>=0) {
                            top += n;
                            bottom = top + size.height;
                        } else {
                            bottom = top + n;
                            top = bottom - size.height; 
                        }
                    } else {
                        switch(parts[1]) {
                            case 'top':
                                top -= offsets.top;
                                bottom = top + size.height;
                                break;
                            case 'bottom':
                                top += offsets.bottom;
                                bottom = top;
                                top = top - size.height;
                                break;
                            case 'center':
                            default:
                                top = top - Math.round(size.height/2);
                                bottom = top + size.height;
                                break;
                        }                    
                    }
                    return (top >= scroll.y && bottom <= scroll.y + page.height);
                })) {
                    // all failed, snap the last position onto the page as best
                    // we can - can't do anything if the element is higher than the
                    // space available.
                    if (bottom > page.height) {
                        top = scroll.y + page.height - size.height;
                    }
                    if (top < 0) {
                        top = 0;
                    }
                }
                element.setStyle('top', top);
                
                /* update the jx layout if necessary */
                var jxl = element.retrieve('jxLayout');
                if (jxl) {
                    jxl.options.left = left;
                    jxl.options.top = top;
                }
        },	
        
        setBusy: function(msg) {
            element = document.id(this.domObj);
            if (!this.busy) {
                this.makeBusy();
            }
            if (Browser.Engine.trident4) {
                this.busy.setContentBoxSize(document.id(element).getBorderBoxSize());
            }        
            if (element && this.busy.parentNode !== element) {
                element.adopt(this.busy);
            }
        },
        
        setLazy: function() {
            if (this.busy) {
                this.busy.dispose();
            }
        },
        
        makeBusy: function() {
            var c = new Element('div', {
                'class':'mxBusy',
                styles: {
                    'opacity': 0.5
                },
                events: {
                    contextmenu: function(e) { e.stop(); }
                }      
            });
            this.busy = c;
        },
    	
        addTo: function(reference, where) {
            var el = document.id(this.addable) || document.id(this.domObj);
            if (el) {
                ref = document.id(reference);
                el.inject(ref,where);
                this.fireEvent('addTo',this);            
            }
            return this;
        },
        
        getId: function() {
            if (!$defined(this.options.id)) {
                ++containerCount;
                this.options.id = "Mx.Container."+containerCount;                
            }
            return this.options.id;
        },
        
        getInnerHeight: function() {
            return this.domObj.getContentBoxSize().height;
        },
        
        getInnerWidth: function() {
            return this.domObj.getContentBoxSize().width;
        },    
        	
        toElement: function() {
            return this.domObj;
        },
        
        isVisible: function() {
            return this.domObj.isVisible();
        }
    });

})()    

}
Mx.Map = new Class({
    Extends: Mx.Container,
    
    Family: "Mx.Map"    

});
Mx.GMap = new Class({

    Extends: Mx.Map,
    
    options: {
        onComplete: Class.empty,
        container: document.body,
        zoomLevel: 8,
        gmapType: 'map',
//        mapConfOpts: ['enableScrollWheelZoom','enableDoubleClickZoom','enableDragging'],
        mapConfOpts: ['enableDragging'],
        mapControls: ['GSmallMapControl','GMapTypeControl','NonExistantControl'],
        center: {
            lat:'50.93074', 
            lng:'10.30518'
        },               
        zoom: {
            min: 4,
            max: 16
        },
        viewPortPadding: 50,
        clusterIconSize: 55,
        iconPadding: 20,
        icons: [
            {
                image: Mx.Base + "css/images/marker.png",
                size: [35,35],
                anchor: [17,35],
                shadow: Mx.Base + "css/images/marker_shadow.png",
                shadowSize: [52,35],
                iconType: 'cluster',
                id: 'marker',
                range: 1
            },
            {
                image: Mx.Base + "css/images/m2.png",
                size: [56,55],
                anchor: [28,27],
                //shadow: Mx.Base + "/css/images/cluster_shadow.png",
                //shadowSize: [16,16],
                iconType: 'cluster',
                range: 15           
            },
            {
                image: Mx.Base + "css/images/m4.png",
                size: [78,77],
                anchor: [38,37],
                //shadow: Mx.Base + "/css/images/cluster_shadow.png",
                //shadowSize: [16,16],
                iconType: 'cluster',
                range: 80           
            }            
        ],
        clusteringEnabled: true        
    },
    
    overlays: [],
        
    markers: [],
    
    clusters: [],
    
    isBusy: false,
    
    clusterCache: [],
       
    initialize: function(options) {
        this.parent($extend(options,{
            icons: options.icons || this.options.icons
        }));
        this.gmap = new GMap2(this.domObj);
        this.setCenter();
        this.setResolution(this.options.zoom.min,this.options.zoom.max);      
        this.addMapControls();
        this.addOptions();  
        this.enableMarkerManager();
        this.fireEvent('onInitEnd');
    },
    
    getClusterIcons: function(nocash) {
        if (this.clusterIcons && !nocash) {
            return this.clusterIcons;
        }
        var ret = new Array();
        $each(this.options.icons,function(iconOptions) {
            if (iconOptions.iconType == "cluster") {
                ret.push(iconOptions);
            }
        });
        if (ret.length) {
            ret.sort(function (a, b) {
                a = a.range; b = b.range;
                return (a < b) - (a > b)
            })    
        }
        this.clusters = ret;
        return ret.length ? ret : false;        
    },
    
    getByRange: function(r) {
        var ret = null, clusters = this.getClusterIcons(); 
        clusters.each(function(iconOptions) {
            if (r <= iconOptions.range) {
                ret = iconOptions;
            }
        });
        if (ret == null) {
            return clusters[0];
        }    
        return ret;
    },    
    
    enableMarkerManager: function() {
    	GEvent.bind(this.getMap(), 'moveend', this, this.onMapMoveEnd);
	    GEvent.bind(this.getMap(), 'zoomend', this, function() {
	        this.closeInfoWindow();
	        this.fireEvent('onZoomEnd');
	    });
	    //GEvent.bind(this.getMap(), 'maptypechanged', this, this.onMapMoveEnd);        
    },
    
    onMapMoveEnd: function() {
        this.currentCenter = this.getCenterLatLng();
        if (this.options.clusteringEnabled) {
            this.redrawMarkers();
        }
    },
    
    setResolution: function(zmin,zmax) {
        // ====== Restricting the range of Zoom Levels =====
        var mt = this.gmap.getMapTypes();
        zmin = zmin == 0 ?  this.options.defaults.zoom.min : zmin;
        zmax = zmax == 0 ?  this.options.defaults.zoom.max : zmax;
        zmin = $type(zmin) == "number" ? zmin : zmin.toInt();
        zmax = $type(zmax) == "number" ? zmax : zmax.toInt();
        for (var i=0; i< mt.length; i++) {
            mt[i].getMinimumResolution = function() {return zmin }
            mt[i].getMaximumResolution = function() {return zmax }
        }
    },   
    
    addMarker: function(opts) {
        var len = this.markers.length;
        return this.markers.push({
            label:  opts.label,
            lat:    opts.lat,
            lng:    opts.lng,
            zoomLevelInformation: [],
            marker: opts.marker,
            indexes: [len]            
        });
    },
    
    clearMarkers: function() {
        this.overlays.each(function(ovl) {
            this.gmap.removeOverlay(ovl);
        },this);
        this.markers = [];
        this.clusterCache = [];
    },
    
    getCurrentMarkers: function() {
        var ret = [];
        this.markers.each(function(marker, index) {
            if (this.options.clusteringEnabled) {
                var zli = marker.zoomLevelInformation[this.getMap().getZoom()];
                if ($defined(zli)) {
                    if (zli.visible) {
                        ret.push({
                            label: marker.label,
                            nodes: zli.nodes,
                            icon:  zli.icon,
                            marker: marker.marker,
                            latitude: zli.latlng.lat(),
                            longitude: zli.latlng.lng(),
                            indexes: zli.indexes
                        });
                    }
                }
            }
            else {
                ret.push({
                    label: marker.label,
                    icon:  marker.icon,
                    marker: marker.marker,
                    latitude: marker.lat,
                    longitude: marker.lng,
                    indexes: [index]
                });
            }
        },this);
        return ret;
    },
    
    redrawMarkers: function() {
        if (this.isVisible()) {
            if (this.markers.length) {
                (function() {
                    this.setBusy();
                    this.fireEvent("onRedrawStart");
                    this.overlays.each(function(ovl) {
                        this.getMap().removeOverlay(ovl);
                    },this);
                    this.overlays = [];
                    if (this.options.clusteringEnabled) {
                        this.buildClusters(this.markers);
                        var bounds = this.getMap().getBounds();
                        this.markers.each(function(marker) {
                            var zli = marker.zoomLevelInformation[this.getMap().getZoom()];
                            if (zli.visible) {
                                if (bounds.containsLatLng(zli.latlng)) {
                                    zli.mm = marker;
                                    var m = new Mx.GMarker( zli , this);                                 
                                    this.getMap().addOverlay(m);
                                    this.overlays.push(m)
                                }
                            }
                        },this);
                    }
                    else {
                        var bounds = this.getMap().getBounds();
                        this.markers.each(function(marker) {
                            marker.latlng = new GLatLng(marker.lat,marker.lng);
                            marker.icon = this.options.icons[marker.marker] || this.options.icons['default'];
                            if (bounds.containsLatLng(marker.latlng)) {
                                var m = new Mx.GMarker( marker , this);                                 
                                this.getMap().addOverlay(m);
                                this.overlays.push(m)
                            }
                        },this);
                    }
                    this.setLazy();
                    this.fireEvent("onRedrawEnd");
                }).wait(10,this);
            }            
        }
    },
    
    getBounds: function(latlng, size, anchorOffset, padding) {
	    var projection = this.getMap().getCurrentMapType().getProjection();
	    padding = padding || 0;
	    var zoom = this.getMap().getZoom();
	    var iconAnchorPoint = projection.fromLatLngToPixel(latlng, zoom);
    	var iconAnchorPointOffset = {x: anchorOffset[0], y: anchorOffset[1] }
    	var iconBoundsPointSw = new GPoint(
    	    iconAnchorPoint.x - iconAnchorPointOffset.x - padding,
    	    iconAnchorPoint.y - iconAnchorPointOffset.y + size[1] + padding
        );
    	var iconBoundsPointNe = new GPoint(
    	    iconAnchorPoint.x - iconAnchorPointOffset.x + size[0] + padding, 
    	    iconAnchorPoint.y - iconAnchorPointOffset.y - padding
        );
    	var iconBoundsLatLngSw = projection.fromPixelToLatLng(iconBoundsPointSw, zoom);
    	var iconBoundsLatLngNe = projection.fromPixelToLatLng(iconBoundsPointNe, zoom);
    	return new GLatLngBounds(iconBoundsLatLngSw, iconBoundsLatLngNe);
    },
    
    buildClusters: function(clusters, zoom) {
        var zoom = this.getMap().getZoom();    
        if (this.clusterCache[zoom]) {
            return;
        }
        
        for (i = clusters.length - 1; i >= 0; i--) {
    	    if (!$defined(clusters[i].zoomLevelInformation[zoom])) {
    	        clusters[i].zoomLevelInformation[zoom] = {
    	            disabled: false,
    	            visible:  true,
    	            bounds:   null,
    	            latlng:   new GLatLng(clusters[i].lat,clusters[i].lng),
    	            icon:     this.options.icons[clusters[i].marker] || this.options.icons['default'],
    	            nodes:    1,
    	            indexes:  [i]
    	        }
    	    }            
        }
        
        var intersectDetected = true;
        var run = 0;      
        while (intersectDetected) {
            intersectDetected = false;
            var nc = 0;
        	for (i = clusters.length - 1; i>=0; i--) {
                if (clusters[i].zoomLevelInformation[zoom].disabled !== true) {
                    ++nc;
                    
            	    if (!clusters[i].zoomLevelInformation[zoom].bounds) {
            	        clusters[i].zoomLevelInformation[zoom].bounds = this.getBounds(clusters[i].zoomLevelInformation[zoom].latlng, clusters[i].zoomLevelInformation[zoom].icon.size, clusters[i].zoomLevelInformation[zoom].icon.anchor);
            	    }
                    for (j = i - 1; j >= 0; j--) {
                        if (clusters[j].zoomLevelInformation[zoom].disabled !== true) {
                    	    if (!clusters[j].zoomLevelInformation[zoom].bounds) { 
                    	        clusters[j].zoomLevelInformation[zoom].bounds = this.getBounds(clusters[j].zoomLevelInformation[zoom].latlng,clusters[j].zoomLevelInformation[zoom].icon.size, clusters[j].zoomLevelInformation[zoom].icon.anchor);
                    	    }                    
            				if (clusters[i].zoomLevelInformation[zoom].bounds.intersects(clusters[j].zoomLevelInformation[zoom].bounds)) {
            				    intersectDetected = true;
            					clusters[i].zoomLevelInformation[zoom].bounds.extend(clusters[j].zoomLevelInformation[zoom].bounds.getSouthWest())
            					clusters[i].zoomLevelInformation[zoom].bounds.extend(clusters[j].zoomLevelInformation[zoom].bounds.getNorthEast())
                                clusters[j].zoomLevelInformation[zoom].disabled = true;
                                clusters[j].zoomLevelInformation[zoom].visible  = false;
            					clusters[i].zoomLevelInformation[zoom].nodes   += clusters[j].zoomLevelInformation[zoom].nodes.toInt();
            					if (clusters[j].zoomLevelInformation[zoom].indexes) {
            					    clusters[i].zoomLevelInformation[zoom].indexes.combine(clusters[j].zoomLevelInformation[zoom].indexes);
            					}
            					else {
            					    clusters[i].zoomLevelInformation[zoom].indexes.push(j);
            					}
            					
            					var icon = this.getByRange(clusters[i].zoomLevelInformation[zoom].nodes);
            					clusters[i].zoomLevelInformation[zoom].icon     = icon;
              					clusters[i].zoomLevelInformation[zoom].latlng   = clusters[i].zoomLevelInformation[zoom].bounds.getCenter();
            					clusters[i].zoomLevelInformation[zoom].bounds   = this.getBounds(clusters[i].zoomLevelInformation[zoom].latlng,icon.size,icon.anchor);
            				}
        				}
        			}
    			}
           	}
        	++run;
        	if (run>5){
        	    break;
        	}
        }
        this.clusterCache[zoom] = true;
    },
    
    openInfoWindow: function(lat,lng,contentElement,offset) {
        offset = offset || {x: 0, y: 0}
        this.closeInfoWindow();
        this.getMap().openInfoWindow( new GLatLng(lat,lng), contentElement, {pixelOffset: new GSize(offset.x, offset.y) }); 
    }, 

    closeInfoWindow: function() {
        this.getMap().closeInfoWindow(); 
    }, 

       
    setSize: function(width, height, animate){
        if (typeof this.getMap() == 'object') {
            this.gmap.checkResize();
        }
    },
    
    getMap: function(){
        return this.gmap;
        
    },
    
    getCenter: function(){
        return this.getMap().getCenter();
    },
    
    getCenterLatLng: function(){
        var ll = this.getCenter();
        return {lat: ll.lat(), lng: ll.lng()};
    },

    addMapControls: function(){
        if (this.options.gmapType === 'map') {
            if ($type(this.options.mapControls) == "array") {
                for(i=0;i<this.options.mapControls.length;i++){
                    this.addMapControl(this.options.mapControls[i]);
                }
            }else if(typeof this.options.mapControls === 'string'){
                this.addMapControl(this.options.mapControls);
            }else if(typeof this.options.mapControls === 'object'){
                this.getMap().addControl(this.options.mapControls);
            }
        }
        
    },
    
    addMapControl: function(mc){
        var mcf = window[mc];
        if (typeof mcf === 'function') {
            this.getMap().addControl(new mcf());
        }    
        
    },
    
    addOptions: function(){
        if ($type(this.options.mapConfOpts) == "array") {
            var mc;
            for(i=0;i<this.options.mapConfOpts.length;i++){
                this.addOption(this.options.mapConfOpts[i]);
            }
        }else if(typeof this.options.mapConfOpts === 'string'){
            this.addOption(this.options.mapConfOpts);
        }        
        
    },
    
    addOption: function(mc){
        var mcf = this.getMap()[mc];
        if (typeof mcf === 'function') {
            this.getMap()[mc]();
        }    
    },
    
    setCenter: function(obj, zoom) {
        obj = obj || this.options.center;
        //autoCenter = $defined(autoCenter) ? autoCenter : true;
        var point = new GLatLng(obj.lat,obj.lng);
        this.getMap().setCenter(point, $pick(zoom,this.gmap.getZoom() || this.options.zoomLevel));
        this.currentCenter = obj;
    },
    
	onSizeChange: function() {
        if (typeof this.getMap() == 'object') {
            this.getMap().checkResize();        
            this.setCenter(this.currentCenter);
        }	
	}
});
Mx.GMarker = new Class({
    //Extends: GOverlay,
    Delegates: true,
    
    initialize: function( options, MxGMap)  {
        this.options = options;
        this.initialize = this.init;
        this.MxGMap = MxGMap;
    },
    
    init: function(map) {
        var icon = this.options.icon;
        this.map = map;
		this.div = new Element('div', {
		    styles: {
		        width: icon.size[0],
		        height: icon.size[1],
		        backgroundImage: 'url('+icon.image+')',
		        textAlign: 'center',
		        lineHeight: icon.size[1],
		        backgroundPosition: (icon.offset[0] || 0 )+ "px "+ (icon.offset[1]|| 0) +"px",
		        fontSize: '9px',
		        fontWeight: 'bold',
		        backgroundRepeat: 'no-repeat',
		        position: 'absolute'
		    }
		});
		
		if (Browser.Engine.trident) {
		    this.div.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+icon.image+"',sizingMethod='scale')";
		    this.div.style.backgroundImage = '';
		}
				      
		if (icon.iconType == "cluster") {
		    this.info = [
		        new Element('div',{
		            styles: {
        		        paddingLeft: icon.capWidth||0,
        		        height: icon.textImageSize[1]||'auto',
        		        backgroundImage: 'url('+icon.textImageL+')',
        		        textAlign: 'center',
        		        lineHeight: icon.textImageSize[1],
        		        backgroundPosition: (icon.textImageOffset[0]||0) + "px "+ (icon.textImageOffset[1]||0)+"px",
        		        fontSize: '9px',
        		        fontWeight: 'bold',
        		        backgroundRepeat: 'no-repeat',
        		        color: icon.textImageColor,
        		        position: 'absolute',
        		        left: icon.textImageAnchor[0]||0,
        		        top: icon.textImageAnchor[1]||0
		            }
		        }),
		        new Element('div',{
		            styles: {
        		        paddingRight: icon.capWidth||0,
        		        height: icon.textImageSize[1]||'auto',
        		        backgroundImage: 'url('+icon.textImageR+')',
        		        textAlign: 'center',
        		        lineHeight: icon.textImageSize[1],
        		        backgroundPosition: "right "+ (icon.textImageOffset[1]||0)+"px",
        		        fontSize: '9px',
        		        fontWeight: 'bold',
        		        backgroundRepeat: 'no-repeat',
        		        color: icon.textImageColor
		            }
		        }),		          
		        new Element('div',{
		            styles: {
        		        width: icon.textImageSize[0]||'auto',
        		        height: icon.textImageSize[1]||'auto',
        		        backgroundImage: 'url('+icon.textImage+')',
        		        textAlign: 'center',
        		        lineHeight: icon.textImageSize[1],
        		        backgroundPosition: (icon.textImageOffset[0]||0) + "px "+ (icon.textImageOffset[1]||0)+"px",
        		        fontSize: '9px',
        		        fontWeight: 'bold',
        		        backgroundRepeat: 'no-repeat',
        		        color: icon.textImageColor
		            },
		            html: this.options.indexes.length		            
		        })	          
            ];
            this.div.adopt(this.info[0].adopt(this.info[1].adopt(this.info[2])));
		}	        
        
        
        this.getMap().getPane(G_MAP_MARKER_PANE ).appendChild(this.div);
        var zli = this.options; var MxGMap = this.MxGMap;
        this.div.addEvent('click',function() {
            MxGMap.fireEvent('onMarkerClick', {
                nodes: zli.nodes,
                icon:  zli.icon,
                latitude: zli.latlng.lat(),
                longitude: zli.latlng.lng(),
                indexes: zli.indexes
            })
        });
    },
    
    remove: function() {
        this.div.dispose();
    },
    
    copy: function() {
//      return new Rectangle(this.bounds_, this.weight_, this.color_,
//                           this.backgroundColor_, this.opacity_);
    },
    
    // Redraw the rectangle based on the current projection and zoom level
    redraw: function(force) {
        //return;
      // We only need to redraw if the coordinate system has changed
        if (!force) return;

        var icon = this.options.icon;        
        var pos = this.getMap().fromLatLngToDivPixel(this.options.latlng)
        this.div.setStyles({left:pos.x - (icon.anchor[0]||0), top: pos.y- (icon.anchor[1]||0)});
    },
    
    getMap: function() {
        return this.map;
    }      
});

/*	SWFObject v2.2 <http://code.google.com/p/swfobject/> 
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> 
*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();/* ************************************************************************************* *\
 * The MIT License
 * Copyright (c) 2007 Fabio Zendhi Nagao - http://zend.lojcomm.com.br
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this
 * software and associated documentation files (the "Software"), to deal in the Software
 * without restriction, including without limitation the rights to use, copy, modify,
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies
 * or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
\* ************************************************************************************* */

var iCarousel = new Class({
	options: {
		animation: {
			type: "fadeNscroll",// fadeNscroll, scroll, fade
			direction: "left",// if type = scroll, set: top || left
			amount: 1,// if type = scroll, set the amount to scroll
			transition: Fx.Transitions.Cubic.easeInOut,
			duration: 500,
			rotate: {
				type: "manual",// auto || manual
				interval: 5000,// if type = auto, set the interval (ms)
				onMouseOver: "stop"// if type = auto, set the onmouseover behavior: stop || proceed
			}
		},

		item: {
			klass: "item",
			size: 100
		},

		idPrevious: "previous",
		idNext: "next",
		idToggle: "toggle",

		onClickPrevious: Class.empty,
		onClickNext: Class.empty,
		onPrevious: Class.empty,
		onNext: Class.empty,
		onGoTo: Class.empty
	},

	initialize: function(container, options) {
		this.setOptions(options);
		this.container = $(container);
		this.aItems = $A($$('.'+ this.options.item.klass));
		this.isMouseOver = false;
		
		var i = 0;
		this.container.getChildren().each(function(){i++;});
		if (i < 2) {
	        $(this.options.idPrevious).setStyle("display","none");
	        $(this.options.idNext).setStyle("display","none");
		} else {
		
		
		
		if(this.options.idPrevious != "undefined" && $(this.options.idPrevious))
			$(this.options.idPrevious).addEvent("click", function(event) {
				new Event(event).stop();
				this._previous();
				this.fireEvent("onClickPrevious", this, 20);
			}.bind(this));// check if value is not "undefined" before start search the dom with $()
		if(this.options.idNext != "undefined" && $(this.options.idNext))
			$(this.options.idNext).addEvent("click", function(event) {
				new Event(event).stop();
				this._next();
				this.fireEvent("onClickNext", this, 20);
			}.bind(this));
		if(this.options.idToggle != "undefined" && $(this.options.idToggle))
			$(this.options.idToggle).addEvent("click", function(event) {new Event(event).stop(); this._toggle()}.bind(this));

		var oAn = this.options.animation; // short hand
		switch(this.options.animation.type.toLowerCase()) {
			case "fade":
				this.aItems.each(function(item) {
					item.fx = item.effect("opacity", {duration: oAn.duration, transition: oAn.transition});
					item.setStyle("opacity", 0);
					item.addEvents({
						"mouseenter": function() {
							this.isMouseOver = true;
							if(this.options.animation.rotate.type == "auto") this.timer = $clear(this.timer);
						}.bind(this),
						"mouseleave": function() {
							this.isMouseOver = false;
							if(this.options.animation.rotate.type == "auto") this.timer = this._autoRotate.periodical(this.options.animation.rotate.interval, this);
						}.bind(this)
					});
				}.bind(this));
				this.height = this.container.getStyle("height").toInt();
				this.atScreen = 0;
				this._animate(this.atScreen);
				break;

			default:
				(2).times(function() {
					this.aItems.each(function(item) {
						item.clone().injectInside(this.container);
					}.bind(this));
				}.bind(this));
				this.aItems = $A($$('.'+ this.options.item.klass));
				this.aItems.each(function(item) {
					item.addEvents({
						"mouseenter": function() {
							this.isMouseOver = true;
							if(this.options.animation.rotate.type == "auto") this.timer = $clear(this.timer);
						}.bind(this),
						"mouseleave": function() {
							this.isMouseOver = false;
							if(this.options.animation.rotate.type == "auto") this.timer = this._autoRotate.periodical(this.options.animation.rotate.interval, this);
						}.bind(this)
					});
				}.bind(this));
				this.fx = new Fx.Morph(this.container, {duration: oAn.duration, transition: oAn.transition, wait: false});
				// this.fx = this.container.effects({duration: oAn.duration, transition: oAn.transition, wait: false});
				this.atScreen = this.aItems.length / 3;
				this.container.setStyle(oAn.direction, - this.atScreen * this.options.item.size);
				break;
		}

		if(this.options.animation.rotate.type == "auto") this.timer = this._autoRotate.periodical(this.options.animation.rotate.interval, this);
		
		}
	},

	goTo: function(n) {
		switch(this.options.animation.type.toLowerCase()) {
			case "fade":
				var lastIndex = this.atScreen;
				this.atScreen = Math.abs(n % (this.aItems.length / 3));
				this._animate(this.atScreen, lastIndex);
				break;

			default:
				this.atScreen = Math.abs(n % (this.aItems.length / 3));
				this.atScreen += this.aItems.length / 3;
				this._animate(this.atScreen);
				break;
		}

		this.fireEvent("onGoTo", this, 20);
	},

	_previous: function() {
		switch(this.options.animation.type.toLowerCase()) {
			case "fade":
				var lastIndex = this.atScreen;
				this.atScreen -= this.options.animation.amount;
				if(this.atScreen < 0) this.atScreen = (this.aItems.length - 1);
				this._animate(this.atScreen, lastIndex);
				break;

			default:
				this.atScreen -= this.options.animation.amount;
				if(this.atScreen < this.aItems.length / 3) {
					this.container.setStyle(this.options.animation.direction, - this.options.item.size * this.aItems.length * 2 / 3);
					this.atScreen = this.aItems.length * 2 / 3 - this.options.animation.amount;
				}
				this._animate(this.atScreen);
				break;
		}

		this.fireEvent("onPrevious", this, 20);
	},

	_next: function() {
		switch(this.options.animation.type.toLowerCase()) {
			case "fade":
				var lastIndex = this.atScreen;
				this.atScreen += this.options.animation.amount;
				if(this.atScreen >= this.aItems.length) this.atScreen = 0;
				this._animate(this.atScreen, lastIndex);
				break;

			default:
				this.atScreen += this.options.animation.amount;
				if(this.atScreen > this.aItems.length * 2 / 3) {
					this.container.setStyle(this.options.animation.direction, - this.options.item.size * this.aItems.length / 3);
					this.atScreen = this.aItems.length / 3 + this.options.animation.amount;
				}
				this._animate(this.atScreen);
				break;
		}

		this.fireEvent("onNext", this, 20);
	},

	_toggle: function() {
		(this.container.getStyle("height").toInt() == 0) ?
			this.container.effect("height", { duration:1000, transition: Fx.Transitions.Sine.easeInOut }).start(this.height):
			this.container.effect("height", { duration:1000, transition: Fx.Transitions.Sine.easeInOut }).start(0);
	},

	_autoRotate: function() {
		if(this.options.animation.rotate.onMouseOver == "stop" && !this.isMouseOver) this._next();
	},

	_animate: function(a, b) {
		switch(this.options.animation.type) {
			case "fade":
				if($defined(b)) {
					this.aItems[b].fx.start(0).chain(function() {
					this.aItems[a].fx.start(1);}.bind(this));
				} else {
					this.aItems[a].fx.start(1);
				}
				break;

			case "scroll":
				var that = this;
				if(that.options.animation.direction == "top") {
					that.fx.start({"top" : - a * that.options.item.size});
				} else {
					that.fx.start({"left" : - a * that.options.item.size});
				}
				break;

			case "fadeNscroll":
				var that = this;
				if(that.options.animation.direction == "top") {
					that.fx.start({"opacity":0.75}).chain(function() {
						that.fx.start({"top" : - a * that.options.item.size}).chain(function() {
							that.fx.start({"opacity": 1});
						});
					});
				} else {
					that.fx.start({"opacity":0.75}).chain(function() {
						that.fx.start({"left" : - a * that.options.item.size}).chain(function() {
							that.fx.start({"opacity": 1});
						});
					});
				}
				break;
		}
	}
});
iCarousel.implement(new Events); // Implements addEvent(type, fn), fireEvent(type, [args], delay) and removeEvent(type, fn)
iCarousel.implement(new Options);// Implements setOptions(defaults, options)
var MootoolsHelper = {};

MootoolsHelper.parseExternalLinks = function() {

    var links = $$('a.externalLink');
    $each(links, function(link) {
        if (!link.onclick) {
            link.onclick = function(event){
                pageTracker._trackPageview("/externalLink/" + link.getProperty('href') );
            }
        }
    });
}

MootoolsHelper.recommendOffer = function(offerUrl) {

    var popup = new Popup ({
        width: 500,
        height: 260,
        url: '/ajax/recommend-form/' + offerUrl,
        parent: document.body,
        onClose: null
    });
    
    popup.open();
}

MootoolsHelper.openPopup = function(url,width,height,callback) {
    
}

var Popup = new Class({

    Extends: Mx.Container,
    
    options: {
        display: false
    },
    
    initialize: function(options) {
        this.parent(options);
        
        this.shim = new IframeShim(this.domObj);
        this.blanket = new Blanket(this.domObj);
                
        this.domObj.setStyles({
            border: '1px solid black',
            backgroundColor: '#333333'
        });
        
        this.toolbarObj = new Element('div',{
            styles: {
                margin: '5px 5px 5px 5px',
                color: 'white'
            },
            align: 'right'   
        }).inject(this.domObj);
        
        new Jx.Button({
          type: 'CustomButton',
          label: 'Schliessen',
          image: Jx.aPixel.src,
          tooltip: 'Schliessen',
          onClick: this.close.bind(this)
        }).addTo(this.toolbarObj);
        
        this.contentObj = new Element('div',{
            styles: {
                margin: '15px 5px 5px 5px',
                backgroundColor: 'white'
            }
        }).inject(this.domObj);
        
        new Jx.Layout(this.contentObj, {top:25}).resize();
                
        var myRequest = new Request({
            url: this.options.url || null,
            method: 'GET',
            data: this.options.data || {}, 
            onSuccess: function(responseText, responseXML) {
                this.contentObj.set('html',responseText);
                var fe = this.contentObj.getElement('form');
                var self = this;
                if (fe) {
                    fe.addEvent('submit', function(e) {
                        e.stop();
                        self.setBusy();
                        this.set('send', {
                            onComplete: function(response) {
                                self.setLazy();
                                self.onLoadComplete(JSON.decode(response));
                            },
                            url: fe.get('action'),
                            method: fe.get('method') || 'post'
                        });
                        this.send();
                    })
                }
            }.bind(this)
        }).send();
    },
    
    onLoadComplete: function(json) {
        if (json.success) {
            this.close();
        } else {
            this.close();
        }
    },
    
    open: function() {
        this.domObj.setStyle('display','block');
        this.domObj.setStyle('zIndex',900);    
        this.domObj.resize();
        this.contentObj.resize();
        this.position(this.domObj, this.options.parent, {
            horizontal: ['center center'],
            vertical: ['top center']
        });
        window.addEvent('resize',function() {
            this.position(this.domObj, this.options.parent, {
                horizontal: ['center center'],
                vertical: ['top center']
            });
            this.shim.position();
        }.bind(this));        
        this.blanket.show();
        this.shim.show();
    },
    
    close: function() {
        this.shim.hide();
        this.blanket.hide();
        this.fireEvent('onClose');
        this.blanket.destroy();
        this.shim.destroy();
        this.domObj.dispose();
    }
    
});

MootoolsHelper.track = function (event) {
    pageTracker._trackPageview("/externalLink/" + event.target.href );
    try{
        var id = event.target.id.split('_');
        var customTracker = new Request({'url': '/track', 'data': 'path='+escape(event.target.href)+'&document_url='+escape(window.location)+'&element_id='+id[0]+'&viewcontainer_name='+id[1]}).send();
    } catch (e) {
        
    }
}

MootoolsHelper.trackClass = function (event) {
    pageTracker._trackPageview("/externalLink/" + event.target.href );
    try{
        var id = event.target.getProperty('class').split('-');
        var customTracker = new Request({'url': '/track', 'data': 'path='+escape(event.target.href)+'&document_url='+escape(window.location)+'&element_id='+id[0]+'&viewcontainer_name='+id[1]}).send();
    } catch (e) {
        
    }
}

MootoolsHelper.trackElement = function (element) {
    pageTracker._trackPageview("/externalLink/" + element.href );
    try{
        var id = element.id.split('-');
        var customTracker = new Request({'url': '/track', 'data': 'path='+escape(element.href)+'&document_url='+escape(window.location)+'&element_id='+id[0]+'&viewcontainer_name='+id[1]}).send();
    } catch (e) {
        
    }
}

MootoolsHelper.trackClickedAsset = function (element) {
    pageTracker._trackPageview("/externalLink/" + element.href );
    try{
        var id = element.getProperty('class').split('-');
        var customTracker = new Request({'url': '/track', 'data': 'path='+escape(element.href)+'&document_url='+escape(window.location)+'&element_id='+id[0]+'&viewcontainer_name='+id[1]}).send();
    } catch (e) {
        
    }
}

MootoolsHelper.trackOfferBooking = function (event) {
    pageTracker._trackPageview("/externalLink/" + event.target.href );
    try{
        var id = event.target.id.split('-');
        var customTracker = new Request({'url': '/trackofferbooking', 'data': 'path='+escape(event.target.href)+'&document_url='+escape(window.location)+'&element_id='+id[0]+'&viewcontainer_name='+id[1]}).send();
    } catch (e) {
        
    }
}

/**
 * Class: Cx
 * Cx is a global singleton object that contains the entire Custom library
 * within it.  All Cx functions, attributes and classes are accessed
 * through the global Cx object.  Mx should not create any other
 * global variables, if you discover that it does then please report
 * it as a bug
 *
 * License: 
 * Copyright (c) 2008, DM Solutions Group Inc.
 * 
 * This file is licensed under an MIT style license
 */

if (typeof Cx === 'undefined') {
    var Cx = {};
} 


if (typeof document.id === 'undefined') {
    document.id = $;
}
// Calendar: a Javascript class for Mootools that adds accessible and unobtrusive date pickers to your form elements <http://electricprism.com/aeron/calendar>
// Calendar RC4, Copyright (c) 2007 Aeron Glemann <http://electricprism.com/aeron>, MIT Style License.
// Mootools 1.2 compatibility by Davorin � ego

var Calendar = new Class({	

  Implements: Options,

	options: {
		blocked: [], // blocked dates 
		classes: [], // ['calendar', 'prev', 'next', 'month', 'year', 'today', 'invalid', 'valid', 'inactive', 'active', 'hover', 'hilite']
		days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // days of the week starting at sunday
		direction: 0, // -1 past, 0 past + future, 1 future
		draggable: true,
		months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
		navigation: 1, // 0 = no nav; 1 = single nav for month; 2 = dual nav for month and year
		offset: 0, // first day of the week: 0 = sunday, 1 = monday, etc..
		onHideStart: Class.empty,
		onHideComplete: Class.empty,
		onShowStart: Class.empty,
		onShowComplete: Class.empty,
		pad: 1, // padding between multiple calendars
		tweak: {x: 0, y: 0} // tweak calendar positioning
	},

	// initialize: calendar constructor
	// @param obj (obj) a js object containing the form elements and format strings { id: 'format', id: 'format' etc }
	// @param props (obj) optional properties

	initialize: function(obj, options) {
		// basic error checking
		if (!obj) { return false; }

		this.setOptions(options);

		// create our classes array
		var keys = ['calendar', 'prev', 'next', 'month', 'year', 'today', 'invalid', 'valid', 'inactive', 'active', 'hover', 'hilite'];

		var values = keys.map(function(key, i) {
			if (this.options.classes[i]) {
				if (this.options.classes[i].length) { key = this.options.classes[i]; }
			}
			return key;
		}, this);

		this.classes = values.associate(keys);

		// create cal element with css styles required for proper cal functioning
		this.calendar = new Element('div', { 
			'styles': { left: '-1000px', opacity: 0, position: 'absolute', top: '-1000px', zIndex: 1000 }
		}).addClass(this.classes.calendar).injectInside(document.body);

		// iex 6 needs a transparent iframe underneath the calendar in order to not allow select elements to render through
		if (window.ie6) {
			this.iframe = new Element('iframe', { 
				'styles': { left: '-1000px', position: 'absolute', top: '-1000px', zIndex: 999 }
			}).injectInside(document.body);
			this.iframe.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';
		}

		// initialize fade method
		this.fx = new Fx.Tween(this.calendar, {
			onStart: function() { 
				if (this.calendar.getStyle('opacity') == 0) { // show
					if (window.ie6) { this.iframe.setStyle('display', 'block'); }
					this.calendar.setStyle('display', 'block');
					this.fireEvent('onShowStart', this.element);
				}
				else { // hide
					this.fireEvent('onHideStart', this.element);
				}
			}.bind(this),
			onComplete: function() { 
				if (this.calendar.getStyle('opacity') == 0) { // hidden
					this.calendar.setStyle('display', 'none');
					if (window.ie6) { this.iframe.setStyle('display', 'none'); }
					this.fireEvent('onHideComplete', this.element);
				}
				else { // shown
					this.fireEvent('onShowComplete', this.element);
				}
			}.bind(this)
		});

		// initialize drag method
		if (window.Drag && this.options.draggable) {
			this.drag = new Drag.Move(this.calendar, { 
				onDrag: function() {
					if (window.ie6) { this.iframe.setStyles({ left: this.calendar.style.left, top: this.calendar.style.top }); } 
				}.bind(this) 
			}); 
		}
		
		// create calendars array
		this.calendars = [];

		var id = 0;
		var d = new Date(); // today

		d.setDate(d.getDate() + this.options.direction.toInt()); // correct today for directional offset

		for (var i in obj) {
			var cal = { 
				button: new Element('button', { 'type': 'button' }),
				el: $(i),
				els: [],
				id: id++,
				month: d.getMonth(),
				visible: false,
				year: d.getFullYear()
			};

			// fix for bad element (naughty, naughty element!)
			if (!this.element(i, obj[i], cal)) { continue; }
			
			cal.el.addClass(this.classes.calendar);

			// create cal button
			cal.button.addClass(this.classes.calendar).addEvent('click', function(cal) { this.toggle(cal); }.pass(cal, this)).injectAfter(cal.el);

			// read in default value
			cal.val = this.read(cal);

			$extend(cal, this.bounds(cal)); // abs bounds of calendar

			$extend(cal, this.values(cal)); // valid days, months, years

			this.rebuild(cal);

			this.calendars.push(cal); // add to cals array		
		}	
	},


	// blocked: returns an array of blocked days for the month / year
	// @param cal (obj)
	// @returns blocked days (array)

	blocked: function(cal) {
		var blocked = [];
		var offset = new Date(cal.year, cal.month, 1).getDay(); // day of the week (offset)
		var last = new Date(cal.year, cal.month + 1, 0).getDate(); // last day of this month
		
		this.options.blocked.each(function(date){
			var values = date.split(' ');
			
			// preparation
			for (var i = 0; i <= 3; i++){ 
				if (!values[i]){ values[i] = (i == 3) ? '' : '*'; } // make sure blocked date contains values for at least d, m and y
				values[i] = values[i].contains(',') ? values[i].split(',') : new Array(values[i]); // split multiple values
				var count = values[i].length - 1;
				for (var j = count; j >= 0; j--){
					if (values[i][j].contains('-')){ // a range
						var val = values[i][j].split('-');
						for (var k = val[0]; k <= val[1]; k++){
							if (!values[i].contains(k)){ values[i].push(k + ''); }
						}
						values[i].splice(j, 1);
					}
				}
			}

			// execution
			if (values[2].contains(cal.year + '') || values[2].contains('*')){
				if (values[1].contains(cal.month + 1 + '') || values[1].contains('*')){
					values[0].each(function(val){ // if blocked value indicates this month / year
						if (val > 0){ blocked.push(val.toInt()); } // add date to blocked array
					});

					if (values[3]){ // optional value for day of week
						for (var i = 0; i < last; i++){
								var day = (i + offset) % 7;
	
								if (values[3].contains(day + '')){ 
									blocked.push(i + 1); // add every date that corresponds to the blocked day of the week to the blocked array
								}
						}
					}
				}
			}
		}, this);

		return blocked;
	},


	// bounds: returns the start / end bounds of the calendar
	// @param cal (obj)
	// @returns obj	

	bounds: function(cal) {
		// 1. first we assume the calendar has no bounds (or a thousand years in either direction)
		
		// by default the calendar will accept a millennium in either direction
		var start = new Date(1000, 0, 1); // jan 1, 1000
		var end = new Date(2999, 11, 31); // dec 31, 2999

		// 2. but if the cal is one directional we adjust accordingly
		var date = new Date().getDate() + this.options.direction.toInt();

		if (this.options.direction > 0) {
			start = new Date();
			start.setDate(date + this.options.pad * cal.id);
		}
		
		if (this.options.direction < 0) {
			end = new Date();
			end.setDate(date - this.options.pad * (this.calendars.length - cal.id - 1));
		}

		// 3. then we can further filter the limits by using the pre-existing values in the selects
		cal.els.each(function(el) {	
			if (el.get('tag') == 'select') {		
				if (el.format.test('(y|Y)')) { // search for a year select
					var years = [];

					el.getChildren().each(function(option) { // get options
						var values = this.unformat(option.value, el.format);
	
						if (!years.contains(values[0])) { years.push(values[0]); } // add to years array
					}, this);
	
					years.sort(this.sort);
			
					if (years[0] > start.getFullYear()) { 
						d = new Date(years[0], start.getMonth() + 1, 0); // last day of new month
					
						if (start.getDate() > d.getDate()) { start.setDate(d.getDate()); }
	
						start.setYear(years[0]); 
					}
					
					if (years.getLast() < end.getFullYear()) { 
						d = new Date(years.getLast(), end.getMonth() + 1, 0); // last day of new month
					
						if (end.getDate() > d.getDate()) { end.setDate(d.getDate()); }
	
						end.setYear(years.getLast());
					}		
				}
	
				if (el.format.test('(F|m|M|n)')) { // search for a month select
					var months_start = [];
					var months_end = [];

					el.getChildren().each(function(option) { // get options
						var values = this.unformat(option.value, el.format);
	
						if ($type(values[0]) != 'number' || values[0] == years[0]) { // if it's a year / month combo for curr year, or simply a month select
							if (!months_start.contains(values[1])) { months_start.push(values[1]); } // add to months array
						}
	
						if ($type(values[0]) != 'number' || values[0] == years.getLast()) { // if it's a year / month combo for curr year, or simply a month select
							if (!months_end.contains(values[1])) { months_end.push(values[1]); } // add to months array
						}
					}, this);
	
					months_start.sort(this.sort);
					months_end.sort(this.sort);
					
					if (months_start[0] > start.getMonth()) { 
						d = new Date(start.getFullYear(), months_start[0] + 1, 0); // last day of new month
					
						if (start.getDate() > d.getDate()) { start.setDate(d.getDate()); }
	
						start.setMonth(months_start[0]); 
					}
					
					if (months_end.getLast() < end.getMonth()) { 
						d = new Date(start.getFullYear(), months_end.getLast() + 1, 0); // last day of new month
					
						if (end.getDate() > d.getDate()) { end.setDate(d.getDate()); }
	
						end.setMonth(months_end.getLast());
					}		
				}
			}
		}, this);
		
		return { 'start': start, 'end': end };
	},


	// caption: returns the caption element with header and navigation
	// @param cal (obj)
	// @returns caption (element)

	caption: function(cal) {
		// start by assuming navigation is allowed
		var navigation = {
			prev: { 'month': true, 'year': true },
			next: { 'month': true, 'year': true }
		};
		
		// if we're in an out of bounds year
		if (cal.year == cal.start.getFullYear()) { 
			navigation.prev.year = false; 
			if (cal.month == cal.start.getMonth() && this.options.navigation == 1) { 
				navigation.prev.month = false;
			}		
		}		
		if (cal.year == cal.end.getFullYear()) { 
			navigation.next.year = false; 
			if (cal.month == cal.end.getMonth() && this.options.navigation == 1) { 
				navigation.next.month = false;
			}
		}

		// special case of improved navigation but months array with only 1 month we can disable all month navigation
		if ($type(cal.months) == 'array') {
			if (cal.months.length == 1 && this.options.navigation == 2) {
				navigation.prev.month = navigation.next.month = false;
			}
		}

		var caption = new Element('caption');

		var prev = new Element('a').addClass(this.classes.prev).appendText('\x3c'); // <		
		var next = new Element('a').addClass(this.classes.next).appendText('\x3e'); // >

		if (this.options.navigation == 2) {
			var month = new Element('span').addClass(this.classes.month).injectInside(caption);
			
			if (navigation.prev.month) { prev.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', -1); }.pass(cal, this)).injectInside(month); }
			
			month.adopt(new Element('span').appendText(this.options.months[cal.month]));

			if (navigation.next.month) { next.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', 1); }.pass(cal, this)).injectInside(month); }

			var year = new Element('span').addClass(this.classes.year).injectInside(caption);

			if (navigation.prev.year) { prev.clone().addEvent('click', function(cal) { this.navigate(cal, 'y', -1); }.pass(cal, this)).injectInside(year); }
			
			year.adopt(new Element('span').appendText(cal.year));

			if (navigation.next.year) { next.clone().addEvent('click', function(cal) { this.navigate(cal, 'y', 1); }.pass(cal, this)).injectInside(year); }
		}
		else { // 1 or 0
			if (navigation.prev.month && this.options.navigation) { prev.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', -1); }.pass(cal, this)).injectInside(caption); }

			caption.adopt(new Element('span').addClass(this.classes.month).appendText(this.options.months[cal.month]));
			
			caption.adopt(new Element('span').addClass(this.classes.year).appendText(cal.year));
			
			if (navigation.next.month && this.options.navigation) { next.clone().addEvent('click', function(cal) { this.navigate(cal, 'm', 1); }.pass(cal, this)).injectInside(caption); }

		}

		return caption;
	},


	// changed: run when a select value is changed
	// @param cal (obj)

	changed: function(cal) {
		cal.val = this.read(cal); // update calendar val from inputs	

		$extend(cal, this.values(cal)); // update bounds - based on curr month

		this.rebuild(cal); // rebuild days select

		if (!cal.val) { return; } // in case the same date was clicked the cal has no set date we should exit		

		if (cal.val.getDate() < cal.days[0]) { cal.val.setDate(cal.days[0]); }
		if (cal.val.getDate() > cal.days.getLast()) { cal.val.setDate(cal.days.getLast()); }
		
		cal.els.each(function(el) {	// then we can set the value to the field
			el.value = this.format(cal.val, el.format); 		
		}, this);
		
		this.check(cal); // checks other cals

		this.calendars.each(function(kal) { // update cal graphic if visible
			if (kal.visible) { this.display(kal); }
		}, this);
	},


	// check: checks other calendars to make sure no overlapping values
	// @param cal (obj)

	check: function(cal) {
		this.calendars.each(function(kal, i) {
			if (kal.val) { // if calendar has value set
				var change = false;
			
				if (i < cal.id) { // preceding calendar
					var bound = new Date(Date.parse(cal.val));
					
					bound.setDate(bound.getDate() - (this.options.pad * (cal.id - i)));

					if (bound < kal.val) { change = true; }
				}
				if (i > cal.id) { // following calendar
					var bound = new Date(Date.parse(cal.val));
					
					bound.setDate(bound.getDate() + (this.options.pad * (i - cal.id)));
					
					if (bound > kal.val) { change = true; }
				}

				if (change) {
					if (kal.start > bound) { bound = kal.start; }
					if (kal.end < bound) { bound = kal.end; }

					kal.month = bound.getMonth();
					kal.year = bound.getFullYear();		

					$extend(kal, this.values(kal));			

					// TODO - IN THE CASE OF SELECT MOVE TO NEAREST VALID VALUE
					// IN THE CASE OF INPUT DISABLE

					// if new date is not valid better unset cal value
					// otherwise it would mean incrementally checking to find the nearest valid date which could be months / years away
					kal.val = kal.days.contains(bound.getDate()) ? bound : null;

					this.write(kal);

					if (kal.visible) { this.display(kal); } // update cal graphic if visible
				}
			}
			else {
				kal.month = cal.month;
				kal.year = cal.year;
			}
		}, this);
	},
	

	// clicked: run when a valid day is clicked in the calendar
	// @param cal (obj)

	clicked: function(td, day, cal) {
		cal.val = (this.value(cal) == day) ? null : new Date(cal.year, cal.month, day); // set new value - if same then disable

		this.write(cal); 

		// ok - in the special case that it's all selects and there's always a date no matter what (at least as far as the form is concerned)
		// we can't let the calendar undo a date selection - it's just not possible!!
		if (!cal.val) { cal.val = this.read(cal); }

		if (cal.val) {
			this.check(cal); // checks other cals						
			this.toggle(cal); // hide cal
		} 
		else { // remove active class and replace with valid
			td.addClass(this.classes.valid);
			td.removeClass(this.classes.active);
		}
	},
	

	// display: create calendar element
	// @param cal (obj)

	display: function(cal) {
		// 1. header and navigation
		this.calendar.empty(); // init div

		this.calendar.className = this.classes.calendar + ' ' + this.options.months[cal.month].toLowerCase();

		var div = new Element('div').injectInside(this.calendar); // a wrapper div to help correct browser css problems with the caption element

		var table = new Element('table').injectInside(div).adopt(this.caption(cal));
				
		// 2. day names		
		var thead = new Element('thead').injectInside(table);

		var tr = new Element('tr').injectInside(thead);
		
		for (var i = 0; i <= 6; i++) {
			var th = this.options.days[(i + this.options.offset) % 7];
			
			tr.adopt(new Element('th', { 'title': th }).appendText(th.substr(0, 1)));
		}

		// 3. day numbers
		var tbody = new Element('tbody').injectInside(table);
		var tr = new Element('tr').injectInside(tbody);

		var d = new Date(cal.year, cal.month, 1);
		var offset = ((d.getDay() - this.options.offset) + 7) % 7; // day of the week (offset)
		var last = new Date(cal.year, cal.month + 1, 0).getDate(); // last day of this month
		var prev = new Date(cal.year, cal.month, 0).getDate(); // last day of previous month
		var active = this.value(cal); // active date (if set and within curr month)
		var valid = cal.days; // valid days for curr month
		var inactive = []; // active dates set by other calendars
		var hilited = [];
		this.calendars.each(function(kal, i) {
			if (kal != cal && kal.val) {
				if (cal.year == kal.val.getFullYear() && cal.month == kal.val.getMonth()) { inactive.push(kal.val.getDate()); }

				if (cal.val) {
					for (var day = 1; day <= last; day++) {
						d.setDate(day);
						
						if ((i < cal.id && d > kal.val && d < cal.val) || (i > cal.id && d > cal.val && d < kal.val)) { 
							if (!hilited.contains(day)) { hilited.push(day); }
						}
					}
				}
			}
		}, this);
		var d = new Date();
		var today = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime(); // today obv 
		
		for (var i = 1; i < 43; i++) { // 1 to 42 (6 x 7 or 6 weeks)
			if ((i - 1) % 7 == 0) { tr = new Element('tr').injectInside(tbody); } // each week is it's own table row

			var td = new Element('td').injectInside(tr);
						
			var day = i - offset;
			var date = new Date(cal.year, cal.month, day);
			
			var cls = '';
			
			if (day === active) { cls = this.classes.active; } // active
			else if (inactive.contains(day)) { cls = this.classes.inactive; } // inactive
			else if (valid.contains(day)) { cls = this.classes.valid; } // valid
			else if (day >= 1 && day <= last) { cls = this.classes.invalid; } // invalid

			if (date.getTime() == today) { cls = cls + ' ' + this.classes.today; } // adds class for today

			if (hilited.contains(day)) { cls = cls + ' ' + this.classes.hilite; } // adds class if hilited

			td.addClass(cls);

			if (valid.contains(day)) { // if it's a valid - clickable - day we add interaction
				td.setProperty('title', this.format(date, 'D M jS Y'));
				
				td.addEvents({
					'click': function(td, day, cal) { 
						this.clicked(td, day, cal); 
					}.pass([td, day, cal], this),
					'mouseover': function(td, cls) { 
						td.addClass(cls); 
					}.pass([td, this.classes.hover]),
					'mouseout': function(td, cls) { 
						td.removeClass(cls); 
					}.pass([td, this.classes.hover])
				});
			}

			// pad calendar with last days of prev month and first days of next month
			if (day < 1) { day = prev + day; }
			else if (day > last) { day = day - last; }

			td.appendText(day);
		}
	},


	// element: helper function
	// @param el (string) element id
	// @param f (string) format string
	// @param cal (obj)

	element: function(el, f, cal) {
		if ($type(f) == 'object') { // in the case of multiple inputs per calendar
			for (var i in f) { 
				if (!this.element(i, f[i], cal)) { return false; }		
			}
			
			return true;
		}

		el = $(el);

		if (!el) { return false; }
		
		el.format = f;
		
		if (el.get('tag') == 'select') { // select elements allow the user to manually set the date via select option
			el.addEvent('change', function(cal) { this.changed(cal); }.pass(cal, this));
		}
		else { // input (type text) elements restrict the user to only setting the date via the calendar
			el.readOnly = true;
			el.addEvent('focus', function(cal) { this.toggle(cal); }.pass(cal, this));
		}

		cal.els.push(el);

		return true;
	},


	// format: formats a date object according to passed in instructions
	// @param date (obj)
	// @param f (string) any combination of punctuation / separators and d, j, D, l, S, m, n, F, M, y, Y
	// @returns string

	format: function(date, format) {
		var str = '';
		
		if (date) {
			var j = date.getDate(); // 1 - 31
      var w = date.getDay(); // 0 - 6
			var l = this.options.days[w]; // Sunday - Saturday
			var n = date.getMonth() + 1; // 1 - 12
			var f = this.options.months[n - 1]; // January - December
			var y = date.getFullYear() + ''; // 19xx - 20xx
			
			for (var i = 0, len = format.length; i < len; i++) {
				var cha = format.charAt(i); // format char
				
				switch(cha) {
					// year cases
					case 'y': // xx - xx
						y = y.substr(2);
					case 'Y': // 19xx - 20xx
						str += y;
						break;
	
					// month cases
					case 'm': // 01 - 12
						if (n < 10) { n = '0' + n; }
					case 'n': // 1 - 12
						str += n;
						break;
	
					case 'M': // Jan - Dec
						f = f.substr(0, 3);
					case 'F': // January - December
						str += f;
						break;
	
					// day cases
					case 'd': // 01 - 31
						if (j < 10) { j = '0' + j; }
					case 'j': // 1 - 31
						str += j;
						break;
	
					case 'D': // Sun - Sat
						l = l.substr(0, 3);
					case 'l': // Sunday - Saturday
						str += l;
						break;
	
					case 'N': // 1 - 7
						w += 1;
					case 'w': // 0 - 6
						str += w;
						break;

					case 'S': // st, nd, rd or th (works well with j)
						if (j % 10 == 1 && j != '11') { str += 'st'; }
						else if (j % 10 == 2 && j != '12') { str += 'nd'; }
						else if (j % 10 == 3 && j != '13') { str += 'rd'; }
						else { str += 'th'; }
						break;
	
					default:
						str += cha;
				}
			}
		}

	  return str; //  return format with values replaced
	},


	// navigate: calendar navigation
	// @param cal (obj)
	// @param type (str) m or y for month or year
	// @param n (int) + or - for next or prev

	navigate: function(cal, type, n) {
		switch (type) {
			case 'm': // month
					if ($type(cal.months) == 'array') {
						var i = cal.months.indexOf(cal.month) + n; // index of current month
						
						if (i < 0 || i == cal.months.length) { // out of range
							if (this.options.navigation == 1) { // if type 1 nav we'll need to increment the year
								this.navigate(cal, 'y', n);		
							}
		
							i = (i < 0) ? cal.months.length - 1 : 0;
						}

						cal.month = cal.months[i];
					}
					else { 
						var i = cal.month + n;
		
						if (i < 0 || i == 12) {
							if (this.options.navigation == 1) {
								this.navigate(cal, 'y', n);	
							}
		
							i = (i < 0) ? 11 : 0;
						}
						
						cal.month = i;
					}		
					break;

				case 'y': // year
					if ($type(cal.years) == 'array') {
						var i = cal.years.indexOf(cal.year) + n;

						cal.year = cal.years[i]; 
					}
					else { 
						cal.year += n;
					}						
					break;		
		}

		$extend(cal, this.values(cal));

		if ($type(cal.months) == 'array') { // if the calendar has a months select
			var i = cal.months.indexOf(cal.month); // and make sure the curr months exists for the new year

			if (i < 0) { cal.month = cal.months[0]; } // otherwise we'll reset the month
		}


		this.display(cal);
	},


	// read: compiles cal value based on array of inputs passed in
	// @param cal (obj)
	// @returns date (obj) or (null)

	read: function(cal) {
		var arr = [null, null, null];

		cal.els.each(function(el) {
			// returns an array which may contain empty values
			var values = this.unformat(el.value, el.format);
			
			values.each(function(val, i) { 
				if ($type(val) == 'number') { arr[i] = val; }
			}); 
		}, this);

		// we can update the cals month and year values
		if ($type(arr[0]) == 'number') { cal.year = arr[0]; }
		if ($type(arr[1]) == 'number') { cal.month = arr[1]; }

		var val = null;

		if (arr.every(function(i) { return $type(i) == 'number'; })) { // if valid date
			var last = new Date(arr[0], arr[1] + 1, 0).getDate(); // last day of month

			if (arr[2] > last) { arr[2] = last; } // make sure we stay within the month (ex in case default day of select is 31 and month is feb)
			
			val = new Date(arr[0], arr[1], arr[2]);
		}

		return (cal.val == val) ? null : val; // if new date matches old return null (same date clicked twice = disable)
	},

	
	// rebuild: rebuilds days + months selects
	// @param cal (obj)

	rebuild: function(cal) {
		cal.els.each(function(el) {			
			/*
			if (el.get('tag') == 'select' && el.format.test('^(F|m|M|n)$')) { // special case for months-only select
				if (!cal.options) { cal.options = el.clone(); } // clone a copy of months select
			
				var val = (cal.val) ? cal.val.getMonth() : el.value.toInt();

				el.empty(); // initialize select

				cal.months.each(function(month) {
					// create an option element
					var option = new Element('option', {
						'selected': (val == month),
						'value': this.format(new Date(1, month, 1), el.format);
					}).appendText(day).injectInside(el);
				}, this);
			}
			*/

			if (el.get('tag') == 'select' && el.format.test('^(d|j)$')) { // special case for days-only select
				var d = this.value(cal);

				if (!d) { d = el.value.toInt(); } // if the calendar doesn't have a set value, try to use value from select

				el.empty(); // initialize select

				cal.days.each(function(day) {
					// create an option element
					var option = new Element('option', {
						'selected': (d == day),
						'value': ((el.format == 'd' && day < 10) ? '0' + day : day)
					}).appendText(day).injectInside(el);
				}, this);
			}
		}, this); 
	},


	// sort: helper function for numerical sorting

	sort: function(a, b) {
		return a - b;
	},


	// toggle: show / hide calendar 
	// @param cal (obj)

	toggle: function(cal) {
		document.removeEvent('mousedown', this.fn); // always remove the current mousedown script first
			
		if (cal.visible) { // simply hide curr cal						
			cal.visible = false;
			cal.button.removeClass(this.classes.active); // active
			
			this.fx.start('opacity', 1, 0);
		}
		else { // otherwise show (may have to hide others)
			// hide cal on out-of-bounds click
			this.fn = function(e, cal) { 
				var e = new Event(e);
			
				var el = e.target;

				var stop = false;
				
				while (el != document.body && el.nodeType == 1) {
					if (el == this.calendar) { stop = true; }
					this.calendars.each(function(kal) {
						if (kal.button == el || kal.els.contains(el)) { stop = true; }
					});

					if (stop) { 
						e.stop();
						return false;
					}
					else { el = el.parentNode; }
				}
				
				this.toggle(cal);
			}.create({ 'arguments': cal, 'bind': this, 'event': true });				

			document.addEvent('mousedown', this.fn);

			this.calendars.each(function(kal) {
				if (kal == cal) {
					kal.visible = true;
					kal.button.addClass(this.classes.active); // css c-icon-active
				}
				else {
					kal.visible = false;
					kal.button.removeClass(this.classes.active); // css c-icon-active
				}
			}, this);
			
			var size = window.getScrollSize();
			
			var coord = cal.button.getCoordinates();

			var x = coord.right + this.options.tweak.x;
			var y = coord.top + this.options.tweak.y;

			// make sure the calendar doesn't open off screen
			if (!this.calendar.coord) { this.calendar.coord = this.calendar.getCoordinates(); }

			if (x + this.calendar.coord.width > size.x) { x -= (x + this.calendar.coord.width - size.x); }
			if (y + this.calendar.coord.height > size.y) { y -= (y + this.calendar.coord.height - size.y); }
			
			this.calendar.setStyles({ left: x + 'px', top: y + 'px' });

			if (window.ie6) { 
				this.iframe.setStyles({ height: this.calendar.coord.height + 'px', left: x + 'px', top: y + 'px', width: this.calendar.coord.width + 'px' }); 
			}

			this.display(cal);
			
			this.fx.start('opacity', 0, 1);
		}
	},


	// unformat: takes a value from an input and parses the d, m and y elements
	// @param val (string)
	// @param f (string) any combination of punctuation / separators and d, j, D, l, S, m, n, F, M, y, Y
	// @returns array
	
	unformat: function(val, f) {
		f = f.escapeRegExp();
		
		var re = {
			d: '([0-9]{2})',
			j: '([0-9]{1,2})',
			D: '(' + this.options.days.map(function(day) { return day.substr(0, 3); }).join('|') + ')',					
			l: '(' + this.options.days.join('|') + ')',
			S: '(st|nd|rd|th)',
			F: '(' + this.options.months.join('|') + ')',
			m: '([0-9]{2})',
			M: '(' + this.options.months.map(function(month) { return month.substr(0, 3); }).join('|') + ')',					
			n: '([0-9]{1,2})',
			Y: '([0-9]{4})',
			y: '([0-9]{2})'
		}

		var arr = []; // array of indexes

		var g = '';

		// convert our format string to regexp
		for (var i = 0; i < f.length; i++) {
			var c = f.charAt(i);
			
			if (re[c]) {
				arr.push(c);

				g += re[c];
			}
			else {
				g += c;
			}
		}

		// match against date
		var matches = val.match('^' + g + '$');
		
		var dates = new Array(3);

		if (matches) {
			matches = matches.slice(1); // remove first match which is the date

			arr.each(function(c, i) {
				i = matches[i];
				
				switch(c) {
					// year cases
					case 'y':
						i = '19' + i; // 2 digit year assumes 19th century (same as JS)
					case 'Y':
						dates[0] = i.toInt();
						break;

					// month cases
					case 'F':
						i = i.substr(0, 3);
					case 'M':
						i = this.options.months.map(function(month) { return month.substr(0, 3); }).indexOf(i) + 1;
					case 'm':
					case 'n':
						dates[1] = i.toInt() - 1;
						break;

					// day cases
					case 'd':
					case 'j':
						dates[2] = i.toInt();
						break;
				}
			}, this);
		}

		return dates;
	},


	// value: returns day value of calendar if set
	// @param cal (obj)
	// @returns day (int) or null

	value: function(cal) {
		var day = null;

		if (cal.val) {
			if (cal.year == cal.val.getFullYear() && cal.month == cal.val.getMonth()) { day = cal.val.getDate(); }
		}

		return day;
	},
	

	// values: returns the years, months (for curr year) and days (for curr month and year) for the calendar
	// @param cal (obj)
	// @returns obj	

	values: function(cal) {
		var years, months, days;

		cal.els.each(function(el) {	
			if (el.get('tag') == 'select') {		
				if (el.format.test('(y|Y)')) { // search for a year select
					years = [];

					el.getChildren().each(function(option) { // get options
						var values = this.unformat(option.value, el.format);
	
						if (!years.contains(values[0])) { years.push(values[0]); } // add to years array
					}, this);
	
					years.sort(this.sort);
				}
	
				if (el.format.test('(F|m|M|n)')) { // search for a month select
					months = []; // 0 - 11 should be

					el.getChildren().each(function(option) { // get options
						var values = this.unformat(option.value, el.format);
	
						if ($type(values[0]) != 'number' || values[0] == cal.year) { // if it's a year / month combo for curr year, or simply a month select
							if (!months.contains(values[1])) { months.push(values[1]); } // add to months array
						}
					}, this);
	
					months.sort(this.sort);
				}
				
				if (el.format.test('(d|j)') && !el.format.test('^(d|j)$')) { // search for a day select, but NOT a days only select
					days = []; // 1 - 31
					
					el.getChildren().each(function(option) { // get options
						var values = this.unformat(option.value, el.format);

						// in the special case of days we dont want the value if its a days only select
						// otherwise that will screw up the options rebuilding
						// we will take the values if they are exact dates though
						if (values[0] == cal.year && values[1] == cal.month) {
							if (!days.contains(values[2])) { days.push(values[2]); } // add to days array
						}
					}, this);
				}
			}
		}, this);
		
		// we start with what would be the first and last days were there no restrictions
		var first = 1;
		var last = new Date(cal.year, cal.month + 1, 0).getDate(); // last day of the month
		
		// if we're in an out of bounds year
		if (cal.year == cal.start.getFullYear()) {
			// in the special case of improved navigation but no months array, we'll need to construct one
			if (months == null && this.options.navigation == 2) {
				months = [];
				
				for (var i = 0; i < 12; i ++) { 
					if (i >= cal.start.getMonth()) { months.push(i); } 
				}
			}
			
			// if we're in an out of bounds month
			if (cal.month == cal.start.getMonth()) { 
				first = cal.start.getDate(); // first day equals day of bound
			}
		}		
		if (cal.year == cal.end.getFullYear()) {
			// in the special case of improved navigation but no months array, we'll need to construct one
			if (months == null && this.options.navigation == 2) {
				months = [];
				
				for (var i = 0; i < 12; i ++) { 
					if (i <= cal.end.getMonth()) { months.push(i); } 
				}
			}

			if (cal.month == cal.end.getMonth()) { 
				last = cal.end.getDate(); // last day equals day of bound
			}
		}

		// let's get our invalid days
		var blocked = this.blocked(cal);

		// finally we can prepare all the valid days in a neat little array
		if ($type(days) == 'array') { // somewhere there was a days select
			days = days.filter(function(day) {
				if (day >= first && day <= last && !blocked.contains(day)) { return day; }
			});
		}
		else { // no days select we'll need to construct a valid days array
			days = [];
			
			for (var i = first; i <= last; i++) { 
				if (!blocked.contains(i)) { days.push(i); }
			}
		}		

		days.sort(this.sort); // sorting our days will give us first and last of month

		return { 'days': days, 'months': months, 'years': years };
	},


	// write: sets calendars value to form elements
	// @param cal (obj)

	write: function(cal) {
		this.rebuild(cal);	 // in the case of options, we'll need to make sure we have the correct number of days available
		
		cal.els.each(function(el) {	// then we can set the value to the field
			el.value = this.format(cal.val, el.format); 		
		}, this);
	}
});

Calendar.implement(new Events, new Options);
Cx.Map = new Class({

    Extends: Mx.Container,

    Implement: [Events, Options],
    
    Family: 'Cx.Map',
    
    Delegates: true,
    
    options: {
        parent: null,
        zoomLevel: 8,
        cls: 'CxMap'  
    },
    
    templates: {
        list: [
            '<div class="mapOfferListContainer" style="border-top: 1px solid gray; margin-top:10px">',
            '<table border="0" cellspacing=0 cellpadding=2>',
                '<tr evt="click,mouseover,mouseout">',
                    '<td class="icon" width="20px" valign="top">{icon}</td>',
                    '<td class="offerDescription">',
                    '<h4>{label}</h4>',
                    '{description}',
                    '</td>',
                '</tr>',
            '</table>',
            '</div>'
        ],      
        windowList: [
            '<div evt="click,mouseover,mouseout" style="padding:5px; border-bottom: 1px solid lightgrey">',
            '{label} &raquo;',
            '</div>'
        ],
        windowDetail: [
                '<div>',
                    '{html}',
                '</div>',
                '<div>',
                    '<div style="float: left;">&laquo; &Uuml;bersicht</div>',
                    '<div>weitere Informationen &raquo; </div>',
                    '<div style="clear:both" />',
                '</div>'                
        ]      
    },
    
    initialize: function(options) {
        this.parent(options);
        
        this.options.display = null;
               
        this.domObj.setStyles({
            border: '1px solid black',
            backgroundColor: '#333333'
        });
        
        this.toolbarObj = new Element('div',{
            styles: {
                margin: '5px 5px 5px 5px',
                color: 'white'
            },
            align: 'right'   
        }).inject(this.domObj);
        
        new Jx.Button({
          type: 'CustomButton',
          label: 'Karte verkleinern',
          image: Jx.aPixel.src,
          tooltip: 'Karte verkleinern',
          onClick: this.close.bind(this)
        }).addTo(this.toolbarObj);
        
        this.contentObj = new Element('div',{
            styles: {
                margin: '15px 5px 5px 5px',
                backgroundColor: 'white'
            }
        }).inject(this.domObj);
        
        new Jx.Layout(this.contentObj, {top:25});
       
        this.splitVertical  = new Jx.Splitter(this.contentObj, {
            splitInto: 2,
            layout: 'vertical',
            containerOptions: [
                {maxHeight: 100, height: 100, minHeight: 100}
            ],
            barOptions: [
                {snap:'before'}
                //{snap:'after',snapElement: snapImg, snapEvents:['click']}
            ]
        });
        
        var snapImg = new Element('img', {
            src: Jx.aPixel.src,
            alt: '',
            title: '',
            'class': this.options.cls+'SnapLeft'
        });
        
        this.splitHorizontal = new Jx.Splitter(this.splitVertical.elements[1], {
            splitInto: 2,
            layout: 'horizontal',
            containerOptions: [
                {minWidth: 260, width: 260, overflow: 'hidden' }
            ],
            barOptions: [
                {snap:'before',snapElement: snapImg, snapEvents:['click']}
            ]
        }); 
        
        this.splitHorizontal.elements[0].setStyles({
            backgroundColor: '#f5f7f6'
        });
        
        this.listObj = new Element('div', {
            styles: {
                margin: '10px',
                padding: '10px',
                border: '1px solid gray',
                backgroundColor: 'white',
                overflow:'auto'
                //cursor: 'pointer'
            }
        }).inject(this.splitHorizontal.elements[0]);
        
        new Jx.Layout(this.listObj);
        

        this.map = new Mx.GMap({
            parent: this.splitHorizontal.elements[1],
            url: this.options.url,
            zoomLevel: this.options.zoomLevel,
            onZoomEnd: this.onZoomEnd.bind(this),
            onRedrawEnd: this.onRedrawEnd.bind(this),
            mapConfOpts: ['enableDragging'],
            mapControls: ['GLargeMapControl'],
            icons: this.options.icons || null,
            onMarkerClick: this.onMarkerClick.bind(this),
            clusteringEnabled: true
        });
        
        this.bubbleContent = new Element('div', {
            styles: {
                margin: 10,
                overflow: 'auto',
                display: 'none'
            },
            id: 'bubbleContent'
        }).inject(document.body);        
        
     
        this.currentZoom = 0;
        
        this.domObj.inject(this.options.parent || document.body);
        
        this.shim = new IframeShim(this.domObj);
        this.blanket = new Blanket(this.domObj);
                
        var myRequest = new Request({
            url: this.options.formUrl || null,
            data: { cmd: 'searchPanel' }, 
            onSuccess: function(responseText, responseXML) {
                var el = this.splitVertical.elements[0].set('html',responseText).disableOverflow();
                myCal1 = new Calendar({ arrival: 'd/m/Y',departure: 'd/m/Y' }, { 
                    direction: 1, 
                    tweak: { x: 0, y: 0 },
                    months: ['Januar', 'Februar', 'M&auml;rz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
                    days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
                    offset: 1              
                });
                var self = this;
                this.splitVertical.elements[0].getElement('form').addEvent('submit', function(e) {
            		//Prevents the default submit event from loading a new page.
		            e.stop();
		            self.setBusy();
		            this.set('send', {
		                onComplete: function(response) {
		                    self.setLazy();
    			            self.onPointsLoaded(JSON.decode(response));
    		            },
    		            url: self.options.url,
    		            method: 'post'
		            });
		            //Send the form.
		            this.send();
	            });
            }.bind(this)
        }).send();        
        
        
    },
    
    onZoomEnd: function() {

    },
    
    onRedrawEnd: function() {
        if (this.currentZoom != this.map.getMap().getZoom()) {
            this.refreshList.wait(200,this,[this.map.getCurrentMarkers()]);
            this.currentZoom = this.map.getMap().getZoom();
        }
    },    
    
    
    loadPoints: function(obj) {
         var myRequest = new Request.JSON({
            url: this.options.url || null,
            data: $merge(obj || {}, { cmd: 'loadPoints' }), 
            onSuccess: this.onPointsLoaded.bind(this)
        }).send();
    },    
    
    onPointsLoaded: function(j,t) {
        this.currentZoom = null;
        this.listObj.empty();
        this.map.clearMarkers();
        this.map.closeInfoWindow();
        this.json = j;   
        j.each(function(e,k) {
            //if (e.lat != 0 && e.lng != 0) { 
                this.map.addMarker({
                    lat: e.lat,
                    lng: e.lng,            
                    label: e.label || '' ,
                    marker: e.category_id        
                });
            //}
        },this);
        this.map.redrawMarkers();
        if (j.length == 1) {
            this.map.setCenter(j[0]);
        }
    },    
    
    refreshList: function(data) {
        var tpl = this.templates.list.join('').toElement();
        this.listObj.empty();
        //this.listObj.adopt(new Element('div', {
        //    'html': 'Gefundene Angebote: <strong>'+data.length+'</strong>'
        //}));
        data.each(function(row,index) {
            if (row.indexes) {
                row.indexes.each(function(i) {
                    var icon = row.icon;
            		var div = new Element('div', {
            		    styles: {
            		        width: icon.size[0]||0,
            		        height: icon.size[1]||0,
            		        backgroundImage: 'url('+icon.image+')',
            		        textAlign: 'center',
            		        lineHeight: icon.size[1],
            		        backgroundPosition: (icon.offset[0]||0) + "px "+ (icon.offset[1]||0)+"px",
            		        fontSize: '9px',
            		        fontWeight: 'bold',
            		        backgroundRepeat: 'no-repeat'
            		    }
            		});  
            		if (Browser.Engine.trident) {
            		    div.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+icon.image+"',sizingMethod='scale')";
            		    div.style.backgroundImage = '';
            		}   
                    /*
                    var element = tpl.clone();
                    var tableColumns = element.getElements('td');
                    tableColumns[0].innerHTML = '';
                    div.inject(tableColumns[0]);
                    tableColumns[1].innerHTML = "<h4>" + this.json[i].label + "</h4>" + this.json[i].description;
                    element.inject(this.listObj).bindEvents(this,'list',[row,index]);
                    */          		         		  
                    tpl.clone().substitute($merge(this.json[i],{
                        icon: div,
                        description: new Element('div',{html:this.json[i].description})
                    })).inject(this.listObj).bindEvents(this,'list',[row,index])                    
                },this);          
            }         
        },this);
        this.splitHorizontal.elements[0].enableOverflow()
    },
    
    onListMouseover: function(row,index,el) {
        el.setStyle('backgroundColor','lightblue');
        //this.map.setCenter({lat:row.latitude, lng:row.longitude});
    },
        
    onListMouseout: function(row,index,el) {
        el.setStyle('backgroundColor','');
    },       
    
    onMarkerClick: function(data) {
        this.onListClick(data);
    },
    
    onListClick: function(row,index,el) {
        var tpl = this.templates.windowList.join('').toElement();
        var maxHeight = this.map.getInnerHeight() - 140;
        var maxWidth = this.map.getInnerWidth() - 140;
        var map = this.map;
        var zoom = this.currentZoom;
        var div = this.bubbleContent;
        div.hide(); 
        div.empty();
        div.inject(document.body);        
        if (row.indexes.length == 1) {
            var myRequest = new Request({
                url: this.options.detailUrl || null,
                data: { cmd: 'loadHtml', id: this.json[row.indexes[0]].id }, 
                onSuccess: function(response) {
                    var width = maxWidth / 2 < 265 ? 265 : maxWidth / 2;
                    div.setStyles({width: width, height: 'auto'});
                    div.innerHTML = response;
  //                  (function() {
                        var size = div.getDimensions({computeSize: true});
                        if (size.height + 2 > maxHeight) {
                            div.setStyle('height',maxHeight);
                        }                        
                        else {
                            div.setStyle('height',size.height + 2 );
                        }
                        div.getElement('a[id=overview_link]').hide();
                        div.show();
                        map.setCenter({lat:row.latitude, lng:row.longitude});
                        map.openInfoWindow(row.latitude, row.longitude, div, { x:0, y:0 });                        
                        
//                    }).delay(1000);
                }.bind(this)
            }).send();
        }
        else {
            div.setStyles({width: 265, height: 'auto'});
            row.indexes.each(function(i) {
                tpl.clone().substitute(this.json[i]).bindEvents(this,'infoWindowList',[this.json[i],row,index]).inject(div);
            },this);
            var size = div.getDimensions({computeSize: true});
            if (size.height > maxHeight) {
                div.setStyle('height',maxHeight);
            }
            if (size.width > maxWidth) {
                div.setStyle('width', maxWidth);
            }
            div.show(); 
            map.openInfoWindow(row.latitude, row.longitude, div, { x:0, y:0 });
            //map.setCenter({lat:row.latitude, lng:row.longitude},this.currentZoom);                          
        }        
    },
    
    onInfoWindowListClick: function(data,row,index,el) {
        var maxHeight = this.map.getInnerHeight() - 140;
        var maxWidth = this.map.getInnerWidth() - 140;
        var map = this.map;
        var zoom = this.currentZoom;
        var div = this.bubbleContent;
        var self = this;   
        var myRequest = new Request({
            url: this.options.detailUrl || null,
            data: { cmd: 'loadHtml', id: data.id }, 
            onSuccess: function(response) {
                    var width = maxWidth / 2 < 265 ? 265 : maxWidth / 2;
                    div.setStyles({width: width, height: 'auto'});
                    div.innerHTML = response;
                    var size = div.getDimensions({computeSize: true});
                    if (size.height + 2 > maxHeight) {
                        div.setStyle('height',maxHeight);
                    }                        
                    else {
                        div.setStyle('height',size.height + 2 );
                    }
                div.getElement('a[id=overview_link]').addEvent('click',function(e) {
                    e.stop();
                    self.onListClick(row,index,el);
                }).show();
                map.getMap().updateInfoWindow();
            }.bind(this)
        }).send();
    },
    
    onInfoWindowListMouseover: function(data,row,index,el) {
        el.setStyle('backgroundColor','lightgrey');
    },
        
    onInfoWindowListMouseout: function(data,row,index,el) {
        el.setStyle('backgroundColor','');
    },       
        
    
    open: function(obj) {
        this.domObj.setStyle('display','block');
        this.domObj.setStyle('zIndex',800);    
        this.domObj.resize();
        this.position(this.domObj, this.options.parent, {
            horizontal: ['center center'],
            vertical: ['top 200']
        });
        this.blanket.show();        
        this.shim.show();        
        this.loadPoints(obj);
        window.addEvent('resize',function() {
            this.position(this.domObj, this.options.parent, {
                horizontal: ['center center'],
                vertical: ['top 200']
            });
            this.shim.position();
        }.bind(this));
    },
    
    close: function() {
        this.shim.hide();
        this.blanket.hide();
        this.domObj.setStyle('display','none');
    }
    
    

});