
/* component.js */
/* ======================================================
/etc/designs/investec/default/desktop/js-component/main.js/jcr:content
====================================================== */
var INV = (function ($, document) {
    var api = {},
        modules = {};

    /*
     * Register new module
     * @params name - name of the module
     * @params api - API object of the module
     * @params init - init function for module, if not defined api.init will be used
     */
    api.register = function (name, api, init) {
        modules[name] = {
            name: name,
            api: api,
            init: init || api.init || function () {}
        };
    };

    var initScheduled = false;
    /*
     * Initializes all registered modules
     */
    api.init = function () {
        if (!initScheduled) {
            initScheduled = true;
            INV.ready(function () {
                try {
                    for (var name in modules) if (modules.hasOwnProperty(name)) {
                        modules[name].init();
                    }
                } finally {
                    initScheduled = false;
                }
            });
        }
    };

    /*
     * Wrapper around $(document).ready - fires given function when (or if) document is ready
     */
    api.ready = function (fn) {
        $(document).ready(fn);
    };

    return api;
})(INVjQuery, document);

INV.init();

INVjQuery(document).ready(function(){
    if(typeof $CQ !== "undefined"){
        $CQ(document).bind("cqUtilsLoaded",function(){
            INV.init();
        });
    }
});


// namespace for components
INV.component = {};


// Cookies
// `inspired by` http://www.quirksmode.org/js/cookies.html

INV.cookie = {
    create: function (name, value, days) {
        var expires = "";

        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            expires = "; expires=" + date.toGMTString();
        }

        document.cookie = name + "=" + value + expires + "; path=/";
    },
    read: function (name) {
        var nameEQ = name + "=",
            ca = document.cookie.split(';'),
            c = null;
        for (var i=0; i < ca.length; i++) {
            c = ca[i];
            while (c.charAt(0)==' ') {
                c = c.substring(1,c.length);
            }
            if (c.indexOf(nameEQ) == 0) {
                return c.substring(nameEQ.length,c.length);
            }
        }
        return null;
    },
    erase: function (name) {
        INV.cookie.create(name, "", -1);
    }
};

// Profile
INV.profile = {
	get: function () {
		return INV.cookie.read("userProfile") || "default";
	}
};

// jQuery plugins
// Author: Cognifide

/*
* Find closest child (including selected element) that matches the selector.
* Behaves similar to jquery .closest but it works down
* @param selector      a selector to match elements against
*/
(function ($) {
  $.fn.closestFind = function (selector) {
      if (this.is(selector)) {
          return this;
      }
      
      return this.find(selector);
  };
})(INVjQuery);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.tabs.js/jcr:content
====================================================== */
/**
 * Tabs component - desktop/js-component/component.tabs.js
 */

INV.component.tabs = (function ($, document) {
	var api = {},
		components = {
			firstShow: [],
			show: []
		};

	function raiseEvent($tab, components) {
		var i;

		for (i = 0; i < components.length; i++) {
			var component = components[i];
			if ($tab.find(component.selector).size() > 0) {
				component.handler($tab);
			}
		}
	}

	function addHandler(selector, handler, components) {
		if (typeof(handler) === 'function') {
			components.push({ 'selector': selector,
				'handler': handler 
			});
		}
	}

	api.firstShow = function(selector, handler) {
		addHandler(selector, handler, components.firstShow);
	};

	api.show = function(selector, handler) {
		addHandler(selector, handler, components.show);
	};

	api.init = function () {
		$(".tabs > .inner:not(.initialized)").each(function () {
			var $tabs = $(this);
			
			$tabs.find(".tabTitle").remove();
			
			$tabs.tabs();

			$tabs.find('.ui-tabs-panel.ui-tabs-hide').addClass('firstShow');

			$tabs.tabs({
				'show': function (event, ui) {
					var $tab = $(ui.panel);

					if ($tab.hasClass('firstShow')) {
						raiseEvent($tab, components.firstShow);
						$tab.removeClass('firstShow');
					}
					raiseEvent($tab, components.show);
				}
			});

			$tabs.addClass("initialized");
		});
	};

	return api;
})(INVjQuery, document);

INV.register("tabs", INV.component.tabs);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.backToTop.js/jcr:content
====================================================== */
/**
 * Back to top component - desktop/js-component/component.backToTop.js
 */

INV.component.backToTop = (function ($, document) {
    var api = {};

    api.init = function () {
        $(".backToTop .inner:not(.initialized)").each(function () {
            var $backToTop = $(this);

            $backToTop.delegate("a", "click", function (event) {
                $('html, body').animate({ scrollTop: 0 });
                $(this).blur();
                event.preventDefault();
            });

            $backToTop.addClass("initialized");
        });
    };

    return api;
})(INVjQuery, document);

INV.register("backToTop", INV.component.backToTop);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.carousel.js/jcr:content
====================================================== */
/**
 * Carousel component - desktop/js-component/component.carousel.js
 */

INV.component.carousel = (function ($, document) {
	var api = {};

	api.delay = 5;
	api.init = function () {

		$(".carousel .inner:not(.initialized)").each(function () {
			var $carousel = $(this),
				$slideNav = $carousel.find(".slidesNav").show(),
				$slideControls = $slideNav.find("li:not(.prev):not(.next)"),
				$slides = $carousel.find(".slide"),

				currentActive = $slides.filter(".active").index(),

				timerId = null,
				context = {
					slides: $slides,
					controls: $slideControls,
					timerId: timerId
				};


			$slideNav.delegate("a", "click", function (e) {
				var $this = $(this),
					$parent = $this.parent(),
					index = $slideControls.index($parent);

				if ($parent.is(".prev,.next")) {
					index = $slides.filter(".active").index();
					index = $parent.hasClass("prev") ? index - 1 : index + 1;
				}
				showSlide(index, context);
				$this.blur();
				e.preventDefault();
			});

			$carousel.addClass("initialized");
			showSlide(currentActive, context);
		});

	};

	var showSlide = function (index, context) {
		var $slides = context.slides,
			$controls = context.controls,
			currentActive = $slides.filter(".active").index();

		clearTimeout(context.timerId);

		index = (index < 0) ? $slides.length - 1 :
				(index >= $slides.length) ? 0 : index;

		if (index != currentActive) {
			$slides.stop(true, true);

			if ($.browser.msie && parseInt($.browser.version) == 6) {
				$slides.filter(".active").hide().removeClass("active");
				$slides.eq(index).show().addClass("active").css("zoom", "1");
			} else {
				$slides.filter(".active").fadeOut(function () {
					$(this).removeClass("active").hide();
				});
				$slides.eq(index).fadeIn(function () {
					$(this).addClass("active");
				});
			}

			$controls
				.removeClass("active")
				.eq(index)
				.addClass("active");
		}
		if (api.delay > 0) {
			context.timerId = setTimeout(function () {
				showSlide(index + 1, context);
			}, api.delay * 1000);
		}

	};

	return api;
})(INVjQuery, document);

INV.register("carousel", INV.component.carousel);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.concertina.js/jcr:content
====================================================== */
/**
 * Concertina component - desktop/js-component/compoenent.concertina.js
 */

INV.component.concertina = (function ($, document) {
	var api = {},
		components = {
			visible: [],
			hidden: []
		};

	function raiseEvent($component, components) {
		var i,
			component;

		for (i = 0; i < components.length; i++) {
			component = components[i];
			if ($component.find(component.selector).size() > 0) {
				component.handler($component);
			}
		}
	}

	function addHandler(selector, handler, components) {
		if (typeof(handler) === 'function') {
			components.push({ 
				'selector': selector,
				'handler': handler 
			});
		}
	}

	function onSlideToggle($component) {
		if ($component.is(':visible')) {
			raiseEvent($component, components.visible);
		}
		else {
			raiseEvent($component, components.hidden);
		}
	}

	api.init = function () {

		// default init
		$(".concertina > .inner:not(.initialized)").each(function () {
			var $concertina = $(this),
				isExpanded = $concertina.hasClass("expanded"),
				isMultiple = $concertina.hasClass("multiple"),
				isFirstOpen = $concertina.hasClass("firstItemOpen");

			if (!isExpanded) {
				$concertina.find(".header").first().addClass("firstConcertinaItem");

				$concertina.find(".header").addClass("closed").each(function () {
					$(this).append("<span class='icon'></span>");
				});

				$concertina.delegate(".header", "click", function () {
					var $header = $(this);
					if (!isMultiple) {
						 $concertina.find(".header").not(this).addClass("closed").next().slideUp();
					}
					$header.toggleClass("closed").next().slideToggle(function() {
						onSlideToggle($header.next());
					});
				});

				if (isFirstOpen) {
					$concertina.find(".firstConcertinaItem").click();
				}
			}

			$concertina.addClass("initialized");
		});

		// init child components
		$(".concertina .inner").each(function () {
			var $concertina = $(this);
			$concertina.find(".header").filter(function (index) {
				return $(".icon", this).length == 0;
			}).each(function () {
				$(this).append("<span class='icon'></span>");
			});
		});
	};

	api.visible = function(selector, handler) {
		addHandler(selector, handler, components.visible);
	};

	api.hidden = function(selector, handler) {
		addHandler(selector, handler, components.hidden);
	};

	return api;
})(INVjQuery, document);

INV.register("concertina", INV.component.concertina);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.confirmableContent.js/jcr:content
====================================================== */
/**
 * Confirmable content component - desktop/js-component/compoenent.confirmableContent.js
 */

INV.component.confirmableContent = (function ($, document) {
	var api = {};

	function showWholeContent($confirmableContent) {
		$(".beforeContent", $confirmableContent).show();
		$(".afterContent", $confirmableContent).show();
	}
	
	function switchToAfterContent($confirmableContent) {
		$(".beforeContent", $confirmableContent).hide();
		$(".buttons", $confirmableContent).hide();
		$(".afterContent", $confirmableContent).show();
	}

	api.init = function () {
		$(".confirmableContent .inner:not(.initialized)").each(function () {
			var $confirmableContent = $(this),
				cookieExpire = 365, /* days */
				cookieName = $confirmableContent.data().name,
				cookieValue = INV.cookie.read(cookieName);

			if (editMode) {
				showWholeContent($confirmableContent);
			} else {
				if ("1" == cookieValue) {
					switchToAfterContent($confirmableContent);
				} else {

					$(".agree", $confirmableContent).click(function (e) {
						INV.cookie.create(cookieName, "1", cookieExpire);
						switchToAfterContent($confirmableContent);
						return false;
					});

					$(".disagree", $confirmableContent).click(function (e) {
						return false;
					});

				}
			}

			$confirmableContent.addClass("initialized");
		});
	};

	return api;
})(INVjQuery, document);

INV.register("confirmableContent", INV.component.confirmableContent);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.findNearestBdm.js/jcr:content
====================================================== */
/**
 * find nearest bdm component - desktop/js-component/component.findNearestBdm.js
 */

INV.component.findNearestBdm = (function ($, document) {
	var api = {};

	api.init = function () {
		$(".findNearestBdm > .inner:not(.initialized)").each(function () {
			var $this = $(this),
				$form = $this.find("form"),
				bdms = $form.data("bdms"),
				isMatched = false;


			$form.submit(function (event) {
				var postcode = $form.find("input[name='postcode']").val().toLowerCase(),
					i, bdmPostcode;

				if (postcode.length > 0) {
					for (i = 0; i < bdms.length; i++) {
						bdmPostcode = bdms[i].postcode.toLowerCase();
						if (postcode.indexOf(bdmPostcode) === 0) {
							$form.attr("action", bdms[i].link);
							isMatched = true;
							break;
						}
					}
				}
				if (!isMatched) {
					event.preventDefault();
				}
			});

			$this.addClass("initialized");
		});
	};
	return api;
}(INVjQuery, document));

INV.register("findNearestBdm", INV.component.findNearestBdm);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.findNearestMortgageAdviser.js/jcr:content
====================================================== */
/**
 * find nearest mortgage adviser component - desktop/js-component/component.findNearestMortgageAdviser.js
 */

INV.component.findNearestMortgageAdviser = (function ($, document) {
	var api = {};

	api.init = function () {
		$(".findNearestMortgageAdviser > .inner:not(.initialized)").each(function () {
			var $this = $(this),
				$form = $this.find("form");

			$form.submit(function (event) {
				var postcode = $form.find("input[name='postcode']").val().toLowerCase();
				if (postcode.length > 0) {
					$form.attr("action", $form.attr("action") + "/" + postcode);
				} else {
					event.preventDefault();
				}
			});

			$this.addClass("initialized");
		});
	};
	return api;
}(INVjQuery, document));

INV.register("findNearestMortgageAdviser", INV.component.findNearestMortgageAdviser);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.footer.js/jcr:content
====================================================== */

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.gallery.js/jcr:content
====================================================== */
/**
 * Gallery component - desktop/js-component/component.gallery.js
 */

INV.component.gallery = (function ($, document) {
	var api = {},
		galleries = [];

	function Gallery($wrapper) {
		this.$wrapper = $wrapper;
		this.$thumbs = $wrapper.find(".thumbnails");
		this.$thumbsList = this.$thumbs.find("li");
		this.$thumb = this.$thumbsList.find("img").eq(0);
		this.$thumbsWrapper = this.$thumbs.find(".thumbnailsWrapper");
		this.$imageView = $wrapper.find(".imageView");
		this.arrows = [];
		this.thumbWidth = 0;
		this.thumbHeight = 0;
	}

	Gallery.prototype.init = function() {
		var context = this;

		this.initGalleryNavOrWait();

		this.$thumbsList.delegate("a:not(.editLink)", "click", function (e) {
			var $link = $(this),
			$img = context.$imageView.find("img"),
			$description = context.$wrapper.find(".description");

			$link.offsetParent().find("a:not(.editLink)").removeClass("active");
			$link.addClass("active");

			// Show big image
			
			$img.fadeOut("fast").one('load', function () {
				$(this).fadeIn();
			}).attr("src", $link.attr("href"));
			$description.text($link.data("description"));

			$img.attr("alt", $link.find("img").attr("alt"))
				.attr("title", $link.find("img").attr("title"));

			context.updateEditLink(context.$imageView, $link);

			e.preventDefault();
		});
	};

	Gallery.prototype.initGalleryNavOrWait = function() {
		var context = this;

		if (!this.isImageLoaded(this.$thumb)) {
			this.$thumb.load(function () {
				context.initGalleryNav(context);
			});
		} else {
			this.initGalleryNav();
		}
	};
	
	Gallery.prototype.initGalleryNav = function(callContext) {
		var context = callContext || this, 
		wrapperHeight = context.$thumb.closest("li").height(),
		arrWidth;

		context.thumbWidth = context.$thumb.closest("li").outerWidth();
		context.thumbHeight = context.$thumb.height();
		context.thumbHeight = (context.thumbHeight > wrapperHeight) ? wrapperHeight : context.thumbHeight; 

		context.$thumbs.height(context.thumbHeight);
		context.$thumbs.css("line-height", context.thumbHeight + "px");

		arrWidth = context.resizeWrappers();
		context.showArrows(arrWidth);
		context.scrollMe(0);
	};

	Gallery.prototype.isImageLoaded = function($image) {
		var loaded = false,
		alt;

		if ($image.length > 0) {
			alt = $image[0].alt;
			$image.css("display", "block").attr("alt", "");
			loaded = $image.width() > 0 && $image.height() > 0;
			$image.css("display", "").attr("alt", alt);
		}

		return loaded;
	};

	Gallery.prototype.updateEditLink = function($imageView, $link) {
		var editUrl = $link.data('editurl');

		if (editUrl !== null && editUrl !== undefined) {
			$imageView.find('.editLink').attr('href', editUrl);
		}
	};
	

	Gallery.prototype.resizeWrappers = function() {
		var thumbWrapWidth = Math.floor(this.$thumbsWrapper.width() / this.thumbWidth) * this.thumbWidth,
		$list = this.$thumbsWrapper.find("ul"),
		tWidth = this.$thumbsList.size() * this.thumbWidth,
		arrowWidth = 0,
		context = this,
		$firstImage = this.$imageView.find("img").first(),
		offset;

		// set image preview size
		if (this.isImageLoaded($firstImage)) {
			this.$imageView.height($firstImage.height());
		}
		else {
			$firstImage.one("load", function () {
				context.$imageView.height($(this).height());
			});
		}

		this.$thumbs.height(this.thumbHeight);

		if (thumbWrapWidth >= tWidth) {
			// all miniatures visible
			this.$thumbsWrapper.width(tWidth);
			offset = (this.$thumbs.outerWidth(true) - this.$thumbsWrapper.width()) / 2;
			this.$thumbs.css({"margin-left": offset + "px",
							"margin-right": offset + "px"});
		} else {
			// not all miniatures visible
			// narrow width to show arrows
			$list.width(tWidth);
			this.$thumbsWrapper.width(thumbWrapWidth);
			arrowWidth = (this.$thumbs.width() - thumbWrapWidth) / 2;
			if (arrowWidth < 15) {
				thumbWrapWidth -= this.thumbWidth;
				this.$thumbsWrapper.width(thumbWrapWidth);
				arrowWidth = (this.$thumbs.width() - thumbWrapWidth) / 2;
			}
			this.$thumbs.css({"padding-left": arrowWidth + "px",
							"padding-right": arrowWidth + "px" });
		}
		return arrowWidth;
	};

	Gallery.prototype.showArrows = function(arrWidth) {
		var context = this,
			thumbsDataTracking = this.$thumbs.data("tracking"),
			$arrow;

		if (arrWidth <= 0) { return; }

		$arrow = $("<span class='prev arrow trackEvent' data-tracking-category='Gallery' data-tracking-event='Click' data-tracking-label='Previous Button'>&#x25c4;</span>")
		.width(arrWidth)
		.addClass("disabled")
		.click(function () {
			var x = context.scrollMe(-1);
			if (x <= 1) {
				$(this).addClass("disabled");
				context.$thumbs.find(".arrow.next").removeClass("disabled");
			} else {
				context.$thumbs.find(".arrow").removeClass("disabled");
			}
		})
		.appendTo(this.$thumbs);
		this.arrows.push($arrow);

		$arrow = $("<span class='next arrow trackEvent' data-tracking-category='Gallery' data-tracking-event='Click' data-tracking-label='Next Button'>&#x25ba;</span>")
		.width(arrWidth)
		.click(function () {
			var x = context.scrollMe(1);
			if (x >= context.$thumbsList.size() - (context.$thumbsWrapper.width() / context.thumbWidth) - 1) {
				$(this).addClass("disabled");
				context.$thumbs.find(".arrow.prev").removeClass("disabled");
			} else {
				context.$thumbs.find(".arrow").removeClass("disabled");
			}
		})
		.appendTo(this.$thumbs);
		this.arrows.push($arrow);
	};

	Gallery.prototype.scrollMe = function(x) {
		var scrlLeft = this.$thumbsWrapper.scrollLeft(),
		currentThumb = scrlLeft / this.thumbWidth,
		newPosition = (currentThumb + x) * this.thumbWidth;

		this.$thumbsWrapper.animate({scrollLeft: newPosition + "px"});
		return currentThumb;
	};

	Gallery.prototype.removeArrows = function() {
		var $arrow;

		$arrow = this.arrows.pop();
		while ($arrow != null) {
			$arrow.remove();
			$arrow = this.arrows.pop();
		}
	};

	Gallery.prototype.resize = function() {
		this.$thumbs.css({
			'margin-left': '',
			'margin-right': '',
			'padding-left': '',
			'padding-right': '',
			'height': '',
			'line-height': ''
		});
		this.$imageView.css('height', '');
		this.$imageView.find("img").unbind();
		this.$thumbsWrapper.css('width', '');
		this.$thumbsWrapper.find("ul").css('width', '');

		this.removeArrows();

		this.initGalleryNavOrWait();
	};

	function resize($context) {
		var i, item;

		for (i = 0; i < galleries.length; i++) {
			item = galleries[i];
			if ($context == null || item.$wrapper.parents().is($context)) {
				item.resize();
			}
		}
	}

	function subscribeTabsFirstShowEvent() {
		if (INV.component.tabs != null && INV.component.tabs.firstShow != null 
				&& typeof(INV.component.tabs.firstShow) === 'function') {
			INV.component.tabs.firstShow('.gallery', resize);
		} 
	}
	
	api.init = function () {
		$(".gallery .inner:not(.initialized)").each(function () {
			var $wrapper = $(this), 
			gallery = new Gallery($(this));

			galleries.push(gallery);
			gallery.init();

			$wrapper.addClass("initialized");
		});
		subscribeTabsFirstShowEvent();
	};

	return api;
}(INVjQuery, document));

INV.register("gallery", INV.component.gallery);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.heroCarousel.js/jcr:content
====================================================== */
/*global INV:true, innerShiv:true */

/**
 * Hero carousel component - desktop/js-component/component.heroCarousel.js
 */

INV.component.heroCarousel = (function ($, document) {
    var api = {};

    var SHOW_ANIMATION_SPEED = 500,
        HIDE_ANIMATION_SPEED = 500,
        COOKIE_NAME = "INVESTEC_HERO_CONFIG";

    var random = function (min, max) {
        return Math.floor(Math.random() * max + min);
    };
  
    // choose one item for each slot from the list of all items
    // by default first items are taken
    var chooseItems = function ($items, method, id) {
        var $slot1, $slot2, $slot3, heroItems;

        var cookieValue = INV.cookie.read(COOKIE_NAME + "_" + id);

        //get stored hero items config
        if (cookieValue) {
            heroItems = JSON.parse(cookieValue);
        } else { //or create new one if not found
            heroItems = {};
            heroItems.slot1 = random(0, $items.find(".slot1 > div").length);
            heroItems.slot2 = random(0, $items.find(".slot2 > div").length);
            heroItems.slot3 = random(0, $items.find(".slot3 > div").length);
            heroItems.active = random(0, 3);
        }

        //chose active slot
        switch(method) {
            case "random":
                heroItems.active = random(0, 3);
                break;
            case "sequential":
                heroItems.active = ++heroItems.active % 3;
                break;
            case "fixed":
				break;
            default:
                //set first items
                heroItems.slot1 = 0;
                heroItems.slot2 = 0;
                heroItems.slot3 = 0;
                // check which element should be active
                heroItems.active = $items.find(".active").index();
                if (heroItems.active === -1) { heroItems.active = 0; }
        }
        //store config
        cookieValue = JSON.stringify(heroItems);
        INV.cookie.create(COOKIE_NAME + "_" + id, cookieValue);

        //get dom elements
        $slot1 = $items.find(".slot1 > div:eq(" + heroItems.slot1 + ")");
        $slot2 = $items.find(".slot2 > div:eq(" + heroItems.slot2 + ")");
        $slot3 = $items.find(".slot3 > div:eq(" + heroItems.slot3 + ")");

        var $chosen = $($slot1).add($slot2).add($slot3);
        $chosen.eq(heroItems.active).addClass("active");

        return $chosen;
    };

  
    var afterHeroItemInit = function ($item, $contentItem) {
        var $video = $contentItem.find(".videoPlayer video");
        if ($video.length) {
            $video[0].player.addEventListener("fullscreenchange", function (isFullscreen) {
                //console.log("fullscreenchange", arguments);
                if (isFullscreen) {
                    $contentItem.closest(".heroCarousel").addClass("fullscreen");
                } else {
                    $contentItem.closest(".heroCarousel").removeClass("fullscreen");
                }
            });
			$video.data("tracking", $item.data("tracking-base"));
        }
    };

    var beforeHeroItemInit = function ($item, $contentItem) {
        var $video = $contentItem.find(".videoPlayer video");
        $video.attr("data-features-share", "false");
        if ($.browser.msie && parseInt($.browser.version, 10) === 7) {
            $video.attr("data-features-fullscreen", "false");
        }
    };

    var beforeHeroChange = function ($currentContent) {
        var $video = $currentContent.find(".videoPlayer video");

        if ($video.length) {
            $video.data("mediaelementplayer").pause();
            $currentContent.closest(".heroCarousel").removeClass("fullscreen");
        }

    };
  
    // builds single hero item
    var buildHeroItem = function (item) {
        var $item = $(item).addClass("heroItem");
        var $image = $("<a>", {
                "class": "thumbnail trackEvent",
                "href": $item.data("thumbnail-link"),
                "data-tracking-category": "Hero Carousel",
                "data-tracking-event": "Expand/Collapse",
                "data-tracking-label": $item.data("tracking-label")
            }).prependTo($item);
        $("<img>", { src: $item.data("thumbnail-src") }).appendTo($image);

        $image.append($item.find(".shortDescription"));
        if ($item.find(".heroReadMore").length) {
            $item.find(".longDescription").addClass("clickable");
        }

        var $contentItem = $("<div class='contentItem'>");

        if ($item.hasClass("active")) {
            $contentItem.addClass("active");
        }

        $contentItem.append($item.find("> .title"));

        $.get($item.data("ajax-content-url"), function (content) {
            $contentItem.prepend(innerShiv(content));
            beforeHeroItemInit($item, $contentItem);
            INV.init(); // initialize added components
            afterHeroItemInit($item, $contentItem);

            if ($contentItem.hasClass("active")) {
                $contentItem.css({opacity: 0});
                var $image = $contentItem.find(".image img");

                if ($image.length) {
                    $image.load(function () {
                        $contentItem.animate({opacity: 1}, SHOW_ANIMATION_SPEED, function () {
                            $contentItem.find("> .title").add($item.find(".longDescription"))
                                .animate({bottom: 0}, SHOW_ANIMATION_SPEED);
                        });
                    });
                } else {
                    $contentItem.animate({opacity: 1}, SHOW_ANIMATION_SPEED, function () {
                        $contentItem.find("> .title").add($item.find(".longDescription"))
                            .animate({bottom: 0}, SHOW_ANIMATION_SPEED);
                    });
                }
            }
        });

        return [ $item, $contentItem ];
    };

    var buildContent = function ($heroCarousel, $items) {
        var $heroItems = $heroCarousel.find(".heroItems").empty(),
            $contentItems = $heroCarousel.find(".contentItems").empty();

        $items.each(function () {
            var built = buildHeroItem(this);

            $heroItems.append(built[0]);
            $contentItems.append(built[1]);

        });
    };



    api.init = function () {
        $(".heroCarousel > .inner:not(.initialized)").each(function () {
            var $heroCarousel = $(this);
            var $allItems = $heroCarousel.find(".allItems");
            var items = chooseItems($allItems, $allItems.data("item-choice-method"), $allItems.data("id"));
            buildContent($heroCarousel, items);

            var $contentItems = $heroCarousel.find(".contentItem"),
                $heroItems = $heroCarousel.find(".heroItem");

            var isAnimated = false;
            $heroItems.delegate(".thumbnail", "click", function (evt) {
                var $heroItem = $(this).closest(".heroItem");

                if (isAnimated || $heroItem.hasClass("active")) {
                    evt.preventDefault();
                    evt.stopPropagation();
                    return;
                }

                var $contentItem = $contentItems.eq($heroItem.index()),
                    $currentHero = $heroItems.filter(".active"),
                    $currentContent = $contentItems.filter(".active");

                beforeHeroChange($currentContent);

                //console.log("hide descriptions started")

                var $currentTitle = $currentContent.find("> .title");

                //console.log("hide images started");
                var $heroDesc = $heroItem.find(".thumbnail");
                isAnimated = true;

                // ANIMATION STEP 1
                // ------------------
                // fade out main content and thumbnail of clicked item
                // slide down description and title
                $currentContent
                    .animate({opacity:0}, {
                        duration: HIDE_ANIMATION_SPEED,
                        step: function (now) {
                            $heroDesc.css({opacity: now});

                            var b = (now-1) * 195;

                            $currentHero.find(".longDescription").css({bottom: b});
                            $currentTitle.css({bottom: b});
                        },
                        complete: function () {
                            //console.log("hide images ended");
                            $currentHero.removeClass("active");
                            $currentContent.removeClass("active");
                            $heroItem.addClass("active");

                            //console.log("show image started")
                            var $heroDesc = $currentHero.find(".thumbnail");

                            // ANIMATION STEP 2
                            // ------------------
                            // fade in new main content and thumbnail of previous item
                            $contentItem.css({opacity:0}).addClass("active").animate({opacity:1}, {
                                duration: SHOW_ANIMATION_SPEED,
                                step: function (now) {
                                    $heroDesc.css({opacity: now});
                                },
                                complete: function () {
                                    //console.log("show image ended")
                                    //console.log("slide descriptions started")
                                    var $title = $contentItem.find("> .title");

                                    // ANIMATION STEP 3
                                    // ------------------
                                    // slide in title and description of current item
                                    $heroItem.find(".longDescription").animate({bottom: 0}, {
                                        duration: SHOW_ANIMATION_SPEED,
                                        step: function (now) {
                                            $title.css({bottom: now});
                                        },
                                        complete: function () {
                                            //console.log("slide descriptions ended")
                                            isAnimated = false;
                                        }
                                    });
                                }
                            });
                        }
                    });

                evt.preventDefault();
            });
            $heroItems
                .delegate(".longDescription.clickable", "hover", function (e) {
                    var $readMore = $(this).find(".heroReadMore");
                    if ($readMore.length) {
                        $readMore.toggleClass("hover");
                    }
                })
                .delegate(".longDescription.clickable", "click", function (e) {
                    // if any link is clicked, just do what link does
                    if (e.target.tagName.toLowerCase() === "a") { return; }

                    // if clicked anywhere inside and there is read more link, go there
                    var $readMore = $(this).find(".heroReadMore");
                    if ($readMore.length) {
                        window.location.href = $readMore.attr("href");
                    }
                })
                .mouseenter(function () {
                    var $thumb = $(this).find(".thumbnail img");
                    $thumb.animate({opacity: 0.8}, 300);
                    setTimeout(function () {
                        $thumb.animate({opacity: 1}, 100);
                    }, 500);
                });

            $heroCarousel.addClass("initialized");
        });
    };

    return api;
})(INVjQuery, document);

INV.register("heroCarousel", INV.component.heroCarousel);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.lightBox.js/jcr:content
====================================================== */
/**
 * Lightbox component - desktop/js-component/component.lightbox.js
 */

INV.component.lightbox = (function ($, document) {
	var api = {},
		$lbOverlay,
		$lbContainer,
		$lbContent,
		$lbHeader,
		lbReady,
		createLightboxMarkup,
		loadLightboxContent,
		appendContent,
		showLightbox,
		hideOverlays,
		positionLightbox,
		applyIEFix = $.browser.msie && parseInt($.browser.version) <= 7,
		assignFx,
		trackEvent,
		fx,
		permanent = false,
		lastConfig = null;

	assignFx = function() {
		fx = {
			show: applyIEFix ? 'show' : 'fadeIn',
			hide: applyIEFix ? 'hide' : 'fadeOut'
		};
	};

	trackEvent = function (config, defaultEvent) {
		var trackingEvent = defaultEvent;

		if (config != null) {
			if (config.tracking != null && $.trim(config.tracking) != "") {
				tracking = config.tracking;
			}
			if (config.trackingEvent != null && $.trim(config.trackingEvent) != "") {
				trackingEvent = config.trackingEvent;
			}
		}

		if (INVTRACKING != null) {
			INVTRACKING.trackVirtualEvent("Lightbox", defaultEvent, trackingEvent);
		}
	};

	createLightboxMarkup = function () {
		lbReady = 1;
		$("body").
			append("<div class='lightboxOverlay'></div>").
			append("<div class='lightboxContainer main'><div class='lbHeader'><h1></h1><span class='lbClose'>X</span></div><div class='lbContent'></div></div>");
		$lbOverlay = $(".lightboxOverlay");
		$lbContainer = $(".lightboxContainer");
		$lbHeader = $lbContainer.find(".lbHeader");
		$lbContent = $(".lbContent");
		assignFx();

		$(".lbClose").click(function (e) {
			hideOverlays();
		});
		$lbOverlay.click(function (e) {
			hideOverlays();
			// TODO: ESC key should close lightbox too.
		});
	};

	loadLightboxContent = function (config) {
		var jqxhr = $.ajax({
			type: "GET",
			url: config.url,
			dataType: "html",
			beforeSend: function (xc) {
				// TODO: show progress bar?
				//$lbOverlay.fadeIn();
				$lbOverlay[fx.show]();
				if (applyIEFix) {
					$lbOverlay.height($(document).height());
				}
			},
			success: function (r) {
				appendContent(r, config);
				showLightbox(config);
			}
		});
	};

	appendContent = function (content, config) {
		var title = '',
			dataTitle;

		$lbContent.empty().append(content);

		dataTitle = $lbContent.find('.lightbox').data('title');

		if (dataTitle != null && dataTitle.length > 0) {
			title = dataTitle;
		}
		else if (config) {
			title = config.title;
		}
		else if (lastConfig) {
			title = lastConfig.title;
		}

		$lbContainer.find(".lbHeader h1").text(title);
	};

	showLightbox = function (config) {
		if (config) {
			lastConfig = config;
		} else {
			config = lastConfig;
		}
		
		if(config.permanent){
			permanent = true;
			$('.lbClose').hide();
		} else {
			permanent = false;
			$('.lbClose').show();
		}
		
		if (config.opaque) {
			$(".lightboxOverlay").addClass("opaque");
		}

		positionLightbox(config);
		//$lbContainer.fadeIn();
		$lbContainer[fx.show]();
		INV.init();
		$(window).bind("resize.lightbox", function () {
			positionLightbox(config);
		});

		trackEvent(config, "Open lightbox");
	};

	// Hide overlays and clear content
	hideOverlays = function () {

		if(!permanent){

			var isResizeRequired = applyIEFix;
			//$lbOverlay.fadeOut();
			$lbOverlay[fx.hide]();
			//$lbContainer.fadeOut(function () {
			$lbContainer[fx.hide](function () {
				$lbContent.empty();
				$(window).unbind("resize.lightbox");
			});

			trackEvent(lastConfig, "Close lightbox");
		}
		
	};

	positionLightbox = function (config) {
		if (!config) {
			config = lastConfig;
		}

		$lbContainer.css({ visibility: "hidden", display: "block"});

		// somehow IE7 has problem with setting proper width for container:
		if (applyIEFix) {
			var $lightbox = $lbContent.find('.lightbox');

			$lbContainer.width($lightbox.outerWidth(true));
			$lbHeader.width($lightbox.width());
		}

		var offset = { top: 0, left: 0 };

		var cw = $lbContainer.width(),
			ch = $lbContainer.height(),
			sw = $("body").width(),
			sh = applyIEFix ? $(document).height() : $("body").height();

		if (config.alignTo) {
			var o = $(config.alignTo).offset();
			offset.top = o.top;
			offset.left =  o.left + $(config.alignTo).outerWidth() - cw;
		} else {
			offset.top = Math.max( (sh/3 - ch/2) - $("html").offset().top , 5);
			offset.left = (sw/2 - cw/2);
		}

		offset.visibility = "visible";
		offset.display = "none";

		$lbContainer.css(offset);

		/*
		if (applyIEFix) {
			$lbContainer.show();
		} else {
			$lbContainer.fadeIn("slow");
		}*/
		$lbContainer[fx.show](applyIEFix ? null : 'slow');
	};

	api.insertContent = function (obj) {
		//$lbOverlay.fadeIn();
		$lbOverlay[fx.show]();
//		var $o = $(obj);
//		var cleanHtml = $o.html().replace(/[\n\r]/gi, "").replace(/<script[^>]*?>.*?<\/script>/gi, "").replace(/height: 80px;/gi, "");
		appendContent(obj);
		positionLightbox();
	};

	api.closeLightbox = function () {
		hideOverlays();
	};

	api.init = function () {
		if (!lbReady) {
			createLightboxMarkup();
		}

		$("a.lightbox:not(.initialized)").each(function () {
			var $t = $(this),
				h = $t.attr("href"),
				r1 = /^\//,
				r2 = /((\.[^\/]+)*\.html)/i;

				if (r1.test(h)) {
					h = h.replace(r2, ".lightbox$1");
					$t.attr("href", h);
				}
			$t.click(function (e) {
				var config = {
						url: $(this).attr("href"),
						title: $(this).attr("title"),
						tracking: $(this).data("tracking"),
						trackingEvent: $(this).data("tracking-event")
				};

				// when 'lightbosAlignTo' class is set
				// lightbox will be aligned to top right corner of this element
				// this is used for social links popup in Site Tools
				if ($(this).hasClass("lightboxAlignTo")) {
					config.alignTo = $(this);
				}
				
				// when 'permanent' class is set
				// user can't close lightbox
				if ($(this).hasClass("permanent")) {
					config.permanent = true;
				}
				
				if ($(this).hasClass("opaque")) {
					config.opaque = true;
				}
				
				loadLightboxContent(config);
				e.preventDefault();
			});
			$t.addClass("initialized");
		});
	};

	return api;
}(INVjQuery, document));

INV.register("lightbox", INV.component.lightbox);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.navigation.js/jcr:content
====================================================== */

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.richText.js/jcr:content
====================================================== */

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.googleMap.js/jcr:content
====================================================== */
/**
 * GoogleMap component - desktop/js-component/component.googleMap.js
 */

INV.component.googleMap = (function ($, document) {
	var api = {},
		isInitialized = false,
		mapApiUrl = 'http://maps.googleapis.com/maps/api/js?sensor=false',
		LoadingStatus = (function () {
			return {
				notLoaded: {},
				loading: {},
				loaded: {}
			};
		} ()),
		apiStatus = LoadingStatus.notLoaded,
		mapConfigs = [],
		maps = [],
		defaultConfig = {
			latitude: 0.0,
			longitude: 0.0,
			zoom: 10,
			marker_title: '',
			description: '',
			width: null,
			height: 250
		};

	function loadMapApi() {
		apiStatus = LoadingStatus.loading;
		$.getScript(mapApiUrl + '&callback=INV.component.googleMap.onMapApiLoaded');
	}

	function resizeInfoWindowContent($container) {
		var $contentContainer = $container.find('.richText').parent().parent();
		$contentContainer.css('width', $contentContainer.width() - 20);
	}

	function createMapInfoWindow(map, marker, config) {
		var infoWindow = new google.maps.InfoWindow({
			content: '<div class="richText">' + config.description + '</div>'
		}),
		openWindowDelegate = function () {
			infoWindow.open(map, marker);
		},
		initLightBoxDelegate = function () {
			if (INV.component.lightbox != null && INV.component.lightbox.init != null
					&& typeof(INV.component.lightbox.init) === 'function') {
				INV.component.lightbox.init();
			}
		},
		resizeContent = function () {
			resizeInfoWindowContent(config.$container);
		};

		google.maps.event.addListener(marker, 'click', openWindowDelegate);
		google.maps.event.addListenerOnce(map, 'tilesloaded', openWindowDelegate);
		google.maps.event.addListenerOnce(infoWindow, 'domready', initLightBoxDelegate);
		google.maps.event.addListenerOnce(infoWindow, 'domready', resizeContent);

		return infoWindow;
	}

	function createMap(config) {
		var latLang = new google.maps.LatLng(config.latitude, config.longitude),
		options = {
			zoom: config.zoom,
			center: latLang,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		},
		map = null,
		marker = null,
		infoWindow = null;

		config.$container.height(config.height + 'px');
		if (config.width !== null) {
			config.$container.width(config.width + 'px');
		}

		map = new google.maps.Map(config.$container.get(0), options);
		marker = new google.maps.Marker({
			position: latLang,
			map: map,
			title: String(config.marker_title)
		});

		if (config.description.length > 0) {
			infoWindow = createMapInfoWindow(map, marker, config);
		}

		maps.push({
			$container: config.$container,
			center: latLang,
			map: map,
			infoWindow: infoWindow
		});
	}

	function initializeMapsIfCan() {
		var config = null;

		if (isInitialized && apiStatus === LoadingStatus.loaded) {
			config = mapConfigs.pop();
			while (config != null) {
				createMap(config);
				config = mapConfigs.pop();
			}
		}
	}

	function resize($context) {
		var i, item;

		for (i = 0; i < maps.length; i++) {
			item = maps[i];
			if ($context == null || item.$container.parents().is($context)) {
				google.maps.event.trigger(item.map, 'resize');
				item.map.panTo(item.center);
				if (item.infoWindow != null) {
					item.infoWindow.close();
					item.infoWindow.open(item.map);
					google.maps.event.addListenerOnce(item.infoWindow, 'domready', function () {
						resizeInfoWindowContent(item.$container);
					});
				}
			}
		}
	}

	function subscribeTabsShowEvent() {
		if (INV.component.tabs != null && INV.component.tabs.show != null 
				&& typeof(INV.component.tabs.show) === 'function') {
			INV.component.tabs.show('.googleMap', resize);
		} 
	}

	function subscribeConcertinaVisibleEvent() {
		if (INV.component.concertina != null && INV.component.concertina.visible != null
			&& typeof(INV.component.concertina.visible) === 'function') {
			INV.component.concertina.visible('.contentElements, .manualConcertinaItemContent', resize);
		}
	}

	api.init = function () {
		$(".googleMap .inner:not(.initialized)").each(function () {
			var $googleMap = $(this),
			$container = $googleMap.find(".map"),
			config;

			if ($container.length > 0) {
				config = $.extend({}, defaultConfig, $container.data());
				config.$container = $container;
				mapConfigs.push(config);

				if (apiStatus === LoadingStatus.notLoaded) {
					loadMapApi();
				}

				$googleMap.addClass("initialized");
			}
		});
		subscribeTabsShowEvent();
		subscribeConcertinaVisibleEvent();

		isInitialized = true;

		initializeMapsIfCan();
	};

	api.onMapApiLoaded = function () {
		if (apiStatus === LoadingStatus.loading && google && google.maps) {
			apiStatus = LoadingStatus.loaded;
			initializeMapsIfCan();
		}
	};

	return api;
}(INVjQuery, document));

INV.register('googleMap', INV.component.googleMap);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.table.js/jcr:content
====================================================== */
/**
 * table component - desktop/js-component/component.table.js
 */

INV.component.table = (function ($, document) {
	var api = {};

	api.init = function () {
		$(".table:not(.initialized)").each(function () {
			var $table = $(this);

			$table.find("table tr:even").addClass("even");

			var $button = $table.find(".table-button");
			$button.click(function () {
				var wrapper = $(this).closest(".table-wrapper");
				var heightB = $(window).height() /2;
				var widthB = $(window).width() /2;
				var link = $(this).attr("href");
				window.open(link, "", "menubar=1,resizable=1,scrollbars=1,width=" + widthB + ",height=" + heightB);
				return false;
			});

			$table.addClass("initialized");
		});
	};
	return api;
})(INVjQuery, document);

INV.register("table", INV.component.table);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.megaMenu.js/jcr:content
====================================================== */
/**
 * Mega Menu component - desktop/js-component/component.megaMenu.js
 */

INV.component.megaMenu = (function ($, document) {
	var api = {};

	function adjustColumnsHeight($columns) {
		var maxHeight = 0;

		$columns.each(function() {
			var $column = $(this),
				columnHeight = $column.height();

			maxHeight = columnHeight > maxHeight ? columnHeight : maxHeight;
		});
		if (maxHeight > 0) {
			$columns.height(maxHeight);
		}
	}

	function isColumnsHeightAdjusted(adjustedColumns, $columns) {
		var isAdjusted = false,
			i;

		for (i = 0; i < adjustedColumns.length; i++) {
			if (adjustedColumns[i].is($columns)) {
				isAdjusted = true;
				break;
			}
		}

		return isAdjusted;
	}

	api.init = function () {
		$(".megaMenu .inner:not(.initialized)").each(function () {
			var $megaMenu = $(this),
				$navTop = $megaMenu.find(".navTop"),
				navWidth = $navTop.width(),
				adjustedColumns = [];

			// Positionioning submenus according to specification
			$navTop.find("> ul > li").each(function () {
				var $item = $(this),
					$columns = $item.find(".columns"),
					pos = -$item.position().left -10,
					col;
				col = $item.addClass("hover").find(".col").outerWidth(); /* submenus column width */
				$item.removeClass("hover");
				
				// Sumbenus columns have their own grid layout except some cases:
				// skip all, when there is no submenu
				if (col!=null){
					// submenu with one column will be always under proper item regardless menu grid
					if ( $columns.hasClass("col_1") ){
						pos = -20;
					} else {
						// check, if shifted submenu is under current item
						// if not then move whole submenu one column right and check again
						while ( (-pos + $item.width()) > $columns.outerWidth(true) ){
							pos = pos + col;
						}
					}
				}
				$columns.css("left", pos);
				
/* 
				var $item = $(this),
					$columns = $item.find(".columns"),
					total = $columns.width() + $item.position().left;

				if (total > navWidth) {
					$columns.css("left", navWidth - total);
				}
*/
			});
			
			/*for ie6 :hover*/
			$(".navTop > ul > li").hover(
				function () {
					var $item = $(this),
						$columns = $item.find('.columns .col');

					$item.addClass("hover");
					if ($columns.length > 0 && !isColumnsHeightAdjusted(adjustedColumns, $columns)) {
						adjustColumnsHeight($columns);
						adjustedColumns.push($columns);
					}
				},
				function () {
					$(this).removeClass("hover");
				}
			);

			$megaMenu.addClass("initialized");
		});
	};

	return api;
}(INVjQuery, document));

INV.register("megaMenu", INV.component.megaMenu);
/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.browse.js/jcr:content
====================================================== */
/**
 * Browse component - desktop/js-component/component.browse.js
 */

INV.component.browse = (function ($, document) {
	var api = {};

	api.init = function () {
		$(".officeBrowser.inner:not(.initialized)").each(function () {
			var $browse = $(this);
			$("div.regionDropdown h4", $browse).each(function (i) {
				var $h4 = $(this);
				$("select.regionDropdown", $browse).append("<option value=" + i + ">" + $h4.text() + "</option");
			});
			disable(true, $browse);
			$(".officeBrowserData", $browse).hide();
			addSelectOfficeOption($browse);
			$(".select-box", $browse).show();

			$browse.addClass("initialized");
		});
 
		$("select.regionDropdown").change(function () {
			var $select = $(this);
			var wrapper =  $select.closest(".browse");
			var arr = "";
			$select.find("option:selected").each(function () {
				if ($(this).val() != "") {
					var obj = $("div.regionDropdown:eq(" + $(this).val() + ") li a");
					arr = $.makeArray(obj);
					addSelectOfficeOption(wrapper);
					$("select.officeDropdown", wrapper).prop("disabled", null);
					disable(false, wrapper);
				} else {
					disable(true, wrapper);
				}
			});
			$.each(arr, function (i) {
				$("select.officeDropdown", wrapper).append("<option value=" + $(this).attr("href") + ">" + $(this).text() + "</option");
			});
		});

		$("select.officeDropdown").change(function () {
			var $select = $(this);
			var wrapper =  $select.closest(".browse");
			$select.find("option:selected").each(function () {
				if ($(this).val() != "") {
					$(".action", wrapper).fadeTo("fast", 1).removeClass("disable");
					$(".action a", wrapper).attr({"href": $(this).val()});
				} else {
					disable(false, wrapper);
				}
			});
		});

		function addSelectOfficeOption($wrapper) {
			var $officeDropDown = $("select.officeDropdown", $wrapper),
			label = $officeDropDown.attr("title");

			$officeDropDown.empty().append("<option value=\"\">" + label + "</option>");
		}

		function disable (select, wrapper) {
			if (select) {
				$("select.officeDropdown", wrapper).attr('disabled', 'disabled');
			}
			$(".action", wrapper).fadeTo("fast", 0.5).addClass("disable");
			$(".action a", wrapper).attr({"href": "javascript:void(0)"});
		}
	};

	return api;
})(INVjQuery, document);

INV.register("browse", INV.component.browse);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.videoPlayer.js/jcr:content
====================================================== */
/**
 * Videoplayer component - desktop/js-component/component.videoPlayer.js
 */
INV.component.videoplayer = (function ($, document) {
	var api = {};

	function setTitleWidth($videoPlayer, $video) {
		var $title = $videoPlayer.find('h3').first(),
			videoOuterWidth = $video.outerWidth(),
			outerWidth = $title.outerWidth();
		$title.width(videoOuterWidth - (outerWidth - $title.width()));
	}

	function attachControlsSizeUpdate($videoplayer, vidElement) {
		var $rail = null,
		onFullScreenChange = function(isFullscreen) {
			if (!isFullscreen) {
				vidElement.player.setControlsSize();
			}
		};

		if (mejs.MediaFeatures.isIE) {
			$rail = $videoplayer.find('.mejs-time-rail');
			vidElement.player.addEventListener("fullscreenchange", onFullScreenChange);
		}
	}

	function resize($container) {
		var $video = $container.find('video'),
			videoElement = $video.get(0);

		if (videoElement != null && videoElement.player != null 
				&& typeof videoElement.player.setControlsSize === 'function') {
			videoElement.player.setControlsSize();
		}
	}

	function subscribeTabsShowEvent() {
		if (INV.component.tabs != null && INV.component.tabs.show != null 
				&& typeof(INV.component.tabs.show) === 'function') {
			INV.component.tabs.show('.videoPlayer', resize);
		} 
	}

	api.init = function () {

		$(".videoPlayer > .inner:not(.initialized)").each(function () {

			var $videoplayer = $(this),
				$video = $videoplayer.find("video"),
				shareEnabled = $video.data("features-share") === undefined ? true : $video.data("features-share"),
				fullscreenEnabled = $video.data("features-fullscreen") === undefined ? true : $video.data("features-fullscreen"),
				vidElement = $video[0];

			var allFeatures = {
				'playpause' : true,
				'progress' :  true,
				'current': true,
				'duration': true,
				'tracks': true,
				'share': shareEnabled,
				'volume': true,
				'fullscreen': fullscreenEnabled,
				'related': true
			};
			var enabledFeatures = $.map(allFeatures, function (value, key) {
				return value ? key : null;
			});

			function trackEvent (eventName, eventLabel) {
				var trackingData = eventLabel + ",source:" + vidElement.currentSrc;
				if (INVTRACKING != null) {
					INVTRACKING.trackVirtualEvent("Video", eventName, trackingData);
				}
			}
			
			// we'll serve FLV version for IE < 9
			if($.browser.msie && parseInt($.browser.version) < 9){
				var src = new Array(),
					flvSrc;
				$video.find("source").each(function(){
					if (this.src.indexOf(".flv")!=-1){
						flvSrc = this.src;
					} else {
						src.push(this);
					}
				});
				if (flvSrc != null && src.length){
					$(src).each(function(){
						$(this).remove();
					})
				}
			}
			
			$video.mediaelementplayer({
				features: enabledFeatures,
				plugins: ['flash','silverlight'],
				pluginPath: cq5uipath + '/desktop/video/',
				flashName: "flashmediaelement.swf",
				silverlightName: "silverlightmediaelement.xap",
				iPadUseNativeControls: true,
				success: function (mediaElement, domObject){
					mediaElement.addEventListener("ended", function (e) {
						if (vidElement.player.isFullScreen) {
							vidElement.player.exitFullScreen();
						}
						trackEvent("Finished", "Video Finished");
					}, false);
					mediaElement.addEventListener("pause", function (e) { trackEvent("Pause", "Pause button"); }, false);
					mediaElement.addEventListener("play", function (e) { trackEvent("Play", "Play button"); }, false);
					mediaElement.addEventListener("seeked", function (e) { trackEvent("Seeking", "Seek bar"); }, false);
				}
			});
			$videoplayer.addClass("initialized");

			setTitleWidth($videoplayer, $video);
			attachControlsSizeUpdate($videoplayer, vidElement);
		});
		subscribeTabsShowEvent();
	};

	return api;
})(INVjQuery, document);

INV.register("videoplayer", INV.component.videoplayer);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.videoPlayerGallery.js/jcr:content
====================================================== */
/**
 * Videoplayer component - desktop/js-component/component.videoPlayer.js
 */

INV.component.videoPlayerGallery = (function ($, document) {
	var api = {};

	api.init = function () {

		$(".videoPlayerGallery > .inner:not(.initialized)").each(function () {
			var $videoGallery = $(this),
				$content = $videoGallery.find("> .componentContent");

			var playlistDataUrl = $videoGallery.data("playlist-json");
			var trackingBase = $videoGallery.data("tracking-base");

			if (playlistDataUrl) {
				$.getJSON($videoGallery.data("playlist-json"), function (data) {

					if (!data.videos) { 
						return;
					}

					var $descContainer = $("<div class='descContainer'>").appendTo($content);
					var $videoContainer = $("<div class='videoPlayer'>").appendTo($content);
					var $playlistContainer = $("<div class='playlistContainer'>").appendTo($content);
					var $thumbsContainer = $("<div class='thumbsContainer'>").appendTo($playlistContainer);

					var $ul = $("<ul class='items'>");

					$.each(data.videos, function (idx, video) {
						function trancateDescription(text, limit) {
							if (text != null) {
								text = $.trim(text).replace(/(\s)+/i," ");
								if (text.length >= limit - 3) {
									text = text.substr(0, 43).split(" ").slice(0, -1).join(" ") + "...";
								}
							}
							return text;
						}
						video.sources = [
							{ src: video.mp4_high, type: 'video/mp4' },
							{ src: video.webm_high, type: 'video/webm' },
							{ src: video.ogg_high, type: 'video/ogg' },
							{ src: video.flv, type: 'video/flv' }
						];

						$('<li>'
							+ (video.thumb_sml ? ('<img src="' + video.thumb_sml + '" />') : 
								( video.thumb ? ('<img src="' + video.thumb + '" />') : '') )
							+ '<div class="videoDesc">'
								+ '<h4>' + video.name + '</h4>'
								+ '<span class="date">' + video.video_date + '</span>'
								+ '<p>' + trancateDescription(video.desc, 46)
									+ ' <a href="#play" class="play">Play</a>'
								+ '</p>'
							+ '</div>'
							+ '</li>')
							.data("video", video)
							.appendTo($ul);
					});

					$ul.appendTo($thumbsContainer);

					if ($ul.outerHeight() > 320) {
						$thumbsContainer
							.before("<a href='#prev' class='prev'>&#x25b2;</a>")
							.after("<a href='#next' class='next'>&#x25bc;</a>")
							.addClass("scrollable")
							.scrollable({ vertical: true });
					}

					$thumbsContainer.delegate("li", "click", function (evt) {
						evt.preventDefault();
						$(this).addClass("active");
						setVideo($(this).data("video"));
					});

					var video = document.createElement("video"),
						firstVideo = data.videos[0];

					if (video.canPlayType) {
						mejs.HtmlMediaElement.setSrc.call(video, firstVideo.sources);
					} else {
						video.src = firstVideo.sources[0].src;
					}

					// set FLV for MSIE >= 9
					if($.browser.msie && parseInt($.browser.version) < 9 && firstVideo.flv){
						video.src = firstVideo.flv;
					}

					video.width = "570";
					video.height = "320";

					$videoContainer.append(video);

					function trackEvent (eventName) {
						var trackingData = trackingBase + ",source:" + $(video).attr("src") + ", " + $descContainer.data("name");
//						if (INVTRACKING != null) {
//							INVTRACKING.trackVirtualEvent("videoplayer", eventName, trackingData);
//						}
					}

					var player = new MediaElementPlayer(video, {
						plugins: ['flash','silverlight'],
						pluginPath: cq5uipath + '/desktop/video/',
						flashName: "flashmediaelement.swf",
						silverlightName: "silverlightmediaelement.xap",
						iPadUseNativeControls: true,
						poster: firstVideo.thumb,
						success: function (mediaElement, domObject) {
							mediaElement.load();
							mediaElement.addEventListener("ended", function (e) {
								if (player.isFullScreen) {
									player.exitFullScreen();
								}
								trackEvent("ended");
							}, false);
							mediaElement.addEventListener("pause", function (e) { trackEvent("pause"); }, false);
							mediaElement.addEventListener("play", function (e) { trackEvent("play"); }, false);
							mediaElement.addEventListener("seeked", function (e) { trackEvent("seeking"); }, false);
						}
					});

					setDescription(firstVideo);

					function setVideo(data) {
						setDescription(data);
						player.pause();
						// FLV for IE <9
						if($.browser.msie && parseInt($.browser.version) < 9 && data.flv){
							player.setSrc(data.flv);
						} else {
							player.setSrc(data.sources);
						}
						player.load();
						player.play();
					}

					function setDescription(data) {
						$descContainer.data("name", data.name);
						$descContainer.html("<p><span class='date'>" + data.video_date + "</span> " + data.desc + "</p>");
					}
				});
			}

			$videoGallery.addClass("initialized");
		});

	};

	return api;
})(INVjQuery, document);

INV.register("videoPlayerGallery", INV.component.videoPlayerGallery);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.search.js/jcr:content
====================================================== */
/**
 * Search component - desktop/js-component/component.search.js
 */

INV.component.search = (function ($, document) {
	var api = {};

	function createLink(label, term) {
		var $link = $("<a/>"),
			data,
			i;

		if (term.length > 0) {
			data = label.split(term);

			for (var i = 0; i < data.length; i++) {
				if (i > 0) {
					$('<b/>').text(term).appendTo($link);
				}
				$link.append(document.createTextNode(data[i]));
			}
		}

		return $link;
	}

	// patch autocomplete to include highlighting
	var oldFn = $.ui.autocomplete.prototype._renderItem;
	$.ui.autocomplete.prototype._renderItem = function(ul, item) {
		var $link = createLink(item.label, this.term.toLowerCase());

		return $("<li></li>")
			.data("item.autocomplete", item)
			.append($link)
			.appendTo(ul);
	};

	// init
	api.init = function () {
		$(".searchResults > .mainComponent.inner:not(.initialized)").each(function () {
			var searchText = $('#qSpan').text();
			searchText = INV.component.searchSuffix.decode(searchText);
			
			if (searchText != '' && searchText != ' ') {
				$(this).find("input").val(searchText);
				$(this).find("#submittedQuery").text(searchText);
				$(this).addClass("hasQuery");
			} else {
				$(this).find("input").val("Search");
			}

			$(this).find("input").focus(function () {
				if (!$(this).parents(".inner:eq(0)").hasClass("wasFocused")) {
					$(this).parents(".inner:eq(0)").addClass("wasFocused");
				}
				if ($(this).parents(".inner:eq(0)").hasClass("hasQuery")) {
					$(this).select();
				} else {
					$(this).val("");
				}
			});
		});

		$(".search > .mainComponent.inner:not(.initialized)").each(function () {
			$(this).find("input").val("Search").focus(function () {
				if (!$(this).parents(".inner:eq(0)").hasClass("wasFocused")) {
					$(this).parents(".inner:eq(0)").addClass("wasFocused");
					$(this).val("");
				}
			});
		});

		$(".search > .mainComponent.inner:not(.initialized), .searchResults > .mainComponent.inner:not(.initialized)").each(function () {
			var searchCache = {},
			lastSearchXhr = null,
			$search = $(this),
			locationToRoot = $search.find("span#root").text(),
			autocompleteAddress = locationToRoot + "/configuration/search-settings/_jcr_content/searchConfiguration.autocomplete.";

			var searchResultsLocation = "";
			if($(this).parent().hasClass("search")) {
				searchResultsLocation = $('#actionHrefSearch').attr('href');
			} else {
				searchResultsLocation = $('#actionHrefSearchResults').attr('href');
			}

			$search.find("form").submit(function () {
				var keyword = $search.find("input").val();
				while (keyword.indexOf("*") == 0) {
					keyword = keyword.substring(1);
				}
				keyword = keyword.substring(0, 200);
				keyword =  INV.component.searchSuffix.encode(keyword);
				
				var target = "";
				var wasFocused = $(this).parents(".inner:eq(0)").hasClass("wasFocused"); 
				var hasQuery = $(this).parents(".inner:eq(0)").hasClass("hasQuery"); 
				if ((!wasFocused && !hasQuery) || (wasFocused && !keyword)) {
					return false;
				} else if((wasFocused || hasQuery) && keyword.length > 0) {
					target = searchResultsLocation + "/" + keyword + ".html";
				} else {
					target = searchResultsLocation;
				}
				window.location = target; 
				return false;
			});

			$search.find("input").autocomplete({
				appendTo: $search,
				position: {
					offset: "0 1"
				},

				source: function (request, response) {
					var term = request.term.toLowerCase();
					var encodedTerm = INV.component.searchSuffix.encode(request.term.toLowerCase());
					if (encodedTerm in searchCache) {
						response(searchCache[encodedTerm]);
						return;
					}

					lastSearchXhr = $.getJSON(autocompleteAddress + encodedTerm + ".html",
						null,
						function (data, status, xhr) {
							searchCache[encodedTerm] = data;
							if (xhr == lastSearchXhr) {
								response(data);
							}
						}
					);
				},

				search: function (event, ui) {
					if (event.target.value.length < 3) {
						$search.children("ul").hide();
						return false;
					}
				},

				focus: function (event, ui) {
					$(this).parents("form").siblings("ul").children("li").each(function(){
						if($(this).children("a").text() == ui.item.value) {
							$(this).addClass("active");
						} else {
							$(this).removeClass("active");
						}
					});
					return true;
				},

				select: function (event, ui) {
					window.location = searchResultsLocation + "/" + ui.item.value + ".html";
					return true;
				}
			});

			$search.addClass("initialized");
		});


	};

	return api;
})(INVjQuery, document);

INV.register("search", INV.component.search);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.pressReleaseArchive.js/jcr:content
====================================================== */
/**
 * Press release archive component - desktop/js-component/component.pressReleaseArchive.js
 */

INV.component.pressReleaseArchive = (function ($, document) {
	var api = {};

	function disable($wrapper) {
		$(".action", $wrapper).fadeTo("fast", 0.5).addClass("disable");
		$(".action a", $wrapper).attr({"href":"javascript:void(0)"});
	}

	function enable($wrapper, href) {
		$(".action", $wrapper).fadeTo("fast", 1).removeClass("disable");
		$(".action a", $wrapper).attr({"href": href});
	}

	api.init = function () {
		$(".pressReleaseArchive.inner:not(.initialized)").each(function () {
			var $archive = $(this);
			$("div.region ul > li > a", $archive).each(function (i) {
				var $a = $(this);
				$("select.archive", $archive).append("<option value=" + $a.attr("href") + ">" + $a.text()+"</option>");
			});
			
			$(".pressReleaseArchiveData", $archive).hide();
			$(".select-box", $archive).show();
			
			disable($archive);
			
			$archive.delegate("select.archive", "change", function () {
				var $select = $(this);
				$select.find("option:selected").each(function () {
					if ($(this).val() != "") {
						enable($archive, $(this).val());
					} else {
						disable($archive);
					}
				});
			});
			
			$archive.addClass("initialized");
		});

	};

	return api;
})(INVjQuery, document);

INV.register("pressReleaseArchive", INV.component.pressReleaseArchive);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.form.js/jcr:content
====================================================== */
/**
 * form - desktop/js-component/component.form.js
 */

// uses jquery.placeholder plugin to add HTML5 placeholder functionality to older browsers
INV.component.placeholder = (function ($, document) {
	var api = {};

	api.init = function () {
		$("form:not(placeholder-form)")
			.placeholderForm().addClass("placeholder-form");

		$("form [placeholder]:not(.placeholder-field)")
			.placeholder().addClass("placeholder-field");
	};

	return api;
}(INVjQuery, document));

INV.register("placeholder", INV.component.placeholder);


/*  */
INV.component.form = (function ($, document) {
	var api = {};

	api.init = function () {

	};

	/* Forms in lightbox */
	api.lightboxForm = function () {
		$(".lightboxContainer form:not(.initialized)").each(function () {
			var $form = $(this);
			$form.submit(function (e) {
				e.preventDefault();
				var action = $form.find("input[name=':action']").attr("value");
				$.post(
					action,
					$form.serializeArray(),
					function (d) {
						INV.component.lightbox.insertContent(d);
					}
				);
			});
			$form.addClass("initialized");
		});
	};

	return api;
}(INVjQuery, document));

INV.register("form", INV.component.form);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.searchNavigators.js/jcr:content
====================================================== */
/**
 * Search navigators component - desktop/js-component/component.searchNavigators.js
 */

INV.component.searchNavigators = (function ($, document) {
	var api = {};

	api.init = function () {
		$(".searchNavigators > .inner:not(.initialized)").each(function () {
			var $searchNavigators = $(this);
			if ($.browser.msie && $.browser.version <= 8) {
				$searchNavigators.find("ul li li:last-child").css("border", "none");
				$searchNavigators.find("li.active > a").css("font-weight", "bold");
			}
			/* list toggling
			 * $searchNavigators.delegate("li:has(ul:has(li)) > a", "click", function (e) {
				var $t = $(this);
				$t.next("ul").slideToggle();
				e.preventDefault();
			});*/
			$searchNavigators.addClass("initialized");
		});
	};
	return api;
})(INVjQuery, document);

INV.register("searchNavigators", INV.component.searchNavigators);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.searchPagination.js/jcr:content
====================================================== */
/**
 * Search pagination component - desktop/js-component/component.searchPagination.js
 */

INV.component.searchPagination = (function ($, document) {
    var api = {};

    api.init = function () {
        $(".searchPagination > .inner:not(.initialized)").each(function () {
			var $pagination = $(this),
				$dropdown = $pagination.find(".perPage"),
				cookieName = "resultsPerPage",
				cookieExpire = 365,
				$itemList = $dropdown.find("ul"),
				icon = "<span class='icon'></span>";

			/* Read cookie and display profile */
			var resultsPerPage = INV.cookie.read(cookieName);
			$dropdown.find(".selected").text(
				$dropdown.find("ul a[rel=" +  (resultsPerPage||10) + "]").text()
			).append(icon);

			$dropdown.delegate(".selected", "mouseover", function (e) {
				$itemList.stop(true, true).slideDown("fast");
			});
			$dropdown.mouseleave(function () {
				$itemList.stop(true, true).delay(1000).slideUp("slow");
			});
			$dropdown.delegate(".selected", "click", function (e) {
				$itemList.slideUp("fast");
			});
			$dropdown.delegate("a", "mouseover", function (e) {
				$itemList.stop(true, true).slideDown("fast");
			});
			$dropdown.delegate("a", "click", function (e) {
				var cookieValue = this.rel;
				$dropdown.find(".selected").text($(this).text());
				INV.cookie.create(cookieName, cookieValue, cookieExpire);
				$itemList.slideUp("fast");
				/* uncomment following lines if you rely on cookies */
				/* e.preventDefault(); */
				/* location.reload();  */
			});
		});
    };

    return api;
})(INVjQuery, document);

INV.register("searchPagination", INV.component.searchPagination);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.searchContacts.js/jcr:content
====================================================== */
/**
 * Search contacts component - desktop/js-component/component.searchContacts.js
 */

INV.component.searchContacts = (function ($, document) {
	var api = {};

	api.init = function () {
		
		$(".searchContacts > .inner:not(.initialized)").each(function () {
			$searchContacts = $(this);
			$searchContacts.addClass("initialized");
			
			$(this).find("input.text").focus(function() {
				var wasFocused = $(this).parents(".searchContacts").hasClass("wasFocused");
				if(!wasFocused) {
					$(this).parents(".searchContacts").addClass("wasFocused");
					$(this).val("");
				}
			});
			
			$(this).find("form").submit(function() {
				var wasFocused = $(this).parents(".searchContacts").hasClass("wasFocused");
				var search = $(this).parents(".inner.form").find("a:hidden").attr("href");
				
				var name = wasFocused? $(this).find("input.text").val() : "";
				var category = $(this).find("select:eq(0)").val();
				var location = $(this).find("select:eq(1)").val();
				
				if (!name && !category && !location) {
					return false;
				}
				
				var encodedCategory = "";
				var encodedLocation = "";
				var encodedName = "";
				var encodedFName = "";
				var encodedLName = "";
				
				if (name.length > 0) {
					encodedName = INV.component.searchSuffix.encode(name);
					encodedFName = INV.component.searchSuffix.encode("fn_" + name);
					encodedLName = INV.component.searchSuffix.encode("ln_" + name);
				}
				if (category.length > 0) {
					encodedCategory = INV.component.searchSuffix.encode("c_" + category);
				}
				if (location.length > 0) {
					encodedLocation = INV.component.searchSuffix.encode("l_" + location);
				}
				
				var customNavigator = $(this).parents(".inner.form").find("span:hidden").text();
				if(customNavigator == "") {
					customNavigator = "custominav";
				}
				
				var fakeKeyword = "";
				if (encodedName.length > 0) {
					fakeKeyword = encodedName + "/";
				} else if (encodedCategory.length > 0) {
					fakeKeyword = INV.component.searchSuffix.encode(category) + "/";
				} else if (encodedLocation.length > 0) {
					fakeKeyword = INV.component.searchSuffix.encode(location) + "/";
				}
				
				
				window.location = search + "/" + fakeKeyword + "[" + customNavigator + "/" + encodedCategory + "|" + encodedLocation + "|" + encodedFName + "|" + encodedLName + "/1,10].html";
				return false;
			});
		});
	};

	return api;
})(INVjQuery, document);

INV.register("searchContacts", INV.component.searchContacts);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.searchSuffix.js/jcr:content
====================================================== */
INV.component.searchSuffix = (function ($, document) {
	var api = {};

	api.encode = function(unencoded) {
		var a = unencoded.split('');

		var result = new Array();

		for (var i=0; i < a.length; i++) {
			var code = a[i].charCodeAt(0);
			if ((code >= 48 && code <= 57) || (code >= 65 && code <= 90) || (code >= 97 && code <= 122)) {//alpha numeric
				result.push(a[i]);
				continue;
			} 
			
			result.push('_' + INV.component.searchSuffix.lpad(code.toString(16)));
		}

		var encoded = result.join('');

		return encoded;
	},
	
	api.lpad = function(hexString) {
		switch (hexString.length) {
			case 4: return hexString;
			case 3: return "0"+hexString;
			case 2: return "00"+hexString;
			case 1: return "000"+hexString;
			default: return hexString.substring(0, Math.min(4, hexString.length));
		}
	},
	
	api.decode = function(encoded) {
		var s = encoded.split(/(?=_)/g);
		
		var result = new Array();
		for (var i = 0; i < s.length; i++) {
			var element = s[i];
				
			if (element.length == 5 && element.indexOf('_') == 0) {
				var hex = parseInt(element.substring(1, 5), 16);
				var c = String.fromCharCode(hex);
				result.push(c); 
			} else if (element.length > 5 && element.indexOf('_') == 0) {
					var hex = parseInt(element.substring(1, 5), 16);
					var c = String.fromCharCode(hex);
					result.push(c + element.substring(5, element.length));
			 	} else {
					result.push(element);
				}
			}
		
		var decoded = result.join('');
		return decoded;
	}
	return api;
})(INVjQuery, document);

INV.register("searchSuffix", INV.component.searchSuffix);
/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.watchdog.js/jcr:content
====================================================== */
/**
 * Back to top component - desktop/js-component/component.backToTop.js
 */

INV.component.watchdog = (function ($, document) {
    var api = {};

    api.init = function () {
        $(".watchdog .inner:not(.initialized)").each(function () {
            var $watchdog = $(this);

            $watchdog.addClass("initialized");
        });
    };

    api.checkSPUserType = function (requiredType) {

        var userType = INV.cookie.read("spUserType");
        
        var isGoogleBot = navigator.userAgent.toLowerCase().indexOf("google") > -1;
        
        if (!isGoogleBot && userType !== requiredType) {
            $("a.lightbox.home_limit").click();
        }
    };
    
    return api;
})(INVjQuery, document);

INV.register("watchdog", INV.component.watchdog);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.userProfileSelector.js/jcr:content
====================================================== */
/**
 * Back to top component - desktop/js-component/component.userProfileSelector.js
 */

INV.component.userProfileSelector = (function ($, document) {
    var api = {};

    var validProfiles = new Array(
        "Private Individual",
        "Corporate Client",
        "Financial Advisor",
        "All"
    );

    getValidProfile = function (profile) {
        if (-1 != INVjQuery.inArray(profile, validProfiles)) {
            return profile;
        }
        if ("individual" == profile) {
            return "Private Individual";
        }
        if ("corporate" == profile) {
            return "Corporate Client";
        }
        if ("intermediary" == profile) {
            return "Financial Advisor";
        }
        return "All";
    };

    api.init = function () {
        $(".userProfileSelector > .inner:not(.initialized)").each(function () {
            var $profileSelector = $(this),
                visit = INV.cookie.read("visitProfile") || 0,
                cookieName = "userProfile",
                cookieExpire = 365, /* days */
                selectorShowDelay = 2, /* seconds */
                visitShowDelay = 2
            ;

            var userProfile = INV.cookie.read(cookieName);

            $profileSelector.delegate(".close", "click", function (e) {
                hideProfileSelector();
                e.preventDefault();
            });

            $profileSelector.delegate("input", "click", function (e) {
                var cookieValue = getValidProfile(this.value);
                INV.cookie.create(cookieName, cookieValue, cookieExpire);
                // update CQ segmentation
                CQ_Analytics.ProfileDataMgr.setProperty("userType", cookieValue);
                hideProfileSelector();
                setTimeout('location.reload();', 100);
            });

            var showProfileSelector = function () {
                $profileSelector.delay(selectorShowDelay * 1000).slideDown();
            };

            var hideProfileSelector = function () {
                $profileSelector.slideUp();
            };

            if (!visit && !userProfile) {
                INV.cookie.create("visitProfile", ++visit, cookieExpire);
                CQ_Analytics.ProfileDataMgr.setProperty("userType", "All");
            } else if (visit == visitShowDelay - 1 && !userProfile) {
                INV.cookie.create("visitProfile", ++visit, cookieExpire);
                CQ_Analytics.ProfileDataMgr.setProperty("userType", "All");
                showProfileSelector();
            } else if (userProfile) { /* Update user profile to new values */
                var cookieValue = getValidProfile(userProfile);
                INV.cookie.create(cookieName, cookieValue, cookieExpire);
                // update CQ segmentation
                CQ_Analytics.ProfileDataMgr.setProperty("userType", cookieValue);
            } else { /* set default value */
                CQ_Analytics.ProfileDataMgr.setProperty("userType", "All");
            }

            $profileSelector.addClass("initialized");
        });
    };

    return api;
})(INVjQuery, document);

INV.register("userProfileSelector", INV.component.userProfileSelector);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.profileSelectorDropdown.js/jcr:content
====================================================== */
/**
 * Selector dropdown component -
 * desktop/js-component/component.profileSelectorDropdown.js
 */

INV.component.profileSelectorDropdown = (function ($, document) {
	var api = {};

	var validProfiles = new Array(
		"Private Individual",
		"Corporate Client",
		"Financial Advisor",
		"All"
	);

	getValidProfile = function (profile) {
		if (-1 != INVjQuery.inArray(profile, validProfiles)) {
			return profile;
		}
		if ("individual" == profile) {
			return "Private Individual";
		}
		if ("corporate" == profile) {
			return "Corporate Client";
		}
		if ("intermediary" == profile) {
			return "Financial Advisor";
		}
		return "All";
	};

	api.init = function () {
		$(".profileSelectorDropdown > .inner:not(.initialized)").each(function () {
			var $profileSelector = $(this),
				$dropdown = $profileSelector.find(".selector"),
				cookieName = "userProfile",
				cookieExpire = 365, /* days */
				$itemList = $dropdown.find("ul"),
				icon = "<span class='icon'></span>",
				handler;

			/* Read cookie and display profile */
			var userProfile = INV.cookie.read(cookieName);
			$dropdown.find(".selectedProfile").text(
				$dropdown.find("ul a[rel=" + getValidProfile(userProfile).replace(" ", "_") + "]").text()
			).append(icon);

			/* Update user profile to new values */
			if (userProfile) {
				var cookieValue = getValidProfile(userProfile);
				INV.cookie.create(cookieName, cookieValue, cookieExpire);
				// update CQ segmentation
				CQ_Analytics.ProfileDataMgr.setProperty("userType", cookieValue);
			} else {
				CQ_Analytics.ProfileDataMgr.setProperty("userType", "All");
			}

			handler = function (e) {
				if ($itemList.is(":visible")){
					$itemList.hide();
					$(document).unbind("click", handler);
				}
			};

			$dropdown.click(function (e) {
				if ($itemList.is(":visible")) {
					$itemList.hide();
				} else {
					$itemList.show();
					e.stopPropagation();
					$(document).bind("click", handler);
				}
			});

			$dropdown.delegate("a", "click", function (e) {
				e.preventDefault();
				var cookieValue = getValidProfile(this.rel.replace("_", " "));
				$dropdown.find(".selectedProfile").text($(this).text()).append(icon);
				INV.cookie.create(cookieName, cookieValue, cookieExpire);
				$itemList.hide();
				// update CQ segmentation
				CQ_Analytics.ProfileDataMgr.setProperty("userType", cookieValue);
				setTimeout('location.reload();', 100);
			});
			$profileSelector.addClass("initialized");
		});
	};

	return api;
})(INVjQuery, document);

INV.register("profileSelectorDropdown", INV.component.profileSelectorDropdown);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.twitter.js/jcr:content
====================================================== */
/**
 * Twitter component - desktop/js-component/component.twitter.js
 */

/*
 * ==========================================================
 * Code taken from Investec Phase 2 twitter component
 */
(function ($) {
    function twitterFeed(options) {
        var defaults = {
                username : '',
                limit : 3,
                interval: 0,
                live: true,
                scrollInterval : 15000,
                maxTweetHeight: 110,
                loaderHolder: '',
                maxTweets: 20
        };

        var settings = $.extend({}, defaults, options);
        //Twitter API allows max 150 requests per hour from one IP,
        //we make it 60 requests to leave margin for page refreshes etc.
        settings.minInterval = 60000;


        if (settings.live)  {
            settings.interval = settings.minInterval;
        }

        return this.each(function () {
            if (settings.loaderHolder) {
                $(settings.loaderHolder).prepend('<span class="loader">&nbsp;</span>');
            }

            var worker = new TweetFeed({
                    container: $(this).find(".tweets"),
                    username: settings.username,
                    limit: settings.limit,
                    scrollInterval: settings.scrollInterval,
                    maxTweetHeight: settings.maxTweetHeight,
                    loaderHolder: settings.loaderHolder,
                    maxTweets: settings.maxTweets
            });
            worker.downloadTweets();

            if (settings.interval) {
                settings.interval = settings.interval < settings.minInterval
                    ? settings.minInterval
                    : settings.interval;

                setTimeout(function () {
                    worker.downloadTweets();
                    setTimeout(arguments.callee, settings.interval);
                }, settings.interval);
            }
        });
    }


    function TweetFeed(config) {
        this.$feedContainer = config.container; //already a jQuery object
        this.username = config.username;
        this.limit = config.limit; // maximum visible tweets
        this.lastId = 0; //id of last retrived item
        this.lastVisibleId = 0; //id of latest visible item
        this.maxTweets = config.maxTweets; //maximum tweets in markup
        this.scrollInterval = config.scrollInterval; //TODO make it 30 sec..
        this.scrollTimeoutId = false;
        this.pendingItems = [];
        this.$loaderHolder = $(config.loaderHolder);

        var _this = this;

        // dummy post to check twit height
        var dummyPost = {
                id: 1,
                text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ut metus non elit vehicula adipiscing. Sed quam ligula, iaculis sit amet sed.",
                created_at: "",
                source: "dummy"
        };
        var d = this.buildTweetItem(dummyPost);
        this.$feedContainer.append(d.css("visibility", "none"));
        config.maxTweetHeight = d.outerHeight();
        d.remove();

        //some stuff needed for animations
        this.$feedContainer
            .css("position", "relative")
            .height(this.limit * config.maxTweetHeight + 10);
    }


    $.extend(TweetFeed.prototype, {

        downloadTweets : function () {
            var feedUrl = "http://twitter.com/status/user_timeline/" + this.username + ".json?count=" + this.maxTweets;
            if (this.lastId) {
                feedUrl += "&since_id=" + this.lastId;
            }
            feedUrl += "&callback=?";

            this.$loaderHolder.addClass("loading");

            var _this = this;

            $.ajax({
                url: feedUrl,
                dataType: 'json',
                success: function (data, textStatus) {
                    _this.$loaderHolder.removeClass(".loading");
                    _this.processTweets(data, textStatus);
                },
                error : function () {
                    _this.$loaderHolder.removeClass("loading");
                },
                complete : function () {
                    _this.$loaderHolder.removeClass("loading");
                }
            });
        },


        processTweets : function (data, textStatus) {
            var $container = this.$feedContainer;
            var statusUrl = "http://www.twitter.com/" + this.username + "/statuses/";
            var _this = this;
            var update = !!this.lastId;

            //use temp container and append all items at once to  the actual container
            var $temp = $("<ul></ul>");
            $.each(data, function (i, post) {
                _this.lastId = _this.lastId < post.id ?  post.id : _this.lastId;
                var $item = _this.buildTweetItem(post, statusUrl);
                $temp.append($item);
            });

            if (!update) { //clear tweets container on first load
                $container.empty();
            }

            var $items = $temp.children();
            if ($container.children("li").length <= this.limit) {
                this.lastVisibleId = $items.first().data('postId');
                this.addAnimate($items, update);
                //remove items above maxTweets limit from the markup
                $container.children("li:gt(" + (this.maxTweets - 1) +")").remove();
            }
            else {
                this.addToPendingQueue($items);
            }

            if (!this.scrollTimeoutId && $container.children("li").length > this.limit) {
                this.scheduleScroll();
            }
        },


        buildTweetItem : function (post, statusUrl) {
            var itemHtml = '<li><p><a href="'+ statusUrl + post.id +'">'
                + post.text
                + '</a></p>'
                + '<span class="details"><span class="date">'
                + this.formatDate(post.created_at)
                + '</span>';
            if (post.source) {
                itemHtml += ' via ' + post.source;
            }
            itemHtml += '</span></li>';

            return $(itemHtml).data({
                'postId' : post.id,
                'postDate' : post.created_at,
                'new' : true });
        },


        scrollTweets : function () {
            var $container = this.$feedContainer;
            var _this = this;

            var $children = $container.children("li");

            //if we are about to show the oldest post again, check if there are
            //pending items wating to be added
            if ($children.first().data('postId') == this.lastVisibleId) {
                if (this.pendingItems.length > 0) {

                    //check if children count will be > 20
                    var diff = $children.length + this.pendingItems.length - this.maxTweets;
                    if (diff > 0) {
                        $container.children("li:gt(" + (this.maxTweets - diff - 1) +")").remove();
                    }

                    $container.append($(this.pendingItems));
                    this.lastVisibleId = $(this.pendingItems[0]).data('postId');
                    this.pendingItems = [];

                }
            }

            var $last = $container.children("li").last().detach();
            //update date of the item to show
            $last.find('.details .date').text(this.formatDate($last.data('postDate')));
            //slide-fade in the item
            this.addAnimate($last);
        },


        addAnimate: function ($items, forceUpdate) {
            $items.css({opacity : 0})
            .hide()
            .prependTo(this.$feedContainer)
            .slideDown(1500, function () {
                var $this = $(this);
                $this.animate({ opacity : 1}, 1000, function () {
                    if (forceUpdate || ($items.length ==1 && $this.data('new'))) {
                        $this.data('new', false);
                    }
                });
            });
        },


        addToPendingQueue : function ($items) {
            this.pendingItems = $items.toArray()
                .concat(this.pendingItems)
                .slice(0, this.maxTweets);
        },


        scheduleScroll : function () {
            if (this.scrollTimeoutId) { //prevent multiple timeouts
                return;
            }
            var _this = this;

            this.scrollTimeoutId = setTimeout(function () {
                _this.scrollTweets();
                _this.scrollTimeoutId = setTimeout(arguments.callee, _this.scrollInterval);
            }, _this.scrollInterval);
        },

        stopScroll : function () {
            if (this.scrollTimeoutId) {
                clearTimeout(this.scrollTimeoutId);
                this.scrollTimeoutId = 0;
            }
        },

        formatDate : function (date) {
             // Calculate how many hours ago was the tweet posted
            date = date.replace("+", "UTC+");
            var date_diff  = new Date() - new Date(date);
            var hours      = Math.round(date_diff/(1000 * 60 * 60));
            var dateString;

            if (hours < 24) {
                switch(hours) {
                    case 0:
                        var minutes = Math.round(date_diff/(1000 * 60));
                        switch(minutes) {
                            case 0:
                            case 1:
                                dateString = "a minute ago";
                                break;
                            default:
                                dateString = minutes + " minutes ago";
                        }
                        break;
                    case 1:
                        dateString = "an hour ago";
                        break;
                    default:
                        dateString = hours + " hours ago";
                }
            }
            else {
                try {
                    dateString = dateFormat(date, "H:MM TT mmm d, yyyy");
                }
                catch(e) {
                    dateString = date;
                }
            }

            return dateString;
        }
    });


    /*
     * Date Format 1.2.3
     * (c) 2007-2009 Steven Levithan <stevenlevithan.com>
     * MIT license
     *
     * Includes enhancements by Scott Trenda <scott.trenda.net>
     * and Kris Kowal <cixar.com/~kris.kowal/>
     *
     * Accepts a date, a mask, or a date and a mask.
     * Returns a formatted version of the given date.
     * The date defaults to the current date/time.
     * The mask defaults to dateFormat.masks.default.
     * 
     * http://blog.stevenlevithan.com/archives/date-time-format
     */

    var dateFormat = function () {
        var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
            timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
            timezoneClip = /[^-+\dA-Z]/g,
            pad = function (val, len) {
                val = String(val);
                len = len || 2;
                while (val.length < len) { val = "0" + val; }
                return val;
            };

        // Regexes and supporting functions are cached through closure
        return function (date, mask, utc) {
            var dF = dateFormat;

            // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
            if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
                mask = date;
                date = undefined;
            }

            // Passing date through Date applies Date.parse, if necessary
            date = date ? new Date(date) : new Date();
            if (isNaN(date)) {
				throw SyntaxError("invalid date");
			}

            mask = String(dF.masks[mask] || mask || dF.masks["default"]);

            // Allow setting the utc argument via the mask
            if (mask.slice(0, 4) == "UTC:") {
                mask = mask.slice(4);
                utc = true;
            }

            var _ = utc ? "getUTC" : "get",
                d = date[_ + "Date"](),
                D = date[_ + "Day"](),
                m = date[_ + "Month"](),
                y = date[_ + "FullYear"](),
                H = date[_ + "Hours"](),
                M = date[_ + "Minutes"](),
                s = date[_ + "Seconds"](),
                L = date[_ + "Milliseconds"](),
                o = utc ? 0 : date.getTimezoneOffset(),
                flags = {
                    d:    d,
                    dd:   pad(d),
                    ddd:  dF.i18n.dayNames[D],
                    dddd: dF.i18n.dayNames[D + 7],
                    m:    m + 1,
                    mm:   pad(m + 1),
                    mmm:  dF.i18n.monthNames[m],
                    mmmm: dF.i18n.monthNames[m + 12],
                    yy:   String(y).slice(2),
                    yyyy: y,
                    h:    H % 12 || 12,
                    hh:   pad(H % 12 || 12),
                    H:    H,
                    HH:   pad(H),
                    M:    M,
                    MM:   pad(M),
                    s:    s,
                    ss:   pad(s),
                    l:    pad(L, 3),
                    L:    pad(L > 99 ? Math.round(L / 10) : L),
                    t:    H < 12 ? "a"  : "p",
                    tt:   H < 12 ? "am" : "pm",
                    T:    H < 12 ? "A"  : "P",
                    TT:   H < 12 ? "AM" : "PM",
                    Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
                    o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
                    S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
                };

            return mask.replace(token, function ($0) {
                return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
            });
        };
    }();

    // Some common format strings
    dateFormat.masks = {
        "default":      "ddd mmm dd yyyy HH:MM:ss",
        shortDate:      "m/d/yy",
        mediumDate:     "mmm d, yyyy",
        longDate:       "mmmm d, yyyy",
        fullDate:       "dddd, mmmm d, yyyy",
        shortTime:      "h:MM TT",
        mediumTime:     "h:MM:ss TT",
        longTime:       "h:MM:ss TT Z",
        isoDate:        "yyyy-mm-dd",
        isoTime:        "HH:MM:ss",
        isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
        isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
    };

    // Internationalization strings
    dateFormat.i18n = {
        dayNames: [
            "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
            "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
        ],
        monthNames: [
            "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
            "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
        ]
    };


    $.fn.extend( {
        twitter: twitterFeed
    });

})(INVjQuery);
/*
 * End of ode taken from Investec Phase 2 twitter component
 * ==========================================================
 */


INV.component.twitter = (function ($, document){
    var api = {};

    api.init = function () {
        $(".twitter > .inner:not(.initialized)").each(function () {
            var $twitter = $(this);

            $twitter.twitter({
                username : $twitter.data("twitter-username"),
                limit : $twitter.data("twitter-limit")
            });

            $twitter.addClass("initialized");
        });
    };

    return api;
})(INVjQuery, document);

INV.register("twitter", INV.component.twitter);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.ticker.js/jcr:content
====================================================== */
/**
 * Ticker component - desktop/js-component/component.ticker.js
 */

INV.component.ticker = (function ($, document) {
	var api = {},
		defaults = {
			path: null,
			configpath: null,
			delay: 10000 //10 seconds slide delay
		},
		SLIDE_ANIMATION_SPEED = 2000;

	function loadData($tickerItems, onSuccessDelegate) {
		var config = $.extend({}, defaults, $tickerItems.data());
		if (config.path !== null && config.configpath !== null) {
			$.getJSON(config.path + '?path=' + config.configpath, onSuccessDelegate);
		}
	}

	function chunk(array, chunkSize) {
		var len = array.length,
			chunks=[];

		for (var i = 0; i < len; i += chunkSize) {
			var chnk = array.slice(i, i + chunkSize);
			chunks.push(chnk);
		}
		return chunks;
	}

	function buildItem(data) {
		return $("#tickerItemTemplate").tmpl(data);
	}

		function buildGroupItems($tickerItems, data, title) {
		//slice data into 3 quote chunks
		var quotes = chunk(data, 3);
		for (var i = 0; i < quotes.length; i++) {
					if (quotes[i][2]) { quotes[i][2].cls = "last"; }

			var $item = buildItem({quotes: quotes[i], title: title});
			$tickerItems.append($item);
		}
	}	

	function setupCarousel($ticker, $carousel) {
		var delay = $carousel.data("delay") * 1000, //ms
			$wrapper = $carousel.find(".tickerItems"),
			$items = $wrapper.find(".tickerItem"),
			itemWidth = $items.eq(0).outerWidth(), 
			count = $items.length,
			index = 0;

				  var scheduleNext = function() {
			var timeoutId = setTimeout(function() {
				index++;
				index = index % count;
				var left = -itemWidth * index;
				$wrapper.animate({"left": left}, {duration: SLIDE_ANIMATION_SPEED, 
					easing: "linear", 
					complete: function() {
						//once we reach last, we're on clone we need to reset index
						if (index === count - 1) { 
							$wrapper.css({"left": 0}); //last i equal to first
							index = 0;
						}
						scheduleNext();
					}});
			 }, delay);
		};

		//set items offscreen
		$wrapper.css({"left": itemWidth});
		$wrapper.animate({"left": 0}, {duration: SLIDE_ANIMATION_SPEED, 
			easing: "swing", 
			complete: function() {
				scheduleNext();
			}});
		var last =  0;
	}

	function buildItems($ticker, data) {
		var $tickerItems = $ticker.find(".tickerItems"),
			/** item width available width, minus date minus item borders **/
			itemWidth =  $ticker.width() -  $ticker.find(".date").outerWidth(true) - 8;
		//share prices
		var $item = null, title = "";

		if (data) {
			if (data.s) {
				title = "Investec share price";
				buildGroupItems($tickerItems, data.s, title);
			}
			if (data.i) {
				title = "Stock market indices";
				buildGroupItems($tickerItems, data.i, title);
			}
			if (data.c) {
				title = "Currencies";
				buildGroupItems($tickerItems, data.c, title);
			}
		}

		var $items = $tickerItems.find(".tickerItem"); 

		//add clone to simulate circular slider
		$items.eq(0).clone().addClass("clone").appendTo($tickerItems);
		$items = $tickerItems.find(".tickerItem"); //requery

		//set items width
		$items.width(itemWidth);
		$tickerItems.width($items.length * $items.eq(0).outerWidth(true));
		setupCarousel($ticker, $ticker.find(".carousel"));
	}

	api.init = function() {
		$(".ticker .inner:not(.initialized)").each(function() {
			var $ticker = $(this);

			loadData($ticker.find(".carousel"), function(data) {
				buildItems($ticker, data);
			});
			$ticker.addClass("initialized");
		});
	};

	return api;
}(INVjQuery, document));

INV.register('ticker', INV.component.ticker);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.pressReleaseArchive.js/jcr:content
====================================================== */
/**
 * Press release archive component - desktop/js-component/component.pressReleaseArchive.js
 */

INV.component.pressReleaseArchive = (function ($, document) {
	var api = {};

	function disable($wrapper) {
		$(".action", $wrapper).fadeTo("fast", 0.5).addClass("disable");
		$(".action a", $wrapper).attr({"href":"javascript:void(0)"});
	}

	function enable($wrapper, href) {
		$(".action", $wrapper).fadeTo("fast", 1).removeClass("disable");
		$(".action a", $wrapper).attr({"href": href});
	}

	api.init = function () {
		$(".pressReleaseArchive.inner:not(.initialized)").each(function () {
			var $archive = $(this);
			$("div.region ul > li > a", $archive).each(function (i) {
				var $a = $(this);
				$("select.archive", $archive).append("<option value=" + $a.attr("href") + ">" + $a.text()+"</option>");
			});
			
			$(".pressReleaseArchiveData", $archive).hide();
			$(".select-box", $archive).show();
			
			disable($archive);
			
			$archive.delegate("select.archive", "change", function () {
				var $select = $(this);
				$select.find("option:selected").each(function () {
					if ($(this).val() != "") {
						enable($archive, $(this).val());
					} else {
						disable($archive);
					}
				});
			});
			
			$archive.addClass("initialized");
		});

	};

	return api;
})(INVjQuery, document);

INV.register("pressReleaseArchive", INV.component.pressReleaseArchive);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.countrySelector.js/jcr:content
====================================================== */
/**
 * country Selector -
 * desktop/js-component/component.countrySelector.js
 */

INV.component.countrySelector = (function ($, document) {
	var api = {};

	api.countryIdFromHost = function (host) {
		if (-1 != host.indexOf("investec.co.za")) {
			return "sa";
		}
		if (-1 != host.indexOf("investec.com.au")) {
			return "au";
		}
		if (-1 != host.indexOf("investec.ie")) {
			return "ie";
		}
		if (-1 != host.indexOf("investec.co.uk")) {
			return "uk";
		}

		return "int";
	};

	api.init = function () {
		$(".countrySelector > .inner:not(.initialized)").each(function () {
			var $countrySelector = $(this),
				cookieName = "INVESTEC_SELECTED_COUNTRY_PAGE",
				$dropdown = $countrySelector.find(".selector"),
				$selectedCountry = $dropdown.find(".selectedCountry"),
				cookieExpire = 365, /* days */
				$itemList = $dropdown.find("ul"),
				icon = "<span class='icon'></span>";

			var currentCountryId = INV.component.countrySelector.countryIdFromHost(window.location.host);
			if (currentCountryId) {
				$selectedCountry.html(
					$dropdown.find("ul a[id='" + currentCountryId + "']").html()
				).append(icon);
			}

			handler = function (e) {
				if ($itemList.is(":visible")){
					$itemList.hide();
					$(document).unbind("click", handler);
				}
			};
			
			$dropdown.click(function (e) {
				if ($itemList.is(":visible")) {
					$itemList.hide();
				} else {
					$itemList.show();
					e.stopPropagation();
					$(document).bind("click", handler);
				}
			});

			$dropdown.delegate(".countrySelector", "click", function (e) {
				$itemList.hide();
			});

			$dropdown.delegate("a", "click", function (e) {
				var $this = $(this),
					cookieValue = $(this).data("cookie");
				INV.cookie.create(cookieName, cookieValue, cookieValue == "" ? 0 : cookieExpire);
				$selectedCountry.html($this.html()).append(icon);
				$dropdown.find("ul").hide();
				// location.reload();
				// e.preventDefault();
			});

			$countrySelector.addClass("initialized");
		});
	};

	return api;
})(INVjQuery, document);

INV.register("countrySelector", INV.component.countrySelector);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.siteTools.js/jcr:content
====================================================== */
/**
 * Site Tools component - desktop/js-component/component.siteTools.js
 */

INV.component.siteTools = (function ($, document) {
    var api = {};

    api.init = function () {
        $(".siteTools .inner:not(.initialized)").each(function () {
            var $siteTools = $(this);

            $siteTools.find(".toolPrint a").click(function(event){
                window.print();
                event.preventDefault();
            });
            
            $siteTools.addClass("initialized");
        });
    };

    api.initSocialLinks = function () {
        $(".shareThis .socialBookmarks a, .share .share-container a").each(function(){
            var href = $(this).attr("href");
            
            href = href.replace(/\{\{url\}\}/ig, encodeURIComponent(document.location.href));
            href = href.replace(/\{\{title\}\}/ig, encodeURIComponent(document.title));
            
            $(this).attr("href", href);
        });
        
        $(".shareThis .socialBookmarks:not(.initialized), .share .share-container:not(.initialized").each(function () {
            $(this).delegate("a", "click", function(e){
                window.open(this.href);
                e.preventDefault();
            }).addClass("initialized");
        });
    }
    
    return api;
})(INVjQuery, document);

INV.register("siteTools", INV.component.siteTools);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.userTypeSelector.js/jcr:content
====================================================== */
/**
 * User type selector component - desktop/js-component/component.userTypeSelector.js
 */

INV.component.userTypeSelector = (function ($, document) {
    var api = {},
        defaults = {
            cookieName: "spUserType",
            financialAdviserUser: "financialAdviser",
            individualInvestorUser: "individualInvestor",
            cookieExpiresAfter: 365, // days
            alertText: "Please read the Terms and Conditions before continuing"
        },
        options = defaults;
	// public api

	api.init = function () {
		 $(".userTypeSelector .inner:not(.initialized)").each(function () {
			 var $selector = $(this);

			 $("a.button.adviser", $selector).click(function() {
				$selector.find('#landingbox_adviser').slideToggle();
			 });
			
			 $("a.button.investor", $selector).click(function() {
				$selector.find('#landingbox_investor').slideToggle();
			 });
			
			 $("a.button.discretionary", $selector).click(function() {
				$selector.find('#landingbox_discretionary').slideToggle();
			 });
			
			$selector.find('a.button.enter_adviser').click(function(){
			if($selector.find('#adviser_agree').attr("checked") != undefined) {
				INV.cookie.create(options.cookieName, options.financialAdviserUser, options.cookieExpiresAfter);
				// redirect
				return true;
			} else {
				alert(defaults.alertText);
				return false;
			}
			 });
			
			 $selector.find('a.button.enter_investor').click(function(){
				if($selector.find('#investor_agree').attr("checked") != undefined) {
					INV.cookie.create(options.cookieName, options.individualInvestorUser, options.cookieExpiresAfter);
					// redirect
					return true;
				} else {
					alert(defaults.alertText);
					return false;
				}
			 });
			
			 $selector.addClass("initialized");
		 });
	};

	return api;
})(INVjQuery, document);

INV.register("userTypeSelector", INV.component.userTypeSelector);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/component.onlineServicesDropdown.js/jcr:content
====================================================== */
/**
 * Online Services Dropdown -
 * desktop/js-component/component.onlineServicesDropdown.js
 */

INV.component.onlineServicesDropdown = (function ($, document) {
	var api = {};

	api.init = function () {
		$(".onlineServicesDropdown > .inner:not(.initialized)").each(function () {
			var $onlineServicesDropdown = $(this),
				$dropdown = $onlineServicesDropdown.find(".selector"),
				$itemList = $dropdown.find("ul"),
				handler;

			handler = function (e) {
				if ($itemList.is(":visible")){
					INVTRACKING.handleTrackEvent($dropdown, e);
					$itemList.hide();
					$(document).unbind("click", handler);
				}
			};

			$dropdown.click(function (e) {
				if ($itemList.is(":visible")) {
					$itemList.hide();
				} else {
					$itemList.show();
					e.stopPropagation();
					$(document).bind("click", handler);
					INVTRACKING.handleTrackEvent($dropdown, e);
				}
			});

			$dropdown.delegate("ul a", "click", function (e) {
				var $this = $(this);
				$dropdown.find("ul").hide();
			});

			$onlineServicesDropdown.find(".selectorHeader .fallbackLink").attr('href', '#');

			$onlineServicesDropdown.addClass("initialized");
		});
	};

	return api;
})(INVjQuery, document);

INV.register("onlineServicesDropdown", INV.component.onlineServicesDropdown);

/* ======================================================
/etc/designs/investec/default/desktop/js-component/additional.js/jcr:content
====================================================== */




