//(function(c) { c.tools = c.tools || { version: {} }; c.tools.version.tabs = "1.0.1"; c.tools.addTabEffect = function(d, e) { b[d] = e }; var b = { "default": function(d) { this.getPanes().hide().eq(d).show() }, fade: function(d) { this.getPanes().hide().eq(d).fadeIn(this.getConf().fadeInSpeed) }, slide: function(d) { this.getCurrentPane().slideUp("fast"); this.getPanes().eq(d).slideDown() }, horizontal: function(d) { if (!c._hW) { c._hW = this.getPanes().eq(0).width() } this.getCurrentPane().animate({ width: 0 }, function() { c(this).hide() }); this.getPanes().eq(d).animate({ width: c._hW }, function() { c(this).show() }) } }; function a(e, f, g) { var d = this; var h; function i(j, k) { c(d).bind(j, function(m, l) { if (k && k.call(this, l.index) === false && l) { l.proceed = false } }); return d } c.each(g, function(j, k) { if (c.isFunction(k)) { i(j, k) } }); c.extend(this, { click: function(k) { if (k === h) { return d } var m = d.getCurrentPane(); var l = e.eq(k); if (typeof k == "string") { l = e.filter("[href=" + k + "]"); k = e.index(l) } if (!l.length) { if (h >= 0) { return d } k = g.initialIndex; l = e.eq(k) } var j = { index: k, proceed: true }; c(d).triggerHandler("onBeforeClick", j); if (!j.proceed) { return d } l.addClass(g.current); b[g.effect].call(d, k); c(d).triggerHandler("onClick", j); e.removeClass(g.current); l.addClass(g.current); h = k; return d }, getConf: function() { return g }, getTabs: function() { return e }, getPanes: function() { return f }, getCurrentPane: function() { return f.eq(h) }, getCurrentTab: function() { return e.eq(h) }, getIndex: function() { return h }, next: function() { return d.click(h + 1) }, prev: function() { return d.click(h - 1) }, onBeforeClick: function(j) { return i("onBeforeClick", j) }, onClick: function(j) { return i("onClick", j) } }); e.each(function(j) { c(this).bind(g.event, function(k) { d.click(j); if (!g.history) { return k.preventDefault() } }) }); if (g.history) { e.history(function(j, k) { d.click(k || 0) }) } if (location.hash) { d.click(location.hash) } else { d.click(g.initialIndex) } f.find("a[href^=#]").click(function() { d.click(c(this).attr("href")) }) } c.fn.tabs = function(g, d) { var e = this.eq(typeof conf == "number" ? conf : 0).data("tabs"); if (e) { return e } var f = { tabs: "a", current: "current", onBeforeClick: null, onClick: null, effect: "default", history: false, initialIndex: 0, event: "click", api: false }; if (c.isFunction(d)) { d = { onBeforeClick: d} } c.extend(f, d); this.each(function() { var h = c(this).find(f.tabs); if (!h.length) { h = c(this).children() } var i = g.jquery ? g : c(g); e = new a(h, i, f); c(this).data("tabs", e) }); return f.api ? e : this } })(jQuery); (function(b) { var c, a; b.prototype.history = function(e) { var d = this; if (b.browser.msie) { if (!a) { a = b("<iframe />").hide().get(0); b("body").append(a); setInterval(function() { var f = a.contentWindow.document; var g = f.location.hash; if (c !== g) { b.event.trigger("hash", g); c = g } }, 100) } d.bind("click.hash", function(g) { var f = a.contentWindow.document; f.open().close(); f.location.hash = b(this).attr("href") }); d.eq(0).triggerHandler("click.hash") } else { setInterval(function() { var f = location.hash; if (d.filter("[href*=" + f + "]").length && f !== c) { c = f; b.event.trigger("hash", f) } }, 100) } b(window).bind("hash", e); return this } })(jQuery); (function(c) { c.tools = c.tools || { version: {} }; c.tools.version.tooltip = "1.0.2"; var b = { toggle: [function() { this.getTip().show() }, function() { this.getTip().hide() } ], fade: [function() { this.getTip().fadeIn(this.getConf().fadeInSpeed) }, function() { this.getTip().fadeOut(this.getConf().fadeOutSpeed) } ] }; c.tools.addTipEffect = function(d, f, e) { b[d] = [f, e] }; c.tools.addTipEffect("slideup", function() { var d = this.getConf(); var e = d.slideOffset || 10; this.getTip().css({ opacity: 0 }).animate({ top: "-=" + e, opacity: d.opacity }, d.slideInSpeed || 200).show() }, function() { var d = this.getConf(); var e = d.slideOffset || 10; this.getTip().animate({ top: "-=" + e, opacity: 0 }, d.slideOutSpeed || 200, function() { c(this).hide().animate({ top: "+=" + (e * 2) }, 0) }) }); function a(f, e) { var d = this; var h = f.next(); if (e.tip) { if (e.tip.indexOf("#") != -1) { h = c(e.tip) } else { h = f.nextAll(e.tip).eq(0); if (!h.length) { h = f.parent().nextAll(e.tip).eq(0) } } } function j(k, l) { c(d).bind(k, function(n, m) { if (l && l.call(this) === false && m) { m.proceed = false } }); return d } c.each(e, function(k, l) { if (c.isFunction(l)) { j(k, l) } }); var g = f.is("input, textarea"); f.bind(g ? "focus" : "mouseover", function(k) { k.target = this; d.show(k); h.hover(function() { d.show() }, function() { d.hide() }) }); f.bind(g ? "blur" : "mouseout", function() { d.hide() }); h.css("opacity", e.opacity); var i = 0; c.extend(d, { show: function(q) { if (q) { f = c(q.target) } clearTimeout(i); if (h.is(":animated") || h.is(":visible")) { return d } var o = { proceed: true }; c(d).trigger("onBeforeShow", o); if (!o.proceed) { return d } var n = f.position().top - h.outerHeight(); var k = h.outerHeight() + f.outerHeight(); var r = e.position[0]; if (r == "center") { n += k / 2 } if (r == "bottom") { n += k } var l = f.outerWidth() + h.outerWidth(); var m = f.position().left + f.outerWidth(); r = e.position[1]; if (r == "center") { m -= l / 2 } if (r == "left") { m -= l } n += e.offset[0]; m += e.offset[1]; h.css({ position: "absolute", top: n, left: m }); b[e.effect][0].call(d); c(d).trigger("onShow"); return d }, hide: function() { clearTimeout(i); i = setTimeout(function() { if (!h.is(":visible")) { return d } var k = { proceed: true }; c(d).trigger("onBeforeHide", k); if (!k.proceed) { return d } b[e.effect][1].call(d); c(d).trigger("onHide") }, e.delay || 1); return d }, isShown: function() { return h.is(":visible, :animated") }, getConf: function() { return e }, getTip: function() { return h }, getTrigger: function() { return f }, onBeforeShow: function(k) { return j("onBeforeShow", k) }, onShow: function(k) { return j("onShow", k) }, onBeforeHide: function(k) { return j("onBeforeHide", k) }, onHide: function(k) { return j("onHide", k) } }) } c.prototype.tooltip = function(d) { var e = this.eq(typeof d == "number" ? d : 0).data("tooltip"); if (e) { return e } var f = { tip: null, effect: "slideup", delay: 30, opacity: 1, position: ["top", "center"], offset: [0, 0], api: false }; if (c.isFunction(d)) { d = { onBeforeShow: d} } c.extend(f, d); this.each(function() { e = new a(c(this), f); c(this).data("tooltip", e) }); return f.api ? e : this } })(jQuery); (function(b) { b.tools = b.tools || { version: {} }; b.tools.version.scrollable = "1.0.5"; var c = null; function a(p, m) { var s = this; if (!c) { c = s } function n(t, u) { b(s).bind(t, function(w, v) { if (u && u.call(this, v.index) === false && v) { v.proceed = false } }); return s } b.each(m, function(t, u) { if (b.isFunction(u)) { n(t, u) } }); var d = !m.vertical; var f = b(m.items, p); var j = 0; function l(u, t) { return u.indexOf("#") != -1 ? b(u).eq(0) : t.siblings(u).eq(0) } var q = l(m.navi, p); var g = l(m.prev, p); var i = l(m.next, p); var h = l(m.prevPage, p); var o = l(m.nextPage, p); b.extend(s, { getIndex: function() { return j }, getConf: function() { return m }, getSize: function() { return s.getItems().size() }, getPageAmount: function() { return Math.ceil(this.getSize() / m.size) }, getPageIndex: function() { return Math.ceil(j / m.size) }, getRoot: function() { return p }, getItemWrap: function() { return f }, getItems: function() { return f.children() }, getVisibleItems: function() { return s.getItems().slice(j, j + m.size) }, seekTo: function(w, u, A) { if (u === undefined) { u = m.speed } if (b.isFunction(u)) { A = u; u = m.speed } if (w < 0) { w = 0 } if (w > s.getSize() - m.size) { return s } var B = s.getItems().eq(w); if (!B.length) { return s } var t = { index: w, proceed: true }; b(s).trigger("onBeforeSeek", t); if (!t.proceed) { return s } if (d) { var v = -B.position().left; f.animate({ left: v }, u, m.easing, A ? function() { A.call(s) } : null) } else { var z = -B.position().top; f.animate({ top: z }, u, m.easing, A ? function() { A.call(s) } : null) } if (q.length) { var x = m.activeClass; var y = Math.ceil(w / m.size); y = Math.min(y, q.children().length - 1); q.children().removeClass(x).eq(y).addClass(x) } if (w === 0) { g.add(h).addClass(m.disabledClass) } else { g.add(h).removeClass(m.disabledClass) } if (w >= s.getSize() - m.size) { i.add(o).addClass(m.disabledClass) } else { i.add(o).removeClass(m.disabledClass) } c = s; j = w; b(s).trigger("onSeek", { index: w }); return s }, move: function(v, u, t) { var w = j + v; if (m.loop && w > (s.getSize() - m.size)) { w = 0 } return this.seekTo(w, u, t) }, next: function(u, t) { return this.move(1, u, t) }, prev: function(u, t) { return this.move(-1, u, t) }, movePage: function(v, u, t) { return this.move(m.size * v, u, t) }, setPage: function(x, y, v) { var u = m.size; var t = u * x; var w = t + u >= this.getSize(); if (w) { t = this.getSize() - m.size } return this.seekTo(t, y, v) }, prevPage: function(u, t) { return this.setPage(this.getPageIndex() - 1, u, t) }, nextPage: function(u, t) { return this.setPage(this.getPageIndex() + 1, u, t) }, begin: function(u, t) { return this.seekTo(0, u, t) }, end: function(u, t) { return this.seekTo(this.getSize() - m.size, u, t) }, reload: function() { return r() }, click: function(u, x, v) { var w = s.getItems().eq(u); var t = m.activeClass; if (u < 0 || u >= this.getSize()) { return s } if (m.size == 2) { if (u == s.getIndex()) { u-- } s.getItems().removeClass(t); w.addClass(t); return this.seekTo(u, x, v) } if (!w.hasClass(t)) { s.getItems().removeClass(t); w.addClass(t); var z = Math.floor(m.size / 2); var y = u - z; if (y > s.getSize() - m.size) { y = s.getSize() - m.size } if (y !== u) { return this.seekTo(y, x, v) } } return s }, onBeforeSeek: function(t) { return n("onBeforeSeek", t) }, onSeek: function(t) { return n("onSeek", t) } }); if (b.isFunction(b.fn.mousewheel)) { p.bind("mousewheel.scrollable", function(u, v) { var t = b.browser.opera ? 1 : -1; s.move(v > 0 ? t : -t, 50); return false }) } g.addClass(m.disabledClass).click(function() { s.prev() }); i.click(function() { s.next() }); o.click(function() { s.nextPage() }); h.addClass(m.disabledClass).click(function() { s.prevPage() }); if (m.keyboard) { b(document).unbind("keydown.scrollable").bind("keydown.scrollable", function(t) { var u = c; if (!u || t.altKey || t.ctrlKey) { return } if (d && (t.keyCode == 37 || t.keyCode == 39)) { u.move(t.keyCode == 37 ? -1 : 1); return t.preventDefault() } if (!d && (t.keyCode == 38 || t.keyCode == 40)) { u.move(t.keyCode == 38 ? -1 : 1); return t.preventDefault() } return true }) } function r() { if (q.is(":empty") || q.data("me") == s) { q.empty(); q.data("me", s); for (var u = 0; u < s.getPageAmount(); u++) { var v = b("<" + m.naviItem + "/>").attr("href", u).click(function(x) { var w = b(this); w.parent().children().removeClass(m.activeClass); w.addClass(m.activeClass); s.setPage(w.attr("href")); return x.preventDefault() }); if (u === 0) { v.addClass(m.activeClass) } q.append(v) } } else { var t = q.children(); t.each(function(w) { var x = b(this); x.attr("href", w); if (w === 0) { x.addClass(m.activeClass) } x.click(function() { q.find("." + m.activeClass).removeClass(m.activeClass); x.addClass(m.activeClass); s.setPage(x.attr("href")) }) }) } if (m.clickable) { s.getItems().each(function(x, w) { var y = b(this); if (!y.data("set")) { y.bind("click.scrollable", function() { s.click(x) }); y.data("set", true) } }) } if (m.hoverClass) { s.getItems().hover(function() { b(this).addClass(m.hoverClass) }, function() { b(this).removeClass(m.hoverClass) }) } return s } r(); var e = null; function k() { if (e) { return } e = setInterval(function() { if (m.interval === 0) { clearInterval(e); e = 0; return } s.next() }, m.interval) } if (m.interval > 0) { p.hover(function() { clearInterval(e); e = 0 }, function() { k() }); b("div.timeline a.prev").add("div.timeline a.next").hover(function() { clearInterval(e); e = 0 }, function() { k() }); k() } } b.fn.scrollable = function(d) { var e = this.eq(typeof d == "number" ? d : 0).data("scrollable"); if (e) { return e } var f = { size: 5, vertical: false, clickable: true, loop: false, interval: 0, speed: 400, keyboard: true, activeClass: "active", disabledClass: "disabled", hoverClass: null, easing: "swing", items: ".items", prev: ".prev", next: ".next", prevPage: ".prevPage", nextPage: ".nextPage", navi: ".navi", naviItem: "a", api: false, onBeforeSeek: null, onSeek: null }; b.extend(f, d); this.each(function() { e = new a(b(this), f); b(this).data("scrollable", e) }); return f.api ? e : this } })(jQuery); (function(b) { b.tools = b.tools || { version: {} }; b.tools.version.overlay = "1.0.4"; var c = []; function a(h, d) { var r = this, q = b(window), f, n, s, i, k, m, l; var e = d.expose && b.tools.version.expose; function p(o, t) { b(r).bind(o, function(v, u) { if (t && t.call(this) === false && u) { u.proceed = false } }); return r } b.each(d, function(o, t) { if (b.isFunction(t)) { p(o, t) } }); var j = d.target || h.attr("rel"); var g = j ? b(j) : null; if (!g) { g = h } else { k = h } q.load(function() { m = g.attr("overlay"); if (!m) { m = g.css("backgroundImage"); if (!m) { throw "background-image CSS property not set for overlay element: " + j } m = m.substring(m.indexOf("(") + 1, m.indexOf(")")).replace(/\"/g, ""); g.css("backgroundImage", "none"); g.attr("overlay", m) } s = g.outerWidth({ margin: true }); i = g.outerHeight({ margin: true }); n = b('<img src="' + m + '"/>'); n.css({ border: 0, position: "absolute", display: "none" }).width(s).attr("overlay", true); b("body").append(n); if (k) { k.bind("click.overlay", function(o) { r.load(o.pageY - q.scrollTop(), o.pageX - q.scrollLeft()); return o.preventDefault() }) } d.close = d.close || ".close"; if (!g.find(d.close).length) { g.prepend('<div class="close"></div>') } f = g.find(d.close); f.bind("click.overlay", function() { r.close() }); if (d.preload) { setTimeout(function() { var o = new Image(); o.src = m }, 2000) } }); b.extend(r, { load: function(w, v) { if (!n) { q.load(function() { r.load(w, v) }); return r } if (r.isOpened()) { return r } if (d.oneInstance) { b.each(c, function() { this.close() }) } var u = { proceed: true }; b(r).trigger("onBeforeLoad", u); if (!u.proceed) { return r } if (e) { n.expose(d.expose); l = n.expose().load() } w = w || d.start.top; v = v || d.start.left; var o = d.finish.top; var t = d.finish.left; if (o == "center") { o = Math.max((q.height() - i) / 2, 0) } if (t == "center") { t = Math.max((q.width() - s) / 2, 0) } if (!d.start.absolute) { w += q.scrollTop(); v += q.scrollLeft() } if (!d.finish.absolute) { o += q.scrollTop(); t += q.scrollLeft() } n.css({ top: w, left: v, width: d.start.width, zIndex: d.zIndex }).show(); n.animate({ top: o, left: t, width: s }, d.speed, function() { g.css({ position: "absolute", top: o, left: t }); var x = n.css("zIndex"); f.add(g).css("zIndex", ++x); g.fadeIn(d.fadeInSpeed, function() { b(r).trigger("onLoad") }) }); return r }, close: function() { if (!r.isOpened()) { return r } var u = { proceed: true }; b(r).trigger("onBeforeClose", u); if (!u.proceed) { return r } if (l) { l.close() } if (n.is(":visible")) { g.hide(); var t = d.start.top; var o = d.start.left; if (k) { u = k.offset(); t = u.top + k.height() / 2; o = u.left + k.width() / 2 } n.animate({ top: t, left: o, width: 0 }, d.closeSpeed, function() { b(r).trigger("onClose", u) }) } return r }, getBackgroundImage: function() { return n }, getContent: function() { return g }, getTrigger: function() { return k }, isOpened: function() { return g.is(":visible") }, getConf: function() { return d }, onBeforeLoad: function(o) { return p("onBeforeLoad", o) }, onLoad: function(o) { return p("onLoad", o) }, onBeforeClose: function(o) { return p("onBeforeClose", o) }, onClose: function(o) { return p("onClose", o) } }); b(document).keydown(function(o) { if (o.keyCode == 27) { r.close() } }); if (d.closeOnClick) { b(document).bind("click.overlay", function(o) { if (!g.is(":visible, :animated")) { return } var t = b(o.target); if (t.attr("overlay")) { return } if (t.parents("[overlay]").length) { return } r.close() }) } } b.fn.overlay = function(e) { var f = this.eq(typeof e == "number" ? e : 0).data("overlay"); if (f) { return f } var d = b(window); var g = { start: { top: Math.round(d.height() / 2), left: Math.round(d.width() / 2), width: 0, absolute: false }, finish: { top: 80, left: "center", absolute: false }, speed: "normal", fadeInSpeed: "fast", closeSpeed: "fast", close: null, oneInstance: true, closeOnClick: true, preload: true, zIndex: 9999, api: false, expose: null, target: null }; if (b.isFunction(e)) { e = { onBeforeLoad: e} } b.extend(true, g, e); this.each(function() { f = new a(b(this), g); c.push(f); b(this).data("overlay", f) }); return g.api ? f : this } })(jQuery); (function(b) { b.tools = b.tools || { version: {} }; b.tools.version.expose = "1.0.3"; function a() { var e = b(window).width(); if (b.browser.mozilla) { return e } var d; if (window.innerHeight && window.scrollMaxY) { d = window.innerWidth + window.scrollMaxX } else { if (document.body.scrollHeight > document.body.offsetHeight) { d = document.body.scrollWidth } else { d = document.body.offsetWidth } } return d < e ? d + 20 : e } function c(g, h) { var e = this, d = null, f = false, i = 0; function j(k, l) { b(e).bind(k, function(n, m) { if (l && l.call(this) === false && m) { m.proceed = false } }); return e } b.each(h, function(k, l) { if (b.isFunction(l)) { j(k, l) } }); b(window).bind("resize.expose", function() { if (d) { d.css({ width: a(), height: b(document).height() }) } }); b.extend(this, { getMask: function() { return d }, getExposed: function() { return g }, getConf: function() { return h }, isLoaded: function() { return f }, load: function() { if (f) { return e } i = g.eq(0).css("zIndex"); if (h.maskId) { d = b("#" + h.maskId) } if (!d || !d.length) { d = b("<div/>").css({ position: "absolute", top: 0, left: 0, width: a(), height: b(document).height(), display: "none", opacity: 0, zIndex: h.zIndex }); if (h.maskId) { d.attr("id", h.maskId) } b("body").append(d); var k = d.css("backgroundColor"); if (!k || k == "transparent" || k == "rgba(0, 0, 0, 0)") { d.css("backgroundColor", h.color) } if (h.closeOnEsc) { b(document).bind("keydown.unexpose", function(n) { if (n.keyCode == 27) { e.close() } }) } if (h.closeOnClick) { d.bind("click.unexpose", function() { e.close() }) } } var m = { proceed: true }; b(e).trigger("onBeforeLoad", m); if (!m.proceed) { return e } b.each(g, function() { var n = b(this); if (!/relative|absolute|fixed/i.test(n.css("position"))) { n.css("position", "relative") } }); g.css({ zIndex: h.zIndex + 1 }); var l = d.height(); if (!this.isLoaded()) { d.css({ opacity: 0, display: "block" }).fadeTo(h.loadSpeed, h.opacity, function() { if (d.height() != l) { d.css("height", l) } b(e).trigger("onLoad") }) } f = true; return e }, close: function() { if (!f) { return e } var k = { proceed: true }; b(e).trigger("onBeforeClose", k); if (k.proceed === false) { return e } d.fadeOut(h.closeSpeed, function() { b(e).trigger("onClose"); g.css({ zIndex: b.browser.msie ? i : null }) }); f = false; return e }, onBeforeLoad: function(k) { return j("onBeforeLoad", k) }, onLoad: function(k) { return j("onLoad", k) }, onBeforeClose: function(k) { return j("onBeforeClose", k) }, onClose: function(k) { return j("onClose", k) } }) } b.fn.expose = function(d) { var e = this.eq(typeof d == "number" ? d : 0).data("expose"); if (e) { return e } var f = { maskId: null, loadSpeed: "slow", closeSpeed: "fast", closeOnClick: true, closeOnEsc: true, zIndex: 9998, opacity: 0.8, color: "#456", api: false }; if (typeof d == "string") { d = { color: d} } b.extend(f, d); this.each(function() { e = new c(b(this), f); b(this).data("expose", e) }); return f.api ? e : this } })(jQuery);
/**
* tools.tabs 1.0.1 - Tabs done rigth.
* 
* Copyright (c) 2009 Tero Piirainen
* http://flowplayer.org/tools/tabs.html
*
* Dual licensed under MIT and GPL 2+ licenses
* http://www.opensource.org/licenses
*
* Launch  : November 2008
* Date: 2009-06-12 11:02:45 +0000 (Fri, 12 Jun 2009)
* Revision: 1911 
*/
(function($) {

	// static constructs
	$.tools = $.tools || { version: {} };

	$.tools.version.tabs = '1.0.1';

	$.tools.addTabEffect = function(name, fn) {
		effects[name] = fn;
	};


	var effects = {
		'default': function(i) {
			this.getPanes().hide().eq(i).show();
		},

		// custom configuration variable: fadeInSpeed
		fade: function(i) {
			this.getPanes().hide().eq(i).fadeIn(this.getConf().fadeInSpeed);
		},

		slide: function(i) {
			this.getCurrentPane().slideUp("fast");
			this.getPanes().eq(i).slideDown();
		},

		horizontal: function(i) {

			// store original width of a pane into memory
			if (!$._hW) { $._hW = this.getPanes().eq(0).width(); }

			// set current pane's width to zero
			this.getCurrentPane().animate({ width: 0 }, function() { $(this).hide(); });

			// grow opened pane to it's original width
			this.getPanes().eq(i).animate({ width: $._hW }, function() { $(this).show(); });
		}
	};


	function Tabs(tabs, panes, opts) {

		var self = this;
		var current;

		// generic binding function
		function bind(name, fn) {
			$(self).bind(name, function(e, args) {
				if (fn && fn.call(this, args.index) === false && args) {
					args.proceed = false;
				}
			});
			return self;
		}

		// bind all callbacks from configuration
		$.each(opts, function(name, fn) {
			if ($.isFunction(fn)) { bind(name, fn); }
		});


		// public methods
		$.extend(this, {
			click: function(i) {

				if (i === current) { return self; }

				var pane = self.getCurrentPane();
				var tab = tabs.eq(i);

				if (typeof i == 'string') {
					tab = tabs.filter("[href=" + i + "]");
					i = tabs.index(tab);
				}

				if (!tab.length) {
					if (current >= 0) { return self; }
					i = opts.initialIndex;
					tab = tabs.eq(i);
				}

				// possibility to cancel click action
				var args = { index: i, proceed: true };
				$(self).triggerHandler("onBeforeClick", args);
				if (!args.proceed) { return self; }

				tab.addClass(opts.current);

				// call the effect
				effects[opts.effect].call(self, i);

				// onClick callback
				$(self).triggerHandler("onClick", args);

				tabs.removeClass(opts.current);
				tab.addClass(opts.current);
				current = i;
				return self;
			},

			getConf: function() {
				return opts;
			},

			getTabs: function() {
				return tabs;
			},

			getPanes: function() {
				return panes;
			},

			getCurrentPane: function() {
				return panes.eq(current);
			},

			getCurrentTab: function() {
				return tabs.eq(current);
			},

			getIndex: function() {
				return current;
			},

			next: function() {
				return self.click(current + 1);
			},

			prev: function() {
				return self.click(current - 1);
			},

			onBeforeClick: function(fn) {
				return bind("onBeforeClick", fn);
			},

			onClick: function(fn) {
				return bind("onClick", fn);
			}

		});


		// setup click actions for each tab
		tabs.each(function(i) {
			$(this).bind(opts.event, function(e) {
				self.click(i);
				if (!opts.history) {
					return e.preventDefault();
				}
			});
		});

		// enable history plugin
		if (opts.history) {
			tabs.history(function(evt, hash) {
				self.click(hash || 0);
			});
		}

		// if no pane is visible --> click on the first tab
		if (location.hash) {
			self.click(location.hash);
		} else {
			self.click(opts.initialIndex);
		}

		// cross tab anchor link
		panes.find("a[href^=#]").click(function() {
			self.click($(this).attr("href"));
		});

	}


	// jQuery plugin implementation
	$.fn.tabs = function(query, arg) {

		// return existing instance
		var el = this.eq(typeof conf == 'number' ? conf : 0).data("tabs");
		if (el) { return el; }


		// setup options
		var opts = {
			tabs: 'a',
			current: 'current',
			onBeforeClick: null,
			onClick: null,
			effect: 'default',
			history: false,
			initialIndex: 0,
			event: 'click',
			api: false
		};

		if ($.isFunction(arg)) {
			arg = { onBeforeClick: arg };
		}

		$.extend(opts, arg);

		// install tabs for each items in jQuery		
		this.each(function() {
			var els = $(this).find(opts.tabs);

			if (!els.length) {
				els = $(this).children();
			}

			var panes = query.jquery ? query : $(query);

			el = new Tabs(els, panes, opts);
			$(this).data("tabs", el);
		});

		return opts.api ? el : this;
	};

})(jQuery);


//{{{ history plugin

/**
*	tools.history plugin. execute a callback when browser's 
* back/forward buttons are pressed.
*	
*	Can be used as a separate tool. Example:
*	
*	$("ul.tabs a").history(function(hash) {		
*		
*	});	
*/
(function($) {

	var hash, iframe;

	// jQuery plugin implementation
	$.prototype.history = function(fn) {

		var el = this;

		// IE
		if ($.browser.msie) {

			// create iframe that is constantly checked for hash changes
			if (!iframe) {
				iframe = $("<iframe />").hide().get(0);
				$("body").append(iframe);

				setInterval(function() {
					var idoc = iframe.contentWindow.document;
					var h = idoc.location.hash;

					if (hash !== h) {
						$.event.trigger("hash", h);
						hash = h;
					}
				}, 100);
			}

			// when link is clicked the iframe hash updated
			el.bind("click.hash", function(e) {
				var doc = iframe.contentWindow.document;
				doc.open().close();
				doc.location.hash = $(this).attr("href");
			});

			// pseudoclick of the first item 
			el.eq(0).triggerHandler("click.hash");


			// other browsers scans for location.hash changes directly withou iframe hack
		} else {
			setInterval(function() {
				var h = location.hash;

				if (el.filter("[href*=" + h + "]").length && h !== hash) {
					hash = h;
					$.event.trigger("hash", h);
				}
			}, 100);
		}

		// bind a history listener
		$(window).bind("hash", fn);

		// return jQuery
		return this;
	};


})(jQuery);

//}}}

/**
* tools.tooltip 1.0.2 - Tooltips done right.
* 
* Copyright (c) 2009 Tero Piirainen
* http://flowplayer.org/tools/tooltip.html
*
* Dual licensed under MIT and GPL 2+ licenses
* http://www.opensource.org/licenses
*
* Launch  : November 2008
* Date: 2009-06-12 11:02:45 +0000 (Fri, 12 Jun 2009)
* Revision: 1911 
*/
(function($) {

	// static constructs
	$.tools = $.tools || { version: {} };

	$.tools.version.tooltip = '1.0.2';


	var effects = {
		toggle: [
			function() { this.getTip().show(); },
			function() { this.getTip().hide(); }
		],

		fade: [
			function() { this.getTip().fadeIn(this.getConf().fadeInSpeed); },
			function() { this.getTip().fadeOut(this.getConf().fadeOutSpeed); }
		]
	};


	$.tools.addTipEffect = function(name, loadFn, hideFn) {
		effects[name] = [loadFn, hideFn];
	};


	/* this is how you add custom effects */

	/*
	default effect: "slideup", custom configuration variables: 
	- slideOffset
	- slideInSpeed
	- slideOutSpeed
	*/
	$.tools.addTipEffect("slideup",

		function() {
			var conf = this.getConf();
			var o = conf.slideOffset || 10;
			this.getTip().css({ opacity: 0 }).animate({
				top: '-=' + o,
				opacity: conf.opacity
			}, conf.slideInSpeed || 200).show();
		},

		function() {
			var conf = this.getConf();
			var o = conf.slideOffset || 10;
			this.getTip().animate({ top: '-=' + o, opacity: 0 }, conf.slideOutSpeed || 200, function() {
				$(this).hide().animate({ top: '+=' + (o * 2) }, 0);
			});
		}
	);

	function Tooltip(trigger, conf) {

		var self = this;

		// find the tip
		var tip = trigger.next();

		if (conf.tip) {

			// single tip. ie: #tip
			if (conf.tip.indexOf("#") != -1) {
				tip = $(conf.tip);

			} else {

				// find sibling
				tip = trigger.nextAll(conf.tip).eq(0);

				// find sibling from the parent element
				if (!tip.length) {
					tip = trigger.parent().nextAll(conf.tip).eq(0);
				}
			}
		}

		// generic binding function
		function bind(name, fn) {
			$(self).bind(name, function(e, args) {
				if (fn && fn.call(this) === false && args) {
					args.proceed = false;
				}
			});

			return self;
		}

		// bind all callbacks from configuration
		$.each(conf, function(name, fn) {
			if ($.isFunction(fn)) { bind(name, fn); }
		});


		// mouse interaction 
		var isInput = trigger.is("input, textarea");
		trigger.bind(isInput ? "focus" : "mouseover", function(e) {
			e.target = this;
			self.show(e);
			tip.hover(function() { self.show(); }, function() { self.hide(); });
		});

		trigger.bind(isInput ? "blur" : "mouseout", function() {
			self.hide();
		});

		tip.css("opacity", conf.opacity);

		var timer = 0;

		$.extend(self, {

			show: function(e) {

				if (e) { trigger = $(e.target); }

				clearTimeout(timer);
				if (tip.is(":animated") || tip.is(":visible")) { return self; }

				// onBeforeShow
				var p = { proceed: true };
				$(self).trigger("onBeforeShow", p);
				if (!p.proceed) { return self; }



				/* calculate tip position */

				// vertical axis
				var top = trigger.position().top - tip.outerHeight();
				var height = tip.outerHeight() + trigger.outerHeight();
				var pos = conf.position[0];
				if (pos == 'center') { top += height / 2; }
				if (pos == 'bottom') { top += height; }


				// horizontal axis
				var width = trigger.outerWidth() + tip.outerWidth();
				var left = trigger.position().left + trigger.outerWidth();
				pos = conf.position[1];


				if (pos == 'center') { left -= width / 2; }
				if (pos == 'left') { left -= width; }

				// offset
				top += conf.offset[0];
				left += conf.offset[1];

				// set position
				tip.css({ position: 'absolute', top: top, left: left });


				effects[conf.effect][0].call(self);
				$(self).trigger("onShow");
				return self;
			},

			hide: function() {
				clearTimeout(timer);

				timer = setTimeout(function() {
					if (!tip.is(":visible")) { return self; }

					// onBeforeHide
					var p = { proceed: true };
					$(self).trigger("onBeforeHide", p);
					if (!p.proceed) { return self; }


					effects[conf.effect][1].call(self);
					$(self).trigger("onHide");

				}, conf.delay || 1);

				return self;
			},

			isShown: function() {
				return tip.is(":visible, :animated");
			},

			getConf: function() {
				return conf;
			},

			getTip: function() {
				return tip;
			},

			getTrigger: function() {
				return trigger;
			},

			// callback functions
			onBeforeShow: function(fn) {
				return bind("onBeforeShow", fn);
			},

			onShow: function(fn) {
				return bind("onShow", fn);
			},

			onBeforeHide: function(fn) {
				return bind("onBeforeHide", fn);
			},

			onHide: function(fn) {
				return bind("onHide", fn);
			}

		});

	}


	// jQuery plugin implementation
	$.prototype.tooltip = function(conf) {

		// return existing instance
		var el = this.eq(typeof conf == 'number' ? conf : 0).data("tooltip");
		if (el) { return el; }

		// setup options
		var opts = {

			/* 			
			- slideOffset
			- slideInSpeed
			- slideOutSpeed 
			*/

			tip: null,
			effect: 'slideup',
			delay: 30,
			opacity: 1,

			// 'top', 'bottom', 'right', 'left', 'center'
			position: ['top', 'center'],
			offset: [0, 0],
			api: false
		};

		if ($.isFunction(conf)) {
			conf = { onBeforeShow: conf };
		}

		$.extend(opts, conf);

		// install tabs for each items in jQuery
		this.each(function() {
			el = new Tooltip($(this), opts);
			$(this).data("tooltip", el);
		});


		return opts.api ? el : this;

	};

})(jQuery);



/**
* jquery.scrollable 1.0.5 - Scroll your HTML with eye candy.
* 
* Copyright (c) 2009 Tero Piirainen
* http://flowplayer.org/tools/scrollable.html
*
* Dual licensed under MIT and GPL 2+ licenses
* http://www.opensource.org/licenses
*
* Launch  : March 2008
* Date: 2009-06-12 11:02:45 +0000 (Fri, 12 Jun 2009)
* Revision: 1911 
*/
(function($) {

	// static constructs
	$.tools = $.tools || { version: {} };

	$.tools.version.scrollable = '1.0.5';

	var current = null;


	// constructor
	function Scrollable(root, conf) {

		// current instance
		var self = this;
		if (!current) { current = self; }

		// generic binding function
		function bind(name, fn) {
			$(self).bind(name, function(e, args) {
				if (fn && fn.call(this, args.index) === false && args) {
					args.proceed = false;
				}
			});

			return self;
		}

		// bind all callbacks from configuration
		$.each(conf, function(name, fn) {
			if ($.isFunction(fn)) { bind(name, fn); }
		});


		// horizontal flag
		var horizontal = !conf.vertical;

		// wrap (root elements for items)
		var wrap = $(conf.items, root);

		// current index
		var index = 0;

		function find(query, ctx) {
			return query.indexOf("#") != -1 ? $(query).eq(0) : ctx.siblings(query).eq(0);
		}

		// get handle to navigational elements
		var navi = find(conf.navi, root);
		var prev = find(conf.prev, root);
		var next = find(conf.next, root);
		var prevPage = find(conf.prevPage, root);
		var nextPage = find(conf.nextPage, root);


		// methods
		$.extend(self, {

			getIndex: function() {
				return index;
			},

			getConf: function() {
				return conf;
			},

			getSize: function() {
				return self.getItems().size();
			},

			getPageAmount: function() {
				return Math.ceil(this.getSize() / conf.size);
			},

			getPageIndex: function() {
				return Math.ceil(index / conf.size);
			},

			getRoot: function() {
				return root;
			},

			getItemWrap: function() {
				return wrap;
			},

			getItems: function() {
				return wrap.children();
			},

			getVisibleItems: function() {
				return self.getItems().slice(index, index + conf.size);
			},

			/* all seeking functions depend on this */
			seekTo: function(i, time, fn) {

				// default speed
				if (time === undefined) { time = conf.speed; }

				// function given as second argument
				if ($.isFunction(time)) {
					fn = time;
					time = conf.speed;
				}

				if (i < 0) { i = 0; }
				if (i > self.getSize() - conf.size) { return self; }

				var item = self.getItems().eq(i);
				if (!item.length) { return self; }


				// onBeforeSeek
				var p = { index: i, proceed: true };
				$(self).trigger("onBeforeSeek", p);
				if (!p.proceed) { return self; }


				if (horizontal) {
					var left = -item.position().left;
					wrap.animate({ left: left }, time, conf.easing, fn ? function() { fn.call(self); } : null);

				} else {
					var top = -item.position().top;
					wrap.animate({ top: top }, time, conf.easing, fn ? function() { fn.call(self); } : null);
				}


				// navi status update
				if (navi.length) {
					var klass = conf.activeClass;
					var page = Math.ceil(i / conf.size);
					page = Math.min(page, navi.children().length - 1);
					navi.children().removeClass(klass).eq(page).addClass(klass);
				}

				// prev buttons disabled flag
				if (i === 0) {
					prev.add(prevPage).addClass(conf.disabledClass);
				} else {
					prev.add(prevPage).removeClass(conf.disabledClass);
				}

				// next buttons disabled flag
				if (i >= self.getSize() - conf.size) {
					next.add(nextPage).addClass(conf.disabledClass);
				} else {
					next.add(nextPage).removeClass(conf.disabledClass);
				}

				current = self;
				index = i;

				// onSeek after index being updated
				$(self).trigger("onSeek", { index: i });
				return self;
			},


			move: function(offset, time, fn) {
				var to = index + offset;
				if (conf.loop && to > (self.getSize() - conf.size)) {
					to = 0;
				}
				return this.seekTo(to, time, fn);
			},

			next: function(time, fn) {
				return this.move(1, time, fn);
			},

			prev: function(time, fn) {
				return this.move(-1, time, fn);
			},

			movePage: function(offset, time, fn) {
				return this.move(conf.size * offset, time, fn);
			},

			setPage: function(page, time, fn) {
				var size = conf.size;
				var index = size * page;
				var lastPage = index + size >= this.getSize();
				if (lastPage) {
					index = this.getSize() - conf.size;
				}
				return this.seekTo(index, time, fn);
			},

			prevPage: function(time, fn) {
				return this.setPage(this.getPageIndex() - 1, time, fn);
			},

			nextPage: function(time, fn) {
				return this.setPage(this.getPageIndex() + 1, time, fn);
			},

			begin: function(time, fn) {
				return this.seekTo(0, time, fn);
			},

			end: function(time, fn) {
				return this.seekTo(this.getSize() - conf.size, time, fn);
			},

			reload: function() {
				return load();
			},

			click: function(index, time, fn) {

				var item = self.getItems().eq(index);
				var klass = conf.activeClass;

				// check that index is sane
				if (index < 0 || index >= this.getSize()) { return self; }


				// special case with two items
				if (conf.size == 2) {
					if (index == self.getIndex()) { index--; }
					self.getItems().removeClass(klass);
					item.addClass(klass);
					return this.seekTo(index, time, fn);
				}


				if (!item.hasClass(klass)) {
					self.getItems().removeClass(klass);
					item.addClass(klass);
					var delta = Math.floor(conf.size / 2);
					var to = index - delta;

					// next to last item must work
					if (to > self.getSize() - conf.size) {
						to = self.getSize() - conf.size;
					}

					if (to !== index) {
						return this.seekTo(to, time, fn);
					}
				}

				return self;
			},

			// callback functions
			onBeforeSeek: function(fn) {
				return bind("onBeforeSeek", fn);
			},

			onSeek: function(fn) {
				return bind("onSeek", fn);
			}

		});


		// mousewheel
		if ($.isFunction($.fn.mousewheel)) {
			root.bind("mousewheel.scrollable", function(e, delta) {
				// opera goes to opposite direction
				var step = $.browser.opera ? 1 : -1;

				self.move(delta > 0 ? step : -step, 50);
				return false;
			});
		}

		// prev button		
		prev.addClass(conf.disabledClass).click(function() {
			self.prev();
		});


		// next button
		next.click(function() {
			self.next();
		});

		// prev page button
		nextPage.click(function() {
			self.nextPage();
		});


		// next page button
		prevPage.addClass(conf.disabledClass).click(function() {
			self.prevPage();
		});


		// keyboard
		if (conf.keyboard) {

			// keyboard works on one instance at the time. thus we need to unbind first
			$(document).unbind("keydown.scrollable").bind("keydown.scrollable", function(evt) {

				var el = current;
				if (!el || evt.altKey || evt.ctrlKey) { return; }

				if (horizontal && (evt.keyCode == 37 || evt.keyCode == 39)) {
					el.move(evt.keyCode == 37 ? -1 : 1);
					return evt.preventDefault();
				}

				if (!horizontal && (evt.keyCode == 38 || evt.keyCode == 40)) {
					el.move(evt.keyCode == 38 ? -1 : 1);
					return evt.preventDefault();
				}

				return true;

			});
		}

		// navi 			
		function load() {

			// generate new entries
			if (navi.is(":empty") || navi.data("me") == self) {

				navi.empty();
				navi.data("me", self);

				for (var i = 0; i < self.getPageAmount(); i++) {

					var item = $("<" + conf.naviItem + "/>").attr("href", i).click(function(e) {
						var el = $(this);
						el.parent().children().removeClass(conf.activeClass);
						el.addClass(conf.activeClass);
						self.setPage(el.attr("href"));
						return e.preventDefault();
					});

					if (i === 0) { item.addClass(conf.activeClass); }
					navi.append(item);
				}

				// assign onClick events to existing entries
			} else {

				// find a entries first -> syntaxically correct
				var els = navi.children();

				els.each(function(i) {
					var item = $(this);
					item.attr("href", i);
					if (i === 0) { item.addClass(conf.activeClass); }

					item.click(function() {
						navi.find("." + conf.activeClass).removeClass(conf.activeClass);
						item.addClass(conf.activeClass);
						self.setPage(item.attr("href"));
					});

				});
			}


			// item.click()
			if (conf.clickable) {
				self.getItems().each(function(index, arg) {
					var el = $(this);
					if (!el.data("set")) {
						el.bind("click.scrollable", function() {
							self.click(index);
						});
						el.data("set", true);
					}
				});
			}


			// hover
			if (conf.hoverClass) {
				self.getItems().hover(function() {
					$(this).addClass(conf.hoverClass);
				}, function() {
					$(this).removeClass(conf.hoverClass);
				});
			}

			return self;
		}

		load();


		// interval stuff
		var timer = null;

		function setTimer() {

			// do not start additional timer if already exists
			if (timer) { return; }

			// construct new timer
			timer = setInterval(function() {

				// check if interval is being changed dynamically during runtime
				if (conf.interval === 0) {
					clearInterval(timer);
					timer = 0;
					return;
				}

				self.next();
			}, conf.interval);
		}

		if (conf.interval > 0) {

			// when mouse enters, autoscroll stops
			root.hover(function() {
				clearInterval(timer);
				timer = 0;

			}, function() {
				setTimer();
			});
			//fbis - added prev and next to items that stop the scroll
			$('div.timeline a.prev').add('div.timeline a.next').hover(function() {
				clearInterval(timer);
				timer = 0;

			}, function() {
				setTimer();
			});

			setTimer();
		}

	}


	// jQuery plugin implementation
	$.fn.scrollable = function(conf) {

		// already constructed --> return API
		var el = this.eq(typeof conf == 'number' ? conf : 0).data("scrollable");
		if (el) { return el; }


		var opts = {

			// basics
			size: 5,
			vertical: false,
			clickable: true,
			loop: false,
			interval: 0,
			speed: 400,
			keyboard: true,

			// other
			activeClass: 'active',
			disabledClass: 'disabled',
			hoverClass: null,
			easing: 'swing',

			// navigational elements
			items: '.items',
			prev: '.prev',
			next: '.next',
			prevPage: '.prevPage',
			nextPage: '.nextPage',
			navi: '.navi',
			naviItem: 'a',
			api: false,


			// callbacks
			onBeforeSeek: null,
			onSeek: null

		};


		$.extend(opts, conf);

		this.each(function() {
			el = new Scrollable($(this), opts);
			$(this).data("scrollable", el);
		});

		return opts.api ? el : this;

	};


})(jQuery);
/**
* tools.overlay 1.0.4 - Overlay HTML with eye candy.
* 
* Copyright (c) 2009 Tero Piirainen
* http://flowplayer.org/tools/overlay.html
*
* Dual licensed under MIT and GPL 2+ licenses
* http://www.opensource.org/licenses
*
* Launch  : March 2008
* Date: 2009-06-12 11:02:45 +0000 (Fri, 12 Jun 2009)
* Revision: 1911 
*/
(function($) {

	// static constructs
	$.tools = $.tools || { version: {} };

	$.tools.version.overlay = '1.0.4';


	var instances = [];


	function Overlay(el, opts) {

		// private variables
		var self = this, w = $(window), closeButton, img, trigger, bg, exposeApi, oHeight, oWidth;
		var expose = opts.expose && $.tools.version.expose;

		// generic binding function
		function bind(name, fn) {
			$(self).bind(name, function(e, args) {
				if (fn && fn.call(this) === false && args) {
					args.proceed = false;
				}
			});
			return self;
		}

		// bind all callbacks from configuration
		$.each(opts, function(name, fn) {
			if ($.isFunction(fn)) { bind(name, fn); }
		});


		// get trigger and overlayed element
		var jq = opts.target || el.attr("rel");
		var o = jq ? $(jq) : null;

		if (!o) { o = el; }
		else { trigger = el; }

		o.addClass(opts.overlayClass);


		// external CSS properties are accessible only on window.onLoad (safari / chrome)
		w.load(function() {

			// get growing image
			bg = o.attr("overlay");

			// // growing image is required (on this version)	
			// if (!bg) { 
			//	bg = o.css("backgroundImage");
			//	
			//	if (bg != 'none') { 
			//					// url("bg.jpg") --> bg.jpg
			//					bg = bg.substring(bg.indexOf("(") + 1, bg.indexOf(")")).replace(/\"/g, "");
			//					o.css("backgroundImage", "none");
			//					o.attr("overlay", bg);							
			// 
			//	} else {
			//		bg = null;
			//	}
			// }
			if (bg) {
				// setup growing image
				img = $('<img src="' + bg + '"/>');
				img.css({ border: 0, position: 'absolute', display: 'none' }).width(o.outerWidth({ margin: true }));
				$('body').append(img);

				// automatic preloading of the image
				if (opts.preload) {
					setTimeout(function() {
						var img = new Image();
						img.src = bg;
					}, 2000);
				}
			} else {
				o.css({ position: 'absolute', display: 'none' }).attr('overlay', 'x');
			}

			// if trigger is given - assign it's click event
			if (trigger) {
				trigger.bind("click.overlay", function(e) {
					self.load(e.pageY - w.scrollTop(), e.pageX - w.scrollLeft());
					return false;
					// return e.preventDefault();
				});
			}

			// close button
			opts.close = opts.close || ".close";

			if (!o.find(opts.close).length) {
				o.prepend('<div class="close"></div>');
			}

			closeButton = o.find(opts.close);

			closeButton.bind("click.overlay", function() {
				self.close();
			});

		});


		// API methods	
		$.extend(self, {

			load: function(top, left) {

				// // lazy loading if things are not setup yet
				// if (!img) { 
				//	w.load(function()  {
				//		self.load(top, left);		
				//	});
				//	return self;
				// }

				// one instance visible at once
				if (self.isOpened()) {
					return self;
				}

				if (opts.oneInstance) {
					$.each(instances, function() {
						this.close();
					});
				}

				// onBeforeLoad
				var p = { proceed: true };
				$(self).trigger("onBeforeLoad", p);
				if (!p.proceed) { return self; }

				// exposing effect
				if (expose) {
					if (img) {
						img.expose(opts.expose);
						exposeApi = img.expose().load();
					} else {
						o.expose(opts.expose);
						exposeApi = o.expose().load();
					}
				}

				// start position			
				top = top || opts.start.top;
				left = left || opts.start.left;

				// finish position 
				var toTop = opts.finish.top;
				var toLeft = opts.finish.left;

				// get overlay's current dimensions
				oWidth = o.outerWidth({ margin: true });
				oHeight = o.outerHeight({ margin: true });

				if (toTop == 'center') { toTop = Math.max((w.height() - oHeight) / 2, 0); }
				if (toLeft == 'center') { toLeft = Math.max((w.width() - oWidth) / 2, 0); }

				// adjust positioning relative to scrolling position
				if (!opts.start.absolute) {
					top += w.scrollTop();
					left += w.scrollLeft();
				}

				if (!opts.finish.absolute) {
					toTop += w.scrollTop();
					toLeft += w.scrollLeft();
				}

				if (img) {
					// initialize background image	
					img.css({ top: top, left: left, width: opts.start.width, zIndex: opts.zIndex }).show();

					// begin growing
					img.animate({ top: toTop, left: toLeft, width: oWidth }, opts.speed, function() {

						// set content on top of the image
						o.css({ position: 'absolute', top: toTop, left: toLeft });
						var z = img.css("zIndex");
						closeButton.add(o).css("zIndex", ++z);

						$(self).trigger("onLoad");

						o.fadeIn(opts.fadeInSpeed);

					});
				} else {
					// fire onLoad first in case this is dynamic
					$(self).trigger("onLoad");

					// get overlay's current dimensions
					oWidth = o.width();
					oHeight = o.height();

					// start small
					o.css({ top: top, left: left, width: opts.start.width, height: opts.start.height, zIndex: opts.zIndex }).show();

					// begin growing
					o.animate({ top: toTop, left: toLeft, width: oWidth, height: oHeight }, opts.speed, function() {
						var z = o.css("zIndex");
						closeButton.add(o).css("zIndex", ++z);
					});
				}

				return self;
			},

			close: function() {

				if (!self.isOpened()) { return self; }

				var p = { proceed: true };
				$(self).trigger("onBeforeClose", p);
				if (!p.proceed) { return self; }

				// close exposing effect
				if (exposeApi) { exposeApi.close(); }

				if (o.is(":visible")) {

					// calculate triggers position
					var top = opts.start.top;
					var left = opts.start.left;

					if (trigger) {
						p = trigger.offset();
						top = p.top + trigger.height() / 2;
						left = p.left + trigger.width() / 2;
					}

					if (img) {
						// hide overlayed content
						o.hide();
						// shrink image
						img.animate({ top: top, left: left, width: 0 }, opts.closeSpeed, function() {
							$(self).trigger("onClose", p);
						});
					} else {
						// shrink overlay
						o.animate({ top: top, left: left, width: 0, height: 0 }, opts.closeSpeed, function() {
							$(self).trigger("onClose", p);
							// hide and restore dimensions
							o.hide().width(oWidth).height(oHeight);
						});
					}
				}

				return self;
			},


			getBackgroundImage: function() {
				return img;
			},

			getContent: function() {
				return o;
			},

			getTrigger: function() {
				return trigger;
			},

			isOpened: function() {
				return o.is(":visible");
			},

			// manipulate start, finish and speeds
			getConf: function() {
				return opts;
			},

			// callback functions
			onBeforeLoad: function(fn) {
				return bind("onBeforeLoad", fn);
			},

			onLoad: function(fn) {
				return bind("onLoad", fn);
			},

			onBeforeClose: function(fn) {
				return bind("onBeforeClose", fn);
			},

			onClose: function(fn) {
				return bind("onClose", fn);
			}

		});


		// keyboard::escape
		$(document).keydown(function(evt) {
			if (evt.keyCode == 27) {
				self.close();
			}
		});


		// when window is clicked outside overlay, we close
		if (opts.closeOnClick) {
			$(document).bind("click.overlay", function(evt) {
				if (!o.is(":visible, :animated")) { return; }
				var target = $(evt.target);
				if (target.attr("overlay")) { return; }
				if (target.parents("[overlay]").length) { return; }
				self.close();
			});
		}

	}

	// jQuery plugin initialization
	$.fn.overlay = function(conf) {

		// already constructed --> return API
		var el = this.eq(typeof conf == 'number' ? conf : 0).data("overlay");
		if (el) { return el; }

		var w = $(window);

		var opts = {

			/* 
			- onBeforeLoad 
			- onLoad
			- onBeforeClose 
			- onClose 
			*/

			start: {
				// by default: button position || window center
				top: Math.round(w.height() / 2),
				left: Math.round(w.width() / 2),
				width: 0,
				height: 0,
				absolute: false
			},

			finish: {
				top: 80,
				left: 'center',
				absolute: false
			},

			speed: 'normal',
			fadeInSpeed: 'fast',
			closeSpeed: 'fast',

			close: null,
			oneInstance: true,
			closeOnClick: true,
			preload: true,
			zIndex: 9999,
			api: false,
			expose: null,
			overlayClass: "isoverlay",

			// target element to be overlayed. by default taken from [rel]
			target: null
		};

		if ($.isFunction(conf)) {
			conf = { onBeforeLoad: conf };
		}

		$.extend(true, opts, conf);


		this.each(function() {
			el = new Overlay($(this), opts);
			instances.push(el);
			$(this).data("overlay", el);
		});

		return opts.api ? el : this;
	};

})(jQuery);

/**
* tools.expose 1.0.3 - Make HTML elements stand out
* 
* Copyright (c) 2009 Tero Piirainen
* http://flowplayer.org/tools/expose.html
*
* Dual licensed under MIT and GPL 2+ licenses
* http://www.opensource.org/licenses
*
* Launch  : June 2008
* Date: 2009-06-12 11:02:45 +0000 (Fri, 12 Jun 2009)
* Revision: 1911 
*/
(function($) {

	// static constructs
	$.tools = $.tools || { version: {} };

	$.tools.version.expose = '1.0.3';

	function getWidth() {

		var w = $(window).width();

		if ($.browser.mozilla) { return w; }

		var x;

		if (window.innerHeight && window.scrollMaxY) {
			x = window.innerWidth + window.scrollMaxX;

			// all but Explorer Mac	
		} else if (document.body.scrollHeight > document.body.offsetHeight) {
			x = document.body.scrollWidth;

		} else {
			x = document.body.offsetWidth;
		}

		return x < w ? x + 20 : w;
	}

	function Expose(els, opts) {

		// private variables
		var self = this, mask = null, loaded = false, origIndex = 0;

		// generic binding function
		function bind(name, fn) {
			$(self).bind(name, function(e, args) {
				if (fn && fn.call(this) === false && args) {
					args.proceed = false;
				}
			});
			return self;
		}

		// bind all callbacks from configuration
		$.each(opts, function(name, fn) {
			if ($.isFunction(fn)) { bind(name, fn); }
		});


		// adjust mask size when window is resized (or firebug is toggled)
		$(window).bind("resize.expose", function() {
			if (mask) {
				mask.css({ width: getWidth(), height: $(document).height() });
			}
		});


		// public methods
		$.extend(this, {

			getMask: function() {
				return mask;
			},

			getExposed: function() {
				return els;
			},

			getConf: function() {
				return opts;
			},

			isLoaded: function() {
				return loaded;
			},

			load: function() {

				// already loaded ?
				if (loaded) { return self; }

				origIndex = els.eq(0).css("zIndex");

				// find existing mask
				if (opts.maskId) { mask = $("#" + opts.maskId); }

				if (!mask || !mask.length) {

					mask = $('<div/>').css({
						position: 'absolute',
						top: 0,
						left: 0,
						width: getWidth(),
						height: $(document).height(),
						display: 'none',
						opacity: 0,
						zIndex: opts.zIndex
					});

					// id
					if (opts.maskId) { mask.attr("id", opts.maskId); }

					$("body").append(mask);


					// background color 
					var bg = mask.css("backgroundColor");

					if (!bg || bg == 'transparent' || bg == 'rgba(0, 0, 0, 0)') {
						mask.css("backgroundColor", opts.color);
					}

					// esc button
					if (opts.closeOnEsc) {
						$(document).bind("keydown.unexpose", function(evt) {
							if (evt.keyCode == 27) {
								self.close();
							}
						});
					}

					// mask click closes
					if (opts.closeOnClick) {
						mask.bind("click.unexpose", function() {
							self.close();
						});
					}
				}

				// possibility to cancel click action
				var p = { proceed: true };
				$(self).trigger("onBeforeLoad", p);
				if (!p.proceed) { return self; }


				// make sure element is positioned absolutely or relatively
				$.each(els, function() {
					var el = $(this);
					if (!/relative|absolute|fixed/i.test(el.css("position"))) {
						el.css("position", "relative");
					}
				});

				// make elements sit on top of the mask
				els.css({ zIndex: opts.zIndex + 1 });


				// reveal mask
				var h = mask.height();

				if (!this.isLoaded()) {
					mask.css({ opacity: 0, display: 'block' }).fadeTo(opts.loadSpeed, opts.opacity, function() {

						// sometimes IE6 misses the height property on fadeTo method
						if (mask.height() != h) { mask.css("height", h); }
						$(self).trigger("onLoad");
					});
				}

				loaded = true;
				return self;
			},


			close: function() {

				if (!loaded) { return self; }

				var p = { proceed: true };
				$(self).trigger("onBeforeClose", p);
				if (p.proceed === false) { return self; }

				mask.fadeOut(opts.closeSpeed, function() {
					$(self).trigger("onClose");
					els.css({ zIndex: $.browser.msie ? origIndex : null });
				});

				loaded = false;
				return self;
			},


			onBeforeLoad: function(fn) {
				return bind("onBeforeLoad", fn);
			},

			onLoad: function(fn) {
				return bind("onLoad", fn);
			},

			onBeforeClose: function(fn) {
				return bind("onBeforeClose", fn);
			},

			onClose: function(fn) {
				return bind("onClose", fn);
			}

		});

	}


	// jQuery plugin implementation
	$.fn.expose = function(conf) {

		var el = this.eq(typeof conf == 'number' ? conf : 0).data("expose");
		if (el) { return el; }

		var opts = {
			/*
			- onBeforeLoad 
			- onLoad
			- onBeforeClose 
			- onClose 
			*/

			// mask settings
			maskId: null,
			loadSpeed: 'slow',
			closeSpeed: 'fast',
			closeOnClick: true,
			closeOnEsc: true,

			// css settings
			zIndex: 9998,
			opacity: 0.8,
			color: '#456',
			api: false
		};

		if (typeof conf == 'string') {
			conf = { color: conf };
		}

		$.extend(opts, conf);

		// construct exposes
		this.each(function() {
			el = new Expose($(this), opts);
			$(this).data("expose", el);
		});

		return opts.api ? el : this;
	};


})(jQuery);
