text: /**
   * @license
   * jQuery Tools 1.2.2 Scrollable - New wave UI design
   *
   * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
   *
   * http://flowplayer.org/tools/scrollable.html
   *
   * Since: March 2008
   * Date:    Wed May 19 06:53:17 2010 +0000
   */
  (function ($) {
  
      // static constructs
      $.tools = $.tools || {version: '1.2.2'};
  
      $.tools.scrollable = {
  
          conf: {
              activeClass: 'active',
              circular: false,
              clonedClass: 'cloned',
              disabledClass: 'disabled',
              easing: 'swing',
              initialIndex: 0,
              item: null,
              items: '.items',
              keyboard: true,
              mousewheel: false,
              next: '.next',
              prev: '.prev',
              speed: 400,
              vertical: false,
              wheelSpeed: 0
          }
      };
  
      // get hidden element's width or height even though it's hidden
      function dim(el, key) {
          var v = parseInt(el.css(key), 10);
          if (v) {
              return v;
          }
          var s = el[0].currentStyle;
          return s && s.width && parseInt(s.width, 10);
      }
  
      function find(root, query) {
          var el = $(query);
          return el.length < 2 ? el : root.parent().find(query);
      }
  
      var current;
  
      // constructor
      function Scrollable(root, conf) {
  
          // current instance
          var self = this,
              fire = root.add(self),
              itemWrap = root.children(),
              index = 0,
              vertical = conf.vertical;
  
          if (!current) {
              current = self;
          }
          if (itemWrap.length > 1) {
              itemWrap = $(conf.items, root);
          }
  
          // methods
          $.extend(self, {
  
              getConf: function () {
                  return conf;
              },
  
              getIndex: function () {
                  return index;
              },
  
              getSize: function () {
                  return self.getItems().size();
              },
  
              getNaviButtons: function () {
                  return prev.add(next);
              },
  
              getRoot: function () {
                  return root;
              },
  
              getItemWrap: function () {
                  return itemWrap;
              },
  
              getItems: function () {
                  return itemWrap.children(conf.item).not("." + conf.clonedClass);
              },
  
              move: function (offset, time) {
                  return self.seekTo(index + offset, time);
              },
  
              next: function (time) {
                  return self.move(1, time);
              },
  
              prev: function (time) {
                  return self.move(-1, time);
              },
  
              begin: function (time) {
                  return self.seekTo(0, time);
              },
  
              end: function (time) {
                  return self.seekTo(self.getSize() - 1, time);
              },
  
              focus: function () {
                  current = self;
                  return self;
              },
  
              addItem: function (item) {
                  item = $(item);
  
                  if (!conf.circular) {
                      itemWrap.append(item);
                  } else {
                      $(".cloned:last").before(item);
                      $(".cloned:first").replaceWith(item.clone().addClass(conf.clonedClass));
                  }
  
                  fire.trigger("onAddItem", [item]);
                  return self;
              },
  
  
              /* all seeking functions depend on this */
              seekTo: function (i, time, fn) {
  
                  // avoid seeking from end clone to the beginning
                  if (conf.circular && i === 0 && index == -1 && time !== 0) {
                      return self;
                  }
  
                  // check that index is sane
                  if (!conf.circular && i < 0 || i > self.getSize() || i < -1) {
                      return self;
                  }
  
                  var item = i;
  
                  if (i.jquery) {
                      i = self.getItems().index(i);
                  } else {
                      item = self.getItems().eq(i);
                  }
  
                  // onBeforeSeek
                  var e = $.Event("onBeforeSeek");
                  if (!fn) {
                      fire.trigger(e, [i, time]);
                      if (e.isDefaultPrevented() || !item.length) {
                          return self;
                      }
                  }
  
                  var props = vertical ? {top: -item.position().top} : {left: -item.position().left};
  
                  index = i;
                  current = self;
                  if (time === undefined) {
                      time = conf.speed;
                  }
  
                  itemWrap.animate(props, time, conf.easing, fn || function () {
                          fire.trigger("onSeek", [i]);
                      });
  
                  return self;
              }
  
          });
  
          // callbacks
          $.each(['onBeforeSeek', 'onSeek', 'onAddItem'], function (i, name) {
  
              // configuration
              if ($.isFunction(conf[name])) {
                  $(self).bind(name, conf[name]);
              }
  
              self[name] = function (fn) {
                  $(self).bind(name, fn);
                  return self;
              };
          });
  
          // circular loop
          if (conf.circular) {
  
              var cloned1 = self.getItems().slice(-1).clone().prependTo(itemWrap),
                  cloned2 = self.getItems().eq(1).clone().appendTo(itemWrap);
  
              cloned1.add(cloned2).addClass(conf.clonedClass);
  
              self.onBeforeSeek(function (e, i, time) {
  
  
                  if (e.isDefaultPrevented()) {
                      return;
                  }
  
                  /*
                   1. animate to the clone without event triggering
                   2. seek to correct position with 0 speed
                   */
                  if (i == -1) {
                      self.seekTo(cloned1, time, function () {
                          self.end(0);
                      });
                      return e.preventDefault();
  
                  } else if (i == self.getSize()) {
                      self.seekTo(cloned2, time, function () {
                          self.begin(0);
                      });
                  }
  
              });
  
              // seek over the cloned item
              self.seekTo(0, 0);
          }
  
          // next/prev buttons
          var prev = find(root, conf.prev).click(function () {
                  self.prev();
              }),
              next = find(root, conf.next).click(function () {
                  self.next();
              });
  
          if (!conf.circular && self.getSize() > 1) {
  
              self.onBeforeSeek(function (e, i) {
                  prev.toggleClass(conf.disabledClass, i <= 0);
                  next.toggleClass(conf.disabledClass, i >= self.getSize() - 1);
              });
          }
  
          // mousewheel support
          if (conf.mousewheel && $.fn.mousewheel) {
              root.mousewheel(function (e, delta) {
                  if (conf.mousewheel) {
                      self.move(delta < 0 ? 1 : -1, conf.wheelSpeed || 50);
                      return false;
                  }
              });
          }
  
          if (conf.keyboard) {
  
              $(document).bind("keydown.scrollable", function (evt) {
  
                  // skip certain conditions
                  if (!conf.keyboard || evt.altKey || evt.ctrlKey || $(evt.target).is(":input")) {
                      return;
                  }
  
                  // does this instance have focus?
                  if (conf.keyboard != 'static' && current != self) {
                      return;
                  }
  
                  var key = evt.keyCode;
  
                  if (vertical && (key == 38 || key == 40)) {
                      self.move(key == 38 ? -1 : 1);
                      return evt.preventDefault();
                  }
  
                  if (!vertical && (key == 37 || key == 39)) {
                      self.move(key == 37 ? -1 : 1);
                      return evt.preventDefault();
                  }
  
              });
          }
  
          // initial index
          $(self).trigger("onBeforeSeek", [conf.initialIndex]);
      }
  
  
      // jQuery plugin implementation
      $.fn.scrollable = function (conf) {
  
          // already constructed --> return API
          var el = this.data("scrollable");
          if (el) {
              return el;
          }
  
          conf = $.extend({}, $.tools.scrollable.conf, conf);
  
          this.each(function () {
              el = new Scrollable($(this), conf);
              $(this).data("scrollable", el);
          });
  
          return conf.api ? el : this;
  
      };
  
  
  })(jQuery);
  