topical media & game development

talk show tell print

lib-jquery-learning-code-10-jquery.ui.1.6.rc3.js / js



  /*
   * jQuery UI Effects @VERSION
   *
   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI/Effects/
   */
  ;(function() {
  
  .effects = .effects || {}; //Add the 'effects' scope
  
  .extend(.effects, {
          version: "@VERSION",
          save: function(el, set) {
                  for(var i=0;i<set.length;i++) {
                          if(set[i] !== null) .data(el[0], "ec.storage."+set[i], el[0].style[set[i]]);
                  }
          },
          restore: function(el, set) {
                  for(var i=0;i<set.length;i++) {
                          if(set[i] !== null) el.css(set[i], .data(el[0], "ec.storage."+set[i]));
                  }
          },
          setMode: function(el, mode) {
                  if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
                  return mode;
          },
          getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
                  // this should be a little more flexible in the future to handle a string & hash
                  var y, x;
                  switch (origin[0]) {
                          case 'top': y = 0; break;
                          case 'middle': y = 0.5; break;
                          case 'bottom': y = 1; break;
                          default: y = origin[0] / original.height;
                  };
                  switch (origin[1]) {
                          case 'left': x = 0; break;
                          case 'center': x = 0.5; break;
                          case 'right': x = 1; break;
                          default: x = origin[1] / original.width;
                  };
                  return {x: x, y: y};
          },
          createWrapper: function(el) {
                  if (el.parent().attr('id') == 'fxWrapper')
                          return el;
                  var props = {width: el.outerWidth({margin:true}), height: el.outerHeight({margin:true}), 'float': el.css('float')};
                  el.wrap('<div id="fxWrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');
                  var wrapper = el.parent();
                  if (el.css('position') == 'static'){
                          wrapper.css({position: 'relative'});
                          el.css({position: 'relative'});
                  } else {
                          var top = el.css('top'); if(isNaN(parseInt(top))) top = 'auto';
                          var left = el.css('left'); if(isNaN(parseInt(left))) left = 'auto';
                          wrapper.css({ position: el.css('position'), top: top, left: left, zIndex: el.css('z-index') }).show();
                          el.css({position: 'relative', top:0, left:0});
                  }
                  wrapper.css(props);
                  return wrapper;
          },
          removeWrapper: function(el) {
                  if (el.parent().attr('id') == 'fxWrapper')
                          return el.parent().replaceWith(el);
                  return el;
          },
          setTransition: function(el, list, factor, val) {
                  val = val || {};
                  .each(list,function(i, x){
                          unit = el.cssUnit(x);
                          if (unit[0] > 0) val[x] = unit[0] * factor + unit[1];
                  });
                  return val;
          },
          animateClass: function(value, duration, easing, callback) {
  
                  var cb = (typeof easing == "function" ? easing : (callback ? callback : null));
                  var ea = (typeof easing == "object" ? easing : null);
  
                  return this.each(function() {
  
                          var offset = {}; var that = this; var oldStyleAttr = that.attr("style") || '';
                          if(typeof oldStyleAttr == 'object') oldStyleAttr = oldStyleAttr["cssText"]; /* Stupidly in IE, style is a object.. */
                          if(value.toggle) { that.hasClass(value.toggle) ? value.remove = value.toggle : value.add = value.toggle; }
  
                          //Let's get a style offset
                          var oldStyle = .extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
                          if(value.add) that.addClass(value.add); if(value.remove) that.removeClass(value.remove);
                          var newStyle = .extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
                          if(value.add) that.removeClass(value.add); if(value.remove) that.addClass(value.remove);
  
                          // The main function to form the object for animation
                          for(var n in newStyle) {
                                  if( typeof newStyle[n] != "function" && newStyle[n] /* No functions and null properties */
                                  && n.indexOf("Moz") == -1 && n.indexOf("length") == -1 /* No mozilla spezific render properties. */
                                  && newStyle[n] != oldStyle[n] /* Only values that have changed are used for the animation */
                                  && (n.match(/color/i) || (!n.match(/color/i) && !isNaN(parseInt(newStyle[n],10)))) /* Only things that can be parsed to integers or colors */
                                  && (oldStyle.position != "static" || (oldStyle.position == "static" && !n.match(/left|top|bottom|right/))) /* No need for positions when dealing with static positions */
                                  ) offset[n] = newStyle[n];
                          }
  
                          that.animate(offset, duration, ea, function() { // Animate the newly constructed offset object
                                  // Change style attribute back to original. For stupid IE, we need to clear the damn object.
                                  if(typeof this.attr("style") == 'object') { this.attr("style")["cssText"] = ""; this.attr("style")["cssText"] = oldStyleAttr; } else this.attr("style", oldStyleAttr);
                                  if(value.add) this.addClass(value.add); if(value.remove) this.removeClass(value.remove);
                                  if(cb) cb.apply(this, arguments);
                          });
  
                  });
          }
  });
  
  //Extend the methods of jQuery
  .fn.extend({
          //Save old methods
          _show: .fn.show,
          _hide: .fn.hide,
          __toggle: .fn.toggle,
          _addClass: .fn.addClass,
          _removeClass: .fn.removeClass,
          _toggleClass: .fn.toggleClass,
          // New ec methods
          effect: function(fx,o,speed,callback) {
                  return .effects[fx] ? .effects[fx].call(this, {method: fx, options: o || {}, duration: speed, callback: callback }) : null;
          },
          show: function() {
                  if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])))
                          return this._show.apply(this, arguments);
                  else {
                          var o = arguments[1] || {}; o['mode'] = 'show';
                          return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]);
                  }
          },
          hide: function() {
                  if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])))
                          return this._hide.apply(this, arguments);
                  else {
                          var o = arguments[1] || {}; o['mode'] = 'hide';
                          return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]);
                  }
          },
          toggle: function(){
                  if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])) || (arguments[0].constructor == Function))
                          return this.__toggle.apply(this, arguments);
                  else {
                          var o = arguments[1] || {}; o['mode'] = 'toggle';
                          return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]);
                  }
          },
          addClass: function(classNames,speed,easing,callback) {
                  return speed ? .effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
          },
          removeClass: function(classNames,speed,easing,callback) {
                  return speed ? .effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
          },
          toggleClass: function(classNames,speed,easing,callback) {
                  return speed ? .effects.animateClass.apply(this, [{ toggle: classNames },speed,easing,callback]) : this._toggleClass(classNames);
          },
          morph: function(remove,add,speed,easing,callback) {
                  return .effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
          },
          switchClass: function() {
                  return this.morph.apply(this, arguments);
          },
          // helper functions
          cssUnit: function(key) {
                  var style = this.css(key), val = [];
                  .each( ['em','px','%','pt'], function(i, unit){
                          if(style.indexOf(unit) > 0)
                                  val = [parseFloat(style), unit];
                  });
                  return val;
          }
  });
  
  /*
   * jQuery Color Animations
   * Copyright 2007 John Resig
   * Released under the MIT and GPL licenses.
   */
  
  // We override the animation for all of these color styles
  .each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
                  .fx.step[attr] = function(fx){
                                  if ( fx.state == 0 ) {
                                                  fx.start = getColor( fx.elem, attr );
                                                  fx.end = getRGB( fx.end );
                                  }
  
                                  fx.elem.style[attr] = "rgb(" + [
                                                  Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
                                                  Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
                                                  Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
                                  ].join(",") + ")";
                  }
  });
  
  // Color Conversion functions from highlightFade
  // By Blair Mitchelmore
  // http://jquery.offput.ca/highlightFade/
  
  // Parse strings looking for color tuples [255,255,255]
  function getRGB(color) {
                  var result;
  
                  // Check if we're already dealing with an array of colors
                  if ( color && color.constructor == Array && color.length == 3 )
                                  return color;
  
                  // Look for rgb(num,num,num)
                  if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
                                  return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
  
                  // Look for rgb(num%,num%,num%)
                  if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*,\s*([0-9]+(?:\.[0-9]+)?)%\s*\)/.exec(color))
                                  return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
  
                  // Look for #a0b1c2
                  if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
                                  return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
  
                  // Look for #fff
                  if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
                                  return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
  
                  // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
                  if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
                                  return colors['transparent'];
  
                  // Otherwise, we're most likely dealing with a named color
                  return colors[.trim(color).toLowerCase()];
  }
  
  function getColor(elem, attr) {
                  var color;
  
                  do {
                                  color = .curCSS(elem, attr);
  
                                  // Keep going until we find an element that has color, or we hit the body
                                  if ( color != '' && color != 'transparent' || .nodeName(elem, "body") )
                                                  break;
  
                                  attr = "backgroundColor";
                  } while ( elem = elem.parentNode );
  
                  return getRGB(color);
  };
  
  // Some named colors to work with
  // From Interface by Stefan Petre
  // http://interface.eyecon.ro/
  
  var colors = {
          aqua:[0,255,255],
          azure:[240,255,255],
          beige:[245,245,220],
          black:[0,0,0],
          blue:[0,0,255],
          brown:[165,42,42],
          cyan:[0,255,255],
          darkblue:[0,0,139],
          darkcyan:[0,139,139],
          darkgrey:[169,169,169],
          darkgreen:[0,100,0],
          darkkhaki:[189,183,107],
          darkmagenta:[139,0,139],
          darkolivegreen:[85,107,47],
          darkorange:[255,140,0],
          darkorchid:[153,50,204],
          darkred:[139,0,0],
          darksalmon:[233,150,122],
          darkviolet:[148,0,211],
          fuchsia:[255,0,255],
          gold:[255,215,0],
          green:[0,128,0],
          indigo:[75,0,130],
          khaki:[240,230,140],
          lightblue:[173,216,230],
          lightcyan:[224,255,255],
          lightgreen:[144,238,144],
          lightgrey:[211,211,211],
          lightpink:[255,182,193],
          lightyellow:[255,255,224],
          lime:[0,255,0],
          magenta:[255,0,255],
          maroon:[128,0,0],
          navy:[0,0,128],
          olive:[128,128,0],
          orange:[255,165,0],
          pink:[255,192,203],
          purple:[128,0,128],
          violet:[128,0,128],
          red:[255,0,0],
          silver:[192,192,192],
          white:[255,255,255],
          yellow:[255,255,0],
          transparent: [255,255,255]
  };
  
  /*
   * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
   *
   * Uses the built in easing capabilities added In jQuery 1.1
   * to offer multiple easing options
   *
   * TERMS OF USE - jQuery Easing
   *
   * Open source under the BSD License.
   *
   * Copyright © 2008 George McGinley Smith
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modification,
   * are permitted provided that the following conditions are met:
   *
   * Redistributions of source code must retain the above copyright notice, this list of
   * conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright notice, this list
   * of conditions and the following disclaimer in the documentation and/or other materials
   * provided with the distribution.
   *
   * Neither the name of the author nor the names of contributors may be used to endorse
   * or promote products derived from this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
  */
  
  // t: current time, b: begInnIng value, c: change In value, d: duration
  .easing.jswing = .easing.swing;
  
  .extend(.easing,
  {
          def: 'easeOutQuad',
          swing: function (x, t, b, c, d) {
                  //alert(.easing.default);
                  return .easing[.easing.def](x, t, b, c, d);
          },
          easeInQuad: function (x, t, b, c, d) {
                  return c*(t/=d)*t + b;
          },
          easeOutQuad: function (x, t, b, c, d) {
                  return -c *(t/=d)*(t-2) + b;
          },
          easeInOutQuad: function (x, t, b, c, d) {
                  if ((t/=d/2) < 1) return c/2*t*t + b;
                  return -c/2 * ((--t)*(t-2) - 1) + b;
          },
          easeInCubic: function (x, t, b, c, d) {
                  return c*(t/=d)*t*t + b;
          },
          easeOutCubic: function (x, t, b, c, d) {
                  return c*((t=t/d-1)*t*t + 1) + b;
          },
          easeInOutCubic: function (x, t, b, c, d) {
                  if ((t/=d/2) < 1) return c/2*t*t*t + b;
                  return c/2*((t-=2)*t*t + 2) + b;
          },
          easeInQuart: function (x, t, b, c, d) {
                  return c*(t/=d)*t*t*t + b;
          },
          easeOutQuart: function (x, t, b, c, d) {
                  return -c * ((t=t/d-1)*t*t*t - 1) + b;
          },
          easeInOutQuart: function (x, t, b, c, d) {
                  if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
                  return -c/2 * ((t-=2)*t*t*t - 2) + b;
          },
          easeInQuint: function (x, t, b, c, d) {
                  return c*(t/=d)*t*t*t*t + b;
          },
          easeOutQuint: function (x, t, b, c, d) {
                  return c*((t=t/d-1)*t*t*t*t + 1) + b;
          },
          easeInOutQuint: function (x, t, b, c, d) {
                  if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
                  return c/2*((t-=2)*t*t*t*t + 2) + b;
          },
          easeInSine: function (x, t, b, c, d) {
                  return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
          },
          easeOutSine: function (x, t, b, c, d) {
                  return c * Math.sin(t/d * (Math.PI/2)) + b;
          },
          easeInOutSine: function (x, t, b, c, d) {
                  return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
          },
          easeInExpo: function (x, t, b, c, d) {
                  return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
          },
          easeOutExpo: function (x, t, b, c, d) {
                  return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
          },
          easeInOutExpo: function (x, t, b, c, d) {
                  if (t==0) return b;
                  if (t==d) return b+c;
                  if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
                  return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
          },
          easeInCirc: function (x, t, b, c, d) {
                  return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
          },
          easeOutCirc: function (x, t, b, c, d) {
                  return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
          },
          easeInOutCirc: function (x, t, b, c, d) {
                  if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
                  return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
          },
          easeInElastic: function (x, t, b, c, d) {
                  var s=1.70158;var p=0;var a=c;
                  if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
                  if (a < Math.abs(c)) { a=c; var s=p/4; }
                  else var s = p/(2*Math.PI) * Math.asin (c/a);
                  return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
          },
          easeOutElastic: function (x, t, b, c, d) {
                  var s=1.70158;var p=0;var a=c;
                  if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
                  if (a < Math.abs(c)) { a=c; var s=p/4; }
                  else var s = p/(2*Math.PI) * Math.asin (c/a);
                  return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
          },
          easeInOutElastic: function (x, t, b, c, d) {
                  var s=1.70158;var p=0;var a=c;
                  if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
                  if (a < Math.abs(c)) { a=c; var s=p/4; }
                  else var s = p/(2*Math.PI) * Math.asin (c/a);
                  if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
                  return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
          },
          easeInBack: function (x, t, b, c, d, s) {
                  if (s == undefined) s = 1.70158;
                  return c*(t/=d)*t*((s+1)*t - s) + b;
          },
          easeOutBack: function (x, t, b, c, d, s) {
                  if (s == undefined) s = 1.70158;
                  return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
          },
          easeInOutBack: function (x, t, b, c, d, s) {
                  if (s == undefined) s = 1.70158;
                  if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
                  return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
          },
          easeInBounce: function (x, t, b, c, d) {
                  return c - .easing.easeOutBounce (x, d-t, 0, c, d) + b;
          },
          easeOutBounce: function (x, t, b, c, d) {
                  if ((t/=d) < (1/2.75)) {
                          return c*(7.5625*t*t) + b;
                  } else if (t < (2/2.75)) {
                          return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
                  } else if (t < (2.5/2.75)) {
                          return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
                  } else {
                          return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
                  }
          },
          easeInOutBounce: function (x, t, b, c, d) {
                  if (t < d/2) return .easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
                  return .easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
          }
  });
  
  /*
   *
   * TERMS OF USE - EASING EQUATIONS
   *
   * Open source under the BSD License.
   *
   * Copyright © 2001 Robert Penner
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modification,
   * are permitted provided that the following conditions are met:
   *
   * Redistributions of source code must retain the above copyright notice, this list of
   * conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright notice, this list
   * of conditions and the following disclaimer in the documentation and/or other materials
   * provided with the distribution.
   *
   * Neither the name of the author nor the names of contributors may be used to endorse
   * or promote products derived from this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   */
  
  })(jQuery);
  /*
   * jQuery UI Effects Explode @VERSION
   *
   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI/Effects/Explode
   *
   * Depends:
   *        effects.core.js
   */
  (function() {
  
  .effects.explode = function(o) {
  
          return this.queue(function() {
  
          var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
          var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
  
          o.options.mode = o.options.mode == 'toggle' ? (this.is(':visible') ? 'hide' : 'show') : o.options.mode;
          var el = this.show().css('visibility', 'hidden');
          var offset = el.offset();
  
          //Substract the margins - not fixing the problem yet.
          offset.top -= parseInt(el.css("marginTop")) || 0;
          offset.left -= parseInt(el.css("marginLeft")) || 0;
  
          var width = el.outerWidth(true);
          var height = el.outerHeight(true);
  
          for(var i=0;i<rows;i++) { // =
                  for(var j=0;j<cells;j++) { // ||
                          el
                                  .clone()
                                  .appendTo('body')
                                  .wrap('<div></div>')
                                  .css({
                                          position: 'absolute',
                                          visibility: 'visible',
                                          left: -j*(width/cells),
                                          top: -i*(height/rows)
                                  })
                                  .parent()
                                  .addClass('effects-explode')
                                  .css({
                                          position: 'absolute',
                                          overflow: 'hidden',
                                          width: width/cells,
                                          height: height/rows,
                                          left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
                                          top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
                                          opacity: o.options.mode == 'show' ? 0 : 1
                                  }).animate({
                                          left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
                                          top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
                                          opacity: o.options.mode == 'show' ? 1 : 0
                                  }, o.duration || 500);
                  }
          }
  
          // Set a timeout, to call the callback approx. when the other animations have finished
          setTimeout(function() {
  
                  o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
                                  if(o.callback) o.callback.apply(el[0]); // Callback
                                  el.dequeue();
  
                                  $('.effects-explode').remove();
  
          }, o.duration || 500);
  
          });
  
  };
  
  })(jQuery);
  
  /*
   * jQuery UI @VERSION
   *
   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI
   */
  ;(function() {
  
  var _remove = .fn.remove,
          isFF2 = .browser.mozilla && (parseFloat(.browser.version) < 1.9);
  
  //Helper functions and ui object
  .ui = {
  
          version: "@VERSION",
  
          // .ui.plugin is deprecated.  Use the proxy pattern instead.
          plugin: {
                  add: function(module, option, set) {
                          var proto = .ui[module].prototype;
                          for(var i in set) {
                                  proto.plugins[i] = proto.plugins[i] || [];
                                  proto.plugins[i].push([option, set[i]]);
                          }
                  },
                  call: function(instance, name, args) {
                          var set = instance.plugins[name];
                          if(!set) { return; }
  
                          for (var i = 0; i < set.length; i++) {
                                  if (instance.options[set[i][0]]) {
                                          set[i][1].apply(instance.element, args);
                                  }
                          }
                  }
          },
  
          contains: function(a, b) {
                  var safari2 = .browser.safari && .browser.version < 522;
              if (a.contains && !safari2) {
                  return a.contains(b);
              }
              if (a.compareDocumentPosition)
                  return !!(a.compareDocumentPosition(b) & 16);
              while (b = b.parentNode)
                    if (b == a) return true;
              return false;
          },
  
          cssCache: {},
          css: function(name) {
                  if (.ui.cssCache[name]) { return .ui.cssCache[name]; }
                  var tmp = $('<div class="ui-gen">').addClass(name).css({position:'absolute', top:'-5000px', left:'-5000px', display:'block'}).appendTo('body');
  
                  //if (!.browser.safari)
                          //tmp.appendTo('body');
  
                  //Opera and Safari set width and height to 0px instead of auto
                  //Safari returns rgba(0,0,0,0) when bgcolor is not set
                  .ui.cssCache[name] = !!(
                          (!(/auto|default/).test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) ||
                          !(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor')))
                  );
                  try { $('body').get(0).removeChild(tmp.get(0));        } catch(e){}
                  return .ui.cssCache[name];
          },
  
          hasScroll: function(el, a) {
  
                  //If overflow is hidden, the element might have extra content, but the user wants to hide it
                  if (el.css('overflow') == 'hidden') { return false; }
  
                  var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
                          has = false;
  
                  if (el[scroll] > 0) { return true; }
  
                  // TODO: determine which cases actually cause this to happen
                  // if the element doesn't have the scroll set, see if it's possible to
                  // set the scroll
                  el[scroll] = 1;
                  has = (el[scroll] > 0);
                  el[scroll] = 0;
                  return has;
          },
  
          isOverAxis: function(x, reference, size) {
                  //Determines when x coordinate is over "b" element axis
                  return (x > reference) && (x < (reference + size));
          },
  
          isOver: function(y, x, top, left, height, width) {
                  //Determines when x, y coordinates is over "b" element
                  return .ui.isOverAxis(y, top, height) && .ui.isOverAxis(x, left, width);
          },
  
          keyCode: {
                  BACKSPACE: 8,
                  CAPS_LOCK: 20,
                  COMMA: 188,
                  CONTROL: 17,
                  DELETE: 46,
                  DOWN: 40,
                  END: 35,
                  ENTER: 13,
                  ESCAPE: 27,
                  HOME: 36,
                  INSERT: 45,
                  LEFT: 37,
                  NUMPAD_ADD: 107,
                  NUMPAD_DECIMAL: 110,
                  NUMPAD_DIVIDE: 111,
                  NUMPAD_ENTER: 108,
                  NUMPAD_MULTIPLY: 106,
                  NUMPAD_SUBTRACT: 109,
                  PAGE_DOWN: 34,
                  PAGE_UP: 33,
                  PERIOD: 190,
                  RIGHT: 39,
                  SHIFT: 16,
                  SPACE: 32,
                  TAB: 9,
                  UP: 38
          }
  
  };
  
  // WAI-ARIA normalization
  if (isFF2) {
          var attr = .attr,
                  removeAttr = .fn.removeAttr,
                  ariaNS = "http://www.w3.org/2005/07/aaa",
                  ariaState = /^aria-/,
                  ariaRole = /^wairole:/;
  
          .attr = function(elem, name, value) {
                  var set = value !== undefined;
  
                  return (name == 'role'
                          ? (set
                                  ? attr.call(this, elem, name, "wairole:" + value)
                                  : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
                          : (ariaState.test(name)
                                  ? (set
                                          ? elem.setAttributeNS(ariaNS,
                                                  name.replace(ariaState, "aaa:"), value)
                                          : attr.call(this, elem, name.replace(ariaState, "aaa:")))
                                  : attr.apply(this, arguments)));
          };
  
          .fn.removeAttr = function(name) {
                  return (ariaState.test(name)
                          ? this.each(function() {
                                  this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
                          }) : removeAttr.call(this, name));
          };
  }
  
  //jQuery plugins
  .fn.extend({
  
          remove: function() {
                  // Safari has a native remove event which actually removes DOM elements,
                  // so we have to use triggerHandler instead of trigger (#3037).
                  $("*", this).add(this).each(function() {
                          this.triggerHandler("remove");
                  });
                  return _remove.apply(this, arguments );
          },
  
          enableSelection: function() {
                  return this
                          .attr('unselectable', 'off')
                          .css('MozUserSelect', '')
                          .unbind('selectstart.ui');
          },
  
          disableSelection: function() {
                  return this
                          .attr('unselectable', 'on')
                          .css('MozUserSelect', 'none')
                          .bind('selectstart.ui', function() { return false; });
          },
  
          scrollParent: function() {
  
                  var scrollParent;
                  if((.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
                          scrollParent = this.parents().filter(function() {
                                  return (/(relative|absolute|fixed)/).test(.curCSS(this,'position',1)) && (/(auto|scroll)/).test(.curCSS(this,'overflow',1)+.curCSS(this,'overflow-y',1)+.curCSS(this,'overflow-x',1));
                          }).eq(0);
                  } else {
                          scrollParent = this.parents().filter(function() {
                                  return (/(auto|scroll)/).test(.curCSS(this,'overflow',1)+.curCSS(this,'overflow-y',1)+.curCSS(this,'overflow-x',1));
                          }).eq(0);
                  }
  
                  return (/fixed/).test(this.css('position')) || !scrollParent.length ? document : scrollParent;
  
          }
  
  });
  
  //Additional selectors
  .extend(.expr[':'], {
  
          data: function(a, i, m) {
                  return .data(a, m[3]);
          },
  
          // TODO: add support for object, area
          tabbable: function(a, i, m) {
  
                  var nodeName = a.nodeName.toLowerCase();
                  function isVisible(element) {
                          return !(element.is(':hidden') || element.parents(':hidden').length);
                  }
  
                  return (
                          // in tab order
                          a.tabIndex >= 0 &&
  
                          ( // filter node types that participate in the tab order
  
                                  // anchor tag
                                  ('a' == nodeName && a.href) ||
  
                                  // enabled form element
                                  (/input|select|textarea|button/.test(nodeName) &&
                                          'hidden' != a.type && !a.disabled)
                          ) &&
  
                          // visible on page
                          isVisible(a)
                  );
  
          }
  
  });
  
  // .widget is a factory to create jQuery plugins
  // taking some boilerplate code out of the plugin code
  function getter(namespace, plugin, method, args) {
          function getMethods(type) {
                  var methods = [namespace][plugin][type] || [];
                  return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
          }
  
          var methods = getMethods('getter');
          if (args.length == 1 && typeof args[0] == 'string') {
                  methods = methods.concat(getMethods('getterSetter'));
          }
          return (.inArray(method, methods) != -1);
  }
  
  .widget = function(name, prototype) {
          var namespace = name.split(".")[0];
          name = name.split(".")[1];
  
          // create plugin method
          .fn[name] = function(options) {
                  var isMethodCall = (typeof options == 'string'),
                          args = Array.prototype.slice.call(arguments, 1);
  
                  // prevent calls to internal methods
                  if (isMethodCall && options.substring(0, 1) == '_') {
                          return this;
                  }
  
                  // handle getter methods
                  if (isMethodCall && getter(namespace, name, options, args)) {
                          var instance = .data(this[0], name);
                          return (instance ? instance[options].apply(instance, args)
                                  : undefined);
                  }
  
                  // handle initialization and non-getter methods
                  return this.each(function() {
                          var instance = .data(this, name);
  
                          // constructor
                          (!instance && !isMethodCall &&
                                  .data(this, name, new [namespace][name](this, options)));
  
                          // method call
                          (instance && isMethodCall && .isFunction(instance[options]) &&
                                  instance[options].apply(instance, args));
                  });
          };
  
          // create widget constructor
          [namespace] = [namespace] || {};
          [namespace][name] = function(element, options) {
                  var self = this;
  
                  this.namespace = namespace;
                  this.widgetName = name;
                  this.widgetEventPrefix = [namespace][name].eventPrefix || name;
                  this.widgetBaseClass = namespace + '-' + name;
  
                  this.options = .extend({},
                          .widget.defaults,
                          [namespace][name].defaults,
                          .metadata && .metadata.get(element)[name],
                          options);
  
                  this.element = element
                          .bind('setData.' + name, function(event, key, value) {
                                  return self._setData(key, value);
                          })
                          .bind('getData.' + name, function(event, key) {
                                  return self._getData(key);
                          })
                          .bind('remove', function() {
                                  return self.destroy();
                          });
  
                  this._init();
          };
  
          // add widget prototype
          [namespace][name].prototype = .extend({}, .widget.prototype, prototype);
  
          // TODO: merge getter and getterSetter properties from widget prototype
          // and plugin prototype
          [namespace][name].getterSetter = 'option';
  };
  
  .widget.prototype = {
          _init: function() {},
          destroy: function() {
                  this.element.removeData(this.widgetName)
                          .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
                          .removeAttr('aria-disabled');
          },
  
          option: function(key, value) {
                  var options = key,
                          self = this;
  
                  if (typeof key == "string") {
                          if (value === undefined) {
                                  return this._getData(key);
                          }
                          options = {};
                          options[key] = value;
                  }
  
                  .each(options, function(key, value) {
                          self._setData(key, value);
                  });
          },
          _getData: function(key) {
                  return this.options[key];
          },
          _setData: function(key, value) {
                  this.options[key] = value;
  
                  if (key == 'disabled') {
                          this.element[value ? 'addClass' : 'removeClass'](
                                  this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
                                  .attr("aria-disabled", value);
                  }
          },
  
          enable: function() {
                  this._setData('disabled', false);
          },
          disable: function() {
                  this._setData('disabled', true);
          },
  
          _trigger: function(type, event, data) {
                  var eventName = (type == this.widgetEventPrefix
                          ? type : this.widgetEventPrefix + type);
                  event = event || .event.fix({ type: eventName, target: this.element[0] });
                  return this.element.triggerHandler(eventName, [event, data], this.options[type]);
          }
  };
  
  .widget.defaults = {
          disabled: false
  };
  
  
Mouse Interaction Plugin *

  
  
  .ui.mouse = {
          _mouseInit: function() {
                  var self = this;
  
                  this.element
                          .bind('mousedown.'+this.widgetName, function(event) {
                                  return self._mouseDown(event);
                          })
                          .bind('click.'+this.widgetName, function(event) {
                                  if(self._preventClickEvent) {
                                          self._preventClickEvent = false;
                                          return false;
                                  }
                          });
  
                  // Prevent text selection in IE
                  if (.browser.msie) {
                          this._mouseUnselectable = this.element.attr('unselectable');
                          this.element.attr('unselectable', 'on');
                  }
  
                  this.started = false;
          },
  
          // TODO: make sure destroying one instance of mouse doesn't mess with
          // other instances of mouse
          _mouseDestroy: function() {
                  this.element.unbind('.'+this.widgetName);
  
                  // Restore text selection in IE
                  (.browser.msie
                          && this.element.attr('unselectable', this._mouseUnselectable));
          },
  
          _mouseDown: function(event) {
                  // we may have missed mouseup (out of window)
                  (this._mouseStarted && this._mouseUp(event));
  
                  this._mouseDownEvent = event;
  
                  var self = this,
                          btnIsLeft = (event.which == 1),
                          elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
                  if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
                          return true;
                  }
  
                  this.mouseDelayMet = !this.options.delay;
                  if (!this.mouseDelayMet) {
                          this._mouseDelayTimer = setTimeout(function() {
                                  self.mouseDelayMet = true;
                          }, this.options.delay);
                  }
  
                  if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
                          this._mouseStarted = (this._mouseStart(event) !== false);
                          if (!this._mouseStarted) {
                                  event.preventDefault();
                                  return true;
                          }
                  }
  
                  // these delegates are required to keep context
                  this._mouseMoveDelegate = function(event) {
                          return self._mouseMove(event);
                  };
                  this._mouseUpDelegate = function(event) {
                          return self._mouseUp(event);
                  };
                  document
                          .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
                          .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  
                  // preventDefault() is used to prevent the selection of text here -
                  // however, in Safari, this causes select boxes not to be selectable
                  // anymore, so this fix is needed
                  if(!.browser.safari) event.preventDefault();
                  return true;
          },
  
          _mouseMove: function(event) {
                  // IE mouseup check - mouseup happened when mouse was out of window
                  if (.browser.msie && !event.button) {
                          return this._mouseUp(event);
                  }
  
                  if (this._mouseStarted) {
                          this._mouseDrag(event);
                          return event.preventDefault();
                  }
  
                  if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
                          this._mouseStarted =
                                  (this._mouseStart(this._mouseDownEvent, event) !== false);
                          (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
                  }
  
                  return !this._mouseStarted;
          },
  
          _mouseUp: function(event) {
                  document
                          .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
                          .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
  
                  if (this._mouseStarted) {
                          this._mouseStarted = false;
                          this._preventClickEvent = true;
                          this._mouseStop(event);
                  }
  
                  return false;
          },
  
          _mouseDistanceMet: function(event) {
                  return (Math.max(
                                  Math.abs(this._mouseDownEvent.pageX - event.pageX),
                                  Math.abs(this._mouseDownEvent.pageY - event.pageY)
                          ) >= this.options.distance
                  );
          },
  
          _mouseDelayMet: function(event) {
                  return this.mouseDelayMet;
          },
  
          // These are placeholder methods, to be overriden by extending plugin
          _mouseStart: function(event) {},
          _mouseDrag: function(event) {},
          _mouseStop: function(event) {},
          _mouseCapture: function(event) { return true; }
  };
  
  .ui.mouse.defaults = {
          cancel: null,
          distance: 1,
          delay: 0
  };
  
  })(jQuery);
  /*
   * jQuery UI Draggable @VERSION
   *
   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI/Draggables
   *
   * Depends:
   *        ui.core.js
   */
  (function() {
  
  .widget("ui.draggable", .extend({}, .ui.mouse, {
  
          _init: function() {
  
                  if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
                          this.element[0].style.position = 'relative';
  
                  (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-draggable"));
                  (this.options.disabled && this.element.addClass('ui-draggable-disabled'));
  
                  this._mouseInit();
  
          },
  
          destroy: function() {
                  if(!this.element.data('draggable')) return;
                  this.element.removeData("draggable").unbind(".draggable").removeClass('ui-draggable ui-draggable-dragging ui-draggable-disabled');
                  this._mouseDestroy();
          },
  
          _mouseCapture: function(event) {
  
                  var o = this.options;
  
                  if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
                          return false;
  
                  //Quit if we're not on a valid handle
                  this.handle = this._getHandle(event);
                  if (!this.handle)
                          return false;
  
                  return true;
  
          },
  
          _mouseStart: function(event) {
  
                  var o = this.options;
  
                  //Create and append the visible helper
                  this.helper = this._createHelper(event);
  
                  //Cache the helper size
                  this._cacheHelperProportions();
  
                  //If ddmanager is used for droppables, set the global draggable
                  if(.ui.ddmanager)
                          .ui.ddmanager.current = this;
  
                  /*
  		 * - Position generation -
  		 * This block generates everything position related - it's the core of draggables.
  		 */
  
                  //Cache the margins of the original element
                  this._cacheMargins();
  
                  //Store the helper's css position
                  this.cssPosition = this.helper.css("position");
                  this.scrollParent = this.helper.scrollParent();
  
                  //The element's absolute position on the page minus margins
                  this.offset = this.element.offset();
                  this.offset = {
                          top: this.offset.top - this.margins.top,
                          left: this.offset.left - this.margins.left
                  };
  
                  .extend(this.offset, {
                          click: { //Where the click happened, relative to the element
                                  left: event.pageX - this.offset.left,
                                  top: event.pageY - this.offset.top
                          },
                          parent: this._getParentOffset(),
                          relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
                  });
  
                  //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
                  if(o.cursorAt)
                          this._adjustOffsetFromHelper(o.cursorAt);
  
                  //Generate the original position
                  this.originalPosition = this._generatePosition(event);
  
                  //Set a containment if given in the options
                  if(o.containment)
                          this._setContainment();
  
                  //Call plugins and callbacks
                  this._propagate("start", event);
  
                  //Recache the helper size
                  this._cacheHelperProportions();
  
                  //Prepare the droppable offsets
                  if (.ui.ddmanager && !o.dropBehaviour)
                          .ui.ddmanager.prepareOffsets(this, event);
  
                  this.helper.addClass("ui-draggable-dragging");
                  this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
                  return true;
          },
  
          _mouseDrag: function(event, noPropagation) {
  
                  //Compute the helpers position
                  this.position = this._generatePosition(event);
                  this.positionAbs = this._convertPositionTo("absolute");
  
                  //Call plugins and callbacks and use the resulting position if something is returned
                  if(!noPropagation) this.position = this._propagate("drag", event) || this.position;
  
                  if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
                  if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
                  if(.ui.ddmanager) .ui.ddmanager.drag(this, event);
  
                  return false;
          },
  
          _mouseStop: function(event) {
  
                  //If we are using droppables, inform the manager about the drop
                  var dropped = false;
                  if (.ui.ddmanager && !this.options.dropBehaviour)
                          var dropped = .ui.ddmanager.drop(this, event);
  
                  if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || (.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
                          var self = this;
                          $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
                                  self._propagate("stop", event);
                                  self._clear();
                          });
                  } else {
                          this._propagate("stop", event);
                          this._clear();
                  }
  
                  return false;
          },
  
          _getHandle: function(event) {
  
                  var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
                  $(this.options.handle, this.element)
                          .find("*")
                          .andSelf()
                          .each(function() {
                                  if(this == event.target) handle = true;
                          });
  
                  return handle;
  
          },
  
          _createHelper: function(event) {
  
                  var o = this.options;
                  var helper = .isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
  
                  if(!helper.parents('body').length)
                          helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
  
                  if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
                          helper.css("position", "absolute");
  
                  return helper;
  
          },
  
          _adjustOffsetFromHelper: function(obj) {
                  if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
                  if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
                  if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
                  if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
          },
  
          _getParentOffset: function() {
  
                  this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset();                        //Get the offsetParent and cache its position
  
                  if((this.offsetParent[0] == document.body && .browser.mozilla)        //Ugly FF3 fix
                  || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && .browser.msie)) //Ugly IE fix
                          po = { top: 0, left: 0 };
  
                  return {
                          top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
                          left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
                  };
  
          },
  
          _getRelativeOffset: function() {
  
                  if(this.cssPosition == "relative") {
                          var p = this.element.position();
                          return {
                                  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
                                  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
                          };
                  } else {
                          return { top: 0, left: 0 };
                  }
  
          },
  
          _cacheMargins: function() {
                  this.margins = {
                          left: (parseInt(this.element.css("marginLeft"),10) || 0),
                          top: (parseInt(this.element.css("marginTop"),10) || 0)
                  };
          },
  
          _cacheHelperProportions: function() {
                  this.helperProportions = {
                          width: this.helper.outerWidth(),
                          height: this.helper.outerHeight()
                  };
          },
  
          _setContainment: function() {
  
                  var o = this.options;
                  if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
                  if(o.containment == 'document' || o.containment == 'window') this.containment = [
                          0 - this.offset.relative.left - this.offset.parent.left,
                          0 - this.offset.relative.top - this.offset.parent.top,
                          $(o.containment == 'document' ? document : window).width() - this.offset.relative.left - this.offset.parent.left - this.helperProportions.width - this.margins.left - (parseInt(this.element.css("marginRight"),10) || 0),
                          ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.offset.relative.top - this.offset.parent.top - this.helperProportions.height - this.margins.top - (parseInt(this.element.css("marginBottom"),10) || 0)
                  ];
  
                  if(!(/^(document|window|parent)/).test(o.containment)) {
                          var ce = $(o.containment)[0];
                          var co = $(o.containment).offset();
                          var over = (ce.css("overflow") != 'hidden');
  
                          this.containment = [
                                  co.left + (parseInt(ce.css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left,
                                  co.top + (parseInt(ce.css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top,
                                  co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt(ce.css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.helperProportions.width - this.margins.left,
                                  co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt(ce.css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.helperProportions.height - this.margins.top
                          ];
                  }
  
          },
  
          _convertPositionTo: function(d, pos) {
  
                  if(!pos) pos = this.position;
                  var mod = d == "absolute" ? 1 : -1;
                  var scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  
                  return {
                          top: (
                                  pos.top                                                                                                                                        // the calculated relative position
                                  + this.offset.relative.top        * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
                                  + this.offset.parent.top * mod                                                                                        // The offsetParent's offset without borders (offset + border)
                                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod
                                  + this.margins.top * mod                                                                                                //Add the margin (you don't want the margin counting in intersection methods)
                          ),
                          left: (
                                  pos.left                                                                                                                                // the calculated relative position
                                  + this.offset.relative.left        * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
                                  + this.offset.parent.left * mod                                                                                        // The offsetParent's offset without borders (offset + border)
                                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) * mod
                                  + this.margins.left * mod                                                                                                //Add the margin (you don't want the margin counting in intersection methods)
                          )
                  };
          },
  
          _generatePosition: function(event) {
  
                  var o = this.options, scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  
                  var position = {
                          top: (
                                  event.pageY                                                                                                                                // The absolute mouse position
                                  - this.offset.click.top                                                                                                        // Click offset (relative to the element)
                                  - this.offset.relative.top                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
                                  - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
                                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )
                          ),
                          left: (
                                  event.pageX                                                                                                                                // The absolute mouse position
                                  - this.offset.click.left                                                                                                // Click offset (relative to the element)
                                  - this.offset.relative.left                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
                                  - this.offset.parent.left                                                                                                // The offsetParent's offset without borders (offset + border)
                                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )
                          )
                  };
  
                  if(!this.originalPosition) return position;                                                                                //If we are not dragging yet, we won't check for options
  
                  /*
  		 * - Position constraining -
  		 * Constrain the position to a mix of grid, containment.
  		 */
                  if(this.containment) {
                          if(position.left < this.containment[0]) position.left = this.containment[0];
                          if(position.top < this.containment[1]) position.top = this.containment[1];
                          if(position.left > this.containment[2]) position.left = this.containment[2];
                          if(position.top > this.containment[3]) position.top = this.containment[3];
                  }
  
                  if(o.grid) {
                          var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1];
                          position.top = this.containment ? (!(top < this.containment[1] || top > this.containment[3]) ? top : (!(top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
  
                          var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0];
                          position.left = this.containment ? (!(left < this.containment[0] || left > this.containment[2]) ? left : (!(left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
                  }
  
                  return position;
          },
  
          _clear: function() {
                  this.helper.removeClass("ui-draggable-dragging");
                  if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
                  //if(.ui.ddmanager) .ui.ddmanager.current = null;
                  this.helper = null;
                  this.cancelHelperRemoval = false;
          },
  
          // From now on bulk stuff - mainly helpers
  
          _propagate: function(n, event) {
                  .ui.plugin.call(this, n, [event, this._uiHash()]);
                  if(n == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
                  return this.element.triggerHandler(n == "drag" ? n : "drag"+n, [event, this._uiHash()], this.options[n]);
          },
  
          plugins: {},
  
          _uiHash: function(event) {
                  return {
                          helper: this.helper,
                          position: this.position,
                          absolutePosition: this.positionAbs,
                          options: this.options
                  };
          }
  
  }));
  
  .extend(.ui.draggable, {
          version: "@VERSION",
          defaults: {
                  appendTo: "parent",
                  axis: false,
                  cancel: ":input",
                  connectToSortable: false,
                  containment: false,
                  cssNamespace: "ui",
                  cursor: "default",
                  cursorAt: null,
                  delay: 0,
                  distance: 1,
                  grid: false,
                  handle: false,
                  helper: "original",
                  iframeFix: false,
                  opacity: 1,
                  refreshPositions: false,
                  revert: false,
                  revertDuration: 500,
                  scope: "default",
                  scroll: true,
                  scrollSensitivity: 20,
                  scrollSpeed: 20,
                  snap: false,
                  snapMode: "both",
                  snapTolerance: 20,
                  stack: false,
                  zIndex: null
          }
  });
  
  .ui.plugin.add("draggable", "connectToSortable", {
          start: function(event, ui) {
  
                  var inst = this.data("draggable");
                  inst.sortables = [];
                  $(ui.options.connectToSortable).each(function() {
                          // 'this' points to a string, and should therefore resolved as query, but instead, if the string is assigned to a variable, it loops through the strings properties,
                          // so we have to append '' to make it anonymous again
                          $(this+'').each(function() {
                                  if(.data(this, 'sortable')) {
                                          var sortable = .data(this, 'sortable');
                                          inst.sortables.push({
                                                  instance: sortable,
                                                  shouldRevert: sortable.options.revert
                                          });
                                          sortable._refreshItems();        //Do a one-time refresh at start to refresh the containerCache
                                          sortable._propagate("activate", event, inst);
                                  }
                          });
                  });
  
          },
          stop: function(event, ui) {
  
                  //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
                  var inst = this.data("draggable");
  
                  .each(inst.sortables, function() {
                          if(this.instance.isOver) {
                                  this.instance.isOver = 0;
                                  inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
                                  this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
                                  if(this.shouldRevert) this.instance.options.revert = true; //revert here
                                  this.instance._mouseStop(event);
  
                                  //Also propagate receive event, since the sortable is actually receiving a element
                                  this.instance.element.triggerHandler("sortreceive", [event, .extend(this.instance._ui(), { sender: inst.element })], this.instance.options["receive"]);
  
                                  this.instance.options.helper = this.instance.options._helper;
                                  
                                  if(inst.options.helper == 'original') {
                                          this.instance.currentItem.css({ top: 'auto', left: 'auto' });
                                  }
  
                          } else {
                                  this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
                                  this.instance._propagate("deactivate", event, inst);
                          }
  
                  });
  
          },
          drag: function(event, ui) {
  
                  var inst = this.data("draggable"), self = this;
  
                  var checkPos = function(o) {
                          var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
                          var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
                          var itemHeight = o.height, itemWidth = o.width;
                          var itemTop = o.top, itemLeft = o.left;
  
                          return .ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
                  };
  
                  .each(inst.sortables, function(i) {
  
                          if(checkPos.call(inst, this.instance.containerCache)) {
  
                                  //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
                                  if(!this.instance.isOver) {
                                          this.instance.isOver = 1;
                                          //Now we fake the start of dragging for the sortable instance,
                                          //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
                                          //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
                                          this.instance.currentItem = self.clone().appendTo(this.instance.element).data("sortable-item", true);
                                          this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
                                          this.instance.options.helper = function() { return ui.helper[0]; };
  
                                          event.target = this.instance.currentItem[0];
                                          this.instance._mouseCapture(event, true);
                                          this.instance._mouseStart(event, true, true);
  
                                          //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
                                          this.instance.offset.click.top = inst.offset.click.top;
                                          this.instance.offset.click.left = inst.offset.click.left;
                                          this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
                                          this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
  
                                          inst._propagate("toSortable", event);
  
                                  }
  
                                  //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
                                  if(this.instance.currentItem) this.instance._mouseDrag(event);
  
                          } else {
  
                                  //If it doesn't intersect with the sortable, and it intersected before,
                                  //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
                                  if(this.instance.isOver) {
                                          this.instance.isOver = 0;
                                          this.instance.cancelHelperRemoval = true;
                                          this.instance.options.revert = false; //No revert here
                                          this.instance._mouseStop(event, true);
                                          this.instance.options.helper = this.instance.options._helper;
  
                                          //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
                                          this.instance.currentItem.remove();
                                          if(this.instance.placeholder) this.instance.placeholder.remove();
  
                                          inst._propagate("fromSortable", event);
                                  }
  
                          };
  
                  });
  
          }
  });
  
  .ui.plugin.add("draggable", "cursor", {
          start: function(event, ui) {
                  var t = $('body');
                  if (t.css("cursor")) ui.options._cursor = t.css("cursor");
                  t.css("cursor", ui.options.cursor);
          },
          stop: function(event, ui) {
                  if (ui.options._cursor) $('body').css("cursor", ui.options._cursor);
          }
  });
  
  .ui.plugin.add("draggable", "iframeFix", {
          start: function(event, ui) {
                  $(ui.options.iframeFix === true ? "iframe" : ui.options.iframeFix).each(function() {
                          $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
                          .css({
                                  width: this.offsetWidth+"px", height: this.offsetHeight+"px",
                                  position: "absolute", opacity: "0.001", zIndex: 1000
                          })
                          .css(this.offset())
                          .appendTo("body");
                  });
          },
          stop: function(event, ui) {
                  $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
          }
  });
  
  .ui.plugin.add("draggable", "opacity", {
          start: function(event, ui) {
                  var t = $(ui.helper);
                  if(t.css("opacity")) ui.options._opacity = t.css("opacity");
                  t.css('opacity', ui.options.opacity);
          },
          stop: function(event, ui) {
                  if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity);
          }
  });
  
  .ui.plugin.add("draggable", "scroll", {
          start: function(event, ui) {
                  var o = ui.options;
                  var i = this.data("draggable");
  
                  if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
  
          },
          drag: function(event, ui) {
  
                  var o = ui.options, scrolled = false;
                  var i = this.data("draggable");
  
                  if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
  
                          if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
                                  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
                          else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
                                  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
  
                          if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
                                  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
                          else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
                                  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
  
                  } else {
  
                          if(event.pageY - document.scrollTop() < o.scrollSensitivity)
                                  scrolled = document.scrollTop(document.scrollTop() - o.scrollSpeed);
                          else if(window.height() - (event.pageY - document.scrollTop()) < o.scrollSensitivity)
                                  scrolled = document.scrollTop(document.scrollTop() + o.scrollSpeed);
  
                          if(event.pageX - document.scrollLeft() < o.scrollSensitivity)
                                  scrolled = document.scrollLeft(document.scrollLeft() - o.scrollSpeed);
                          else if(window.width() - (event.pageX - document.scrollLeft()) < o.scrollSensitivity)
                                  scrolled = document.scrollLeft(document.scrollLeft() + o.scrollSpeed);
  
                  }
  
                  if(scrolled !== false && .ui.ddmanager && !o.dropBehaviour)
                          .ui.ddmanager.prepareOffsets(i, event);
  
                  // This is a special case where we need to modify a offset calculated on start, since the following happened:
                  // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
                  // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
                  //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
                  if(scrolled !== false && i.cssPosition == 'absolute' && i.scrollParent[0] != document && .ui.contains(i.scrollParent[0], i.offsetParent[0])) {
                          i.offset.parent = i._getParentOffset();
                          
                  }
                  
                  // This is another very weird special case that only happens for relative elements:
                  // 1. If the css position is relative
                  // 2. and the scroll parent is the document or similar to the offset parent
                  // we have to refresh the relative offset during the scroll so there are no jumps
                  if(scrolled !== false && i.cssPosition == 'relative' && !(i.scrollParent[0] != document && i.scrollParent[0] != i.offsetParent[0])) {
                          i.offset.relative = i._getRelativeOffset();
                  }
                  
  
          }
  });
  
  .ui.plugin.add("draggable", "snap", {
          start: function(event, ui) {
  
                  var inst = this.data("draggable");
                  inst.snapElements = [];
  
                  $(ui.options.snap.constructor != String ? ( ui.options.snap.items || ':data(draggable)' ) : ui.options.snap).each(function() {
                          var t = this; var o = t.offset();
                          if(this != inst.element[0]) inst.snapElements.push({
                                  item: this,
                                  width: t.outerWidth(), height: t.outerHeight(),
                                  top: o.top, left: o.left
                          });
                  });
  
          },
          drag: function(event, ui) {
  
                  var inst = this.data("draggable");
                  var d = ui.options.snapTolerance;
  
                  var x1 = ui.absolutePosition.left, x2 = x1 + inst.helperProportions.width,
                          y1 = ui.absolutePosition.top, y2 = y1 + inst.helperProportions.height;
  
                  for (var i = inst.snapElements.length - 1; i >= 0; i--){
  
                          var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
                                  t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
  
                          //Yes, I know, this is insane ;)
                          if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
                                  if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, .extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
                                  inst.snapElements[i].snapping = false;
                                  continue;
                          }
  
                          if(ui.options.snapMode != 'inner') {
                                  var ts = Math.abs(t - y2) <= d;
                                  var bs = Math.abs(b - y1) <= d;
                                  var ls = Math.abs(l - x2) <= d;
                                  var rs = Math.abs(r - x1) <= d;
                                  if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
                                  if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
                                  if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
                                  if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
                          }
  
                          var first = (ts || bs || ls || rs);
  
                          if(ui.options.snapMode != 'outer') {
                                  var ts = Math.abs(t - y1) <= d;
                                  var bs = Math.abs(b - y2) <= d;
                                  var ls = Math.abs(l - x1) <= d;
                                  var rs = Math.abs(r - x2) <= d;
                                  if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
                                  if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
                                  if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
                                  if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
                          }
  
                          if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
                                  (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, .extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
                          inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
  
                  };
  
          }
  });
  
  .ui.plugin.add("draggable", "stack", {
          start: function(event, ui) {
                  var group = .makeArray($(ui.options.stack.group)).sort(function(a,b) {
                          return (parseInt(a.css("zIndex"),10) || ui.options.stack.min) - (parseInt(b.css("zIndex"),10) || ui.options.stack.min);
                  });
  
                  group.each(function(i) {
                          this.style.zIndex = ui.options.stack.min + i;
                  });
  
                  this[0].style.zIndex = ui.options.stack.min + group.length;
          }
  });
  
  .ui.plugin.add("draggable", "zIndex", {
          start: function(event, ui) {
                  var t = $(ui.helper);
                  if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex");
                  t.css('zIndex', ui.options.zIndex);
          },
          stop: function(event, ui) {
                  if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex);
          }
  });
  
  })(jQuery);
  /*
   * jQuery UI Droppable @VERSION
   *
   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI/Droppables
   *
   * Depends:
   *        ui.core.js
   *        ui.draggable.js
   */
  (function() {
  
  .widget("ui.droppable", {
  
          _init: function() {
  
                  var o = this.options, accept = o.accept;
                  this.isover = 0; this.isout = 1;
  
                  this.options.accept = this.options.accept && .isFunction(this.options.accept) ? this.options.accept : function(d) {
                          return d.is(accept);
                  };
  
                  //Store the droppable's proportions
                  this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
  
                  // Add the reference and positions to the manager
                  .ui.ddmanager.droppables[this.options.scope] = .ui.ddmanager.droppables[this.options.scope] || [];
                  .ui.ddmanager.droppables[this.options.scope].push(this);
  
                  (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-droppable"));
  
          },
  
          destroy: function() {
                  var drop = .ui.ddmanager.droppables[this.options.scope];
                  for ( var i = 0; i < drop.length; i++ )
                          if ( drop[i] == this )
                                  drop.splice(i, 1);
  
                  this.element
                          .removeClass("ui-droppable-disabled")
                          .removeData("droppable")
                          .unbind(".droppable");
          },
  
          _setData: function(key, value) {
  
                  if(key == 'accept') {
                          this.options.accept = value && .isFunction(value) ? value : function(d) {
                                  return d.is(accept);
                          };
                  } else {
                          .widget.prototype._setData.apply(this, arguments);
                  }
  
          },
  
          _activate: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  .ui.plugin.call(this, 'activate', [event, this.ui(draggable)]);
                  if(draggable) this.element.triggerHandler("dropactivate", [event, this.ui(draggable)], this.options.activate);
  
          },
  
          _deactivate: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  .ui.plugin.call(this, 'deactivate', [event, this.ui(draggable)]);
                  if(draggable) this.element.triggerHandler("dropdeactivate", [event, this.ui(draggable)], this.options.deactivate);
  
          },
  
          _over: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  
                  if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
                          .ui.plugin.call(this, 'over', [event, this.ui(draggable)]);
                          this.element.triggerHandler("dropover", [event, this.ui(draggable)], this.options.over);
                  }
  
          },
  
          _out: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  
                  if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
                          .ui.plugin.call(this, 'out', [event, this.ui(draggable)]);
                          this.element.triggerHandler("dropout", [event, this.ui(draggable)], this.options.out);
                  }
  
          },
  
          _drop: function(event,custom) {
  
                  var draggable = custom || .ui.ddmanager.current;
                  if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
  
                  var childrenIntersection = false;
                  this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
                          var inst = .data(this, 'droppable');
                          if(inst.options.greedy && .ui.intersect(draggable, .extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) {
                                  childrenIntersection = true; return false;
                          }
                  });
                  if(childrenIntersection) return false;
  
                  if(this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
                          .ui.plugin.call(this, 'drop', [event, this.ui(draggable)]);
                          this.element.triggerHandler("drop", [event, this.ui(draggable)], this.options.drop);
                          return this.element;
                  }
  
                  return false;
  
          },
  
          plugins: {},
  
          ui: function(c) {
                  return {
                          draggable: (c.currentItem || c.element),
                          helper: c.helper,
                          position: c.position,
                          absolutePosition: c.positionAbs,
                          options: this.options,
                          element: this.element
                  };
          }
  
  });
  
  .extend(.ui.droppable, {
          version: "@VERSION",
          defaults: {
                  accept: '*',
                  activeClass: null,
                  cssNamespace: 'ui',
                  greedy: false,
                  hoverClass: null,
                  scope: 'default',
                  tolerance: 'intersect'
          }
  });
  
  .ui.intersect = function(draggable, droppable, toleranceMode) {
  
          if (!droppable.offset) return false;
  
          var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
                  y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
          var l = droppable.offset.left, r = l + droppable.proportions.width,
                  t = droppable.offset.top, b = t + droppable.proportions.height;
  
          switch (toleranceMode) {
                  case 'fit':
                          return (l < x1 && x2 < r
                                  && t < y1 && y2 < b);
                          break;
                  case 'intersect':
                          return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
                                  && x2 - (draggable.helperProportions.width / 2) < r // Left Half
                                  && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
                                  && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
                          break;
                  case 'pointer':
                          var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
                                  draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
                                  isOver = .ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
                          return isOver;
                          break;
                  case 'touch':
                          return (
                                          (y1 >= t && y1 <= b) ||        // Top edge touching
                                          (y2 >= t && y2 <= b) ||        // Bottom edge touching
                                          (y1 < t && y2 > b)                // Surrounded vertically
                                  ) && (
                                          (x1 >= l && x1 <= r) ||        // Left edge touching
                                          (x2 >= l && x2 <= r) ||        // Right edge touching
                                          (x1 < l && x2 > r)                // Surrounded horizontally
                                  );
                          break;
                  default:
                          return false;
                          break;
                  }
  
  };
  
  /*
          This manager tracks offsets of draggables and droppables
  */
  .ui.ddmanager = {
          current: null,
          droppables: { 'default': [] },
          prepareOffsets: function(t, event) {
  
                  var m = .ui.ddmanager.droppables[t.options.scope];
                  var type = event ? event.type : null; // workaround for #2317
                  var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
  
                  droppablesLoop: for (var i = 0; i < m.length; i++) {
  
                          if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element,(t.currentItem || t.element)))) continue;        //No disabled and non-accepted
                          for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
                          m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                                                         //If the element is not visible, continue
  
                          m[i].offset = m[i].element.offset();
                          m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
  
                          if(type == "dragstart" || type == "sortactivate") m[i]._activate.call(m[i], event);                                                                                 //Activate the droppable if used directly from draggables
  
                  }
  
          },
          drop: function(draggable, event) {
  
                  var dropped = false;
                  .each(.ui.ddmanager.droppables[draggable.options.scope], function() {
  
                          if(!this.options) return;
                          if (!this.options.disabled && this.visible && .ui.intersect(draggable, this, this.options.tolerance))
                                  dropped = this._drop.call(this, event);
  
                          if (!this.options.disabled && this.visible && this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
                                  this.isout = 1; this.isover = 0;
                                  this._deactivate.call(this, event);
                          }
  
                  });
                  return dropped;
  
          },
          drag: function(draggable, event) {
  
                  //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
                  if(draggable.options.refreshPositions) .ui.ddmanager.prepareOffsets(draggable, event);
  
                  //Run through all droppables and check their positions based on specific tolerance options
  
                  .each(.ui.ddmanager.droppables[draggable.options.scope], function() {
  
                          if(this.options.disabled || this.greedyChild || !this.visible) return;
                          var intersects = .ui.intersect(draggable, this, this.options.tolerance);
  
                          var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
                          if(!c) return;
  
                          var parentInstance;
                          if (this.options.greedy) {
                                  var parent = this.element.parents(':data(droppable):eq(0)');
                                  if (parent.length) {
                                          parentInstance = .data(parent[0], 'droppable');
                                          parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
                                  }
                          }
  
                          // we just moved into a greedy child
                          if (parentInstance && c == 'isover') {
                                  parentInstance['isover'] = 0;
                                  parentInstance['isout'] = 1;
                                  parentInstance._out.call(parentInstance, event);
                          }
  
                          this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
                          this[c == "isover" ? "_over" : "_out"].call(this, event);
  
                          // we just moved out of a greedy child
                          if (parentInstance && c == 'isout') {
                                  parentInstance['isout'] = 0;
                                  parentInstance['isover'] = 1;
                                  parentInstance._over.call(parentInstance, event);
                          }
                  });
  
          }
  };
  
  /*
   * Droppable Extensions
   */
  
  .ui.plugin.add("droppable", "activeClass", {
          activate: function(event, ui) {
                  this.addClass(ui.options.activeClass);
          },
          deactivate: function(event, ui) {
                  this.removeClass(ui.options.activeClass);
          },
          drop: function(event, ui) {
                  this.removeClass(ui.options.activeClass);
          }
  });
  
  .ui.plugin.add("droppable", "hoverClass", {
          over: function(event, ui) {
                  this.addClass(ui.options.hoverClass);
          },
          out: function(event, ui) {
                  this.removeClass(ui.options.hoverClass);
          },
          drop: function(event, ui) {
                  this.removeClass(ui.options.hoverClass);
          }
  });
  
  })(jQuery);
  /*
   * jQuery UI Resizable @VERSION
   *
   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI/Resizables
   *
   * Depends:
   *        ui.core.js
   */
  (function() {
  
  .widget("ui.resizable", .extend({}, .ui.mouse, {
  
          _init: function() {
  
                  var self = this, o = this.options;
  
                  var elpos = this.element.css('position');
  
                  this.originalElement = this.element;
  
                  // simulate .ui-resizable { position: relative; }
                  this.element.addClass("ui-resizable").css({ position: /static/.test(elpos) ? 'relative' : elpos });
  
                  .extend(o, {
                          _aspectRatio: !!(o.aspectRatio),
                          helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null,
                          knobHandles: o.knobHandles === true ? 'ui-resizable-knob-handle' : o.knobHandles
                  });
  
                  //Default Theme
                  var aBorder = '1px solid #DEDEDE';
  
                  o.defaultTheme = {
                          'ui-resizable': { display: 'block' },
                          'ui-resizable-handle': { position: 'absolute', background: '#F2F2F2', fontSize: '0.1px' },
                          'ui-resizable-n': { cursor: 'n-resize', height: '4px', left: '0px', right: '0px', borderTop: aBorder },
                          'ui-resizable-s': { cursor: 's-resize', height: '4px', left: '0px', right: '0px', borderBottom: aBorder },
                          'ui-resizable-e': { cursor: 'e-resize', width: '4px', top: '0px', bottom: '0px', borderRight: aBorder },
                          'ui-resizable-w': { cursor: 'w-resize', width: '4px', top: '0px', bottom: '0px', borderLeft: aBorder },
                          'ui-resizable-se': { cursor: 'se-resize', width: '4px', height: '4px', borderRight: aBorder, borderBottom: aBorder },
                          'ui-resizable-sw': { cursor: 'sw-resize', width: '4px', height: '4px', borderBottom: aBorder, borderLeft: aBorder },
                          'ui-resizable-ne': { cursor: 'ne-resize', width: '4px', height: '4px', borderRight: aBorder, borderTop: aBorder },
                          'ui-resizable-nw': { cursor: 'nw-resize', width: '4px', height: '4px', borderLeft: aBorder, borderTop: aBorder }
                  };
  
                  o.knobTheme = {
                          'ui-resizable-handle': { background: '#F2F2F2', border: '1px solid #808080', height: '8px', width: '8px' },
                          'ui-resizable-n': { cursor: 'n-resize', top: '0px', left: '45%' },
                          'ui-resizable-s': { cursor: 's-resize', bottom: '0px', left: '45%' },
                          'ui-resizable-e': { cursor: 'e-resize', right: '0px', top: '45%' },
                          'ui-resizable-w': { cursor: 'w-resize', left: '0px', top: '45%' },
                          'ui-resizable-se': { cursor: 'se-resize', right: '0px', bottom: '0px' },
                          'ui-resizable-sw': { cursor: 'sw-resize', left: '0px', bottom: '0px' },
                          'ui-resizable-nw': { cursor: 'nw-resize', left: '0px', top: '0px' },
                          'ui-resizable-ne': { cursor: 'ne-resize', right: '0px', top: '0px' }
                  };
  
                  o._nodeName = this.element[0].nodeName;
  
                  //Wrap the element if it cannot hold child nodes
                  if(o._nodeName.match(/canvas|textarea|input|select|button|img/i)) {
                          var el = this.element;
  
                          //Opera fixing relative position
                          if (/relative/.test(el.css('position')) && .browser.opera)
                                  el.css({ position: 'relative', top: 'auto', left: 'auto' });
  
                          //Create a wrapper element and set the wrapper to the new current internal element
                          el.wrap(
                                  $('<div class="ui-wrapper"        style="overflow: hidden;"></div>').css( {
                                          position: el.css('position'),
                                          width: el.outerWidth(),
                                          height: el.outerHeight(),
                                          top: el.css('top'),
                                          left: el.css('left')
                                  })
                          );
  
                          var oel = this.element; this.element = this.element.parent();
  
                          // store instance on wrapper
                          this.element.data('resizable', this);
  
                          //Move margins to the wrapper
                          this.element.css({ marginLeft: oel.css("marginLeft"), marginTop: oel.css("marginTop"),
                                  marginRight: oel.css("marginRight"), marginBottom: oel.css("marginBottom")
                          });
  
                          oel.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
  
                          //Prevent Safari textarea resize
                          if (.browser.safari && o.preventDefault) oel.css('resize', 'none');
  
                          o.proportionallyResize = oel.css({ position: 'static', zoom: 1, display: 'block' });
  
                          // avoid IE jump
                          this.element.css({ margin: oel.css('margin') });
  
                          // fix handlers offset
                          this._proportionallyResize();
                  }
  
                  if(!o.handles) o.handles = !$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' };
                  if(o.handles.constructor == String) {
  
                          o.zIndex = o.zIndex || 1000;
  
                          if(o.handles == 'all') o.handles = 'n,e,s,w,se,sw,ne,nw';
  
                          var n = o.handles.split(","); o.handles = {};
  
                          // insertions are applied when don't have theme loaded
                          var insertionsDefault = {
                                  handle: 'position: absolute; display: none; overflow:hidden;',
                                  n: 'top: 0pt; width:100%;',
                                  e: 'right: 0pt; height:100%;',
                                  s: 'bottom: 0pt; width:100%;',
                                  w: 'left: 0pt; height:100%;',
                                  se: 'bottom: 0pt; right: 0px;',
                                  sw: 'bottom: 0pt; left: 0px;',
                                  ne: 'top: 0pt; right: 0px;',
                                  nw: 'top: 0pt; left: 0px;'
                          };
  
                          for(var i = 0; i < n.length; i++) {
                                  var handle = .trim(n[i]), dt = o.defaultTheme, hname = 'ui-resizable-'+handle, loadDefault = !.ui.css(hname) && !o.knobHandles, userKnobClass = .ui.css('ui-resizable-knob-handle'),
                                                          allDefTheme = .extend(dt[hname], dt['ui-resizable-handle']), allKnobTheme = .extend(o.knobTheme[hname], !userKnobClass ? o.knobTheme['ui-resizable-handle'] : {});
  
                                  // increase zIndex of sw, se, ne, nw axis
                                  var applyZIndex = /sw|se|ne|nw/.test(handle) ? { zIndex: ++o.zIndex } : {};
  
                                  var defCss = (loadDefault ? insertionsDefault[handle] : ''),
                                          axis = $(['<div class="ui-resizable-handle ', hname, '" style="', defCss, insertionsDefault.handle, '"></div>'].join('')).css( applyZIndex );
                                  o.handles[handle] = '.ui-resizable-'+handle;
  
                                  this.element.append(
                                          //Theme detection, if not loaded, load o.defaultTheme
                                          axis.css( loadDefault ? allDefTheme : {} )
                                                  // Load the knobHandle css, fix width, height, top, left...
                                                  .css( o.knobHandles ? allKnobTheme : {} ).addClass(o.knobHandles ? 'ui-resizable-knob-handle' : '').addClass(o.knobHandles)
                                  );
                          }
  
                          if (o.knobHandles) this.element.addClass('ui-resizable-knob').css( !.ui.css('ui-resizable-knob') ? { /*border: '1px #fff dashed'*/ } : {} );
                  }
  
                  this._renderAxis = function(target) {
                          target = target || this.element;
  
                          for(var i in o.handles) {
                                  if(o.handles[i].constructor == String)
                                          o.handles[i] = $(o.handles[i], this.element).show();
  
                                  if (o.transparent)
                                          o.handles[i].css({opacity:0});
  
                                  //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
                                  if (this.element.is('.ui-wrapper') &&
                                          o._nodeName.match(/textarea|input|select|button/i)) {
  
                                          var axis = $(o.handles[i], this.element), padWrapper = 0;
  
                                          //Checking the correct pad and border
                                          padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
  
                                          //The padding type i have to apply...
                                          var padPos = [ 'padding',
                                                  /ne|nw|n/.test(i) ? 'Top' :
                                                  /se|sw|s/.test(i) ? 'Bottom' :
                                                  /^e/.test(i) ? 'Right' : 'Left' ].join("");
  
                                          if (!o.transparent)
                                                  target.css(padPos, padWrapper);
  
                                          this._proportionallyResize();
                                  }
                                  if(!$(o.handles[i]).length) continue;
                          }
                  };
  
                  this._renderAxis(this.element);
                  o._handles = $('.ui-resizable-handle', self.element);
  
                  if (o.disableSelection)
                          o._handles.disableSelection();
  
                  //Matching axis name
                  o._handles.mouseover(function() {
                          if (!o.resizing) {
                                  if (this.className)
                                          var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
                                  //Axis, default = se
                                  self.axis = o.axis = axis && axis[1] ? axis[1] : 'se';
                          }
                  });
  
                  //If we want to auto hide the elements
                  if (o.autoHide) {
                          o._handles.hide();
                          $(self.element).addClass("ui-resizable-autohide").hover(function() {
                                  this.removeClass("ui-resizable-autohide");
                                  o._handles.show();
                          },
                          function(){
                                  if (!o.resizing) {
                                          this.addClass("ui-resizable-autohide");
                                          o._handles.hide();
                                  }
                          });
                  }
  
                  this._mouseInit();
          },
  
          destroy: function() {
                  var el = this.element, wrapped = el.children(".ui-resizable").get(0);
  
                  this._mouseDestroy();
  
                  var _destroy = function(exp) {
                          exp.removeClass("ui-resizable ui-resizable-disabled")
                                  .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
                  };
  
                  _destroy(el);
  
                  if (el.is('.ui-wrapper') && wrapped) {
                          el.parent().append(
                                  wrapped.css({
                                          position: el.css('position'),
                                          width: el.outerWidth(),
                                          height: el.outerHeight(),
                                          top: el.css('top'),
                                          left: el.css('left')
                                  })
                          ).end().remove();
  
                          _destroy(wrapped);
                  }
          },
  
          _mouseCapture: function(event) {
  
                  if(this.options.disabled) return false;
  
                  var handle = false;
                  for(var i in this.options.handles) {
                          if($(this.options.handles[i])[0] == event.target) handle = true;
                  }
                  if (!handle) return false;
  
                  return true;
  
          },
  
          _mouseStart: function(event) {
  
                  var o = this.options, iniPos = this.element.position(), el = this.element,
                          num = function(v) { return parseInt(v, 10) || 0; }, ie6 = .browser.msie && .browser.version < 7;
                  o.resizing = true;
                  o.documentScroll = { top: document.scrollTop(), left: document.scrollLeft() };
  
                  // bugfix #1749
                  if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
  
                          // sOffset decides if document scrollOffset will be added to the top/left of the resizable element
                          var sOffset = .browser.msie && !o.containment && (/absolute/).test(el.css('position')) && !(/relative/).test(el.parent().css('position'));
                          var dscrollt = sOffset ? o.documentScroll.top : 0, dscrolll = sOffset ? o.documentScroll.left : 0;
  
                          el.css({ position: 'absolute', top: (iniPos.top + dscrollt), left: (iniPos.left + dscrolll) });
                  }
  
                  //Opera fixing relative position
                  if (.browser.opera && (/relative/).test(el.css('position')))
                          el.css({ position: 'relative', top: 'auto', left: 'auto' });
  
                  this._renderProxy();
  
                  var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
  
                  if (o.containment) {
                          curleft += $(o.containment).scrollLeft()||0;
                          curtop += $(o.containment).scrollTop()||0;
                  }
  
                  //Store needed variables
                  this.offset = this.helper.offset();
                  this.position = { left: curleft, top: curtop };
                  this.size = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
                  this.originalSize = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
                  this.originalPosition = { left: curleft, top: curtop };
                  this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
                  this.originalMousePosition = { left: event.pageX, top: event.pageY };
  
                  //Aspect Ratio
                  o.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height)||1);
  
                  if (o.preserveCursor) {
                      var cursor = $('.ui-resizable-' + this.axis).css('cursor');
                      $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
                  }
  
                  this._propagate("start", event);
                  return true;
          },
  
          _mouseDrag: function(event) {
  
                  //Increase performance, avoid regex
                  var el = this.helper, o = this.options, props = {},
                          self = this, smp = this.originalMousePosition, a = this.axis;
  
                  var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
                  var trigger = this._change[a];
                  if (!trigger) return false;
  
                  // Calculate the attrs that will be change
                  var data = trigger.apply(this, [event, dx, dy]), ie6 = .browser.msie && .browser.version < 7, csdif = this.sizeDiff;
  
                  if (o._aspectRatio || event.shiftKey)
                          data = this._updateRatio(data, event);
  
                  data = this._respectSize(data, event);
  
                  // plugins callbacks need to be called first
                  this._propagate("resize", event);
  
                  el.css({
                          top: this.position.top + "px", left: this.position.left + "px",
                          width: this.size.width + "px", height: this.size.height + "px"
                  });
  
                  if (!o.helper && o.proportionallyResize)
                          this._proportionallyResize();
  
                  this._updateCache(data);
  
                  // calling the user callback at the end
                  this.element.triggerHandler("resize", [event, this.ui()], this.options["resize"]);
  
                  return false;
          },
  
          _mouseStop: function(event) {
  
                  this.options.resizing = false;
                  var o = this.options, num = function(v) { return parseInt(v, 10) || 0; }, self = this;
  
                  if(o.helper) {
                          var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName),
                                                  soffseth = ista && .ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
                                                          soffsetw = ista ? 0 : self.sizeDiff.width;
  
                          var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
                                  left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
                                  top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
  
                          if (!o.animate)
                                  this.element.css(.extend(s, { top: top, left: left }));
  
                          if (o.helper && !o.animate) this._proportionallyResize();
                  }
  
                  if (o.preserveCursor)
                          $('body').css('cursor', 'auto');
  
                  this._propagate("stop", event);
  
                  if (o.helper) this.helper.remove();
  
                  return false;
          },
  
          _updateCache: function(data) {
                  var o = this.options;
                  this.offset = this.helper.offset();
                  if (data.left) this.position.left = data.left;
                  if (data.top) this.position.top = data.top;
                  if (data.height) this.size.height = data.height;
                  if (data.width) this.size.width = data.width;
          },
  
          _updateRatio: function(data, event) {
  
                  var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
  
                  if (data.height) data.width = (csize.height * o.aspectRatio);
                  else if (data.width) data.height = (csize.width / o.aspectRatio);
  
                  if (a == 'sw') {
                          data.left = cpos.left + (csize.width - data.width);
                          data.top = null;
                  }
                  if (a == 'nw') {
                          data.top = cpos.top + (csize.height - data.height);
                          data.left = cpos.left + (csize.width - data.width);
                  }
  
                  return data;
          },
  
          _respectSize: function(data, event) {
  
                  var el = this.helper, o = this.options, pRatio = o._aspectRatio || event.shiftKey, a = this.axis,
                                  ismaxw = data.width && o.maxWidth && o.maxWidth < data.width, ismaxh = data.height && o.maxHeight && o.maxHeight < data.height,
                                          isminw = data.width && o.minWidth && o.minWidth > data.width, isminh = data.height && o.minHeight && o.minHeight > data.height;
  
                  if (isminw) data.width = o.minWidth;
                  if (isminh) data.height = o.minHeight;
                  if (ismaxw) data.width = o.maxWidth;
                  if (ismaxh) data.height = o.maxHeight;
  
                  var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
                  var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
  
                  if (isminw && cw) data.left = dw - o.minWidth;
                  if (ismaxw && cw) data.left = dw - o.maxWidth;
                  if (isminh && ch)        data.top = dh - o.minHeight;
                  if (ismaxh && ch)        data.top = dh - o.maxHeight;
  
                  // fixing jump error on top/left - bug #2330
                  var isNotwh = !data.width && !data.height;
                  if (isNotwh && !data.left && data.top) data.top = null;
                  else if (isNotwh && !data.top && data.left) data.left = null;
  
                  return data;
          },
  
          _proportionallyResize: function() {
                  var o = this.options;
                  if (!o.proportionallyResize) return;
                  var prel = o.proportionallyResize, el = this.helper || this.element;
  
                  if (!o.borderDif) {
                          var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
                                  p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
  
                          o.borderDif = .map(b, function(v, i) {
                                  var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
                                  return border + padding;
                          });
                  }
                  prel.css({
                          height: (el.height() - o.borderDif[0] - o.borderDif[2]) + "px",
                          width: (el.width() - o.borderDif[1] - o.borderDif[3]) + "px"
                  });
          },
  
          _renderProxy: function() {
                  var el = this.element, o = this.options;
                  this.elementOffset = el.offset();
  
                  if(o.helper) {
                          this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
  
                          // fix ie6 offset
                          var ie6 = .browser.msie && .browser.version < 7, ie6offset = (ie6 ? 1 : 0),
                          pxyoffset = ( ie6 ? 2 : -1 );
  
                          this.helper.addClass(o.helper).css({
                                  width: el.outerWidth() + pxyoffset,
                                  height: el.outerHeight() + pxyoffset,
                                  position: 'absolute',
                                  left: this.elementOffset.left - ie6offset +'px',
                                  top: this.elementOffset.top - ie6offset +'px',
                                  zIndex: ++o.zIndex
                          });
  
                          this.helper.appendTo("body");
  
                          if (o.disableSelection)
                                  this.helper.disableSelection();
  
                  } else {
                          this.helper = el;
                  }
          },
  
          _change: {
                  e: function(event, dx, dy) {
                          return { width: this.originalSize.width + dx };
                  },
                  w: function(event, dx, dy) {
                          var o = this.options, cs = this.originalSize, sp = this.originalPosition;
                          return { left: sp.left + dx, width: cs.width - dx };
                  },
                  n: function(event, dx, dy) {
                          var o = this.options, cs = this.originalSize, sp = this.originalPosition;
                          return { top: sp.top + dy, height: cs.height - dy };
                  },
                  s: function(event, dx, dy) {
                          return { height: this.originalSize.height + dy };
                  },
                  se: function(event, dx, dy) {
                          return .extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
                  },
                  sw: function(event, dx, dy) {
                          return .extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
                  },
                  ne: function(event, dx, dy) {
                          return .extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
                  },
                  nw: function(event, dx, dy) {
                          return .extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
                  }
          },
  
          _propagate: function(n, event) {
                  .ui.plugin.call(this, n, [event, this.ui()]);
                  if (n != "resize") this.element.triggerHandler(["resize", n].join(""), [event, this.ui()], this.options[n]);
          },
  
          plugins: {},
  
          ui: function() {
                  return {
                          originalElement: this.originalElement,
                          element: this.element,
                          helper: this.helper,
                          position: this.position,
                          size: this.size,
                          options: this.options,
                          originalSize: this.originalSize,
                          originalPosition: this.originalPosition
                  };
          }
  
  }));
  
  .extend(.ui.resizable, {
          version: "@VERSION",
          defaults: {
                  alsoResize: false,
                  animate: false,
                  animateDuration: "slow",
                  animateEasing: "swing",
                  aspectRatio: false,
                  autoHide: false,
                  cancel: ":input",
                  containment: false,
                  delay: 0,
                  disableSelection: true,
                  distance: 1,
                  ghost: false,
                  grid: false,
                  knobHandles: false,
                  maxHeight: null,
                  maxWidth: null,
                  minHeight: 10,
                  minWidth: 10,
                  preserveCursor: true,
                  preventDefault: true,
                  proportionallyResize: false,
                  transparent: false
          }
  });
  
  /*
   * Resizable Extensions
   */
  
  .ui.plugin.add("resizable", "alsoResize", {
  
          start: function(event, ui) {
                  var o = ui.options, self = this.data("resizable"),
  
                  _store = function(exp) {
                          exp.each(function() {
                                  this.data("resizable-alsoresize", {
                                          width: parseInt(this.width(), 10), height: parseInt(this.height(), 10),
                                          left: parseInt(this.css('left'), 10), top: parseInt(this.css('top'), 10)
                                  });
                          });
                  };
  
                  if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
                          if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0];        _store(o.alsoResize); }
                          else { .each(o.alsoResize, function(exp, c) { _store(exp); }); }
                  }else{
                          _store(o.alsoResize);
                  }
          },
  
          resize: function(event, ui){
                  var o = ui.options, self = this.data("resizable"), os = self.originalSize, op = self.originalPosition;
  
                  var delta = {
                          height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
                          top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
                  },
  
                  _alsoResize = function(exp, c) {
                          exp.each(function() {
                                  var start = this.data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
  
                                  .each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
                                          var sum = (start[prop]||0) + (delta[prop]||0);
                                          if (sum && sum >= 0)
                                                  style[prop] = sum || null;
                                  });
                                  this.css(style);
                          });
                  };
  
                  if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
                          .each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });
                  }else{
                          _alsoResize(o.alsoResize);
                  }
          },
  
          stop: function(event, ui){
                  this.removeData("resizable-alsoresize-start");
          }
  });
  
  .ui.plugin.add("resizable", "animate", {
  
          stop: function(event, ui) {
                  var o = ui.options, self = this.data("resizable");
  
                  var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName),
                                                  soffseth = ista && .ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
                                                          soffsetw = ista ? 0 : self.sizeDiff.width;
  
                  var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
                                          left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
                                                  top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
  
                  self.element.animate(
                          .extend(style, top && left ? { top: top, left: left } : {}), {
                                  duration: o.animateDuration,
                                  easing: o.animateEasing,
                                  step: function() {
  
                                          var data = {
                                                  width: parseInt(self.element.css('width'), 10),
                                                  height: parseInt(self.element.css('height'), 10),
                                                  top: parseInt(self.element.css('top'), 10),
                                                  left: parseInt(self.element.css('left'), 10)
                                          };
  
                                          if (pr) pr.css({ width: data.width, height: data.height });
  
                                          // propagating resize, and updating values for each animation step
                                          self._updateCache(data);
                                          self._propagate("animate", event);
  
                                  }
                          }
                  );
          }
  
  });
  
  .ui.plugin.add("resizable", "containment", {
  
          start: function(event, ui) {
                  var o = ui.options, self = this.data("resizable"), el = self.element;
                  var oc = o.containment,        ce = (oc instanceof ) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
                  if (!ce) return;
  
                  self.containerElement = ce;
  
                  if (/document/.test(oc) || oc == document) {
                          self.containerOffset = { left: 0, top: 0 };
                          self.containerPosition = { left: 0, top: 0 };
  
                          self.parentData = {
                                  element: document, left: 0, top: 0,
                                  width: document.width(), height: document.height() || document.body.parentNode.scrollHeight
                          };
                  }
  
                  // i'm a node, so compute top, left, right, bottom
                  else{
                          self.containerOffset = ce.offset();
                          self.containerPosition = ce.position();
                          self.containerSize = { height: ce.innerHeight(), width: ce.innerWidth() };
  
                          var co = self.containerOffset, ch = self.containerSize.height,        cw = self.containerSize.width,
                                                  width = (.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = (.ui.hasScroll(ce) ? ce.scrollHeight : ch);
  
                          self.parentData = {
                                  element: ce, left: co.left, top: co.top, width: width, height: height
                          };
                  }
          },
  
          resize: function(event, ui) {
                  var o = ui.options, self = this.data("resizable"),
                                  ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
                                  pRatio = o._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
  
                  if (ce[0] != document && (/static/).test(ce.css('position')))
                          cop = self.containerPosition;
  
                  if (cp.left < (o.helper ? co.left : 0)) {
                          self.size.width = self.size.width + (o.helper ? (self.position.left - co.left) : (self.position.left - cop.left));
                          if (pRatio) self.size.height = self.size.width / o.aspectRatio;
                          self.position.left = o.helper ? co.left : 0;
                  }
  
                  if (cp.top < (o.helper ? co.top : 0)) {
                          self.size.height = self.size.height + (o.helper ? (self.position.top - co.top) : self.position.top);
                          if (pRatio) self.size.width = self.size.height * o.aspectRatio;
                          self.position.top = o.helper ? co.top : 0;
                  }
  
                  var woset = Math.abs( (o.helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
                                          hoset = Math.abs( (o.helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
  
                  if (woset + self.size.width >= self.parentData.width) {
                          self.size.width = self.parentData.width - woset;
                          if (pRatio) self.size.height = self.size.width / o.aspectRatio;
                  }
  
                  if (hoset + self.size.height >= self.parentData.height) {
                          self.size.height = self.parentData.height - hoset;
                          if (pRatio) self.size.width = self.size.height * o.aspectRatio;
                  }
          },
  
          stop: function(event, ui){
                  var o = ui.options, self = this.data("resizable"), cp = self.position,
                                  co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
  
                  var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
  
                  if (o.helper && !o.animate && (/relative/).test(ce.css('position')))
                          this.css({ left: ho.left - cop.left - co.left, width: w, height: h });
  
                  if (o.helper && !o.animate && (/static/).test(ce.css('position')))
                          this.css({ left: ho.left - cop.left - co.left, width: w, height: h });
  
          }
  });
  
  .ui.plugin.add("resizable", "ghost", {
  
          start: function(event, ui) {
                  var o = ui.options, self = this.data("resizable"), pr = o.proportionallyResize, cs = self.size;
  
                  if (!pr) self.ghost = self.element.clone();
                  else self.ghost = pr.clone();
  
                  self.ghost.css(
                          { opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }
                  )
                  .addClass('ui-resizable-ghost').addClass(typeof o.ghost == 'string' ? o.ghost : '');
  
                  self.ghost.appendTo(self.helper);
  
          },
  
          resize: function(event, ui){
                  var o = ui.options, self = this.data("resizable"), pr = o.proportionallyResize;
  
                  if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
  
          },
  
          stop: function(event, ui){
                  var o = ui.options, self = this.data("resizable"), pr = o.proportionallyResize;
                  if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
          }
  
  });
  
  .ui.plugin.add("resizable", "grid", {
  
          resize: function(event, ui) {
                  var o = ui.options, self = this.data("resizable"), cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
                  o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
                  var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
  
                  if (/^(se|s|e)/.test(a)) {
                          self.size.width = os.width + ox;
                          self.size.height = os.height + oy;
                  }
                  else if (/^(ne)/.test(a)) {
                          self.size.width = os.width + ox;
                          self.size.height = os.height + oy;
                          self.position.top = op.top - oy;
                  }
                  else if (/^(sw)/.test(a)) {
                          self.size.width = os.width + ox;
                          self.size.height = os.height + oy;
                          self.position.left = op.left - ox;
                  }
                  else {
                          self.size.width = os.width + ox;
                          self.size.height = os.height + oy;
                          self.position.top = op.top - oy;
                          self.position.left = op.left - ox;
                  }
          }
  
  });
  
  })(jQuery);
  /*
   * jQuery UI Dialog @VERSION
   *
   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI/Dialog
   *
   * Depends:
   *        ui.core.js
   *        ui.draggable.js
   *        ui.resizable.js
   */
  (function() {
  
  var setDataSwitch = {
          dragStart: "start.draggable",
          drag: "drag.draggable",
          dragStop: "stop.draggable",
          maxHeight: "maxHeight.resizable",
          minHeight: "minHeight.resizable",
          maxWidth: "maxWidth.resizable",
          minWidth: "minWidth.resizable",
          resizeStart: "start.resizable",
          resize: "drag.resizable",
          resizeStop: "stop.resizable"
  };
  
  .widget("ui.dialog", {
  
          _init: function() {
                  this.originalTitle = this.element.attr('title');
                  this.options.title = this.options.title || this.originalTitle;
  
                  var self = this,
                          options = this.options,
  
                          title = options.title || '&nbsp;',
                          titleId = .ui.dialog.getTitleId(this.element),
  
                          uiDialog = (this.uiDialog = $('<div/>'))
                                  .appendTo(document.body)
                                  .hide()
                                  .addClass(
                                          'ui-dialog ' +
                                          'ui-widget ' +
                                          'ui-widget-content ' +
                                          'ui-corner-all ' +
                                          options.dialogClass
                                  )
                                  .css({
                                          position: 'absolute',
                                          overflow: 'hidden',
                                          zIndex: options.zIndex
                                  })
                                  // setting tabIndex makes the div focusable
                                  // setting outline to 0 prevents a border on focus in Mozilla
                                  .attr('tabIndex', -1).css('outline', 0).keydown(function(ev) {
                                          (options.closeOnEscape && ev.keyCode
                                                  && ev.keyCode == .ui.keyCode.ESCAPE && self.close());
                                  })
                                  .attr({
                                          role: 'dialog',
                                          'aria-labelledby': titleId
                                  })
                                  .mousedown(function() {
                                          self.moveToTop();
                                  }),
  
                          uiDialogContent = this.element
                                  .removeAttr('title')
                                  .addClass(
                                          'ui-dialog-content ' +
                                          'ui-widget-content')
                                  .appendTo(uiDialog),
  
                          uiDialogTitlebar = (this.uiDialogTitlebar = $('<div></div>'))
                                  .addClass(
                                          'ui-dialog-titlebar ' +
                                          'ui-widget-header ' +
                                          'ui-corner-all ' +
                                          'ui-helper-clearfix'
                                  )
                                  .prependTo(uiDialog),
  
                          uiDialogTitlebarClose = $('<a href="#"/>')
                                  .addClass(
                                          'ui-dialog-titlebar-close ' +
                                          'ui-corner-all'
                                  )
                                  .attr('role', 'button')
                                  .hover(
                                          function() {
                                                  uiDialogTitlebarClose.addClass('ui-state-hover');
                                          },
                                          function() {
                                                  uiDialogTitlebarClose.removeClass('ui-state-hover');
                                          }
                                  )
                                  .focus(function() {
                                          uiDialogTitlebarClose.addClass('ui-state-focus');
                                  })
                                  .blur(function() {
                                          uiDialogTitlebarClose.removeClass('ui-state-focus');
                                  })
                                  .mousedown(function(ev) {
                                          ev.stopPropagation();
                                  })
                                  .click(function() {
                                          self.close();
                                          return false;
                                  })
                                  .appendTo(uiDialogTitlebar),
  
                          uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>'))
                                  .addClass(
                                          'ui-icon ' +
                                          'ui-icon-closethick'
                                  )
                                  .text(options.closeText)
                                  .appendTo(uiDialogTitlebarClose),
  
                          uiDialogTitle = $('<span/>')
                                  .addClass('ui-dialog-title')
                                  .attr('id', titleId)
                                  .html(title)
                                  .prependTo(uiDialogTitlebar),
  
                          uiDialogButtonPane = (this.uiDialogButtonPane = $('<div></div>'))
                                  .addClass(
                                          'ui-dialog-buttonpane ' +
                                          'ui-widget-content ' +
                                          'ui-helper-clearfix'
                                  )
                                  .appendTo(uiDialog);
  
                  uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
  
                  (options.draggable && .fn.draggable && this._makeDraggable());
                  (options.resizable && .fn.resizable && this._makeResizable());
  
                  this._createButtons(options.buttons);
                  this._isOpen = false;
  
                  (options.bgiframe && .fn.bgiframe && uiDialog.bgiframe());
                  (options.autoOpen && this.open());
          },
  
          destroy: function() {
                  (this.overlay && this.overlay.destroy());
                  this.uiDialog.hide();
                  this.element
                          .unbind('.dialog')
                          .removeData('dialog')
                          .removeClass('ui-dialog-content ui-widget-content')
                          .hide().appendTo('body');
                  this.uiDialog.remove();
  
                  (this.originalTitle && this.element.attr('title', this.originalTitle));
          },
  
          close: function() {
                  if (false === this._trigger('beforeclose', null, { options: this.options })) {
                          return;
                  }
  
                  (this.overlay && this.overlay.destroy());
                  this.uiDialog
                          .hide(this.options.hide)
                          .unbind('keypress.ui-dialog');
  
                  this._trigger('close', null, { options: this.options });
                  .ui.dialog.overlay.resize();
  
                  this._isOpen = false;
          },
  
          isOpen: function() {
                  return this._isOpen;
          },
  
          // the force parameter allows us to move modal dialogs to their correct
          // position on open
          moveToTop: function(force) {
  
                  if ((this.options.modal && !force)
                          || (!this.options.stack && !this.options.modal)) {
                          return this._trigger('focus', null, { options: this.options });
                  }
  
                  var maxZ = this.options.zIndex, options = this.options;
                  $('.ui-dialog:visible').each(function() {
                          maxZ = Math.max(maxZ, parseInt(this.css('z-index'), 10) || options.zIndex);
                  });
                  (this.overlay && this.overlay.el.css('z-index', ++maxZ));
  
                  //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
                  //  http://ui.jquery.com/bugs/ticket/3193
  		var saveScroll = { scrollTop: this.element.attr('scrollTop'), scrollLeft: this.element.attr('scrollLeft') };
                  this.uiDialog.css('z-index', ++maxZ);
                  this.element.attr(saveScroll);
                  this._trigger('focus', null, { options: this.options });
          },
  
          open: function() {
                  if (this._isOpen) { return; }
  
                  this.overlay = this.options.modal ? new .ui.dialog.overlay(this) : null;
                  (this.uiDialog.next().length && this.uiDialog.appendTo('body'));
                  this._size();
                  this._position(this.options.position);
                  this.uiDialog.show(this.options.show);
                  this.moveToTop(true);
  
                  // prevent tabbing out of modal dialogs
                  (this.options.modal && this.uiDialog.bind('keypress.ui-dialog', function(event) {
                          if (event.keyCode != .ui.keyCode.TAB) {
                                  return;
                          }
  
                          var tabbables = $(':tabbable', this),
                                  first = tabbables.filter(':first')[0],
                                  last  = tabbables.filter(':last')[0];
  
                          if (event.target == last && !event.shiftKey) {
                                  setTimeout(function() {
                                          first.focus();
                                  }, 1);
                          } else if (event.target == first && event.shiftKey) {
                                  setTimeout(function() {
                                          last.focus();
                                  }, 1);
                          }
                  }));
  
                  this.uiDialog.find(':tabbable:first').focus();
                  this._trigger('open', null, { options: this.options });
                  this._isOpen = true;
          },
  
          _createButtons: function(buttons) {
                  var self = this,
                          hasButtons = false,
                          uiDialogButtonPane = this.uiDialogButtonPane;
  
                  // remove any existing buttons
                  uiDialogButtonPane.empty().hide();
  
                  .each(buttons, function() { return !(hasButtons = true); });
                  if (hasButtons) {
                          uiDialogButtonPane.show();
                          .each(buttons, function(name, fn) {
                                  $('<button type="button"></button>')
                                          .addClass(
                                                  'ui-state-default ' +
                                                  'ui-corner-all'
                                          )
                                          .text(name)
                                          .click(function() { fn.apply(self.element[0], arguments); })
                                          .hover(
                                                  function() {
                                                          this.addClass('ui-state-hover');
                                                  },
                                                  function() {
                                                          this.removeClass('ui-state-hover');
                                                  }
                                          )
                                          .focus(function() {
                                                  this.addClass('ui-state-focus');
                                          })
                                          .blur(function() {
                                                  this.removeClass('ui-state-focus');
                                          })
                                          .appendTo(uiDialogButtonPane);
                          });
                  }
          },
  
          _makeDraggable: function() {
                  var self = this,
                          options = this.options;
  
                  this.uiDialog.draggable({
                          cancel: '.ui-dialog-content',
                          helper: options.dragHelper,
                          handle: '.ui-dialog-titlebar',
                          start: function() {
                                  (options.dragStart && options.dragStart.apply(self.element[0], arguments));
                          },
                          drag: function() {
                                  (options.drag && options.drag.apply(self.element[0], arguments));
                          },
                          stop: function() {
                                  (options.dragStop && options.dragStop.apply(self.element[0], arguments));
                                  .ui.dialog.overlay.resize();
                          }
                  });
          },
  
          _makeResizable: function(handles) {
                  handles = (handles === undefined ? this.options.resizable : handles);
                  var self = this,
                          options = this.options,
                          resizeHandles = typeof handles == 'string'
                                  ? handles
                                  : 'n,e,s,w,se,sw,ne,nw';
  
                  this.uiDialog.resizable({
                          cancel: '.ui-dialog-content',
                          alsoResize: this.element,
                          helper: options.resizeHelper,
                          maxWidth: options.maxWidth,
                          maxHeight: options.maxHeight,
                          minWidth: options.minWidth,
                          minHeight: options.minHeight,
                          start: function() {
                                  (options.resizeStart && options.resizeStart.apply(self.element[0], arguments));
                          },
                          resize: function() {
                                  (options.resize && options.resize.apply(self.element[0], arguments));
                          },
                          handles: resizeHandles,
                          stop: function() {
                                  (options.resizeStop && options.resizeStop.apply(self.element[0], arguments));
                                  .ui.dialog.overlay.resize();
                          }
                  })
                  .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
          },
  
          _position: function(pos) {
                  var wnd = window, doc = document,
                          pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
                          minTop = pTop;
  
                  if (.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
                          pos = [
                                  pos == 'right' || pos == 'left' ? pos : 'center',
                                  pos == 'top' || pos == 'bottom' ? pos : 'middle'
                          ];
                  }
                  if (pos.constructor != Array) {
                          pos = ['center', 'middle'];
                  }
                  if (pos[0].constructor == Number) {
                          pLeft += pos[0];
                  } else {
                          switch (pos[0]) {
                                  case 'left':
                                          pLeft += 0;
                                          break;
                                  case 'right':
                                          pLeft += wnd.width() - this.uiDialog.outerWidth();
                                          break;
                                  default:
                                  case 'center':
                                          pLeft += (wnd.width() - this.uiDialog.outerWidth()) / 2;
                          }
                  }
                  if (pos[1].constructor == Number) {
                          pTop += pos[1];
                  } else {
                          switch (pos[1]) {
                                  case 'top':
                                          pTop += 0;
                                          break;
                                  case 'bottom':
                                          // Opera check fixes #3564, can go away with jQuery 1.3
                                          pTop += (.browser.opera ? window.innerHeight : wnd.height()) - this.uiDialog.outerHeight();
                                          break;
                                  default:
                                  case 'middle':
                                          // Opera check fixes #3564, can go away with jQuery 1.3
                                          pTop += ((.browser.opera ? window.innerHeight : wnd.height()) - this.uiDialog.outerHeight()) / 2;
                          }
                  }
  
                  // prevent the dialog from being too high (make sure the titlebar
                  // is accessible)
                  pTop = Math.max(pTop, minTop);
                  this.uiDialog.css({top: pTop, left: pLeft});
          },
  
          _setData: function(key, value){
                  (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
                  switch (key) {
                          case "buttons":
                                  this._createButtons(value);
                                  break;
                          case "closeText":
                                  this.uiDialogTitlebarCloseText.text(value);
                                  break;
                          case "draggable":
                                  (value
                                          ? this._makeDraggable()
                                          : this.uiDialog.draggable('destroy'));
                                  break;
                          case "height":
                                  this.uiDialog.height(value);
                                  break;
                          case "position":
                                  this._position(value);
                                  break;
                          case "resizable":
                                  var uiDialog = this.uiDialog,
                                          isResizable = this.uiDialog.is(':data(resizable)');
  
                                  // currently resizable, becoming non-resizable
                                  (isResizable && !value && uiDialog.resizable('destroy'));
  
                                  // currently resizable, changing handles
                                  (isResizable && typeof value == 'string' &&
                                          uiDialog.resizable('option', 'handles', value));
  
                                  // currently non-resizable, becoming resizable
                                  (isResizable || this._makeResizable(value));
  
                                  break;
                          case "title":
                                  $(".ui-dialog-title", this.uiDialogTitlebar).html(value || '&nbsp;');
                                  break;
                          case "width":
                                  this.uiDialog.width(value);
                                  break;
                  }
  
                  .widget.prototype._setData.apply(this, arguments);
          },
  
          _size: function() {
                  /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
  		 * divs will both have width and height set, so we need to reset them
  		 */
                  var options = this.options;
  
                  // reset content sizing
                  this.element.css({
                          height: 0,
                          width: 'auto'
                  });
  
                  // reset wrapper sizing
                  // determine the height of all the non-content elements
                  var nonContentHeight = this.uiDialog.css({
                                  height: 'auto',
                                  width: options.width
                          })
                          .height();
  
                  this.element
                          .css({
                                  minHeight: options.minHeight - nonContentHeight,
                                  height: options.height == 'auto'
                                          ? 'auto'
                                          : options.height - nonContentHeight
                          });
          }
  });
  
  /*
   * jQuery UI Droppable @VERSION
   *
   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI/Droppables
   *
   * Depends:
   *        ui.core.js
   *        ui.draggable.js
   */
  (function() {
  
  .widget("ui.droppable", {
  
          _init: function() {
  
                  var o = this.options, accept = o.accept;
                  this.isover = 0; this.isout = 1;
  
                  this.options.accept = this.options.accept && .isFunction(this.options.accept) ? this.options.accept : function(d) {
                          return d.is(accept);
                  };
  
                  //Store the droppable's proportions
                  this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
  
                  // Add the reference and positions to the manager
                  .ui.ddmanager.droppables[this.options.scope] = .ui.ddmanager.droppables[this.options.scope] || [];
                  .ui.ddmanager.droppables[this.options.scope].push(this);
  
                  (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-droppable"));
  
          },
  
          destroy: function() {
                  var drop = .ui.ddmanager.droppables[this.options.scope];
                  for ( var i = 0; i < drop.length; i++ )
                          if ( drop[i] == this )
                                  drop.splice(i, 1);
  
                  this.element
                          .removeClass("ui-droppable-disabled")
                          .removeData("droppable")
                          .unbind(".droppable");
          },
  
          _setData: function(key, value) {
  
                  if(key == 'accept') {
                          this.options.accept = value && .isFunction(value) ? value : function(d) {
                                  return d.is(accept);
                          };
                  } else {
                          .widget.prototype._setData.apply(this, arguments);
                  }
  
          },
  
          _activate: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  .ui.plugin.call(this, 'activate', [event, this.ui(draggable)]);
                  if(draggable) this.element.triggerHandler("dropactivate", [event, this.ui(draggable)], this.options.activate);
  
          },
  
          _deactivate: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  .ui.plugin.call(this, 'deactivate', [event, this.ui(draggable)]);
                  if(draggable) this.element.triggerHandler("dropdeactivate", [event, this.ui(draggable)], this.options.deactivate);
  
          },
  
          _over: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  
                  if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
                          .ui.plugin.call(this, 'over', [event, this.ui(draggable)]);
                          this.element.triggerHandler("dropover", [event, this.ui(draggable)], this.options.over);
                  }
  
          },
  
          _out: function(event) {
  
                  var draggable = .ui.ddmanager.current;
                  if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
  
                  if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
                          .ui.plugin.call(this, 'out', [event, this.ui(draggable)]);
                          this.element.triggerHandler("dropout", [event, this.ui(draggable)], this.options.out);
                  }
  
          },
  
          _drop: function(event,custom) {
  
                  var draggable = custom || .ui.ddmanager.current;
                  if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
  
                  var childrenIntersection = false;
                  this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
                          var inst = .data(this, 'droppable');
                          if(inst.options.greedy && .ui.intersect(draggable, .extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) {
                                  childrenIntersection = true; return false;
                          }
                  });
                  if(childrenIntersection) return false;
  
                  if(this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
                          .ui.plugin.call(this, 'drop', [event, this.ui(draggable)]);
                          this.element.triggerHandler("drop", [event, this.ui(draggable)], this.options.drop);
                          return this.element;
                  }
  
                  return false;
  
          },
  
          plugins: {},
  
          ui: function(c) {
                  return {
                          draggable: (c.currentItem || c.element),
                          helper: c.helper,
                          position: c.position,
                          absolutePosition: c.positionAbs,
                          options: this.options,
                          element: this.element
                  };
          }
  
  });
  
  .extend(.ui.droppable, {
          version: "@VERSION",
          defaults: {
                  accept: '*',
                  activeClass: null,
                  cssNamespace: 'ui',
                  greedy: false,
                  hoverClass: null,
                  scope: 'default',
                  tolerance: 'intersect'
          }
  });
  
  .ui.intersect = function(draggable, droppable, toleranceMode) {
  
          if (!droppable.offset) return false;
  
          var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
                  y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
          var l = droppable.offset.left, r = l + droppable.proportions.width,
                  t = droppable.offset.top, b = t + droppable.proportions.height;
  
          switch (toleranceMode) {
                  case 'fit':
                          return (l < x1 && x2 < r
                                  && t < y1 && y2 < b);
                          break;
                  case 'intersect':
                          return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
                                  && x2 - (draggable.helperProportions.width / 2) < r // Left Half
                                  && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
                                  && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
                          break;
                  case 'pointer':
                          var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
                                  draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
                                  isOver = .ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
                          return isOver;
                          break;
                  case 'touch':
                          return (
                                          (y1 >= t && y1 <= b) ||        // Top edge touching
                                          (y2 >= t && y2 <= b) ||        // Bottom edge touching
                                          (y1 < t && y2 > b)                // Surrounded vertically
                                  ) && (
                                          (x1 >= l && x1 <= r) ||        // Left edge touching
                                          (x2 >= l && x2 <= r) ||        // Right edge touching
                                          (x1 < l && x2 > r)                // Surrounded horizontally
                                  );
                          break;
                  default:
                          return false;
                          break;
                  }
  
  };
  
  /*
          This manager tracks offsets of draggables and droppables
  */
  .ui.ddmanager = {
          current: null,
          droppables: { 'default': [] },
          prepareOffsets: function(t, event) {
  
                  var m = .ui.ddmanager.droppables[t.options.scope];
                  var type = event ? event.type : null; // workaround for #2317
                  var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
  
                  droppablesLoop: for (var i = 0; i < m.length; i++) {
  
                          if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element,(t.currentItem || t.element)))) continue;        //No disabled and non-accepted
                          for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
                          m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                                                         //If the element is not visible, continue
  
                          m[i].offset = m[i].element.offset();
                          m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
  
                          if(type == "dragstart" || type == "sortactivate") m[i]._activate.call(m[i], event);                                                                                 //Activate the droppable if used directly from draggables
  
                  }
  
          },
          drop: function(draggable, event) {
  
                  var dropped = false;
                  .each(.ui.ddmanager.droppables[draggable.options.scope], function() {
  
                          if(!this.options) return;
                          if (!this.options.disabled && this.visible && .ui.intersect(draggable, this, this.options.tolerance))
                                  dropped = this._drop.call(this, event);
  
                          if (!this.options.disabled && this.visible && this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
                                  this.isout = 1; this.isover = 0;
                                  this._deactivate.call(this, event);
                          }
  
                  });
                  return dropped;
  
          },
          drag: function(draggable, event) {
  
                  //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
                  if(draggable.options.refreshPositions) .ui.ddmanager.prepareOffsets(draggable, event);
  
                  //Run through all droppables and check their positions based on specific tolerance options
  
                  .each(.ui.ddmanager.droppables[draggable.options.scope], function() {
  
                          if(this.options.disabled || this.greedyChild || !this.visible) return;
                          var intersects = .ui.intersect(draggable, this, this.options.tolerance);
  
                          var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
                          if(!c) return;
  
                          var parentInstance;
                          if (this.options.greedy) {
                                  var parent = this.element.parents(':data(droppable):eq(0)');
                                  if (parent.length) {
                                          parentInstance = .data(parent[0], 'droppable');
                                          parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
                                  }
                          }
  
                          // we just moved into a greedy child
                          if (parentInstance && c == 'isover') {
                                  parentInstance['isover'] = 0;
                                  parentInstance['isout'] = 1;
                                  parentInstance._out.call(parentInstance, event);
                          }
  
                          this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
                          this[c == "isover" ? "_over" : "_out"].call(this, event);
  
                          // we just moved out of a greedy child
                          if (parentInstance && c == 'isout') {
                                  parentInstance['isout'] = 0;
                                  parentInstance['isover'] = 1;
                                  parentInstance._over.call(parentInstance, event);
                          }
                  });
  
          }
  };
  
  /*
   * Droppable Extensions
   */
  
  .ui.plugin.add("droppable", "activeClass", {
          activate: function(event, ui) {
                  this.addClass(ui.options.activeClass);
          },
          deactivate: function(event, ui) {
                  this.removeClass(ui.options.activeClass);
          },
          drop: function(event, ui) {
                  this.removeClass(ui.options.activeClass);
          }
  });
  
  .ui.plugin.add("droppable", "hoverClass", {
          over: function(event, ui) {
                  this.addClass(ui.options.hoverClass);
          },
          out: function(event, ui) {
                  this.removeClass(ui.options.hoverClass);
          },
          drop: function(event, ui) {
                  this.removeClass(ui.options.hoverClass);
          }
  });
  
  })(jQuery);
  /*
   * jQuery UI Sortable @VERSION
   *
   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
   * Dual licensed under the MIT (MIT-LICENSE.txt)
   * and GPL (GPL-LICENSE.txt) licenses.
   *
   * http://docs.jquery.com/UI/Sortables
   *
   * Depends:
   *        ui.core.js
   */
  (function() {
  
  .widget("ui.sortable", .extend({}, .ui.mouse, {
          _init: function() {
  
                  var o = this.options;
                  this.containerCache = {};
                  this.element.addClass("ui-sortable");
  
                  //Get the items
                  this.refresh();
  
                  //Let's determine if the items are floating
                  this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false;
  
                  //Let's determine the parent's offset
                  this.offset = this.element.offset();
  
                  //Initialize mouse events for interaction
                  this._mouseInit();
  
          },
  
          destroy: function() {
                  this.element
                          .removeClass("ui-sortable ui-sortable-disabled")
                          .removeData("sortable")
                          .unbind(".sortable");
                  this._mouseDestroy();
  
                  for ( var i = this.items.length - 1; i >= 0; i-- )
                          this.items[i].item.removeData("sortable-item");
          },
  
          _mouseCapture: function(event, overrideHandle) {
  
                  if (this.reverting) {
                          return false;
                  }
  
                  if(this.options.disabled || this.options.type == 'static') return false;
  
                  //We have to refresh the items data once first
                  this._refreshItems(event);
  
                  //Find out if the clicked node (or one of its parents) is a actual item in this.items
                  var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
                          if(.data(this, 'sortable-item') == self) {
                                  currentItem = this;
                                  return false;
                          }
                  });
                  if(.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
  
                  if(!currentItem) return false;
                  if(this.options.handle && !overrideHandle) {
                          var validHandle = false;
  
                          $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
                          if(!validHandle) return false;
                  }
  
                  this.currentItem = currentItem;
                  this._removeCurrentsFromItems();
                  return true;
  
          },
  
          _mouseStart: function(event, overrideHandle, noActivation) {
  
                  var o = this.options;
                  this.currentContainer = this;
  
                  //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
                  this.refreshPositions();
  
                  //Create and append the visible helper
                  this.helper = this._createHelper(event);
  
                  //Cache the helper size
                  this._cacheHelperProportions();
  
                  /*
  		 * - Position generation -
  		 * This block generates everything position related - it's the core of draggables.
  		 */
  
                  //Cache the margins of the original element
                  this._cacheMargins();
  
                  //Get the next scrolling parent
                  this.scrollParent = this.helper.scrollParent();
  
                  //The element's absolute position on the page minus margins
                  this.offset = this.currentItem.offset();
  
                  this.offset = {
                          top: this.offset.top - this.margins.top,
                          left: this.offset.left - this.margins.left
                  };
  
                  // Only after we got the offset, we can change the helper's position to absolute
                  // TODO: Still need to figure out a way to make relative sorting possible
                  this.helper.css("position", "absolute");
                  this.cssPosition = this.helper.css("position");
  
                  .extend(this.offset, {
                          click: { //Where the click happened, relative to the element
                                  left: event.pageX - this.offset.left,
                                  top: event.pageY - this.offset.top
                          },
                          parent: this._getParentOffset(),
                          relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
                  });
  
                  //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
                  if(o.cursorAt)
                          this._adjustOffsetFromHelper(o.cursorAt);
  
                  //Generate the original position
                  this.originalPosition = this._generatePosition(event);
  
                  //Cache the former DOM position
                  this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
  
                  //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
                  if(this.helper[0] != this.currentItem[0]) {
                          this.currentItem.hide();
                  }
  
                  //Create the placeholder
                  this._createPlaceholder();
  
                  //Set a containment if given in the options
                  if(o.containment)
                          this._setContainment();
  
                  //Call plugins and callbacks
                  this._propagate("start", event);
  
                  //Recache the helper size
                  if(!this._preserveHelperProportions)
                          this._cacheHelperProportions();
  
                  //Post 'activate' events to possible containers
                  if(!noActivation) {
                           for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._propagate("activate", event, this); }
                  }
  
                  //Prepare possible droppables
                  if(.ui.ddmanager)
                          .ui.ddmanager.current = this;
  
                  if (.ui.ddmanager && !o.dropBehaviour)
                          .ui.ddmanager.prepareOffsets(this, event);
  
                  this.dragging = true;
  
                  this.helper.addClass('ui-sortable-helper');
                  this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
                  return true;
  
          },
  
          _mouseDrag: function(event) {
  
                  //Compute the helpers position
                  this.position = this._generatePosition(event);
                  this.positionAbs = this._convertPositionTo("absolute");
  
                  if (!this.lastPositionAbs) {
                          this.lastPositionAbs = this.positionAbs;
                  }
  
                  //Call the internal plugins
                  .ui.plugin.call(this, "sort", [event, this._ui()]);
  
                  //Regenerate the absolute position used for position checks
                  this.positionAbs = this._convertPositionTo("absolute");
  
                  //Set the helper position
                  if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
                  if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
  
                  //Rearrange
                  for (var i = this.items.length - 1; i >= 0; i--) {
  
                          //Cache variables and intersection, continue if no intersection
                          var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
                          if (!intersection) continue;
  
                          if(itemElement != this.currentItem[0] //cannot intersect with itself
                                  &&        this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
                                  &&        !.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
                                  && (this.options.type == 'semi-dynamic' ? !.ui.contains(this.element[0], itemElement) : true)
                          ) {
  
                                  this.direction = intersection == 1 ? "down" : "up";
  
                                  if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
                                          this.options.sortIndicator.call(this, event, item);
                                  } else {
                                          break;
                                  }
  
                                  this._propagate("change", event); //Call plugins and callbacks
                                  break;
                          }
                  }
  
                  //Post events to containers
                  this._contactContainers(event);
  
                  //Interconnect with droppables
                  if(.ui.ddmanager) .ui.ddmanager.drag(this, event);
  
                  //Call callbacks
                  this._trigger('sort', event, this._ui());
  
                  this.lastPositionAbs = this.positionAbs;
                  return false;
  
          },
  
          _mouseStop: function(event, noPropagation) {
  
                  if(!event) return;
  
                  //If we are using droppables, inform the manager about the drop
                  if (.ui.ddmanager && !this.options.dropBehaviour)
                          .ui.ddmanager.drop(this, event);
  
                  if(this.options.revert) {
                          var self = this;
                          var cur = self.placeholder.offset();
  
                          self.reverting = true;
  
                          $(this.helper).animate({
                                  left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
                                  top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
                          }, parseInt(this.options.revert, 10) || 500, function() {
                                  self._clear(event);
                          });
                  } else {
                          this._clear(event, noPropagation);
                  }
  
                  return false;
  
          },
  
          cancel: function() {
  
                  if(this.dragging) {
  
                          this._mouseUp();
  
                          if(this.options.helper == "original")
                                  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
                          else
                                  this.currentItem.show();
  
                          //Post deactivating events to containers
                          for (var i = this.containers.length - 1; i >= 0; i--){
                                  this.containers[i]._propagate("deactivate", null, this);
                                  if(this.containers[i].containerCache.over) {
                                          this.containers[i]._propagate("out", null, this);
                                          this.containers[i].containerCache.over = 0;
                                  }
                          }
  
                  }
  
                  //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
                  if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
                  if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
  
                  .extend(this, {
                          helper: null,
                          dragging: false,
                          reverting: false,
                          _noFinalSort: null
                  });
  
                  if(this.domPosition.prev) {
                          $(this.domPosition.prev).after(this.currentItem);
                  } else {
                          $(this.domPosition.parent).prepend(this.currentItem);
                  }
  
                  return true;
  
          },
  
          serialize: function(o) {
  
                  var items = this._getItemsAsjQuery(o && o.connected);
                  var str = []; o = o || {};
  
                  items.each(function() {
                          var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
                          if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
                  });
  
                  return str.join('&');
  
          },
  
          toArray: function(o) {
  
                  var items = this._getItemsAsjQuery(o && o.connected);
                  var ret = []; o = o || {};
  
                  items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
                  return ret;
  
          },
  
          /* Be careful with the following core functions */
          _intersectsWith: function(item) {
  
                  var x1 = this.positionAbs.left,
                          x2 = x1 + this.helperProportions.width,
                          y1 = this.positionAbs.top,
                          y2 = y1 + this.helperProportions.height;
  
                  var l = item.left,
                          r = l + item.width,
                          t = item.top,
                          b = t + item.height;
  
                  var dyClick = this.offset.click.top,
                          dxClick = this.offset.click.left;
  
                  var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
  
                  if(           this.options.tolerance == "pointer"
                          || this.options.forcePointerForContainers
                          || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
                  ) {
                          return isOverElement;
                  } else {
  
                          return (l < x1 + (this.helperProportions.width / 2) // Right Half
                                  && x2 - (this.helperProportions.width / 2) < r // Left Half
                                  && t < y1 + (this.helperProportions.height / 2) // Bottom Half
                                  && y2 - (this.helperProportions.height / 2) < b ); // Top Half
  
                  }
          },
  
          _intersectsWithPointer: function(item) {
  
                  var isOverElementHeight = .ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
                          isOverElementWidth = .ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
                          isOverElement = isOverElementHeight && isOverElementWidth,
                          verticalDirection = this._getDragVerticalDirection(),
                          horizontalDirection = this._getDragHorizontalDirection();
  
                  if (!isOverElement)
                          return false;
  
                  return this.floating ?
                          ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
                          : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
  
          },
  
          _intersectsWithSides: function(item) {
  
                  var isOverBottomHalf = .ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
                          isOverRightHalf = .ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
                          verticalDirection = this._getDragVerticalDirection(),
                          horizontalDirection = this._getDragHorizontalDirection();
  
                  if (this.floating && horizontalDirection) {
                          return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
                  } else {
                          return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
                  }
  
          },
  
          _getDragVerticalDirection: function() {
                  var delta = this.positionAbs.top - this.lastPositionAbs.top;
                  return delta != 0 && (delta > 0 ? "down" : "up");
          },
  
          _getDragHorizontalDirection: function() {
                  var delta = this.positionAbs.left - this.lastPositionAbs.left;
                  return delta != 0 && (delta > 0 ? "right" : "left");
          },
  
          refresh: function(event) {
                  this._refreshItems(event);
                  this.refreshPositions();
          },
  
          _getItemsAsjQuery: function(connected) {
  
                  var self = this;
                  var items = [];
                  var queries = [];
  
                  if(this.options.connectWith && connected) {
                          for (var i = this.options.connectWith.length - 1; i >= 0; i--){
                                  var cur = $(this.options.connectWith[i]);
                                  for (var j = cur.length - 1; j >= 0; j--){
                                          var inst = .data(cur[j], 'sortable');
                                          if(inst && inst != this && !inst.options.disabled) {
                                                  queries.push([.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper"), inst]);
                                          }
                                  };
                          };
                  }
  
                  queries.push([.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper"), this]);
  
                  for (var i = queries.length - 1; i >= 0; i--){
                          queries[i][0].each(function() {
                                  items.push(this);
                          });
                  };
  
                  return items;
  
          },
  
          _removeCurrentsFromItems: function() {
  
                  var list = this.currentItem.find(":data(sortable-item)");
  
                  for (var i=0; i < this.items.length; i++) {
  
                          for (var j=0; j < list.length; j++) {
                                  if(list[j] == this.items[i].item[0])
                                          this.items.splice(i,1);
                          };
  
                  };
  
          },
  
          _refreshItems: function(event) {
  
                  this.items = [];
                  this.containers = [this];
                  var items = this.items;
                  var self = this;
                  var queries = [[.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
  
                  if(this.options.connectWith) {
                          for (var i = this.options.connectWith.length - 1; i >= 0; i--){
                                  var cur = $(this.options.connectWith[i]);
                                  for (var j = cur.length - 1; j >= 0; j--){
                                          var inst = .data(cur[j], 'sortable');
                                          if(inst && inst != this && !inst.options.disabled) {
                                                  queries.push([.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
                                                  this.containers.push(inst);
                                          }
                                  };
                          };
                  }
  
                  for (var i = queries.length - 1; i >= 0; i--) {
                          var targetData = queries[i][1];
                          var _queries = queries[i][0];
  
                          for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
                                  var item = $(_queries[j]);
  
                                  item.data('sortable-item', targetData); // Data for target checking (mouse manager)
  
                                  items.push({
                                          item: item,
                                          instance: targetData,
                                          width: 0, height: 0,
                                          left: 0, top: 0
                                  });
                          };
                  };
  
          },
  
          refreshPositions: function(fast) {
  
                  //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
                  if(this.offsetParent && this.helper) {
                          this.offset.parent = this._getParentOffset();
                  }
  
                  for (var i = this.items.length - 1; i >= 0; i--){
                          var item = this.items[i];
  
                          //We ignore calculating positions of all connected containers when we're not over them
                          if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
                                  continue;
  
                          var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
  
                          if (!fast) {
                                  if (this.options.accurateIntersection) {
                                          item.width = t.outerWidth();
                                          item.height = t.outerHeight();
                                  }
                                  else {
                                          item.width = t[0].offsetWidth;
                                          item.height = t[0].offsetHeight;
                                  }
                          }
  
                          var p = t.offset();
                          item.left = p.left;
                          item.top = p.top;
                  };
  
                  if(this.options.custom && this.options.custom.refreshContainers) {
                          this.options.custom.refreshContainers.call(this);
                  } else {
                          for (var i = this.containers.length - 1; i >= 0; i--){
                                  var p = this.containers[i].element.offset();
                                  this.containers[i].containerCache.left = p.left;
                                  this.containers[i].containerCache.top = p.top;
                                  this.containers[i].containerCache.width        = this.containers[i].element.outerWidth();
                                  this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
                          };
                  }
  
          },
  
          _createPlaceholder: function(that) {
  
                  var self = that || this, o = self.options;
  
                  if(!o.placeholder || o.placeholder.constructor == String) {
                          var className = o.placeholder;
                          o.placeholder = {
                                  element: function() {
  
                                          var el = $(document.createElement(self.currentItem[0].nodeName))
                                                  .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
                                                  .removeClass('ui-sortable-helper')[0];
  
                                          if(!className) {
                                                  el.style.visibility = "hidden";
                                                  document.body.appendChild(el);
                                                  // Name attributes are removed, otherwice causes elements to be unchecked
                                                  // Expando attributes also have to be removed because of stupid IE (no condition, doesn't hurt in other browsers)
                                                  el.innerHTML = self.currentItem[0].innerHTML.replace(/name\=\"[^\"\']+\"/g, '').replace(/jQuery[0-9]+\=\"[^\"\']+\"/g, '');
                                                  document.body.removeChild(el);
                                          };
  
                                          return el;
                                  },
                                  update: function(container, p) {
                                          if(className && !o.forcePlaceholderSize) return;
                                          if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
                                          if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
                                  }
                          };
                  }
  
                  //Create the placeholder
                  self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
  
                  //Append it after the actual current item
                  self.currentItem.after(self.placeholder);
  
                  //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
                  o.placeholder.update(self, self.placeholder);
  
          },
  
          _contactContainers: function(event) {
                  for (var i = this.containers.length - 1; i >= 0; i--){
  
                          if(this._intersectsWith(this.containers[i].containerCache)) {
                                  if(!this.containers[i].containerCache.over) {
  
                                          if(this.currentContainer != this.containers[i]) {
  
                                                  //When entering a new container, we will find the item with the least distance and append our item near it
                                                  var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[i].floating ? 'left' : 'top'];
                                                  for (var j = this.items.length - 1; j >= 0; j--) {
                                                          if(!.ui.contains(this.containers[i].element[0], this.items[j].item[0])) continue;
                                                          var cur = this.items[j][this.containers[i].floating ? 'left' : 'top'];
                                                          if(Math.abs(cur - base) < dist) {
                                                                  dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
                                                          }
                                                  }
  
                                                  if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
                                                          continue;
  
                                                  this.currentContainer = this.containers[i];
                                                  itemWithLeastDistance ? this.options.sortIndicator.call(this, event, itemWithLeastDistance, null, true) : this.options.sortIndicator.call(this, event, null, this.containers[i].element, true);
                                                  this._propagate("change", event); //Call plugins and callbacks
                                                  this.containers[i]._propagate("change", event, this); //Call plugins and callbacks
  
                                                  //Update the placeholder
                                                  this.options.placeholder.update(this.currentContainer, this.placeholder);
  
                                          }
  
                                          this.containers[i]._propagate("over", event, this);
                                          this.containers[i].containerCache.over = 1;
                                  }
                          } else {
                                  if(this.containers[i].containerCache.over) {
                                          this.containers[i]._propagate("out", event, this);
                                          this.containers[i].containerCache.over = 0;
                                  }
                          }
  
                  };
          },
  
          _createHelper: function(event) {
  
                  var o = this.options;
                  var helper = .isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
  
                  if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
                          $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
  
                  if(helper[0] == this.currentItem[0])
                          this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
  
                  if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
                  if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
  
                  return helper;
  
          },
  
          _adjustOffsetFromHelper: function(obj) {
                  if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
                  if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
                  if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
                  if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
          },
  
          _getParentOffset: function() {
  
                  //Get the offsetParent and cache its position
                  this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset();
  
                  if((this.offsetParent[0] == document.body && .browser.mozilla)        //Ugly FF3 fix
                  || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && .browser.msie)) //Ugly IE fix
                          po = { top: 0, left: 0 };
  
                  return {
                          top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
                          left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
                  };
  
          },
  
          _getRelativeOffset: function() {
  
                  if(this.cssPosition == "relative") {
                          var p = this.currentItem.position();
                          return {
                                  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
                                  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
                          };
                  } else {
                          return { top: 0, left: 0 };
                  }
  
          },
  
          _cacheMargins: function() {
                  this.margins = {
                          left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
                          top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
                  };
          },
  
          _cacheHelperProportions: function() {
                  this.helperProportions = {
                          width: this.helper.outerWidth(),
                          height: this.helper.outerHeight()
                  };
          },
  
          _setContainment: function() {
  
                  var o = this.options;
                  if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
                  if(o.containment == 'document' || o.containment == 'window') this.containment = [
                          0 - this.offset.relative.left - this.offset.parent.left,
                          0 - this.offset.relative.top - this.offset.parent.top,
                          $(o.containment == 'document' ? document : window).width() - this.offset.relative.left - this.offset.parent.left - this.margins.left - (parseInt(this.currentItem.css("marginRight"),10) || 0),
                          ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.offset.relative.top - this.offset.parent.top - this.margins.top - (parseInt(this.currentItem.css("marginBottom"),10) || 0)
                  ];
  
                  if(!(/^(document|window|parent)/).test(o.containment)) {
                          var ce = $(o.containment)[0];
                          var co = $(o.containment).offset();
                          var over = (ce.css("overflow") != 'hidden');
  
                          this.containment = [
                                  co.left + (parseInt(ce.css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left,
                                  co.top + (parseInt(ce.css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top,
                                  co.left + (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt(ce.css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left,
                                  co.top + (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt(ce.css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top
                          ];
                  }
  
          },
  
          _convertPositionTo: function(d, pos) {
  
                  if(!pos) pos = this.position;
                  var mod = d == "absolute" ? 1 : -1;
                  var scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  
                  return {
                          top: (
                                  pos.top                                                                                                                                        // the calculated relative position
                                  + this.offset.relative.top        * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
                                  + this.offset.parent.top * mod                                                                                        // The offsetParent's offset without borders (offset + border)
                                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod
                                  + this.margins.top * mod                                                                                                //Add the margin (you don't want the margin counting in intersection methods)
                          ),
                          left: (
                                  pos.left                                                                                                                                // the calculated relative position
                                  + this.offset.relative.left        * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
                                  + this.offset.parent.left * mod                                                                                        // The offsetParent's offset without borders (offset + border)
                                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) * mod
                                  + this.margins.left * mod                                                                                                //Add the margin (you don't want the margin counting in intersection methods)
                          )
                  };
          },
  
          _generatePosition: function(event) {
  
                  var o = this.options, scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  
                  var position = {
                          top: (
                                  event.pageY                                                                                                                                // The absolute mouse position
                                  - this.offset.click.top                                                                                                        // Click offset (relative to the element)
                                  - this.offset.relative.top                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
                                  - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
                                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )
                          ),
                          left: (
                                  event.pageX                                                                                                                                // The absolute mouse position
                                  - this.offset.click.left                                                                                                // Click offset (relative to the element)
                                  - this.offset.relative.left                                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
                                  - this.offset.parent.left                                                                                                // The offsetParent's offset without borders (offset + border)
                                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
                          )
                  };
  
                  if(!this.originalPosition) return position;                                                                                //If we are not dragging yet, we won't check for options
  
                  /*
  		 * - Position constraining -
  		 * Constrain the position to a mix of grid, containment.
  		 */
                  if(this.containment) {
                          if(position.left < this.containment[0]) position.left = this.containment[0];
                          if(position.top < this.containment[1]) position.top = this.containment[1];
                          if(position.left + this.helperProportions.width > this.containment[2]) position.left = this.containment[2] - this.helperProportions.width;
                          if(position.top + this.helperProportions.height > this.containment[3]) position.top = this.containment[3] - this.helperProportions.height;
                  }
  
                  if(o.grid) {
                          var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1];
                          position.top = this.containment ? (!(top < this.containment[1] || top > this.containment[3]) ? top : (!(top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
  
                          var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0];
                          position.left = this.containment ? (!(left < this.containment[0] || left > this.containment[2]) ? left : (!(left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
                  }
  
                  return position;
          },
  
          _rearrange: function(event, i, a, hardRefresh) {
  
                  a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
  
                  //Various things done here to improve the performance:
                  // 1. we create a setTimeout, that calls refreshPositions
                  // 2. on the instance, we have a counter variable, that get's higher after every append
                  // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
                  // 4. this lets only the last addition to the timeout stack through
                  this.counter = this.counter ? ++this.counter : 1;
                  var self = this, counter = this.counter;
  
                  window.setTimeout(function() {
                          if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
                  },0);
  
          },
  
          _clear: function(event, noPropagation) {
  
                  this.reverting = false;
  
                  //We first have to update the dom position of the actual currentItem
                  if(!this._noFinalSort) this.placeholder.before(this.currentItem);
                  this._noFinalSort = null;
  
                  if(this.helper[0] == this.currentItem[0]) {
                          for(var i in this._storedCSS) {
                                  if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
                          }
                          this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
                  } else {
                          this.currentItem.show();
                  }
  
                  if(this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) this._propagate("update", event, null, noPropagation); //Trigger update callback if the DOM position has changed
                  if(!.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
                          this._propagate("remove", event, null, noPropagation);
                          for (var i = this.containers.length - 1; i >= 0; i--){
                                  if(.ui.contains(this.containers[i].element[0], this.currentItem[0])) {
                                          this.containers[i]._propagate("update", event, this, noPropagation);
                                          this.containers[i]._propagate("receive", event, this, noPropagation);
                                  }
                          };
                  };
  
                  //Post events to containers
                  for (var i = this.containers.length - 1; i >= 0; i--){
                          this.containers[i]._propagate("deactivate", event, this, noPropagation);
                          if(this.containers[i].containerCache.over) {
                                  this.containers[i]._propagate("out", event, this);
                                  this.containers[i].containerCache.over = 0;
                          }
                  }
  
                  this.dragging = false;
                  if(this.cancelHelperRemoval) {
                          this._propagate("beforeStop", event, null, noPropagation);
                          this._propagate("stop", event, null, noPropagation);
                          return false;
                  }
  
                  this._propagate("beforeStop", event, null, noPropagation);
  
                  //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
                  this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
  
                  if(this.options.helper != "original") this.helper.remove(); this.helper = null;
                  this._propagate("stop", event, null, noPropagation);
  
                  return true;
  
          },
  
          _propagate: function(n, event, inst, noPropagation) {
                  .ui.plugin.call(this, n, [event, this._ui(inst)]);
                  var dontCancel = !noPropagation ? this.element.triggerHandler(n == "sort" ? n : "sort"+n, [event, this._ui(inst)], this.options[n]) : true;
                  if(dontCancel === false) this.cancel();
          },
  
          plugins: {},
  
          _ui: function(inst) {
                  var self = inst || this;
                  return {
                          helper: self.helper,
                          placeholder: self.placeholder || $([]),
                          position: self.position,
                          absolutePosition: self.positionAbs,
                          item: self.currentItem,
                          sender: inst ? inst.element : null
                  };
          }
  
  }));
  
  .extend(.ui.sortable, {
          getter: "serialize toArray",
          version: "@VERSION",
          defaults: {
                  accurateIntersection: true,
                  appendTo: "parent",
                  cancel: ":input",
                  delay: 0,
                  distance: 1,
                  dropOnEmpty: true,
                  forcePlaceholderSize: false,
                  forceHelperSize: false,
                  helper: "original",
                  items: '> *',
                  scope: "default",
                  scroll: true,
                  scrollSensitivity: 20,
                  scrollSpeed: 20,
                  sortIndicator: .ui.sortable.prototype._rearrange,
                  tolerance: "default",
                  zIndex: 1000
          }
  });
  
  /*
   * Sortable Extensions
   */
  
  .ui.plugin.add("sortable", "cursor", {
          start: function(event, ui) {
                  var t = $('body'), i = this.data('sortable');
                  if (t.css("cursor")) i.options._cursor = t.css("cursor");
                  t.css("cursor", i.options.cursor);
          },
          beforeStop: function(event, ui) {
                  var i = this.data('sortable');
                  if (i.options._cursor) $('body').css("cursor", i.options._cursor);
          }
  });
  
  .ui.plugin.add("sortable", "opacity", {
          start: function(event, ui) {
                  var t = ui.helper, i = this.data('sortable');
                  if(t.css("opacity")) i.options._opacity = t.css("opacity");
                  t.css('opacity', i.options.opacity);
          },
          beforeStop: function(event, ui) {
                  var i = this.data('sortable');
                  if(i.options._opacity) $(ui.helper).css('opacity', i.options._opacity);
          }
  });
  
  .ui.plugin.add("sortable", "scroll", {
          start: function(event, ui) {
                  var i = this.data("sortable"), o = i.options;
                  if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
          },
          sort: function(event, ui) {
  
                  var i = this.data("sortable"), o = i.options, scrolled = false;
  
                  if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
  
                          if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
                                  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
                          else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
                                  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
  
                          if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
                                  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
                          else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
                                  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
  
                  } else {
  
                          if(event.pageY - document.scrollTop() < o.scrollSensitivity)
                                  scrolled = document.scrollTop(document.scrollTop() - o.scrollSpeed);
                          else if(window.height() - (event.pageY - document.scrollTop()) < o.scrollSensitivity)
                                  scrolled = document.scrollTop(document.scrollTop() + o.scrollSpeed);
  
                          if(event.pageX - document.scrollLeft() < o.scrollSensitivity)
                                  scrolled = document.scrollLeft(document.scrollLeft() - o.scrollSpeed);
                          else if(window.width() - (event.pageX - document.scrollLeft()) < o.scrollSensitivity)
                                  scrolled = document.scrollLeft(document.scrollLeft() + o.scrollSpeed);
  
                  }
  
                  if(scrolled !== false && .ui.ddmanager && !o.dropBehaviour)
                          .ui.ddmanager.prepareOffsets(i, event);
  
                  //This is a special case where we need to modify a offset calculated on start, since the following happened:
                  // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
                  // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
                  //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
                  if(scrolled !== false && i.cssPosition == 'absolute' && i.scrollParent[0] != document && .ui.contains(i.scrollParent[0], i.offsetParent[0])) {
                          i.offset.parent = i._getParentOffset();
                  }
                  
                  // This is another very weird special case that only happens for relative elements:
                  // 1. If the css position is relative
                  // 2. and the scroll parent is the document or similar to the offset parent
                  // we have to refresh the relative offset during the scroll so there are no jumps
                  if(scrolled !== false && i.cssPosition == 'relative' && !(i.scrollParent[0] != document && i.scrollParent[0] != i.offsetParent[0])) {
                          i.offset.relative = i._getRelativeOffset();
                  }
  
          }
  });
  
  .ui.plugin.add("sortable", "zIndex", {
          start: function(event, ui) {
                  var t = ui.helper, i = this.data('sortable');
                  if(t.css("zIndex")) i.options._zIndex = t.css("zIndex");
                  t.css('zIndex', i.options.zIndex);
          },
          beforeStop: function(event, ui) {
                  var i = this.data('sortable');
                  if(i.options._zIndex) $(ui.helper).css('zIndex', i.options._zIndex == 'auto' ? '' : i.options._zIndex);
          }
  });
  
  })(jQuery);
  
  .extend(.ui.dialog, {
          version: "@VERSION",
          defaults: {
                  autoOpen: true,
                  bgiframe: false,
                  buttons: {},
                  closeOnEscape: true,
                  closeText: 'close',
                  draggable: true,
                  height: 'auto',
                  minHeight: 150,
                  minWidth: 150,
                  modal: false,
                  overlay: {},
                  position: 'center',
                  resizable: true,
                  stack: true,
                  width: 300,
                  zIndex: 1000
          },
  
          getter: 'isOpen',
  
          uuid: 0,
  
          getTitleId: function(el) {
                  return 'ui-dialog-title-' + (el.attr('id') || ++this.uuid);
          },
  
          overlay: function(dialog) {
                  this.el = .ui.dialog.overlay.create(dialog);
          }
  });
  
  .extend(.ui.dialog.overlay, {
          instances: [],
          events: .map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
                  function(event) { return event + '.dialog-overlay'; }).join(' '),
          create: function(dialog) {
                  if (this.instances.length === 0) {
                          // prevent use of anchors and inputs
                          // we use a setTimeout in case the overlay is created from an
                          // event that we're going to be cancelling (see #2804)
                          setTimeout(function() {
                                  $('a, :input').bind(.ui.dialog.overlay.events, function() {
                                          // allow use of the element if inside a dialog and
                                          // - there are no modal dialogs
                                          // - there are modal dialogs, but we are in front of the topmost modal
                                          var allow = false;
                                          var dialog = this.parents('.ui-dialog');
                                          if (dialog.length) {
                                                  var overlays = $('.ui-dialog-overlay');
                                                  if (overlays.length) {
                                                          var maxZ = parseInt(overlays.css('z-index'), 10);
                                                          overlays.each(function() {
                                                                  maxZ = Math.max(maxZ, parseInt(this.css('z-index'), 10));
                                                          });
                                                          allow = parseInt(dialog.css('z-index'), 10) > maxZ;
                                                  } else {
                                                          allow = true;
                                                  }
                                          }
                                          return allow;
                                  });
                          }, 1);
  
                          // allow closing by pressing the escape key
                          document.bind('keydown.dialog-overlay', function(event) {
                                  (dialog.options.closeOnEscape && event.keyCode
                                                  && event.keyCode == .ui.keyCode.ESCAPE && dialog.close());
                          });
  
                          // handle window resize
                          window.bind('resize.dialog-overlay', .ui.dialog.overlay.resize);
                  }
  
                  var el = $('<div></div>').appendTo(document.body)
                          .addClass('ui-dialog-overlay').css(.extend({
                                  borderWidth: 0, margin: 0, padding: 0,
                                  position: 'absolute', top: 0, left: 0,
                                  width: this.width(),
                                  height: this.height()
                          }, dialog.options.overlay));
  
                  (dialog.options.bgiframe && .fn.bgiframe && el.bgiframe());
  
                  this.instances.push(el);
                  return el;
          },
  
          destroy: function(el) {
                  this.instances.splice(.inArray(this.instances, el), 1);
  
                  if (this.instances.length === 0) {
                          $('a, :input').add([document, window]).unbind('.dialog-overlay');
                  }
  
                  el.remove();
          },
  
          height: function() {
                  // handle IE 6
                  if (.browser.msie && .browser.version < 7) {
                          var scrollHeight = Math.max(
                                  document.documentElement.scrollHeight,
                                  document.body.scrollHeight
                          );
                          var offsetHeight = Math.max(
                                  document.documentElement.offsetHeight,
                                  document.body.offsetHeight
                          );
  
                          if (scrollHeight < offsetHeight) {
                                  return window.height() + 'px';
                          } else {
                                  return scrollHeight + 'px';
                          }
                  // handle Opera
                  } else if (.browser.opera) {
                          return Math.max(
                                  window.innerHeight,
                                  document.height()
                          ) + 'px';
                  // handle "good" browsers
                  } else {
                          return document.height() + 'px';
                  }
          },
  
          width: function() {
                  // handle IE 6
                  if (.browser.msie && .browser.version < 7) {
                          var scrollWidth = Math.max(
                                  document.documentElement.scrollWidth,
                                  document.body.scrollWidth
                          );
                          var offsetWidth = Math.max(
                                  document.documentElement.offsetWidth,
                                  document.body.offsetWidth
                          );
  
                          if (scrollWidth < offsetWidth) {
                                  return window.width() + 'px';
                          } else {
                                  return scrollWidth + 'px';
                          }
                  // handle Opera
                  } else if (.browser.opera) {
                          return Math.max(
                                  window.innerWidth,
                                  document.width()
                          ) + 'px';
                  // handle "good" browsers
                  } else {
                          return document.width() + 'px';
                  }
          },
  
          resize: function() {
                  /* If the dialog is draggable and the user drags it past the
  		 * right edge of the window, the document becomes wider so we
  		 * need to stretch the overlay. If the user then drags the
  		 * dialog back to the left, the document will become narrower,
  		 * so we need to shrink the overlay to the appropriate size.
  		 * This is handled by shrinking the overlay before setting it
  		 * to the full document size.
  		 */
                  var overlays = $([]);
                  .each(.ui.dialog.overlay.instances, function() {
                          overlays = overlays.add(this);
                  });
  
                  overlays.css({
                          width: 0,
                          height: 0
                  }).css({
                          width: .ui.dialog.overlay.width(),
                          height: .ui.dialog.overlay.height()
                  });
          }
  });
  
  .extend(.ui.dialog.overlay.prototype, {
          destroy: function() {
                  .ui.dialog.overlay.destroy(this.el);
          }
  });
  
  })(jQuery);
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.