[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/jquery_ui/jquery.ui.old/ui/ -> jquery.ui.all.js (source)

   1  /*

   2   * jQuery UI 1.6

   3   *

   4   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

   5   * Dual licensed under the MIT (MIT-LICENSE.txt)

   6   * and GPL (GPL-LICENSE.txt) licenses.

   7   *

   8   * http://docs.jquery.com/UI

   9   */
  10  ;(function($) {
  11  
  12  var _remove = $.fn.remove,
  13      isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
  14  
  15  //Helper functions and ui object

  16  $.ui = {
  17  
  18      version: "1.6",
  19  
  20      // $.ui.plugin is deprecated.  Use the proxy pattern instead.

  21      plugin: {
  22          add: function(module, option, set) {
  23              var proto = $.ui[module].prototype;
  24              for(var i in set) {
  25                  proto.plugins[i] = proto.plugins[i] || [];
  26                  proto.plugins[i].push([option, set[i]]);
  27              }
  28          },
  29          call: function(instance, name, args) {
  30              var set = instance.plugins[name];
  31              if(!set) { return; }
  32  
  33              for (var i = 0; i < set.length; i++) {
  34                  if (instance.options[set[i][0]]) {
  35                      set[i][1].apply(instance.element, args);
  36                  }
  37              }
  38          }
  39      },
  40  
  41      contains: function(a, b) {
  42          var safari2 = $.browser.safari && $.browser.version < 522;
  43          if (a.contains && !safari2) {
  44              return a.contains(b);
  45          }
  46          if (a.compareDocumentPosition)
  47              return !!(a.compareDocumentPosition(b) & 16);
  48          while (b = b.parentNode)
  49                if (b == a) return true;
  50          return false;
  51      },
  52  
  53      cssCache: {},
  54      css: function(name) {
  55          if ($.ui.cssCache[name]) { return $.ui.cssCache[name]; }
  56          var tmp = $('<div class="ui-gen">').addClass(name).css({position:'absolute', top:'-5000px', left:'-5000px', display:'block'}).appendTo('body');
  57  
  58          //if (!$.browser.safari)

  59              //tmp.appendTo('body');

  60  
  61          //Opera and Safari set width and height to 0px instead of auto

  62          //Safari returns rgba(0,0,0,0) when bgcolor is not set

  63          $.ui.cssCache[name] = !!(
  64              (!(/auto|default/).test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) ||
  65              !(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor')))
  66          );
  67          try { $('body').get(0).removeChild(tmp.get(0));    } catch(e){}
  68          return $.ui.cssCache[name];
  69      },
  70  
  71      hasScroll: function(el, a) {
  72  
  73          //If overflow is hidden, the element might have extra content, but the user wants to hide it

  74          if ($(el).css('overflow') == 'hidden') { return false; }
  75  
  76          var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
  77              has = false;
  78  
  79          if (el[scroll] > 0) { return true; }
  80  
  81          // TODO: determine which cases actually cause this to happen

  82          // if the element doesn't have the scroll set, see if it's possible to

  83          // set the scroll

  84          el[scroll] = 1;
  85          has = (el[scroll] > 0);
  86          el[scroll] = 0;
  87          return has;
  88      },
  89  
  90      isOverAxis: function(x, reference, size) {
  91          //Determines when x coordinate is over "b" element axis

  92          return (x > reference) && (x < (reference + size));
  93      },
  94  
  95      isOver: function(y, x, top, left, height, width) {
  96          //Determines when x, y coordinates is over "b" element

  97          return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
  98      },
  99  
 100      keyCode: {
 101          BACKSPACE: 8,
 102          CAPS_LOCK: 20,
 103          COMMA: 188,
 104          CONTROL: 17,
 105          DELETE: 46,
 106          DOWN: 40,
 107          END: 35,
 108          ENTER: 13,
 109          ESCAPE: 27,
 110          HOME: 36,
 111          INSERT: 45,
 112          LEFT: 37,
 113          NUMPAD_ADD: 107,
 114          NUMPAD_DECIMAL: 110,
 115          NUMPAD_DIVIDE: 111,
 116          NUMPAD_ENTER: 108,
 117          NUMPAD_MULTIPLY: 106,
 118          NUMPAD_SUBTRACT: 109,
 119          PAGE_DOWN: 34,
 120          PAGE_UP: 33,
 121          PERIOD: 190,
 122          RIGHT: 39,
 123          SHIFT: 16,
 124          SPACE: 32,
 125          TAB: 9,
 126          UP: 38
 127      }
 128  
 129  };
 130  
 131  // WAI-ARIA normalization

 132  if (isFF2) {
 133      var attr = $.attr,
 134          removeAttr = $.fn.removeAttr,
 135          ariaNS = "http://www.w3.org/2005/07/aaa",
 136          ariaState = /^aria-/,
 137          ariaRole = /^wairole:/;
 138  
 139      $.attr = function(elem, name, value) {
 140          var set = value !== undefined;
 141  
 142          return (name == 'role'
 143              ? (set
 144                  ? attr.call(this, elem, name, "wairole:" + value)
 145                  : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
 146              : (ariaState.test(name)
 147                  ? (set
 148                      ? elem.setAttributeNS(ariaNS,
 149                          name.replace(ariaState, "aaa:"), value)
 150                      : attr.call(this, elem, name.replace(ariaState, "aaa:")))
 151                  : attr.apply(this, arguments)));
 152      };
 153  
 154      $.fn.removeAttr = function(name) {
 155          return (ariaState.test(name)
 156              ? this.each(function() {
 157                  this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
 158              }) : removeAttr.call(this, name));
 159      };
 160  }
 161  
 162  //jQuery plugins

 163  $.fn.extend({
 164  
 165      remove: function() {
 166          // Safari has a native remove event which actually removes DOM elements,

 167          // so we have to use triggerHandler instead of trigger (#3037).

 168          $("*", this).add(this).each(function() {
 169              $(this).triggerHandler("remove");
 170          });
 171          return _remove.apply(this, arguments );
 172      },
 173  
 174      enableSelection: function() {
 175          return this
 176              .attr('unselectable', 'off')
 177              .css('MozUserSelect', '')
 178              .unbind('selectstart.ui');
 179      },
 180  
 181      disableSelection: function() {
 182          return this
 183              .attr('unselectable', 'on')
 184              .css('MozUserSelect', 'none')
 185              .bind('selectstart.ui', function() { return false; });
 186      },
 187  
 188      scrollParent: function() {
 189  
 190          var scrollParent;
 191          if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
 192              scrollParent = this.parents().filter(function() {
 193                  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));
 194              }).eq(0);
 195          } else {
 196              scrollParent = this.parents().filter(function() {
 197                  return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
 198              }).eq(0);
 199          }
 200  
 201          return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
 202  
 203  
 204      }
 205  
 206  });
 207  
 208  
 209  //Additional selectors

 210  $.extend($.expr[':'], {
 211  
 212      data: function(a, i, m) {
 213          return $.data(a, m[3]);
 214      },
 215  
 216      // TODO: add support for object, area

 217      tabbable: function(a, i, m) {
 218  
 219          var nodeName = a.nodeName.toLowerCase();
 220  		function isVisible(element) {
 221              return !($(element).is(':hidden') || $(element).parents(':hidden').length);
 222          }
 223  
 224          return (
 225              // in tab order

 226              a.tabIndex >= 0 &&
 227  
 228              ( // filter node types that participate in the tab order
 229  
 230                  // anchor tag

 231                  ('a' == nodeName && a.href) ||
 232  
 233                  // enabled form element

 234                  (/input|select|textarea|button/.test(nodeName) &&
 235                      'hidden' != a.type && !a.disabled)
 236              ) &&
 237  
 238              // visible on page

 239              isVisible(a)
 240          );
 241  
 242      }
 243  
 244  });
 245  
 246  
 247  // $.widget is a factory to create jQuery plugins

 248  // taking some boilerplate code out of the plugin code

 249  function getter(namespace, plugin, method, args) {
 250  	function getMethods(type) {
 251          var methods = $[namespace][plugin][type] || [];
 252          return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
 253      }
 254  
 255      var methods = getMethods('getter');
 256      if (args.length == 1 && typeof args[0] == 'string') {
 257          methods = methods.concat(getMethods('getterSetter'));
 258      }
 259      return ($.inArray(method, methods) != -1);
 260  }
 261  
 262  $.widget = function(name, prototype) {
 263      var namespace = name.split(".")[0];
 264      name = name.split(".")[1];
 265  
 266      // create plugin method

 267      $.fn[name] = function(options) {
 268          var isMethodCall = (typeof options == 'string'),
 269              args = Array.prototype.slice.call(arguments, 1);
 270  
 271          // prevent calls to internal methods

 272          if (isMethodCall && options.substring(0, 1) == '_') {
 273              return this;
 274          }
 275  
 276          // handle getter methods

 277          if (isMethodCall && getter(namespace, name, options, args)) {
 278              var instance = $.data(this[0], name);
 279              return (instance ? instance[options].apply(instance, args)
 280                  : undefined);
 281          }
 282  
 283          // handle initialization and non-getter methods

 284          return this.each(function() {
 285              var instance = $.data(this, name);
 286  
 287              // constructor

 288              (!instance && !isMethodCall &&
 289                  $.data(this, name, new $[namespace][name](this, options)));
 290  
 291              // method call

 292              (instance && isMethodCall && $.isFunction(instance[options]) &&
 293                  instance[options].apply(instance, args));
 294          });
 295      };
 296  
 297      // create widget constructor

 298      $[namespace] = $[namespace] || {};
 299      $[namespace][name] = function(element, options) {
 300          var self = this;
 301  
 302          this.widgetName = name;
 303          this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
 304          this.widgetBaseClass = namespace + '-' + name;
 305  
 306          this.options = $.extend({},
 307              $.widget.defaults,
 308              $[namespace][name].defaults,
 309              $.metadata && $.metadata.get(element)[name],
 310              options);
 311  
 312          this.element = $(element)
 313              .bind('setData.' + name, function(event, key, value) {
 314                  return self._setData(key, value);
 315              })
 316              .bind('getData.' + name, function(event, key) {
 317                  return self._getData(key);
 318              })
 319              .bind('remove', function() {
 320                  return self.destroy();
 321              });
 322  
 323          this._init();
 324      };
 325  
 326      // add widget prototype

 327      $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
 328  
 329      // TODO: merge getter and getterSetter properties from widget prototype

 330      // and plugin prototype

 331      $[namespace][name].getterSetter = 'option';
 332  };
 333  
 334  $.widget.prototype = {
 335      _init: function() {},
 336      destroy: function() {
 337          this.element.removeData(this.widgetName);
 338      },
 339  
 340      option: function(key, value) {
 341          var options = key,
 342              self = this;
 343  
 344          if (typeof key == "string") {
 345              if (value === undefined) {
 346                  return this._getData(key);
 347              }
 348              options = {};
 349              options[key] = value;
 350          }
 351  
 352          $.each(options, function(key, value) {
 353              self._setData(key, value);
 354          });
 355      },
 356      _getData: function(key) {
 357          return this.options[key];
 358      },
 359      _setData: function(key, value) {
 360          this.options[key] = value;
 361  
 362          if (key == 'disabled') {
 363              this.element[value ? 'addClass' : 'removeClass'](
 364                  this.widgetBaseClass + '-disabled');
 365          }
 366      },
 367  
 368      enable: function() {
 369          this._setData('disabled', false);
 370      },
 371      disable: function() {
 372          this._setData('disabled', true);
 373      },
 374  
 375      _trigger: function(type, event, data) {
 376          var eventName = (type == this.widgetEventPrefix
 377              ? type : this.widgetEventPrefix + type);
 378          event = event || $.event.fix({ type: eventName, target: this.element[0] });
 379          return this.element.triggerHandler(eventName, [event, data], this.options[type]);
 380      }
 381  };
 382  
 383  $.widget.defaults = {
 384      disabled: false
 385  };
 386  
 387  
 388  /** Mouse Interaction Plugin **/

 389  
 390  $.ui.mouse = {
 391      _mouseInit: function() {
 392          var self = this;
 393  
 394          this.element
 395              .bind('mousedown.'+this.widgetName, function(event) {
 396                  return self._mouseDown(event);
 397              })
 398              .bind('click.'+this.widgetName, function(event) {
 399                  if(self._preventClickEvent) {
 400                      self._preventClickEvent = false;
 401                      return false;
 402                  }
 403              });
 404  
 405          // Prevent text selection in IE

 406          if ($.browser.msie) {
 407              this._mouseUnselectable = this.element.attr('unselectable');
 408              this.element.attr('unselectable', 'on');
 409          }
 410  
 411          this.started = false;
 412      },
 413  
 414      // TODO: make sure destroying one instance of mouse doesn't mess with

 415      // other instances of mouse

 416      _mouseDestroy: function() {
 417          this.element.unbind('.'+this.widgetName);
 418  
 419          // Restore text selection in IE

 420          ($.browser.msie
 421              && this.element.attr('unselectable', this._mouseUnselectable));
 422      },
 423  
 424      _mouseDown: function(event) {
 425          // we may have missed mouseup (out of window)

 426          (this._mouseStarted && this._mouseUp(event));
 427  
 428          this._mouseDownEvent = event;
 429  
 430          var self = this,
 431              btnIsLeft = (event.which == 1),
 432              elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
 433          if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
 434              return true;
 435          }
 436  
 437          this.mouseDelayMet = !this.options.delay;
 438          if (!this.mouseDelayMet) {
 439              this._mouseDelayTimer = setTimeout(function() {
 440                  self.mouseDelayMet = true;
 441              }, this.options.delay);
 442          }
 443  
 444          if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 445              this._mouseStarted = (this._mouseStart(event) !== false);
 446              if (!this._mouseStarted) {
 447                  event.preventDefault();
 448                  return true;
 449              }
 450          }
 451  
 452          // these delegates are required to keep context

 453          this._mouseMoveDelegate = function(event) {
 454              return self._mouseMove(event);
 455          };
 456          this._mouseUpDelegate = function(event) {
 457              return self._mouseUp(event);
 458          };
 459          $(document)
 460              .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
 461              .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
 462  
 463          // preventDefault() is used to prevent the selection of text here -

 464          // however, in Safari, this causes select boxes not to be selectable

 465          // anymore, so this fix is needed

 466          if(!$.browser.safari) event.preventDefault();
 467          return true;
 468      },
 469  
 470      _mouseMove: function(event) {
 471          // IE mouseup check - mouseup happened when mouse was out of window

 472          if ($.browser.msie && !event.button) {
 473              return this._mouseUp(event);
 474          }
 475  
 476          if (this._mouseStarted) {
 477              this._mouseDrag(event);
 478              return event.preventDefault();
 479          }
 480  
 481          if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 482              this._mouseStarted =
 483                  (this._mouseStart(this._mouseDownEvent, event) !== false);
 484              (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
 485          }
 486  
 487          return !this._mouseStarted;
 488      },
 489  
 490      _mouseUp: function(event) {
 491          $(document)
 492              .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
 493              .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
 494  
 495          if (this._mouseStarted) {
 496              this._mouseStarted = false;
 497              this._preventClickEvent = true;
 498              this._mouseStop(event);
 499          }
 500  
 501          return false;
 502      },
 503  
 504      _mouseDistanceMet: function(event) {
 505          return (Math.max(
 506                  Math.abs(this._mouseDownEvent.pageX - event.pageX),
 507                  Math.abs(this._mouseDownEvent.pageY - event.pageY)
 508              ) >= this.options.distance
 509          );
 510      },
 511  
 512      _mouseDelayMet: function(event) {
 513          return this.mouseDelayMet;
 514      },
 515  
 516      // These are placeholder methods, to be overriden by extending plugin

 517      _mouseStart: function(event) {},
 518      _mouseDrag: function(event) {},
 519      _mouseStop: function(event) {},
 520      _mouseCapture: function(event) { return true; }
 521  };
 522  
 523  $.ui.mouse.defaults = {
 524      cancel: null,
 525      distance: 1,
 526      delay: 0
 527  };
 528  
 529  })(jQuery);
 530  /*

 531   * jQuery UI Draggable 1.6

 532   *

 533   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

 534   * Dual licensed under the MIT (MIT-LICENSE.txt)

 535   * and GPL (GPL-LICENSE.txt) licenses.

 536   *

 537   * http://docs.jquery.com/UI/Draggables

 538   *

 539   * Depends:

 540   *    ui.core.js

 541   */
 542  (function($) {
 543  
 544  $.widget("ui.draggable", $.extend({}, $.ui.mouse, {
 545  
 546      _init: function() {
 547  
 548          if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
 549              this.element[0].style.position = 'relative';
 550  
 551          (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-draggable"));
 552          (this.options.disabled && this.element.addClass('ui-draggable-disabled'));
 553  
 554          this._mouseInit();
 555  
 556      },
 557  
 558      destroy: function() {
 559          if(!this.element.data('draggable')) return;
 560          this.element.removeData("draggable").unbind(".draggable").removeClass('ui-draggable ui-draggable-dragging ui-draggable-disabled');
 561          this._mouseDestroy();
 562      },
 563  
 564      _mouseCapture: function(event) {
 565  
 566          var o = this.options;
 567  
 568          if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
 569              return false;
 570  
 571          //Quit if we're not on a valid handle

 572          this.handle = this._getHandle(event);
 573          if (!this.handle)
 574              return false;
 575  
 576          return true;
 577  
 578      },
 579  
 580      _mouseStart: function(event) {
 581  
 582          var o = this.options;
 583  
 584          //Create and append the visible helper

 585          this.helper = this._createHelper(event);
 586  
 587          //Cache the helper size

 588          this._cacheHelperProportions();
 589  
 590          //If ddmanager is used for droppables, set the global draggable

 591          if($.ui.ddmanager)
 592              $.ui.ddmanager.current = this;
 593  
 594          /*

 595           * - Position generation -

 596           * This block generates everything position related - it's the core of draggables.

 597           */
 598  
 599          //Cache the margins of the original element

 600          this._cacheMargins();
 601  
 602          //Store the helper's css position

 603          this.cssPosition = this.helper.css("position");
 604          this.scrollParent = this.helper.scrollParent();
 605  
 606          //The element's absolute position on the page minus margins

 607          this.offset = this.element.offset();
 608          this.offset = {
 609              top: this.offset.top - this.margins.top,
 610              left: this.offset.left - this.margins.left
 611          };
 612  
 613          $.extend(this.offset, {
 614              click: { //Where the click happened, relative to the element
 615                  left: event.pageX - this.offset.left,
 616                  top: event.pageY - this.offset.top
 617              },
 618              parent: this._getParentOffset(),
 619              relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
 620          });
 621  
 622          //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied

 623          if(o.cursorAt)
 624              this._adjustOffsetFromHelper(o.cursorAt);
 625  
 626          //Generate the original position

 627          this.originalPosition = this._generatePosition(event);
 628  
 629          //Set a containment if given in the options

 630          if(o.containment)
 631              this._setContainment();
 632  
 633          //Call plugins and callbacks

 634          this._propagate("start", event);
 635  
 636          //Recache the helper size

 637          this._cacheHelperProportions();
 638  
 639          //Prepare the droppable offsets

 640          if ($.ui.ddmanager && !o.dropBehaviour)
 641              $.ui.ddmanager.prepareOffsets(this, event);
 642  
 643          this.helper.addClass("ui-draggable-dragging");
 644          this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position

 645          return true;
 646      },
 647  
 648      _mouseDrag: function(event, noPropagation) {
 649  
 650          //Compute the helpers position

 651          this.position = this._generatePosition(event);
 652          this.positionAbs = this._convertPositionTo("absolute");
 653  
 654          //Call plugins and callbacks and use the resulting position if something is returned

 655          if(!noPropagation) this.position = this._propagate("drag", event) || this.position;
 656  
 657          if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
 658          if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
 659          if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
 660  
 661          return false;
 662      },
 663  
 664      _mouseStop: function(event) {
 665  
 666          //If we are using droppables, inform the manager about the drop

 667          var dropped = false;
 668          if ($.ui.ddmanager && !this.options.dropBehaviour)
 669              var dropped = $.ui.ddmanager.drop(this, event);
 670  
 671          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))) {
 672              var self = this;
 673              $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
 674                  self._propagate("stop", event);
 675                  self._clear();
 676              });
 677          } else {
 678              this._propagate("stop", event);
 679              this._clear();
 680          }
 681  
 682          return false;
 683      },
 684  
 685      _getHandle: function(event) {
 686  
 687          var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
 688          $(this.options.handle, this.element)
 689              .find("*")
 690              .andSelf()
 691              .each(function() {
 692                  if(this == event.target) handle = true;
 693              });
 694  
 695          return handle;
 696  
 697      },
 698  
 699      _createHelper: function(event) {
 700  
 701          var o = this.options;
 702          var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
 703  
 704          if(!helper.parents('body').length)
 705              helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
 706  
 707          if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
 708              helper.css("position", "absolute");
 709  
 710          return helper;
 711  
 712      },
 713  
 714      _adjustOffsetFromHelper: function(obj) {
 715          if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
 716          if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
 717          if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
 718          if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
 719      },
 720  
 721      _getParentOffset: function() {
 722  
 723          this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset();            //Get the offsetParent and cache its position

 724  
 725          if((this.offsetParent[0] == document.body && $.browser.mozilla)    //Ugly FF3 fix
 726          || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
 727              po = { top: 0, left: 0 };
 728  
 729          return {
 730              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
 731              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
 732          };
 733  
 734      },
 735  
 736      _getRelativeOffset: function() {
 737  
 738          if(this.cssPosition == "relative") {
 739              var p = this.element.position();
 740              return {
 741                  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
 742                  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
 743              };
 744          } else {
 745              return { top: 0, left: 0 };
 746          }
 747  
 748      },
 749  
 750      _cacheMargins: function() {
 751          this.margins = {
 752              left: (parseInt(this.element.css("marginLeft"),10) || 0),
 753              top: (parseInt(this.element.css("marginTop"),10) || 0)
 754          };
 755      },
 756  
 757      _cacheHelperProportions: function() {
 758          this.helperProportions = {
 759              width: this.helper.outerWidth(),
 760              height: this.helper.outerHeight()
 761          };
 762      },
 763  
 764      _setContainment: function() {
 765  
 766          var o = this.options;
 767          if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
 768          if(o.containment == 'document' || o.containment == 'window') this.containment = [
 769              0 - this.offset.relative.left - this.offset.parent.left,
 770              0 - this.offset.relative.top - this.offset.parent.top,
 771              $(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),
 772              ($(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)
 773          ];
 774  
 775          if(!(/^(document|window|parent)$/).test(o.containment)) {
 776              var ce = $(o.containment)[0];
 777              var co = $(o.containment).offset();
 778              var over = ($(ce).css("overflow") != 'hidden');
 779  
 780              this.containment = [
 781                  co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left,
 782                  co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top,
 783                  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,
 784                  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
 785              ];
 786          }
 787  
 788      },
 789  
 790      _convertPositionTo: function(d, pos) {
 791  
 792          if(!pos) pos = this.position;
 793          var mod = d == "absolute" ? 1 : -1;
 794          var scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
 795  
 796          return {
 797              top: (
 798                  pos.top                                                                    // the calculated relative position
 799                  + this.offset.relative.top    * mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
 800                  + this.offset.parent.top * mod                                            // The offsetParent's offset without borders (offset + border)
 801                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod
 802                  + this.margins.top * mod                                                //Add the margin (you don't want the margin counting in intersection methods)
 803              ),
 804              left: (
 805                  pos.left                                                                // the calculated relative position
 806                  + this.offset.relative.left    * mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
 807                  + this.offset.parent.left * mod                                            // The offsetParent's offset without borders (offset + border)
 808                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) * mod
 809                  + this.margins.left * mod                                                //Add the margin (you don't want the margin counting in intersection methods)
 810              )
 811          };
 812      },
 813  
 814      _generatePosition: function(event) {
 815  
 816          var o = this.options, scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
 817  
 818          var position = {
 819              top: (
 820                  event.pageY                                                                // The absolute mouse position
 821                  - this.offset.click.top                                                    // Click offset (relative to the element)
 822                  - this.offset.relative.top                                                // Only for relative positioned nodes: Relative offset from element to offset parent
 823                  - this.offset.parent.top                                                // The offsetParent's offset without borders (offset + border)
 824                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )
 825              ),
 826              left: (
 827                  event.pageX                                                                // The absolute mouse position
 828                  - this.offset.click.left                                                // Click offset (relative to the element)
 829                  - this.offset.relative.left                                                // Only for relative positioned nodes: Relative offset from element to offset parent
 830                  - this.offset.parent.left                                                // The offsetParent's offset without borders (offset + border)
 831                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )
 832              )
 833          };
 834  
 835          if(!this.originalPosition) return position;                                        //If we are not dragging yet, we won't check for options

 836  
 837          /*

 838           * - Position constraining -

 839           * Constrain the position to a mix of grid, containment.

 840           */
 841          if(this.containment) {
 842              if(position.left < this.containment[0]) position.left = this.containment[0];
 843              if(position.top < this.containment[1]) position.top = this.containment[1];
 844              if(position.left > this.containment[2]) position.left = this.containment[2];
 845              if(position.top > this.containment[3]) position.top = this.containment[3];
 846          }
 847  
 848          if(o.grid) {
 849              var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1];
 850              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;
 851  
 852              var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0];
 853              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;
 854          }
 855  
 856          return position;
 857      },
 858  
 859      _clear: function() {
 860          this.helper.removeClass("ui-draggable-dragging");
 861          if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
 862          //if($.ui.ddmanager) $.ui.ddmanager.current = null;

 863          this.helper = null;
 864          this.cancelHelperRemoval = false;
 865      },
 866  
 867      // From now on bulk stuff - mainly helpers

 868  
 869      _propagate: function(n, event) {
 870          $.ui.plugin.call(this, n, [event, this._uiHash()]);
 871          if(n == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins

 872          return this.element.triggerHandler(n == "drag" ? n : "drag"+n, [event, this._uiHash()], this.options[n]);
 873      },
 874  
 875      plugins: {},
 876  
 877      _uiHash: function(event) {
 878          return {
 879              helper: this.helper,
 880              position: this.position,
 881              absolutePosition: this.positionAbs,
 882              options: this.options
 883          };
 884      }
 885  
 886  }));
 887  
 888  $.extend($.ui.draggable, {
 889      version: "1.6",
 890      defaults: {
 891          appendTo: "parent",
 892          axis: false,
 893          cancel: ":input",
 894          connectToSortable: false,
 895          containment: false,
 896          cssNamespace: "ui",
 897          cursor: "default",
 898          cursorAt: null,
 899          delay: 0,
 900          distance: 1,
 901          grid: false,
 902          handle: false,
 903          helper: "original",
 904          iframeFix: false,
 905          opacity: 1,
 906          refreshPositions: false,
 907          revert: false,
 908          revertDuration: 500,
 909          scope: "default",
 910          scroll: true,
 911          scrollSensitivity: 20,
 912          scrollSpeed: 20,
 913          snap: false,
 914          snapMode: "both",
 915          snapTolerance: 20,
 916          stack: false,
 917          zIndex: null
 918      }
 919  });
 920  
 921  $.ui.plugin.add("draggable", "connectToSortable", {
 922      start: function(event, ui) {
 923  
 924          var inst = $(this).data("draggable");
 925          inst.sortables = [];
 926          $(ui.options.connectToSortable).each(function() {
 927              // '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,

 928              // so we have to append '' to make it anonymous again

 929              $(this+'').each(function() {
 930                  if($.data(this, 'sortable')) {
 931                      var sortable = $.data(this, 'sortable');
 932                      inst.sortables.push({
 933                          instance: sortable,
 934                          shouldRevert: sortable.options.revert
 935                      });
 936                      sortable._refreshItems();    //Do a one-time refresh at start to refresh the containerCache

 937                      sortable._propagate("activate", event, inst);
 938                  }
 939              });
 940          });
 941  
 942      },
 943      stop: function(event, ui) {
 944  
 945          //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper

 946          var inst = $(this).data("draggable");
 947  
 948          $.each(inst.sortables, function() {
 949              if(this.instance.isOver) {
 950                  this.instance.isOver = 0;
 951                  inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance

 952                  this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)

 953                  if(this.shouldRevert) this.instance.options.revert = true; //revert here

 954                  this.instance._mouseStop(event);
 955  
 956                  //Also propagate receive event, since the sortable is actually receiving a element

 957                  this.instance.element.triggerHandler("sortreceive", [event, $.extend(this.instance._ui(), { sender: inst.element })], this.instance.options["receive"]);
 958  
 959                  this.instance.options.helper = this.instance.options._helper;
 960                  
 961                  if(inst.options.helper == 'original') {
 962                      this.instance.currentItem.css({ top: 'auto', left: 'auto' });
 963                  }
 964  
 965              } else {
 966                  this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance

 967                  this.instance._propagate("deactivate", event, inst);
 968              }
 969  
 970          });
 971  
 972      },
 973      drag: function(event, ui) {
 974  
 975          var inst = $(this).data("draggable"), self = this;
 976  
 977          var checkPos = function(o) {
 978              var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
 979              var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
 980              var itemHeight = o.height, itemWidth = o.width;
 981              var itemTop = o.top, itemLeft = o.left;
 982  
 983              return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
 984          };
 985  
 986          $.each(inst.sortables, function(i) {
 987  
 988              if(checkPos.call(inst, this.instance.containerCache)) {
 989  
 990                  //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once

 991                  if(!this.instance.isOver) {
 992                      this.instance.isOver = 1;
 993                      //Now we fake the start of dragging for the sortable instance,

 994                      //by cloning the list group item, appending it to the sortable and using it as inst.currentItem

 995                      //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)

 996                      this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
 997                      this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it

 998                      this.instance.options.helper = function() { return ui.helper[0]; };
 999  
1000                      event.target = this.instance.currentItem[0];
1001                      this.instance._mouseCapture(event, true);
1002                      this.instance._mouseStart(event, true, true);
1003  
1004                      //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes

1005                      this.instance.offset.click.top = inst.offset.click.top;
1006                      this.instance.offset.click.left = inst.offset.click.left;
1007                      this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1008                      this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1009  
1010                      inst._propagate("toSortable", event);
1011  
1012                  }
1013  
1014                  //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

1015                  if(this.instance.currentItem) this.instance._mouseDrag(event);
1016  
1017              } else {
1018  
1019                  //If it doesn't intersect with the sortable, and it intersected before,

1020                  //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval

1021                  if(this.instance.isOver) {
1022                      this.instance.isOver = 0;
1023                      this.instance.cancelHelperRemoval = true;
1024                      this.instance.options.revert = false; //No revert here

1025                      this.instance._mouseStop(event, true);
1026                      this.instance.options.helper = this.instance.options._helper;
1027  
1028                      //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size

1029                      this.instance.currentItem.remove();
1030                      if(this.instance.placeholder) this.instance.placeholder.remove();
1031  
1032                      inst._propagate("fromSortable", event);
1033                  }
1034  
1035              };
1036  
1037          });
1038  
1039      }
1040  });
1041  
1042  $.ui.plugin.add("draggable", "cursor", {
1043      start: function(event, ui) {
1044          var t = $('body');
1045          if (t.css("cursor")) ui.options._cursor = t.css("cursor");
1046          t.css("cursor", ui.options.cursor);
1047      },
1048      stop: function(event, ui) {
1049          if (ui.options._cursor) $('body').css("cursor", ui.options._cursor);
1050      }
1051  });
1052  
1053  $.ui.plugin.add("draggable", "iframeFix", {
1054      start: function(event, ui) {
1055          $(ui.options.iframeFix === true ? "iframe" : ui.options.iframeFix).each(function() {
1056              $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1057              .css({
1058                  width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1059                  position: "absolute", opacity: "0.001", zIndex: 1000
1060              })
1061              .css($(this).offset())
1062              .appendTo("body");
1063          });
1064      },
1065      stop: function(event, ui) {
1066          $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers

1067      }
1068  });
1069  
1070  $.ui.plugin.add("draggable", "opacity", {
1071      start: function(event, ui) {
1072          var t = $(ui.helper);
1073          if(t.css("opacity")) ui.options._opacity = t.css("opacity");
1074          t.css('opacity', ui.options.opacity);
1075      },
1076      stop: function(event, ui) {
1077          if(ui.options._opacity) $(ui.helper).css('opacity', ui.options._opacity);
1078      }
1079  });
1080  
1081  $.ui.plugin.add("draggable", "scroll", {
1082      start: function(event, ui) {
1083          var o = ui.options;
1084          var i = $(this).data("draggable");
1085  
1086          if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1087  
1088      },
1089      drag: function(event, ui) {
1090  
1091          var o = ui.options, scrolled = false;
1092          var i = $(this).data("draggable");
1093  
1094          if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1095  
1096              if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1097                  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1098              else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1099                  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1100  
1101              if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1102                  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1103              else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1104                  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1105  
1106          } else {
1107  
1108              if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1109                  scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1110              else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1111                  scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1112  
1113              if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1114                  scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1115              else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1116                  scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1117  
1118          }
1119  
1120          if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1121              $.ui.ddmanager.prepareOffsets(i, event);
1122  
1123  
1124  
1125          // This is a special case where we need to modify a offset calculated on start, since the following happened:

1126          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent

1127          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that

1128          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag

1129          if(scrolled !== false && i.cssPosition == 'absolute' && i.scrollParent[0] != document && $.ui.contains(i.scrollParent[0], i.offsetParent[0])) {
1130              i.offset.parent = i._getParentOffset();
1131              
1132          }
1133          
1134          // This is another very weird special case that only happens for relative elements:

1135          // 1. If the css position is relative

1136          // 2. and the scroll parent is the document or similar to the offset parent

1137          // we have to refresh the relative offset during the scroll so there are no jumps

1138          if(scrolled !== false && i.cssPosition == 'relative' && !(i.scrollParent[0] != document && i.scrollParent[0] != i.offsetParent[0])) {
1139              i.offset.relative = i._getRelativeOffset();
1140          }
1141          
1142  
1143      }
1144  });
1145  
1146  $.ui.plugin.add("draggable", "snap", {
1147      start: function(event, ui) {
1148  
1149          var inst = $(this).data("draggable");
1150          inst.snapElements = [];
1151  
1152          $(ui.options.snap.constructor != String ? ( ui.options.snap.items || ':data(draggable)' ) : ui.options.snap).each(function() {
1153              var $t = $(this); var $o = $t.offset();
1154              if(this != inst.element[0]) inst.snapElements.push({
1155                  item: this,
1156                  width: $t.outerWidth(), height: $t.outerHeight(),
1157                  top: $o.top, left: $o.left
1158              });
1159          });
1160  
1161      },
1162      drag: function(event, ui) {
1163  
1164          var inst = $(this).data("draggable");
1165          var d = ui.options.snapTolerance;
1166  
1167          var x1 = ui.absolutePosition.left, x2 = x1 + inst.helperProportions.width,
1168              y1 = ui.absolutePosition.top, y2 = y1 + inst.helperProportions.height;
1169  
1170          for (var i = inst.snapElements.length - 1; i >= 0; i--){
1171  
1172              var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1173                  t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1174  
1175              //Yes, I know, this is insane ;)

1176              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))) {
1177                  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 })));
1178                  inst.snapElements[i].snapping = false;
1179                  continue;
1180              }
1181  
1182              if(ui.options.snapMode != 'inner') {
1183                  var ts = Math.abs(t - y2) <= d;
1184                  var bs = Math.abs(b - y1) <= d;
1185                  var ls = Math.abs(l - x2) <= d;
1186                  var rs = Math.abs(r - x1) <= d;
1187                  if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
1188                  if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
1189                  if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
1190                  if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
1191              }
1192  
1193              var first = (ts || bs || ls || rs);
1194  
1195              if(ui.options.snapMode != 'outer') {
1196                  var ts = Math.abs(t - y1) <= d;
1197                  var bs = Math.abs(b - y2) <= d;
1198                  var ls = Math.abs(l - x1) <= d;
1199                  var rs = Math.abs(r - x2) <= d;
1200                  if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
1201                  if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
1202                  if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
1203                  if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
1204              }
1205  
1206              if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1207                  (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1208              inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1209  
1210          };
1211  
1212      }
1213  });
1214  
1215  $.ui.plugin.add("draggable", "stack", {
1216      start: function(event, ui) {
1217          var group = $.makeArray($(ui.options.stack.group)).sort(function(a,b) {
1218              return (parseInt($(a).css("zIndex"),10) || ui.options.stack.min) - (parseInt($(b).css("zIndex"),10) || ui.options.stack.min);
1219          });
1220  
1221          $(group).each(function(i) {
1222              this.style.zIndex = ui.options.stack.min + i;
1223          });
1224  
1225          this[0].style.zIndex = ui.options.stack.min + group.length;
1226      }
1227  });
1228  
1229  $.ui.plugin.add("draggable", "zIndex", {
1230      start: function(event, ui) {
1231          var t = $(ui.helper);
1232          if(t.css("zIndex")) ui.options._zIndex = t.css("zIndex");
1233          t.css('zIndex', ui.options.zIndex);
1234      },
1235      stop: function(event, ui) {
1236          if(ui.options._zIndex) $(ui.helper).css('zIndex', ui.options._zIndex);
1237      }
1238  });
1239  
1240  })(jQuery);
1241  /*

1242   * jQuery UI Droppable 1.6

1243   *

1244   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

1245   * Dual licensed under the MIT (MIT-LICENSE.txt)

1246   * and GPL (GPL-LICENSE.txt) licenses.

1247   *

1248   * http://docs.jquery.com/UI/Droppables

1249   *

1250   * Depends:

1251   *    ui.core.js

1252   *    ui.draggable.js

1253   */
1254  (function($) {
1255  
1256  $.widget("ui.droppable", {
1257  
1258      _init: function() {
1259  
1260          var o = this.options, accept = o.accept;
1261          this.isover = 0; this.isout = 1;
1262  
1263          this.options.accept = this.options.accept && $.isFunction(this.options.accept) ? this.options.accept : function(d) {
1264              return d.is(accept);
1265          };
1266  
1267          //Store the droppable's proportions

1268          this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1269  
1270          // Add the reference and positions to the manager

1271          $.ui.ddmanager.droppables[this.options.scope] = $.ui.ddmanager.droppables[this.options.scope] || [];
1272          $.ui.ddmanager.droppables[this.options.scope].push(this);
1273  
1274          (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-droppable"));
1275  
1276      },
1277  
1278      destroy: function() {
1279          var drop = $.ui.ddmanager.droppables[this.options.scope];
1280          for ( var i = 0; i < drop.length; i++ )
1281              if ( drop[i] == this )
1282                  drop.splice(i, 1);
1283  
1284          this.element
1285              .removeClass("ui-droppable-disabled")
1286              .removeData("droppable")
1287              .unbind(".droppable");
1288      },
1289  
1290      _setData: function(key, value) {
1291  
1292          if(key == 'accept') {
1293              this.options.accept = value && $.isFunction(value) ? value : function(d) {
1294                  return d.is(accept);
1295              };
1296          } else {
1297              $.widget.prototype._setData.apply(this, arguments);
1298          }
1299  
1300      },
1301  
1302      _activate: function(event) {
1303  
1304          var draggable = $.ui.ddmanager.current;
1305          $.ui.plugin.call(this, 'activate', [event, this.ui(draggable)]);
1306          if(draggable) this.element.triggerHandler("dropactivate", [event, this.ui(draggable)], this.options.activate);
1307  
1308      },
1309  
1310      _deactivate: function(event) {
1311  
1312          var draggable = $.ui.ddmanager.current;
1313          $.ui.plugin.call(this, 'deactivate', [event, this.ui(draggable)]);
1314          if(draggable) this.element.triggerHandler("dropdeactivate", [event, this.ui(draggable)], this.options.deactivate);
1315  
1316      },
1317  
1318      _over: function(event) {
1319  
1320          var draggable = $.ui.ddmanager.current;
1321          if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element

1322  
1323          if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
1324              $.ui.plugin.call(this, 'over', [event, this.ui(draggable)]);
1325              this.element.triggerHandler("dropover", [event, this.ui(draggable)], this.options.over);
1326          }
1327  
1328      },
1329  
1330      _out: function(event) {
1331  
1332          var draggable = $.ui.ddmanager.current;
1333          if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element

1334  
1335          if (this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
1336              $.ui.plugin.call(this, 'out', [event, this.ui(draggable)]);
1337              this.element.triggerHandler("dropout", [event, this.ui(draggable)], this.options.out);
1338          }
1339  
1340      },
1341  
1342      _drop: function(event,custom) {
1343  
1344          var draggable = custom || $.ui.ddmanager.current;
1345          if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element

1346  
1347          var childrenIntersection = false;
1348          this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1349              var inst = $.data(this, 'droppable');
1350              if(inst.options.greedy && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) {
1351                  childrenIntersection = true; return false;
1352              }
1353          });
1354          if(childrenIntersection) return false;
1355  
1356          if(this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
1357              $.ui.plugin.call(this, 'drop', [event, this.ui(draggable)]);
1358              this.element.triggerHandler("drop", [event, this.ui(draggable)], this.options.drop);
1359              return this.element;
1360          }
1361  
1362          return false;
1363  
1364      },
1365  
1366      plugins: {},
1367  
1368      ui: function(c) {
1369          return {
1370              draggable: (c.currentItem || c.element),
1371              helper: c.helper,
1372              position: c.position,
1373              absolutePosition: c.positionAbs,
1374              options: this.options,
1375              element: this.element
1376          };
1377      }
1378  
1379  });
1380  
1381  $.extend($.ui.droppable, {
1382      version: "1.6",
1383      defaults: {
1384          accept: '*',
1385          activeClass: null,
1386          cssNamespace: 'ui',
1387          greedy: false,
1388          hoverClass: null,
1389          scope: 'default',
1390          tolerance: 'intersect'
1391      }
1392  });
1393  
1394  $.ui.intersect = function(draggable, droppable, toleranceMode) {
1395  
1396      if (!droppable.offset) return false;
1397  
1398      var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1399          y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1400      var l = droppable.offset.left, r = l + droppable.proportions.width,
1401          t = droppable.offset.top, b = t + droppable.proportions.height;
1402  
1403      switch (toleranceMode) {
1404          case 'fit':
1405              return (l < x1 && x2 < r
1406                  && t < y1 && y2 < b);
1407              break;
1408          case 'intersect':
1409              return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1410                  && x2 - (draggable.helperProportions.width / 2) < r // Left Half
1411                  && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1412                  && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half

1413              break;
1414          case 'pointer':
1415              var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
1416                  draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
1417                  isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
1418              return isOver;
1419              break;
1420          case 'touch':
1421              return (
1422                      (y1 >= t && y1 <= b) ||    // Top edge touching
1423                      (y2 >= t && y2 <= b) ||    // Bottom edge touching
1424                      (y1 < t && y2 > b)        // Surrounded vertically
1425                  ) && (
1426                      (x1 >= l && x1 <= r) ||    // Left edge touching
1427                      (x2 >= l && x2 <= r) ||    // Right edge touching
1428                      (x1 < l && x2 > r)        // Surrounded horizontally
1429                  );
1430              break;
1431          default:
1432              return false;
1433              break;
1434          }
1435  
1436  };
1437  
1438  /*

1439      This manager tracks offsets of draggables and droppables

1440  */
1441  $.ui.ddmanager = {
1442      current: null,
1443      droppables: { 'default': [] },
1444      prepareOffsets: function(t, event) {
1445  
1446          var m = $.ui.ddmanager.droppables[t.options.scope];
1447          var type = event ? event.type : null; // workaround for #2317

1448          var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
1449  
1450          droppablesLoop: for (var i = 0; i < m.length; i++) {
1451  
1452              if(m[i].options.disabled || (t && !m[i].options.accept.call(m[i].element,(t.currentItem || t.element)))) continue;    //No disabled and non-accepted

1453              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

1454              m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                     //If the element is not visible, continue

1455  
1456              m[i].offset = m[i].element.offset();
1457              m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
1458  
1459              if(type == "dragstart" || type == "sortactivate") m[i]._activate.call(m[i], event);                                         //Activate the droppable if used directly from draggables

1460  
1461          }
1462  
1463      },
1464      drop: function(draggable, event) {
1465  
1466          var dropped = false;
1467          $.each($.ui.ddmanager.droppables[draggable.options.scope], function() {
1468  
1469              if(!this.options) return;
1470              if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
1471                  dropped = this._drop.call(this, event);
1472  
1473              if (!this.options.disabled && this.visible && this.options.accept.call(this.element,(draggable.currentItem || draggable.element))) {
1474                  this.isout = 1; this.isover = 0;
1475                  this._deactivate.call(this, event);
1476              }
1477  
1478          });
1479          return dropped;
1480  
1481      },
1482      drag: function(draggable, event) {
1483  
1484          //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.

1485          if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
1486  
1487          //Run through all droppables and check their positions based on specific tolerance options

1488  
1489          $.each($.ui.ddmanager.droppables[draggable.options.scope], function() {
1490  
1491              if(this.options.disabled || this.greedyChild || !this.visible) return;
1492              var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
1493  
1494              var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
1495              if(!c) return;
1496  
1497              var parentInstance;
1498              if (this.options.greedy) {
1499                  var parent = this.element.parents(':data(droppable):eq(0)');
1500                  if (parent.length) {
1501                      parentInstance = $.data(parent[0], 'droppable');
1502                      parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
1503                  }
1504              }
1505  
1506              // we just moved into a greedy child

1507              if (parentInstance && c == 'isover') {
1508                  parentInstance['isover'] = 0;
1509                  parentInstance['isout'] = 1;
1510                  parentInstance._out.call(parentInstance, event);
1511              }
1512  
1513              this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
1514              this[c == "isover" ? "_over" : "_out"].call(this, event);
1515  
1516              // we just moved out of a greedy child

1517              if (parentInstance && c == 'isout') {
1518                  parentInstance['isout'] = 0;
1519                  parentInstance['isover'] = 1;
1520                  parentInstance._over.call(parentInstance, event);
1521              }
1522          });
1523  
1524      }
1525  };
1526  
1527  /*

1528   * Droppable Extensions

1529   */
1530  
1531  $.ui.plugin.add("droppable", "activeClass", {
1532      activate: function(event, ui) {
1533          $(this).addClass(ui.options.activeClass);
1534      },
1535      deactivate: function(event, ui) {
1536          $(this).removeClass(ui.options.activeClass);
1537      },
1538      drop: function(event, ui) {
1539          $(this).removeClass(ui.options.activeClass);
1540      }
1541  });
1542  
1543  $.ui.plugin.add("droppable", "hoverClass", {
1544      over: function(event, ui) {
1545          $(this).addClass(ui.options.hoverClass);
1546      },
1547      out: function(event, ui) {
1548          $(this).removeClass(ui.options.hoverClass);
1549      },
1550      drop: function(event, ui) {
1551          $(this).removeClass(ui.options.hoverClass);
1552      }
1553  });
1554  
1555  })(jQuery);
1556  /*

1557   * jQuery UI Resizable 1.6

1558   *

1559   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

1560   * Dual licensed under the MIT (MIT-LICENSE.txt)

1561   * and GPL (GPL-LICENSE.txt) licenses.

1562   *

1563   * http://docs.jquery.com/UI/Resizables

1564   *

1565   * Depends:

1566   *    ui.core.js

1567   */
1568  (function($) {
1569  
1570  $.widget("ui.resizable", $.extend({}, $.ui.mouse, {
1571  
1572      _init: function() {
1573  
1574          var self = this, o = this.options;
1575  
1576          var elpos = this.element.css('position');
1577  
1578          this.originalElement = this.element;
1579  
1580          // simulate .ui-resizable { position: relative; }

1581          this.element.addClass("ui-resizable").css({ position: /static/.test(elpos) ? 'relative' : elpos });
1582  
1583          $.extend(o, {
1584              _aspectRatio: !!(o.aspectRatio),
1585              helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null,
1586              knobHandles: o.knobHandles === true ? 'ui-resizable-knob-handle' : o.knobHandles
1587          });
1588  
1589          //Default Theme

1590          var aBorder = '1px solid #DEDEDE';
1591  
1592          o.defaultTheme = {
1593              'ui-resizable': { display: 'block' },
1594              'ui-resizable-handle': { position: 'absolute', background: '#F2F2F2', fontSize: '0.1px' },
1595              'ui-resizable-n': { cursor: 'n-resize', height: '4px', left: '0px', right: '0px', borderTop: aBorder },
1596              'ui-resizable-s': { cursor: 's-resize', height: '4px', left: '0px', right: '0px', borderBottom: aBorder },
1597              'ui-resizable-e': { cursor: 'e-resize', width: '4px', top: '0px', bottom: '0px', borderRight: aBorder },
1598              'ui-resizable-w': { cursor: 'w-resize', width: '4px', top: '0px', bottom: '0px', borderLeft: aBorder },
1599              'ui-resizable-se': { cursor: 'se-resize', width: '4px', height: '4px', borderRight: aBorder, borderBottom: aBorder },
1600              'ui-resizable-sw': { cursor: 'sw-resize', width: '4px', height: '4px', borderBottom: aBorder, borderLeft: aBorder },
1601              'ui-resizable-ne': { cursor: 'ne-resize', width: '4px', height: '4px', borderRight: aBorder, borderTop: aBorder },
1602              'ui-resizable-nw': { cursor: 'nw-resize', width: '4px', height: '4px', borderLeft: aBorder, borderTop: aBorder }
1603          };
1604  
1605          o.knobTheme = {
1606              'ui-resizable-handle': { background: '#F2F2F2', border: '1px solid #808080', height: '8px', width: '8px' },
1607              'ui-resizable-n': { cursor: 'n-resize', top: '0px', left: '45%' },
1608              'ui-resizable-s': { cursor: 's-resize', bottom: '0px', left: '45%' },
1609              'ui-resizable-e': { cursor: 'e-resize', right: '0px', top: '45%' },
1610              'ui-resizable-w': { cursor: 'w-resize', left: '0px', top: '45%' },
1611              'ui-resizable-se': { cursor: 'se-resize', right: '0px', bottom: '0px' },
1612              'ui-resizable-sw': { cursor: 'sw-resize', left: '0px', bottom: '0px' },
1613              'ui-resizable-nw': { cursor: 'nw-resize', left: '0px', top: '0px' },
1614              'ui-resizable-ne': { cursor: 'ne-resize', right: '0px', top: '0px' }
1615          };
1616  
1617          o._nodeName = this.element[0].nodeName;
1618  
1619          //Wrap the element if it cannot hold child nodes

1620          if(o._nodeName.match(/canvas|textarea|input|select|button|img/i)) {
1621              var el = this.element;
1622  
1623              //Opera fixing relative position

1624              if (/relative/.test(el.css('position')) && $.browser.opera)
1625                  el.css({ position: 'relative', top: 'auto', left: 'auto' });
1626  
1627              //Create a wrapper element and set the wrapper to the new current internal element

1628              el.wrap(
1629                  $('<div class="ui-wrapper"    style="overflow: hidden;"></div>').css( {
1630                      position: el.css('position'),
1631                      width: el.outerWidth(),
1632                      height: el.outerHeight(),
1633                      top: el.css('top'),
1634                      left: el.css('left')
1635                  })
1636              );
1637  
1638              var oel = this.element; this.element = this.element.parent();
1639  
1640              // store instance on wrapper

1641              this.element.data('resizable', this);
1642  
1643              //Move margins to the wrapper

1644              this.element.css({ marginLeft: oel.css("marginLeft"), marginTop: oel.css("marginTop"),
1645                  marginRight: oel.css("marginRight"), marginBottom: oel.css("marginBottom")
1646              });
1647  
1648              oel.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
1649  
1650              //Prevent Safari textarea resize

1651              if ($.browser.safari && o.preventDefault) oel.css('resize', 'none');
1652  
1653              o.proportionallyResize = oel.css({ position: 'static', zoom: 1, display: 'block' });
1654  
1655              // avoid IE jump

1656              this.element.css({ margin: oel.css('margin') });
1657  
1658              // fix handlers offset

1659              this._proportionallyResize();
1660          }
1661  
1662          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' };
1663          if(o.handles.constructor == String) {
1664  
1665              o.zIndex = o.zIndex || 1000;
1666  
1667              if(o.handles == 'all') o.handles = 'n,e,s,w,se,sw,ne,nw';
1668  
1669              var n = o.handles.split(","); o.handles = {};
1670  
1671              // insertions are applied when don't have theme loaded

1672              var insertionsDefault = {
1673                  handle: 'position: absolute; display: none; overflow:hidden;',
1674                  n: 'top: 0pt; width:100%;',
1675                  e: 'right: 0pt; height:100%;',
1676                  s: 'bottom: 0pt; width:100%;',
1677                  w: 'left: 0pt; height:100%;',
1678                  se: 'bottom: 0pt; right: 0px;',
1679                  sw: 'bottom: 0pt; left: 0px;',
1680                  ne: 'top: 0pt; right: 0px;',
1681                  nw: 'top: 0pt; left: 0px;'
1682              };
1683  
1684              for(var i = 0; i < n.length; i++) {
1685                  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'),
1686                              allDefTheme = $.extend(dt[hname], dt['ui-resizable-handle']), allKnobTheme = $.extend(o.knobTheme[hname], !userKnobClass ? o.knobTheme['ui-resizable-handle'] : {});
1687  
1688                  // increase zIndex of sw, se, ne, nw axis

1689                  var applyZIndex = /sw|se|ne|nw/.test(handle) ? { zIndex: ++o.zIndex } : {};
1690  
1691                  var defCss = (loadDefault ? insertionsDefault[handle] : ''),
1692                      axis = $(['<div class="ui-resizable-handle ', hname, '" style="', defCss, insertionsDefault.handle, '"></div>'].join('')).css( applyZIndex );
1693                  o.handles[handle] = '.ui-resizable-'+handle;
1694  
1695                  this.element.append(
1696                      //Theme detection, if not loaded, load o.defaultTheme

1697                      axis.css( loadDefault ? allDefTheme : {} )
1698                          // Load the knobHandle css, fix width, height, top, left...

1699                          .css( o.knobHandles ? allKnobTheme : {} ).addClass(o.knobHandles ? 'ui-resizable-knob-handle' : '').addClass(o.knobHandles)
1700                  );
1701              }
1702  
1703              if (o.knobHandles) this.element.addClass('ui-resizable-knob').css( !$.ui.css('ui-resizable-knob') ? { /*border: '1px #fff dashed'*/ } : {} );
1704          }
1705  
1706          this._renderAxis = function(target) {
1707              target = target || this.element;
1708  
1709              for(var i in o.handles) {
1710                  if(o.handles[i].constructor == String)
1711                      o.handles[i] = $(o.handles[i], this.element).show();
1712  
1713                  if (o.transparent)
1714                      o.handles[i].css({opacity:0});
1715  
1716                  //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)

1717                  if (this.element.is('.ui-wrapper') &&
1718                      o._nodeName.match(/textarea|input|select|button/i)) {
1719  
1720                      var axis = $(o.handles[i], this.element), padWrapper = 0;
1721  
1722                      //Checking the correct pad and border

1723                      padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
1724  
1725                      //The padding type i have to apply...

1726                      var padPos = [ 'padding',
1727                          /ne|nw|n/.test(i) ? 'Top' :
1728                          /se|sw|s/.test(i) ? 'Bottom' :
1729                          /^e$/.test(i) ? 'Right' : 'Left' ].join("");
1730  
1731                      if (!o.transparent)
1732                          target.css(padPos, padWrapper);
1733  
1734                      this._proportionallyResize();
1735                  }
1736                  if(!$(o.handles[i]).length) continue;
1737              }
1738          };
1739  
1740          this._renderAxis(this.element);
1741          o._handles = $('.ui-resizable-handle', self.element);
1742  
1743          if (o.disableSelection)
1744              o._handles.disableSelection();
1745  
1746          //Matching axis name

1747          o._handles.mouseover(function() {
1748              if (!o.resizing) {
1749                  if (this.className)
1750                      var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
1751                  //Axis, default = se

1752                  self.axis = o.axis = axis && axis[1] ? axis[1] : 'se';
1753              }
1754          });
1755  
1756          //If we want to auto hide the elements

1757          if (o.autoHide) {
1758              o._handles.hide();
1759              $(self.element).addClass("ui-resizable-autohide").hover(function() {
1760                  $(this).removeClass("ui-resizable-autohide");
1761                  o._handles.show();
1762              },
1763              function(){
1764                  if (!o.resizing) {
1765                      $(this).addClass("ui-resizable-autohide");
1766                      o._handles.hide();
1767                  }
1768              });
1769          }
1770  
1771          this._mouseInit();
1772      },
1773  
1774      destroy: function() {
1775          var el = this.element, wrapped = el.children(".ui-resizable").get(0);
1776  
1777          this._mouseDestroy();
1778  
1779          var _destroy = function(exp) {
1780              $(exp).removeClass("ui-resizable ui-resizable-disabled")
1781                  .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
1782          };
1783  
1784          _destroy(el);
1785  
1786          if (el.is('.ui-wrapper') && wrapped) {
1787              el.parent().append(
1788                  $(wrapped).css({
1789                      position: el.css('position'),
1790                      width: el.outerWidth(),
1791                      height: el.outerHeight(),
1792                      top: el.css('top'),
1793                      left: el.css('left')
1794                  })
1795              ).end().remove();
1796  
1797              _destroy(wrapped);
1798          }
1799      },
1800  
1801      _mouseCapture: function(event) {
1802  
1803          if(this.options.disabled) return false;
1804  
1805          var handle = false;
1806          for(var i in this.options.handles) {
1807              if($(this.options.handles[i])[0] == event.target) handle = true;
1808          }
1809          if (!handle) return false;
1810  
1811          return true;
1812  
1813      },
1814  
1815      _mouseStart: function(event) {
1816  
1817          var o = this.options, iniPos = this.element.position(), el = this.element,
1818              ie6 = $.browser.msie && $.browser.version < 7;
1819          o.resizing = true;
1820          o.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
1821  
1822          // bugfix #1749

1823          if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
1824  
1825              // sOffset decides if document scrollOffset will be added to the top/left of the resizable element

1826              var sOffset = $.browser.msie && !o.containment && (/absolute/).test(el.css('position')) && !(/relative/).test(el.parent().css('position'));
1827              var dscrollt = sOffset ? this.documentScroll.top : 0, dscrolll = sOffset ? this.documentScroll.left : 0;
1828  
1829              el.css({ position: 'absolute', top: (iniPos.top + dscrollt), left: (iniPos.left + dscrolll) });
1830          }
1831  
1832          //Opera fixing relative position

1833          if ($.browser.opera && (/relative/).test(el.css('position')))
1834              el.css({ position: 'relative', top: 'auto', left: 'auto' });
1835  
1836          this._renderProxy();
1837  
1838          var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
1839  
1840          if (o.containment) {
1841              curleft += $(o.containment).scrollLeft()||0;
1842              curtop += $(o.containment).scrollTop()||0;
1843          }
1844  
1845          //Store needed variables

1846          this.offset = this.helper.offset();
1847          this.position = { left: curleft, top: curtop };
1848          this.size = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
1849          this.originalSize = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
1850          this.originalPosition = { left: curleft, top: curtop };
1851          this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
1852          this.originalMousePosition = { left: event.pageX, top: event.pageY };
1853  
1854          //Aspect Ratio

1855          o.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height)||1);
1856  
1857          if (o.preserveCursor) {
1858              var cursor = $('.ui-resizable-' + this.axis).css('cursor');
1859              $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
1860          }
1861  
1862          this._propagate("start", event);
1863          return true;
1864      },
1865  
1866      _mouseDrag: function(event) {
1867  
1868          //Increase performance, avoid regex

1869          var el = this.helper, o = this.options, props = {},
1870              self = this, smp = this.originalMousePosition, a = this.axis;
1871  
1872          var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
1873          var trigger = this._change[a];
1874          if (!trigger) return false;
1875  
1876          // Calculate the attrs that will be change

1877          var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
1878  
1879          if (o._aspectRatio || event.shiftKey)
1880              data = this._updateRatio(data, event);
1881  
1882          data = this._respectSize(data, event);
1883  
1884          // plugins callbacks need to be called first

1885          this._propagate("resize", event);
1886  
1887          el.css({
1888              top: this.position.top + "px", left: this.position.left + "px",
1889              width: this.size.width + "px", height: this.size.height + "px"
1890          });
1891  
1892          if (!o.helper && o.proportionallyResize)
1893              this._proportionallyResize();
1894  
1895          this._updateCache(data);
1896  
1897          // calling the user callback at the end

1898          this.element.triggerHandler("resize", [event, this.ui()], this.options["resize"]);
1899  
1900          return false;
1901      },
1902  
1903      _mouseStop: function(event) {
1904  
1905          this.options.resizing = false;
1906          var o = this.options, self = this;
1907  
1908          if(o.helper) {
1909              var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName),
1910                          soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
1911                              soffsetw = ista ? 0 : self.sizeDiff.width;
1912  
1913              var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
1914                  left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
1915                  top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
1916  
1917              if (!o.animate)
1918                  this.element.css($.extend(s, { top: top, left: left }));
1919  
1920              if (o.helper && !o.animate) this._proportionallyResize();
1921          }
1922  
1923          if (o.preserveCursor)
1924              $('body').css('cursor', 'auto');
1925  
1926          this._propagate("stop", event);
1927  
1928          if (o.helper) this.helper.remove();
1929  
1930          return false;
1931      },
1932  
1933      _updateCache: function(data) {
1934          var o = this.options;
1935          this.offset = this.helper.offset();
1936          if (data.left) this.position.left = data.left;
1937          if (data.top) this.position.top = data.top;
1938          if (data.height) this.size.height = data.height;
1939          if (data.width) this.size.width = data.width;
1940      },
1941  
1942      _updateRatio: function(data, event) {
1943  
1944          var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
1945  
1946          if (data.height) data.width = (csize.height * o.aspectRatio);
1947          else if (data.width) data.height = (csize.width / o.aspectRatio);
1948  
1949          if (a == 'sw') {
1950              data.left = cpos.left + (csize.width - data.width);
1951              data.top = null;
1952          }
1953          if (a == 'nw') {
1954              data.top = cpos.top + (csize.height - data.height);
1955              data.left = cpos.left + (csize.width - data.width);
1956          }
1957  
1958          return data;
1959      },
1960  
1961      _respectSize: function(data, event) {
1962  
1963          var el = this.helper, o = this.options, pRatio = o._aspectRatio || event.shiftKey, a = this.axis,
1964                  ismaxw = data.width && o.maxWidth && o.maxWidth < data.width, ismaxh = data.height && o.maxHeight && o.maxHeight < data.height,
1965                      isminw = data.width && o.minWidth && o.minWidth > data.width, isminh = data.height && o.minHeight && o.minHeight > data.height;
1966  
1967          if (isminw) data.width = o.minWidth;
1968          if (isminh) data.height = o.minHeight;
1969          if (ismaxw) data.width = o.maxWidth;
1970          if (ismaxh) data.height = o.maxHeight;
1971  
1972          var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
1973          var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
1974  
1975          if (isminw && cw) data.left = dw - o.minWidth;
1976          if (ismaxw && cw) data.left = dw - o.maxWidth;
1977          if (isminh && ch)    data.top = dh - o.minHeight;
1978          if (ismaxh && ch)    data.top = dh - o.maxHeight;
1979  
1980          // fixing jump error on top/left - bug #2330

1981          var isNotwh = !data.width && !data.height;
1982          if (isNotwh && !data.left && data.top) data.top = null;
1983          else if (isNotwh && !data.top && data.left) data.left = null;
1984  
1985          return data;
1986      },
1987  
1988      _proportionallyResize: function() {
1989          var o = this.options;
1990          if (!o.proportionallyResize) return;
1991          var prel = o.proportionallyResize, el = this.helper || this.element;
1992  
1993          if (!o.borderDif) {
1994              var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
1995                  p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
1996  
1997              o.borderDif = $.map(b, function(v, i) {
1998                  var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
1999                  return border + padding;
2000              });
2001          }
2002          prel.css({
2003              height: (el.height() - o.borderDif[0] - o.borderDif[2]) + "px",
2004              width: (el.width() - o.borderDif[1] - o.borderDif[3]) + "px"
2005          });
2006      },
2007  
2008      _renderProxy: function() {
2009          var el = this.element, o = this.options;
2010          this.elementOffset = el.offset();
2011  
2012          if(o.helper) {
2013              this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2014  
2015              // fix ie6 offset

2016              var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2017              pxyoffset = ( ie6 ? 2 : -1 );
2018  
2019              this.helper.addClass(o.helper).css({
2020                  width: el.outerWidth() + pxyoffset,
2021                  height: el.outerHeight() + pxyoffset,
2022                  position: 'absolute',
2023                  left: this.elementOffset.left - ie6offset +'px',
2024                  top: this.elementOffset.top - ie6offset +'px',
2025                  zIndex: ++o.zIndex
2026              });
2027  
2028              this.helper.appendTo("body");
2029  
2030              if (o.disableSelection)
2031                  this.helper.disableSelection();
2032  
2033          } else {
2034              this.helper = el;
2035          }
2036      },
2037  
2038      _change: {
2039          e: function(event, dx, dy) {
2040              return { width: this.originalSize.width + dx };
2041          },
2042          w: function(event, dx, dy) {
2043              var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2044              return { left: sp.left + dx, width: cs.width - dx };
2045          },
2046          n: function(event, dx, dy) {
2047              var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2048              return { top: sp.top + dy, height: cs.height - dy };
2049          },
2050          s: function(event, dx, dy) {
2051              return { height: this.originalSize.height + dy };
2052          },
2053          se: function(event, dx, dy) {
2054              return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2055          },
2056          sw: function(event, dx, dy) {
2057              return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2058          },
2059          ne: function(event, dx, dy) {
2060              return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2061          },
2062          nw: function(event, dx, dy) {
2063              return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2064          }
2065      },
2066  
2067      _propagate: function(n, event) {
2068          $.ui.plugin.call(this, n, [event, this.ui()]);
2069          if (n != "resize") this.element.triggerHandler(["resize", n].join(""), [event, this.ui()], this.options[n]);
2070      },
2071  
2072      plugins: {},
2073  
2074      ui: function() {
2075          return {
2076              originalElement: this.originalElement,
2077              element: this.element,
2078              helper: this.helper,
2079              position: this.position,
2080              size: this.size,
2081              options: this.options,
2082              originalSize: this.originalSize,
2083              originalPosition: this.originalPosition
2084          };
2085      }
2086  
2087  }));
2088  
2089  $.extend($.ui.resizable, {
2090      version: "1.6",
2091      defaults: {
2092          alsoResize: false,
2093          animate: false,
2094          animateDuration: "slow",
2095          animateEasing: "swing",
2096          aspectRatio: false,
2097          autoHide: false,
2098          cancel: ":input",
2099          containment: false,
2100          disableSelection: true,
2101          distance: 1,
2102          delay: 0,
2103          ghost: false,
2104          grid: false,
2105          knobHandles: false,
2106          maxHeight: null,
2107          maxWidth: null,
2108          minHeight: 10,
2109          minWidth: 10,
2110          preserveCursor: true,
2111          preventDefault: true,
2112          proportionallyResize: false,
2113          transparent: false
2114      }
2115  });
2116  
2117  /*

2118   * Resizable Extensions

2119   */
2120  
2121  $.ui.plugin.add("resizable", "alsoResize", {
2122  
2123      start: function(event, ui) {
2124          var o = ui.options, self = $(this).data("resizable"),
2125  
2126          _store = function(exp) {
2127              $(exp).each(function() {
2128                  $(this).data("resizable-alsoresize", {
2129                      width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
2130                      left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
2131                  });
2132              });
2133          };
2134  
2135          if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2136              if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0];    _store(o.alsoResize); }
2137              else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); }
2138          }else{
2139              _store(o.alsoResize);
2140          }
2141      },
2142  
2143      resize: function(event, ui){
2144          var o = ui.options, self = $(this).data("resizable"), os = self.originalSize, op = self.originalPosition;
2145  
2146          var delta = {
2147              height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2148              top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2149          },
2150  
2151          _alsoResize = function(exp, c) {
2152              $(exp).each(function() {
2153                  var start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
2154  
2155                  $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
2156                      var sum = (start[prop]||0) + (delta[prop]||0);
2157                      if (sum && sum >= 0)
2158                          style[prop] = sum || null;
2159                  });
2160                  $(this).css(style);
2161              });
2162          };
2163  
2164          if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2165              $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });
2166          }else{
2167              _alsoResize(o.alsoResize);
2168          }
2169      },
2170  
2171      stop: function(event, ui){
2172          $(this).removeData("resizable-alsoresize-start");
2173      }
2174  });
2175  
2176  $.ui.plugin.add("resizable", "animate", {
2177  
2178      stop: function(event, ui) {
2179          var o = ui.options, self = $(this).data("resizable");
2180  
2181          var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName),
2182                          soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2183                              soffsetw = ista ? 0 : self.sizeDiff.width;
2184  
2185          var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2186                      left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2187                          top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2188  
2189          self.element.animate(
2190              $.extend(style, top && left ? { top: top, left: left } : {}), {
2191                  duration: o.animateDuration,
2192                  easing: o.animateEasing,
2193                  step: function() {
2194  
2195                      var data = {
2196                          width: parseInt(self.element.css('width'), 10),
2197                          height: parseInt(self.element.css('height'), 10),
2198                          top: parseInt(self.element.css('top'), 10),
2199                          left: parseInt(self.element.css('left'), 10)
2200                      };
2201  
2202                      if (pr) pr.css({ width: data.width, height: data.height });
2203  
2204                      // propagating resize, and updating values for each animation step

2205                      self._updateCache(data);
2206                      self._propagate("animate", event);
2207  
2208                  }
2209              }
2210          );
2211      }
2212  
2213  });
2214  
2215  $.ui.plugin.add("resizable", "containment", {
2216  
2217      start: function(event, ui) {
2218          var o = ui.options, self = $(this).data("resizable"), el = self.element;
2219          var oc = o.containment,    ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2220          if (!ce) return;
2221  
2222          self.containerElement = $(ce);
2223  
2224          if (/document/.test(oc) || oc == document) {
2225              self.containerOffset = { left: 0, top: 0 };
2226              self.containerPosition = { left: 0, top: 0 };
2227  
2228              self.parentData = {
2229                  element: $(document), left: 0, top: 0,
2230                  width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2231              };
2232          }
2233  
2234          // i'm a node, so compute top, left, right, bottom

2235          else{
2236              var element = $(ce), p = [];
2237              $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2238  
2239              self.containerOffset = element.offset();
2240              self.containerPosition = element.position();
2241              self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2242  
2243              var co = self.containerOffset, ch = self.containerSize.height,    cw = self.containerSize.width,
2244                          width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2245  
2246              self.parentData = {
2247                  element: ce, left: co.left, top: co.top, width: width, height: height
2248              };
2249          }
2250      },
2251  
2252      resize: function(event, ui) {
2253          var o = ui.options, self = $(this).data("resizable"),
2254                  ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2255                  pRatio = o._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2256  
2257          if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2258  
2259          if (cp.left < (o.helper ? co.left : 0)) {
2260              self.size.width = self.size.width + (o.helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2261              if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2262              self.position.left = o.helper ? co.left : 0;
2263          }
2264  
2265          if (cp.top < (o.helper ? co.top : 0)) {
2266              self.size.height = self.size.height + (o.helper ? (self.position.top - co.top) : self.position.top);
2267              if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2268              self.position.top = o.helper ? co.top : 0;
2269          }
2270  
2271          self.offset.left = self.parentData.left+self.position.left;
2272          self.offset.top = self.parentData.top+self.position.top;
2273  
2274          var woset = Math.abs( (o.helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2275                      hoset = Math.abs( (o.helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2276  
2277          var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2278              isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2279  
2280          if(isParent && isOffsetRelative) woset -= self.parentData.left;
2281  
2282          if (woset + self.size.width >= self.parentData.width) {
2283              self.size.width = self.parentData.width - woset;
2284              if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2285          }
2286  
2287          if (hoset + self.size.height >= self.parentData.height) {
2288              self.size.height = self.parentData.height - hoset;
2289              if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2290          }
2291      },
2292  
2293      stop: function(event, ui){
2294          var o = ui.options, self = $(this).data("resizable"), cp = self.position,
2295                  co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2296  
2297          var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2298  
2299          if (o.helper && !o.animate && (/relative/).test(ce.css('position')))
2300              $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2301  
2302          if (o.helper && !o.animate && (/static/).test(ce.css('position')))
2303              $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2304  
2305      }
2306  });
2307  
2308  $.ui.plugin.add("resizable", "ghost", {
2309  
2310      start: function(event, ui) {
2311          var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize, cs = self.size;
2312  
2313          if (!pr) self.ghost = self.element.clone();
2314          else self.ghost = pr.clone();
2315  
2316          self.ghost.css(
2317              { opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }
2318          )
2319          .addClass('ui-resizable-ghost').addClass(typeof o.ghost == 'string' ? o.ghost : '');
2320  
2321          self.ghost.appendTo(self.helper);
2322  
2323      },
2324  
2325      resize: function(event, ui){
2326          var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize;
2327  
2328          if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2329  
2330      },
2331  
2332      stop: function(event, ui){
2333          var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize;
2334          if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2335      }
2336  
2337  });
2338  
2339  $.ui.plugin.add("resizable", "grid", {
2340  
2341      resize: function(event, ui) {
2342          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;
2343          o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2344          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);
2345  
2346          if (/^(se|s|e)$/.test(a)) {
2347              self.size.width = os.width + ox;
2348              self.size.height = os.height + oy;
2349          }
2350          else if (/^(ne)$/.test(a)) {
2351              self.size.width = os.width + ox;
2352              self.size.height = os.height + oy;
2353              self.position.top = op.top - oy;
2354          }
2355          else if (/^(sw)$/.test(a)) {
2356              self.size.width = os.width + ox;
2357              self.size.height = os.height + oy;
2358              self.position.left = op.left - ox;
2359          }
2360          else {
2361              self.size.width = os.width + ox;
2362              self.size.height = os.height + oy;
2363              self.position.top = op.top - oy;
2364              self.position.left = op.left - ox;
2365          }
2366      }
2367  
2368  });
2369  
2370  var num = function(v) {
2371      return parseInt(v, 10) || 0;
2372  };
2373  
2374  })(jQuery);
2375  /*

2376   * jQuery UI Selectable 1.6

2377   *

2378   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

2379   * Dual licensed under the MIT (MIT-LICENSE.txt)

2380   * and GPL (GPL-LICENSE.txt) licenses.

2381   *

2382   * http://docs.jquery.com/UI/Selectables

2383   *

2384   * Depends:

2385   *    ui.core.js

2386   */
2387  (function($) {
2388  
2389  $.widget("ui.selectable", $.extend({}, $.ui.mouse, {
2390  
2391      _init: function() {
2392          var self = this;
2393  
2394          this.element.addClass("ui-selectable");
2395  
2396          this.dragged = false;
2397  
2398          // cache selectee children based on filter

2399          var selectees;
2400          this.refresh = function() {
2401              selectees = $(self.options.filter, self.element[0]);
2402              selectees.each(function() {
2403                  var $this = $(this);
2404                  var pos = $this.offset();
2405                  $.data(this, "selectable-item", {
2406                      element: this,
2407                      $element: $this,
2408                      left: pos.left,
2409                      top: pos.top,
2410                      right: pos.left + $this.width(),
2411                      bottom: pos.top + $this.height(),
2412                      startselected: false,
2413                      selected: $this.hasClass('ui-selected'),
2414                      selecting: $this.hasClass('ui-selecting'),
2415                      unselecting: $this.hasClass('ui-unselecting')
2416                  });
2417              });
2418          };
2419          this.refresh();
2420  
2421          this.selectees = selectees.addClass("ui-selectee");
2422  
2423          this._mouseInit();
2424  
2425          this.helper = $(document.createElement('div'))
2426              .css({border:'1px dotted black'})
2427              .addClass("ui-selectable-helper");
2428      },
2429  
2430      destroy: function() {
2431          this.element
2432              .removeClass("ui-selectable ui-selectable-disabled")
2433              .removeData("selectable")
2434              .unbind(".selectable");
2435          this._mouseDestroy();
2436      },
2437  
2438      _mouseStart: function(event) {
2439          var self = this;
2440  
2441          this.opos = [event.pageX, event.pageY];
2442  
2443          if (this.options.disabled)
2444              return;
2445  
2446          var options = this.options;
2447  
2448          this.selectees = $(options.filter, this.element[0]);
2449  
2450          // selectable START callback

2451          this.element.triggerHandler("selectablestart", [event, {
2452              "selectable": this.element[0],
2453              "options": options
2454          }], options.start);
2455  
2456          $('body').append(this.helper);
2457          // position helper (lasso)

2458          this.helper.css({
2459              "z-index": 100,
2460              "position": "absolute",
2461              "left": event.clientX,
2462              "top": event.clientY,
2463              "width": 0,
2464              "height": 0
2465          });
2466  
2467          if (options.autoRefresh) {
2468              this.refresh();
2469          }
2470  
2471          this.selectees.filter('.ui-selected').each(function() {
2472              var selectee = $.data(this, "selectable-item");
2473              selectee.startselected = true;
2474              if (!event.metaKey) {
2475                  selectee.$element.removeClass('ui-selected');
2476                  selectee.selected = false;
2477                  selectee.$element.addClass('ui-unselecting');
2478                  selectee.unselecting = true;
2479                  // selectable UNSELECTING callback

2480                  self.element.triggerHandler("selectableunselecting", [event, {
2481                      selectable: self.element[0],
2482                      unselecting: selectee.element,
2483                      options: options
2484                  }], options.unselecting);
2485              }
2486          });
2487  
2488          var isSelectee = false;
2489          $(event.target).parents().andSelf().each(function() {
2490              if($.data(this, "selectable-item")) isSelectee = true;
2491          });
2492          return this.options.keyboard ? !isSelectee : true;
2493      },
2494  
2495      _mouseDrag: function(event) {
2496          var self = this;
2497          this.dragged = true;
2498  
2499          if (this.options.disabled)
2500              return;
2501  
2502          var options = this.options;
2503  
2504          var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
2505          if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
2506          if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
2507          this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
2508  
2509          this.selectees.each(function() {
2510              var selectee = $.data(this, "selectable-item");
2511              //prevent helper from being selected if appendTo: selectable

2512              if (!selectee || selectee.element == self.element[0])
2513                  return;
2514              var hit = false;
2515              if (options.tolerance == 'touch') {
2516                  hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
2517              } else if (options.tolerance == 'fit') {
2518                  hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
2519              }
2520  
2521              if (hit) {
2522                  // SELECT

2523                  if (selectee.selected) {
2524                      selectee.$element.removeClass('ui-selected');
2525                      selectee.selected = false;
2526                  }
2527                  if (selectee.unselecting) {
2528                      selectee.$element.removeClass('ui-unselecting');
2529                      selectee.unselecting = false;
2530                  }
2531                  if (!selectee.selecting) {
2532                      selectee.$element.addClass('ui-selecting');
2533                      selectee.selecting = true;
2534                      // selectable SELECTING callback

2535                      self.element.triggerHandler("selectableselecting", [event, {
2536                          selectable: self.element[0],
2537                          selecting: selectee.element,
2538                          options: options
2539                      }], options.selecting);
2540                  }
2541              } else {
2542                  // UNSELECT

2543                  if (selectee.selecting) {
2544                      if (event.metaKey && selectee.startselected) {
2545                          selectee.$element.removeClass('ui-selecting');
2546                          selectee.selecting = false;
2547                          selectee.$element.addClass('ui-selected');
2548                          selectee.selected = true;
2549                      } else {
2550                          selectee.$element.removeClass('ui-selecting');
2551                          selectee.selecting = false;
2552                          if (selectee.startselected) {
2553                              selectee.$element.addClass('ui-unselecting');
2554                              selectee.unselecting = true;
2555                          }
2556                          // selectable UNSELECTING callback

2557                          self.element.triggerHandler("selectableunselecting", [event, {
2558                              selectable: self.element[0],
2559                              unselecting: selectee.element,
2560                              options: options
2561                          }], options.unselecting);
2562                      }
2563                  }
2564                  if (selectee.selected) {
2565                      if (!event.metaKey && !selectee.startselected) {
2566                          selectee.$element.removeClass('ui-selected');
2567                          selectee.selected = false;
2568  
2569                          selectee.$element.addClass('ui-unselecting');
2570                          selectee.unselecting = true;
2571                          // selectable UNSELECTING callback

2572                          self.element.triggerHandler("selectableunselecting", [event, {
2573                              selectable: self.element[0],
2574                              unselecting: selectee.element,
2575                              options: options
2576                          }], options.unselecting);
2577                      }
2578                  }
2579              }
2580          });
2581  
2582          return false;
2583      },
2584  
2585      _mouseStop: function(event) {
2586          var self = this;
2587  
2588          this.dragged = false;
2589  
2590          var options = this.options;
2591  
2592          $('.ui-unselecting', this.element[0]).each(function() {
2593              var selectee = $.data(this, "selectable-item");
2594              selectee.$element.removeClass('ui-unselecting');
2595              selectee.unselecting = false;
2596              selectee.startselected = false;
2597              self.element.triggerHandler("selectableunselected", [event, {
2598                  selectable: self.element[0],
2599                  unselected: selectee.element,
2600                  options: options
2601              }], options.unselected);
2602          });
2603          $('.ui-selecting', this.element[0]).each(function() {
2604              var selectee = $.data(this, "selectable-item");
2605              selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
2606              selectee.selecting = false;
2607              selectee.selected = true;
2608              selectee.startselected = true;
2609              self.element.triggerHandler("selectableselected", [event, {
2610                  selectable: self.element[0],
2611                  selected: selectee.element,
2612                  options: options
2613              }], options.selected);
2614          });
2615          this.element.triggerHandler("selectablestop", [event, {
2616              selectable: self.element[0],
2617              options: this.options
2618          }], this.options.stop);
2619  
2620          this.helper.remove();
2621  
2622          return false;
2623      }
2624  
2625  }));
2626  
2627  $.extend($.ui.selectable, {
2628      version: "1.6",
2629      defaults: {
2630          appendTo: 'body',
2631          autoRefresh: true,
2632          cancel: ":input",
2633          delay: 0,
2634          distance: 1,
2635          filter: '*',
2636          tolerance: 'touch'
2637      }
2638  });
2639  
2640  })(jQuery);
2641  /*

2642   * jQuery UI Sortable 1.6

2643   *

2644   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

2645   * Dual licensed under the MIT (MIT-LICENSE.txt)

2646   * and GPL (GPL-LICENSE.txt) licenses.

2647   *

2648   * http://docs.jquery.com/UI/Sortables

2649   *

2650   * Depends:

2651   *    ui.core.js

2652   */
2653  (function($) {
2654  
2655  $.widget("ui.sortable", $.extend({}, $.ui.mouse, {
2656      _init: function() {
2657  
2658          var o = this.options;
2659          this.containerCache = {};
2660          this.element.addClass("ui-sortable");
2661  
2662          //Get the items

2663          this.refresh();
2664  
2665          //Let's determine if the items are floating

2666          this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) : false;
2667  
2668          //Let's determine the parent's offset

2669          this.offset = this.element.offset();
2670  
2671          //Initialize mouse events for interaction

2672          this._mouseInit();
2673  
2674      },
2675  
2676      destroy: function() {
2677          this.element
2678              .removeClass("ui-sortable ui-sortable-disabled")
2679              .removeData("sortable")
2680              .unbind(".sortable");
2681          this._mouseDestroy();
2682  
2683          for ( var i = this.items.length - 1; i >= 0; i-- )
2684              this.items[i].item.removeData("sortable-item");
2685      },
2686  
2687      _mouseCapture: function(event, overrideHandle) {
2688  
2689          if (this.reverting) {
2690              return false;
2691          }
2692  
2693          if(this.options.disabled || this.options.type == 'static') return false;
2694  
2695          //We have to refresh the items data once first

2696          this._refreshItems(event);
2697  
2698          //Find out if the clicked node (or one of its parents) is a actual item in this.items

2699          var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
2700              if($.data(this, 'sortable-item') == self) {
2701                  currentItem = $(this);
2702                  return false;
2703              }
2704          });
2705          if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
2706  
2707          if(!currentItem) return false;
2708          if(this.options.handle && !overrideHandle) {
2709              var validHandle = false;
2710  
2711              $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
2712              if(!validHandle) return false;
2713          }
2714  
2715          this.currentItem = currentItem;
2716          this._removeCurrentsFromItems();
2717          return true;
2718  
2719      },
2720  
2721      _mouseStart: function(event, overrideHandle, noActivation) {
2722  
2723          var o = this.options;
2724          this.currentContainer = this;
2725  
2726          //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture

2727          this.refreshPositions();
2728  
2729          //Create and append the visible helper

2730          this.helper = this._createHelper(event);
2731  
2732          //Cache the helper size

2733          this._cacheHelperProportions();
2734  
2735          /*

2736           * - Position generation -

2737           * This block generates everything position related - it's the core of draggables.

2738           */
2739  
2740          //Cache the margins of the original element

2741          this._cacheMargins();
2742  
2743          //Get the next scrolling parent

2744          this.scrollParent = this.helper.scrollParent();
2745  
2746          //The element's absolute position on the page minus margins

2747          this.offset = this.currentItem.offset();
2748  
2749          this.offset = {
2750              top: this.offset.top - this.margins.top,
2751              left: this.offset.left - this.margins.left
2752          };
2753  
2754          // Only after we got the offset, we can change the helper's position to absolute

2755          // TODO: Still need to figure out a way to make relative sorting possible

2756          this.helper.css("position", "absolute");
2757          this.cssPosition = this.helper.css("position");
2758  
2759          $.extend(this.offset, {
2760              click: { //Where the click happened, relative to the element
2761                  left: event.pageX - this.offset.left,
2762                  top: event.pageY - this.offset.top
2763              },
2764              parent: this._getParentOffset(),
2765              relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
2766          });
2767  
2768          //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied

2769          if(o.cursorAt)
2770              this._adjustOffsetFromHelper(o.cursorAt);
2771  
2772          //Generate the original position

2773          this.originalPosition = this._generatePosition(event);
2774  
2775          //Cache the former DOM position

2776          this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
2777  
2778          //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

2779          if(this.helper[0] != this.currentItem[0]) {
2780              this.currentItem.hide();
2781          }
2782  
2783          //Create the placeholder

2784          this._createPlaceholder();
2785  
2786          //Set a containment if given in the options

2787          if(o.containment)
2788              this._setContainment();
2789  
2790          //Call plugins and callbacks

2791          this._propagate("start", event);
2792  
2793          //Recache the helper size

2794          if(!this._preserveHelperProportions)
2795              this._cacheHelperProportions();
2796  
2797  
2798          //Post 'activate' events to possible containers

2799          if(!noActivation) {
2800               for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._propagate("activate", event, this); }
2801          }
2802  
2803          //Prepare possible droppables

2804          if($.ui.ddmanager)
2805              $.ui.ddmanager.current = this;
2806  
2807          if ($.ui.ddmanager && !o.dropBehaviour)
2808              $.ui.ddmanager.prepareOffsets(this, event);
2809  
2810          this.dragging = true;
2811  
2812          this.helper.addClass('ui-sortable-helper');
2813          this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position

2814          return true;
2815  
2816      },
2817  
2818      _mouseDrag: function(event) {
2819  
2820          //Compute the helpers position

2821          this.position = this._generatePosition(event);
2822          this.positionAbs = this._convertPositionTo("absolute");
2823  
2824          if (!this.lastPositionAbs) {
2825              this.lastPositionAbs = this.positionAbs;
2826          }
2827  
2828          //Call the internal plugins

2829          $.ui.plugin.call(this, "sort", [event, this._ui()]);
2830  
2831          //Regenerate the absolute position used for position checks

2832          this.positionAbs = this._convertPositionTo("absolute");
2833  
2834          //Set the helper position

2835          if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
2836          if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
2837  
2838          //Rearrange

2839          for (var i = this.items.length - 1; i >= 0; i--) {
2840  
2841              //Cache variables and intersection, continue if no intersection

2842              var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
2843              if (!intersection) continue;
2844  
2845              if(itemElement != this.currentItem[0] //cannot intersect with itself
2846                  &&    this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
2847                  &&    !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
2848                  && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
2849              ) {
2850  
2851                  this.direction = intersection == 1 ? "down" : "up";
2852  
2853                  if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
2854                      this.options.sortIndicator.call(this, event, item);
2855                  } else {
2856                      break;
2857                  }
2858  
2859                  this._propagate("change", event); //Call plugins and callbacks

2860                  break;
2861              }
2862          }
2863  
2864          //Post events to containers

2865          this._contactContainers(event);
2866  
2867          //Interconnect with droppables

2868          if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
2869  
2870          //Call callbacks

2871          this._trigger('sort', event, this._ui());
2872  
2873          this.lastPositionAbs = this.positionAbs;
2874          return false;
2875  
2876      },
2877  
2878      _mouseStop: function(event, noPropagation) {
2879  
2880          if(!event) return;
2881  
2882          //If we are using droppables, inform the manager about the drop

2883          if ($.ui.ddmanager && !this.options.dropBehaviour)
2884              $.ui.ddmanager.drop(this, event);
2885  
2886          if(this.options.revert) {
2887              var self = this;
2888              var cur = self.placeholder.offset();
2889  
2890              self.reverting = true;
2891  
2892              $(this.helper).animate({
2893                  left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
2894                  top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
2895              }, parseInt(this.options.revert, 10) || 500, function() {
2896                  self._clear(event);
2897              });
2898          } else {
2899              this._clear(event, noPropagation);
2900          }
2901  
2902          return false;
2903  
2904      },
2905  
2906      cancel: function() {
2907  
2908          if(this.dragging) {
2909  
2910              this._mouseUp();
2911  
2912              if(this.options.helper == "original")
2913                  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
2914              else
2915                  this.currentItem.show();
2916  
2917              //Post deactivating events to containers

2918              for (var i = this.containers.length - 1; i >= 0; i--){
2919                  this.containers[i]._propagate("deactivate", null, this);
2920                  if(this.containers[i].containerCache.over) {
2921                      this.containers[i]._propagate("out", null, this);
2922                      this.containers[i].containerCache.over = 0;
2923                  }
2924              }
2925  
2926          }
2927  
2928          //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!

2929          if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
2930          if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
2931  
2932          $.extend(this, {
2933              helper: null,
2934              dragging: false,
2935              reverting: false,
2936              _noFinalSort: null
2937          });
2938  
2939          if(this.domPosition.prev) {
2940              $(this.domPosition.prev).after(this.currentItem);
2941          } else {
2942              $(this.domPosition.parent).prepend(this.currentItem);
2943          }
2944  
2945          return true;
2946  
2947      },
2948  
2949      serialize: function(o) {
2950  
2951          var items = this._getItemsAsjQuery(o && o.connected);
2952          var str = []; o = o || {};
2953  
2954          $(items).each(function() {
2955              var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
2956              if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
2957          });
2958  
2959          return str.join('&');
2960  
2961      },
2962  
2963      toArray: function(o) {
2964  
2965          var items = this._getItemsAsjQuery(o && o.connected);
2966          var ret = []; o = o || {};
2967  
2968          items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
2969          return ret;
2970  
2971      },
2972  
2973      /* Be careful with the following core functions */

2974      _intersectsWith: function(item) {
2975  
2976          var x1 = this.positionAbs.left,
2977              x2 = x1 + this.helperProportions.width,
2978              y1 = this.positionAbs.top,
2979              y2 = y1 + this.helperProportions.height;
2980  
2981          var l = item.left,
2982              r = l + item.width,
2983              t = item.top,
2984              b = t + item.height;
2985  
2986          var dyClick = this.offset.click.top,
2987              dxClick = this.offset.click.left;
2988  
2989          var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
2990  
2991          if(       this.options.tolerance == "pointer"
2992              || this.options.forcePointerForContainers
2993              || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
2994          ) {
2995              return isOverElement;
2996          } else {
2997  
2998              return (l < x1 + (this.helperProportions.width / 2) // Right Half
2999                  && x2 - (this.helperProportions.width / 2) < r // Left Half
3000                  && t < y1 + (this.helperProportions.height / 2) // Bottom Half
3001                  && y2 - (this.helperProportions.height / 2) < b ); // Top Half

3002  
3003          }
3004      },
3005  
3006      _intersectsWithPointer: function(item) {
3007  
3008          var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3009              isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3010              isOverElement = isOverElementHeight && isOverElementWidth,
3011              verticalDirection = this._getDragVerticalDirection(),
3012              horizontalDirection = this._getDragHorizontalDirection();
3013  
3014          if (!isOverElement)
3015              return false;
3016  
3017          return this.floating ?
3018              ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3019              : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3020  
3021      },
3022  
3023      _intersectsWithSides: function(item) {
3024  
3025          var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3026              isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3027              verticalDirection = this._getDragVerticalDirection(),
3028              horizontalDirection = this._getDragHorizontalDirection();
3029  
3030          if (this.floating && horizontalDirection) {
3031              return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3032          } else {
3033              return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3034          }
3035  
3036      },
3037  
3038      _getDragVerticalDirection: function() {
3039          var delta = this.positionAbs.top - this.lastPositionAbs.top;
3040          return delta != 0 && (delta > 0 ? "down" : "up");
3041      },
3042  
3043      _getDragHorizontalDirection: function() {
3044          var delta = this.positionAbs.left - this.lastPositionAbs.left;
3045          return delta != 0 && (delta > 0 ? "right" : "left");
3046      },
3047  
3048      refresh: function(event) {
3049          this._refreshItems(event);
3050          this.refreshPositions();
3051      },
3052  
3053      _getItemsAsjQuery: function(connected) {
3054  
3055          var self = this;
3056          var items = [];
3057          var queries = [];
3058  
3059          if(this.options.connectWith && connected) {
3060              for (var i = this.options.connectWith.length - 1; i >= 0; i--){
3061                  var cur = $(this.options.connectWith[i]);
3062                  for (var j = cur.length - 1; j >= 0; j--){
3063                      var inst = $.data(cur[j], 'sortable');
3064                      if(inst && inst != this && !inst.options.disabled) {
3065                          queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper"), inst]);
3066                      }
3067                  };
3068              };
3069          }
3070  
3071          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]);
3072  
3073          for (var i = queries.length - 1; i >= 0; i--){
3074              queries[i][0].each(function() {
3075                  items.push(this);
3076              });
3077          };
3078  
3079          return $(items);
3080  
3081      },
3082  
3083      _removeCurrentsFromItems: function() {
3084  
3085          var list = this.currentItem.find(":data(sortable-item)");
3086  
3087          for (var i=0; i < this.items.length; i++) {
3088  
3089              for (var j=0; j < list.length; j++) {
3090                  if(list[j] == this.items[i].item[0])
3091                      this.items.splice(i,1);
3092              };
3093  
3094          };
3095  
3096      },
3097  
3098      _refreshItems: function(event) {
3099  
3100          this.items = [];
3101          this.containers = [this];
3102          var items = this.items;
3103          var self = this;
3104          var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3105  
3106          if(this.options.connectWith) {
3107              for (var i = this.options.connectWith.length - 1; i >= 0; i--){
3108                  var cur = $(this.options.connectWith[i]);
3109                  for (var j = cur.length - 1; j >= 0; j--){
3110                      var inst = $.data(cur[j], 'sortable');
3111                      if(inst && inst != this && !inst.options.disabled) {
3112                          queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3113                          this.containers.push(inst);
3114                      }
3115                  };
3116              };
3117          }
3118  
3119          for (var i = queries.length - 1; i >= 0; i--) {
3120              var targetData = queries[i][1];
3121              var _queries = queries[i][0];
3122  
3123              for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3124                  var item = $(_queries[j]);
3125  
3126                  item.data('sortable-item', targetData); // Data for target checking (mouse manager)

3127  
3128                  items.push({
3129                      item: item,
3130                      instance: targetData,
3131                      width: 0, height: 0,
3132                      left: 0, top: 0
3133                  });
3134              };
3135          };
3136  
3137      },
3138  
3139      refreshPositions: function(fast) {
3140  
3141          //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change

3142          if(this.offsetParent && this.helper) {
3143              this.offset.parent = this._getParentOffset();
3144          }
3145  
3146          for (var i = this.items.length - 1; i >= 0; i--){
3147              var item = this.items[i];
3148  
3149              //We ignore calculating positions of all connected containers when we're not over them

3150              if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3151                  continue;
3152  
3153              var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3154  
3155              if (!fast) {
3156                  if (this.options.accurateIntersection) {
3157                      item.width = t.outerWidth();
3158                      item.height = t.outerHeight();
3159                  }
3160                  else {
3161                      item.width = t[0].offsetWidth;
3162                      item.height = t[0].offsetHeight;
3163                  }
3164              }
3165  
3166              var p = t.offset();
3167              item.left = p.left;
3168              item.top = p.top;
3169          };
3170  
3171          if(this.options.custom && this.options.custom.refreshContainers) {
3172              this.options.custom.refreshContainers.call(this);
3173          } else {
3174              for (var i = this.containers.length - 1; i >= 0; i--){
3175                  var p = this.containers[i].element.offset();
3176                  this.containers[i].containerCache.left = p.left;
3177                  this.containers[i].containerCache.top = p.top;
3178                  this.containers[i].containerCache.width    = this.containers[i].element.outerWidth();
3179                  this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3180              };
3181          }
3182  
3183      },
3184  
3185      _createPlaceholder: function(that) {
3186  
3187          var self = that || this, o = self.options;
3188  
3189          if(!o.placeholder || o.placeholder.constructor == String) {
3190              var className = o.placeholder;
3191              o.placeholder = {
3192                  element: function() {
3193  
3194                      var el = $(document.createElement(self.currentItem[0].nodeName))
3195                          .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3196                          .removeClass('ui-sortable-helper')[0];
3197  
3198                      if(!className) {
3199                          el.style.visibility = "hidden";
3200                          document.body.appendChild(el);
3201                          // Name attributes are removed, otherwice causes elements to be unchecked

3202                          // Expando attributes also have to be removed because of stupid IE (no condition, doesn't hurt in other browsers)

3203                          el.innerHTML = self.currentItem[0].innerHTML.replace(/name\=\"[^\"\']+\"/g, '').replace(/jQuery[0-9]+\=\"[^\"\']+\"/g, '');
3204                          document.body.removeChild(el);
3205                      };
3206  
3207                      return el;
3208                  },
3209                  update: function(container, p) {
3210                      if(className && !o.forcePlaceholderSize) return;
3211                      if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3212                      if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3213                  }
3214              };
3215          }
3216  
3217          //Create the placeholder

3218          self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3219  
3220          //Append it after the actual current item

3221          self.currentItem.after(self.placeholder);
3222  
3223          //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)

3224          o.placeholder.update(self, self.placeholder);
3225  
3226      },
3227  
3228      _contactContainers: function(event) {
3229          for (var i = this.containers.length - 1; i >= 0; i--){
3230  
3231              if(this._intersectsWith(this.containers[i].containerCache)) {
3232                  if(!this.containers[i].containerCache.over) {
3233  
3234                      if(this.currentContainer != this.containers[i]) {
3235  
3236                          //When entering a new container, we will find the item with the least distance and append our item near it

3237                          var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[i].floating ? 'left' : 'top'];
3238                          for (var j = this.items.length - 1; j >= 0; j--) {
3239                              if(!$.ui.contains(this.containers[i].element[0], this.items[j].item[0])) continue;
3240                              var cur = this.items[j][this.containers[i].floating ? 'left' : 'top'];
3241                              if(Math.abs(cur - base) < dist) {
3242                                  dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
3243                              }
3244                          }
3245  
3246                          if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
3247                              continue;
3248  
3249                          this.currentContainer = this.containers[i];
3250                          itemWithLeastDistance ? this.options.sortIndicator.call(this, event, itemWithLeastDistance, null, true) : this.options.sortIndicator.call(this, event, null, this.containers[i].element, true);
3251                          this._propagate("change", event); //Call plugins and callbacks

3252                          this.containers[i]._propagate("change", event, this); //Call plugins and callbacks

3253  
3254                          //Update the placeholder

3255                          this.options.placeholder.update(this.currentContainer, this.placeholder);
3256  
3257                      }
3258  
3259                      this.containers[i]._propagate("over", event, this);
3260                      this.containers[i].containerCache.over = 1;
3261                  }
3262              } else {
3263                  if(this.containers[i].containerCache.over) {
3264                      this.containers[i]._propagate("out", event, this);
3265                      this.containers[i].containerCache.over = 0;
3266                  }
3267              }
3268  
3269          };
3270      },
3271  
3272      _createHelper: function(event) {
3273  
3274          var o = this.options;
3275          var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3276  
3277          if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3278              $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3279  
3280          if(helper[0] == this.currentItem[0])
3281              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") };
3282  
3283          if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3284          if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3285  
3286          return helper;
3287  
3288      },
3289  
3290      _adjustOffsetFromHelper: function(obj) {
3291          if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
3292          if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
3293          if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
3294          if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
3295      },
3296  
3297      _getParentOffset: function() {
3298  
3299          //Get the offsetParent and cache its position

3300          this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset();
3301  
3302          if((this.offsetParent[0] == document.body && $.browser.mozilla)    //Ugly FF3 fix
3303          || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
3304              po = { top: 0, left: 0 };
3305  
3306          return {
3307              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
3308              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
3309          };
3310  
3311      },
3312  
3313      _getRelativeOffset: function() {
3314  
3315          if(this.cssPosition == "relative") {
3316              var p = this.currentItem.position();
3317              return {
3318                  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
3319                  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
3320              };
3321          } else {
3322              return { top: 0, left: 0 };
3323          }
3324  
3325      },
3326  
3327      _cacheMargins: function() {
3328          this.margins = {
3329              left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
3330              top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
3331          };
3332      },
3333  
3334      _cacheHelperProportions: function() {
3335          this.helperProportions = {
3336              width: this.helper.outerWidth(),
3337              height: this.helper.outerHeight()
3338          };
3339      },
3340  
3341      _setContainment: function() {
3342  
3343          var o = this.options;
3344          if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
3345          if(o.containment == 'document' || o.containment == 'window') this.containment = [
3346              0 - this.offset.relative.left - this.offset.parent.left,
3347              0 - this.offset.relative.top - this.offset.parent.top,
3348              $(o.containment == 'document' ? document : window).width() - this.offset.relative.left - this.offset.parent.left - this.margins.left - (parseInt(this.currentItem.css("marginRight"),10) || 0),
3349              ($(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)
3350          ];
3351  
3352          if(!(/^(document|window|parent)$/).test(o.containment)) {
3353              var ce = $(o.containment)[0];
3354              var co = $(o.containment).offset();
3355              var over = ($(ce).css("overflow") != 'hidden');
3356  
3357              this.containment = [
3358                  co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) - this.offset.relative.left - this.offset.parent.left - this.margins.left,
3359                  co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) - this.offset.relative.top - this.offset.parent.top - this.margins.top,
3360                  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,
3361                  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
3362              ];
3363          }
3364  
3365      },
3366  
3367      _convertPositionTo: function(d, pos) {
3368  
3369          if(!pos) pos = this.position;
3370          var mod = d == "absolute" ? 1 : -1;
3371          var scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3372  
3373          return {
3374              top: (
3375                  pos.top                                                                    // the calculated relative position
3376                  + this.offset.relative.top    * mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
3377                  + this.offset.parent.top * mod                                            // The offsetParent's offset without borders (offset + border)
3378                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod
3379                  + this.margins.top * mod                                                //Add the margin (you don't want the margin counting in intersection methods)
3380              ),
3381              left: (
3382                  pos.left                                                                // the calculated relative position
3383                  + this.offset.relative.left    * mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
3384                  + this.offset.parent.left * mod                                            // The offsetParent's offset without borders (offset + border)
3385                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) ) * mod
3386                  + this.margins.left * mod                                                //Add the margin (you don't want the margin counting in intersection methods)
3387              )
3388          };
3389      },
3390  
3391      _generatePosition: function(event) {
3392  
3393          var o = this.options, scroll = this[(this.cssPosition == 'absolute' ? 'offset' : 'scroll')+'Parent'], scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3394  
3395          var position = {
3396              top: (
3397                  event.pageY                                                                // The absolute mouse position
3398                  - this.offset.click.top                                                    // Click offset (relative to the element)
3399                  - this.offset.relative.top                                                // Only for relative positioned nodes: Relative offset from element to offset parent
3400                  - this.offset.parent.top                                                // The offsetParent's offset without borders (offset + border)
3401                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )
3402              ),
3403              left: (
3404                  event.pageX                                                                // The absolute mouse position
3405                  - this.offset.click.left                                                // Click offset (relative to the element)
3406                  - this.offset.relative.left                                                // Only for relative positioned nodes: Relative offset from element to offset parent
3407                  - this.offset.parent.left                                                // The offsetParent's offset without borders (offset + border)
3408                  + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : ( scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
3409              )
3410          };
3411  
3412          if(!this.originalPosition) return position;                                        //If we are not dragging yet, we won't check for options

3413  
3414          /*

3415           * - Position constraining -

3416           * Constrain the position to a mix of grid, containment.

3417           */
3418          if(this.containment) {
3419              if(position.left < this.containment[0]) position.left = this.containment[0];
3420              if(position.top < this.containment[1]) position.top = this.containment[1];
3421              if(position.left + this.helperProportions.width > this.containment[2]) position.left = this.containment[2] - this.helperProportions.width;
3422              if(position.top + this.helperProportions.height > this.containment[3]) position.top = this.containment[3] - this.helperProportions.height;
3423          }
3424  
3425          if(o.grid) {
3426              var top = this.originalPosition.top + Math.round((position.top - this.originalPosition.top) / o.grid[1]) * o.grid[1];
3427              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;
3428  
3429              var left = this.originalPosition.left + Math.round((position.left - this.originalPosition.left) / o.grid[0]) * o.grid[0];
3430              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;
3431          }
3432  
3433          return position;
3434      },
3435  
3436      _rearrange: function(event, i, a, hardRefresh) {
3437  
3438          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));
3439  
3440          //Various things done here to improve the performance:

3441          // 1. we create a setTimeout, that calls refreshPositions

3442          // 2. on the instance, we have a counter variable, that get's higher after every append

3443          // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same

3444          // 4. this lets only the last addition to the timeout stack through

3445          this.counter = this.counter ? ++this.counter : 1;
3446          var self = this, counter = this.counter;
3447  
3448          window.setTimeout(function() {
3449              if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove

3450          },0);
3451  
3452      },
3453  
3454      _clear: function(event, noPropagation) {
3455  
3456          this.reverting = false;
3457  
3458          //We first have to update the dom position of the actual currentItem

3459          if(!this._noFinalSort) this.placeholder.before(this.currentItem);
3460          this._noFinalSort = null;
3461  
3462          if(this.helper[0] == this.currentItem[0]) {
3463              for(var i in this._storedCSS) {
3464                  if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
3465              }
3466              this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3467          } else {
3468              this.currentItem.show();
3469          }
3470  
3471          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

3472          if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
3473              this._propagate("remove", event, null, noPropagation);
3474              for (var i = this.containers.length - 1; i >= 0; i--){
3475                  if($.ui.contains(this.containers[i].element[0], this.currentItem[0])) {
3476                      this.containers[i]._propagate("update", event, this, noPropagation);
3477                      this.containers[i]._propagate("receive", event, this, noPropagation);
3478                  }
3479              };
3480          };
3481  
3482          //Post events to containers

3483          for (var i = this.containers.length - 1; i >= 0; i--){
3484              this.containers[i]._propagate("deactivate", event, this, noPropagation);
3485              if(this.containers[i].containerCache.over) {
3486                  this.containers[i]._propagate("out", event, this);
3487                  this.containers[i].containerCache.over = 0;
3488              }
3489          }
3490  
3491          this.dragging = false;
3492          if(this.cancelHelperRemoval) {
3493              this._propagate("beforeStop", event, null, noPropagation);
3494              this._propagate("stop", event, null, noPropagation);
3495              return false;
3496          }
3497  
3498          this._propagate("beforeStop", event, null, noPropagation);
3499  
3500          //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!

3501          this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3502  
3503          if(this.options.helper != "original") this.helper.remove(); this.helper = null;
3504          this._propagate("stop", event, null, noPropagation);
3505  
3506          return true;
3507  
3508      },
3509  
3510      _propagate: function(n, event, inst, noPropagation) {
3511          $.ui.plugin.call(this, n, [event, this._ui(inst)]);
3512          var dontCancel = !noPropagation ? this.element.triggerHandler(n == "sort" ? n : "sort"+n, [event, this._ui(inst)], this.options[n]) : true;
3513          if(dontCancel === false) this.cancel();
3514      },
3515  
3516      plugins: {},
3517  
3518      _ui: function(inst) {
3519          var self = inst || this;
3520          return {
3521              helper: self.helper,
3522              placeholder: self.placeholder || $([]),
3523              position: self.position,
3524              absolutePosition: self.positionAbs,
3525              item: self.currentItem,
3526              sender: inst ? inst.element : null
3527          };
3528      }
3529  
3530  }));
3531  
3532  $.extend($.ui.sortable, {
3533      getter: "serialize toArray",
3534      version: "1.6",
3535      defaults: {
3536          accurateIntersection: true,
3537          appendTo: "parent",
3538          cancel: ":input",
3539          delay: 0,
3540          distance: 1,
3541          dropOnEmpty: true,
3542          forcePlaceholderSize: false,
3543          forceHelperSize: false,
3544          helper: "original",
3545          items: '> *',
3546          scope: "default",
3547          scroll: true,
3548          scrollSensitivity: 20,
3549          scrollSpeed: 20,
3550          sortIndicator: $.ui.sortable.prototype._rearrange,
3551          tolerance: "default",
3552          zIndex: 1000
3553      }
3554  });
3555  
3556  /*

3557   * Sortable Extensions

3558   */
3559  
3560  $.ui.plugin.add("sortable", "cursor", {
3561      start: function(event, ui) {
3562          var t = $('body'), i = $(this).data('sortable');
3563          if (t.css("cursor")) i.options._cursor = t.css("cursor");
3564          t.css("cursor", i.options.cursor);
3565      },
3566      beforeStop: function(event, ui) {
3567          var i = $(this).data('sortable');
3568          if (i.options._cursor) $('body').css("cursor", i.options._cursor);
3569      }
3570  });
3571  
3572  $.ui.plugin.add("sortable", "opacity", {
3573      start: function(event, ui) {
3574          var t = ui.helper, i = $(this).data('sortable');
3575          if(t.css("opacity")) i.options._opacity = t.css("opacity");
3576          t.css('opacity', i.options.opacity);
3577      },
3578      beforeStop: function(event, ui) {
3579          var i = $(this).data('sortable');
3580          if(i.options._opacity) $(ui.helper).css('opacity', i.options._opacity);
3581      }
3582  });
3583  
3584  $.ui.plugin.add("sortable", "scroll", {
3585      start: function(event, ui) {
3586          var i = $(this).data("sortable"), o = i.options;
3587          if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
3588      },
3589      sort: function(event, ui) {
3590  
3591          var i = $(this).data("sortable"), o = i.options, scrolled = false;
3592  
3593          if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
3594  
3595              if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3596                  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
3597              else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
3598                  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
3599  
3600              if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3601                  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
3602              else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
3603                  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
3604  
3605          } else {
3606  
3607              if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3608                  scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3609              else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3610                  scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3611  
3612              if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3613                  scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3614              else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3615                  scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3616  
3617          }
3618  
3619          if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3620              $.ui.ddmanager.prepareOffsets(i, event);
3621  
3622  
3623  
3624          //This is a special case where we need to modify a offset calculated on start, since the following happened:

3625          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent

3626          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that

3627          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag

3628          if(scrolled !== false && i.cssPosition == 'absolute' && i.scrollParent[0] != document && $.ui.contains(i.scrollParent[0], i.offsetParent[0])) {
3629              i.offset.parent = i._getParentOffset();
3630          }
3631          
3632          // This is another very weird special case that only happens for relative elements:

3633          // 1. If the css position is relative

3634          // 2. and the scroll parent is the document or similar to the offset parent

3635          // we have to refresh the relative offset during the scroll so there are no jumps

3636          if(scrolled !== false && i.cssPosition == 'relative' && !(i.scrollParent[0] != document && i.scrollParent[0] != i.offsetParent[0])) {
3637              i.offset.relative = i._getRelativeOffset();
3638          }
3639  
3640      }
3641  });
3642  
3643  $.ui.plugin.add("sortable", "zIndex", {
3644      start: function(event, ui) {
3645          var t = ui.helper, i = $(this).data('sortable');
3646          if(t.css("zIndex")) i.options._zIndex = t.css("zIndex");
3647          t.css('zIndex', i.options.zIndex);
3648      },
3649      beforeStop: function(event, ui) {
3650          var i = $(this).data('sortable');
3651          if(i.options._zIndex) $(ui.helper).css('zIndex', i.options._zIndex == 'auto' ? '' : i.options._zIndex);
3652      }
3653  });
3654  
3655  })(jQuery);
3656  /*

3657   * jQuery UI Effects 1.6

3658   *

3659   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

3660   * Dual licensed under the MIT (MIT-LICENSE.txt)

3661   * and GPL (GPL-LICENSE.txt) licenses.

3662   *

3663   * http://docs.jquery.com/UI/Effects/

3664   */
3665  ;(function($) {
3666  
3667  $.effects = $.effects || {}; //Add the 'effects' scope

3668  
3669  $.extend($.effects, {
3670      version: "1.6",
3671      save: function(el, set) {
3672          for(var i=0;i<set.length;i++) {
3673              if(set[i] !== null) $.data(el[0], "ec.storage."+set[i], el[0].style[set[i]]);
3674          }
3675      },
3676      restore: function(el, set) {
3677          for(var i=0;i<set.length;i++) {
3678              if(set[i] !== null) el.css(set[i], $.data(el[0], "ec.storage."+set[i]));
3679          }
3680      },
3681      setMode: function(el, mode) {
3682          if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle

3683          return mode;
3684      },
3685      getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
3686          // this should be a little more flexible in the future to handle a string & hash

3687          var y, x;
3688          switch (origin[0]) {
3689              case 'top': y = 0; break;
3690              case 'middle': y = 0.5; break;
3691              case 'bottom': y = 1; break;
3692              default: y = origin[0] / original.height;
3693          };
3694          switch (origin[1]) {
3695              case 'left': x = 0; break;
3696              case 'center': x = 0.5; break;
3697              case 'right': x = 1; break;
3698              default: x = origin[1] / original.width;
3699          };
3700          return {x: x, y: y};
3701      },
3702      createWrapper: function(el) {
3703          if (el.parent().attr('id') == 'fxWrapper')
3704              return el;
3705          var props = {width: el.outerWidth({margin:true}), height: el.outerHeight({margin:true}), 'float': el.css('float')};
3706          el.wrap('<div id="fxWrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');
3707          var wrapper = el.parent();
3708          if (el.css('position') == 'static'){
3709              wrapper.css({position: 'relative'});
3710              el.css({position: 'relative'});
3711          } else {
3712              var top = el.css('top'); if(isNaN(parseInt(top))) top = 'auto';
3713              var left = el.css('left'); if(isNaN(parseInt(left))) left = 'auto';
3714              wrapper.css({ position: el.css('position'), top: top, left: left, zIndex: el.css('z-index') }).show();
3715              el.css({position: 'relative', top:0, left:0});
3716          }
3717          wrapper.css(props);
3718          return wrapper;
3719      },
3720      removeWrapper: function(el) {
3721          if (el.parent().attr('id') == 'fxWrapper')
3722              return el.parent().replaceWith(el);
3723          return el;
3724      },
3725      setTransition: function(el, list, factor, val) {
3726          val = val || {};
3727          $.each(list,function(i, x){
3728              unit = el.cssUnit(x);
3729              if (unit[0] > 0) val[x] = unit[0] * factor + unit[1];
3730          });
3731          return val;
3732      },
3733      animateClass: function(value, duration, easing, callback) {
3734  
3735          var cb = (typeof easing == "function" ? easing : (callback ? callback : null));
3736          var ea = (typeof easing == "object" ? easing : null);
3737  
3738          return this.each(function() {
3739  
3740              var offset = {}; var that = $(this); var oldStyleAttr = that.attr("style") || '';
3741              if(typeof oldStyleAttr == 'object') oldStyleAttr = oldStyleAttr["cssText"]; /* Stupidly in IE, style is a object.. */
3742              if(value.toggle) { that.hasClass(value.toggle) ? value.remove = value.toggle : value.add = value.toggle; }
3743  
3744              //Let's get a style offset

3745              var oldStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
3746              if(value.add) that.addClass(value.add); if(value.remove) that.removeClass(value.remove);
3747              var newStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
3748              if(value.add) that.removeClass(value.add); if(value.remove) that.addClass(value.remove);
3749  
3750              // The main function to form the object for animation

3751              for(var n in newStyle) {
3752                  if( typeof newStyle[n] != "function" && newStyle[n] /* No functions and null properties */
3753                  && n.indexOf("Moz") == -1 && n.indexOf("length") == -1 /* No mozilla spezific render properties. */
3754                  && newStyle[n] != oldStyle[n] /* Only values that have changed are used for the animation */
3755                  && (n.match(/color/i) || (!n.match(/color/i) && !isNaN(parseInt(newStyle[n],10)))) /* Only things that can be parsed to integers or colors */
3756                  && (oldStyle.position != "static" || (oldStyle.position == "static" && !n.match(/left|top|bottom|right/))) /* No need for positions when dealing with static positions */
3757                  ) offset[n] = newStyle[n];
3758              }
3759  
3760              that.animate(offset, duration, ea, function() { // Animate the newly constructed offset object
3761                  // Change style attribute back to original. For stupid IE, we need to clear the damn object.

3762                  if(typeof $(this).attr("style") == 'object') { $(this).attr("style")["cssText"] = ""; $(this).attr("style")["cssText"] = oldStyleAttr; } else $(this).attr("style", oldStyleAttr);
3763                  if(value.add) $(this).addClass(value.add); if(value.remove) $(this).removeClass(value.remove);
3764                  if(cb) cb.apply(this, arguments);
3765              });
3766  
3767          });
3768      }
3769  });
3770  
3771  //Extend the methods of jQuery

3772  $.fn.extend({
3773      //Save old methods

3774      _show: $.fn.show,
3775      _hide: $.fn.hide,
3776      __toggle: $.fn.toggle,
3777      _addClass: $.fn.addClass,
3778      _removeClass: $.fn.removeClass,
3779      _toggleClass: $.fn.toggleClass,
3780      // New ec methods

3781      effect: function(fx,o,speed,callback) {
3782          return $.effects[fx] ? $.effects[fx].call(this, {method: fx, options: o || {}, duration: speed, callback: callback }) : null;
3783      },
3784      show: function() {
3785          if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])))
3786              return this._show.apply(this, arguments);
3787          else {
3788              var o = arguments[1] || {}; o['mode'] = 'show';
3789              return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]);
3790          }
3791      },
3792      hide: function() {
3793          if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])))
3794              return this._hide.apply(this, arguments);
3795          else {
3796              var o = arguments[1] || {}; o['mode'] = 'hide';
3797              return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]);
3798          }
3799      },
3800      toggle: function(){
3801          if(!arguments[0] || (arguments[0].constructor == Number || /(slow|normal|fast)/.test(arguments[0])) || (arguments[0].constructor == Function))
3802              return this.__toggle.apply(this, arguments);
3803          else {
3804              var o = arguments[1] || {}; o['mode'] = 'toggle';
3805              return this.effect.apply(this, [arguments[0], o, arguments[2] || o.duration, arguments[3] || o.callback]);
3806          }
3807      },
3808      addClass: function(classNames,speed,easing,callback) {
3809          return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
3810      },
3811      removeClass: function(classNames,speed,easing,callback) {
3812          return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
3813      },
3814      toggleClass: function(classNames,speed,easing,callback) {
3815          return speed ? $.effects.animateClass.apply(this, [{ toggle: classNames },speed,easing,callback]) : this._toggleClass(classNames);
3816      },
3817      morph: function(remove,add,speed,easing,callback) {
3818          return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
3819      },
3820      switchClass: function() {
3821          return this.morph.apply(this, arguments);
3822      },
3823      // helper functions

3824      cssUnit: function(key) {
3825          var style = this.css(key), val = [];
3826          $.each( ['em','px','%','pt'], function(i, unit){
3827              if(style.indexOf(unit) > 0)
3828                  val = [parseFloat(style), unit];
3829          });
3830          return val;
3831      }
3832  });
3833  
3834  /*

3835   * jQuery Color Animations

3836   * Copyright 2007 John Resig

3837   * Released under the MIT and GPL licenses.

3838   */
3839  
3840  // We override the animation for all of these color styles

3841  $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
3842          $.fx.step[attr] = function(fx){
3843                  if ( fx.state == 0 ) {
3844                          fx.start = getColor( fx.elem, attr );
3845                          fx.end = getRGB( fx.end );
3846                  }
3847  
3848                  fx.elem.style[attr] = "rgb(" + [
3849                          Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0]), 255), 0),
3850                          Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1]), 255), 0),
3851                          Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2]), 255), 0)
3852                  ].join(",") + ")";
3853          }
3854  });
3855  
3856  // Color Conversion functions from highlightFade

3857  // By Blair Mitchelmore

3858  // http://jquery.offput.ca/highlightFade/

3859  
3860  // Parse strings looking for color tuples [255,255,255]

3861  function getRGB(color) {
3862          var result;
3863  
3864          // Check if we're already dealing with an array of colors

3865          if ( color && color.constructor == Array && color.length == 3 )
3866                  return color;
3867  
3868          // Look for rgb(num,num,num)

3869          if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
3870                  return [parseInt(result[1]), parseInt(result[2]), parseInt(result[3])];
3871  
3872          // Look for rgb(num%,num%,num%)

3873          if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
3874                  return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
3875  
3876          // Look for #a0b1c2

3877          if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
3878                  return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
3879  
3880          // Look for #fff

3881          if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
3882                  return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
3883  
3884          // Look for rgba(0, 0, 0, 0) == transparent in Safari 3

3885          if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
3886                  return colors['transparent'];
3887  
3888          // Otherwise, we're most likely dealing with a named color

3889          return colors[$.trim(color).toLowerCase()];
3890  }
3891  
3892  function getColor(elem, attr) {
3893          var color;
3894  
3895          do {
3896                  color = $.curCSS(elem, attr);
3897  
3898                  // Keep going until we find an element that has color, or we hit the body

3899                  if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
3900                          break;
3901  
3902                  attr = "backgroundColor";
3903          } while ( elem = elem.parentNode );
3904  
3905          return getRGB(color);
3906  };
3907  
3908  // Some named colors to work with

3909  // From Interface by Stefan Petre

3910  // http://interface.eyecon.ro/

3911  
3912  var colors = {
3913      aqua:[0,255,255],
3914      azure:[240,255,255],
3915      beige:[245,245,220],
3916      black:[0,0,0],
3917      blue:[0,0,255],
3918      brown:[165,42,42],
3919      cyan:[0,255,255],
3920      darkblue:[0,0,139],
3921      darkcyan:[0,139,139],
3922      darkgrey:[169,169,169],
3923      darkgreen:[0,100,0],
3924      darkkhaki:[189,183,107],
3925      darkmagenta:[139,0,139],
3926      darkolivegreen:[85,107,47],
3927      darkorange:[255,140,0],
3928      darkorchid:[153,50,204],
3929      darkred:[139,0,0],
3930      darksalmon:[233,150,122],
3931      darkviolet:[148,0,211],
3932      fuchsia:[255,0,255],
3933      gold:[255,215,0],
3934      green:[0,128,0],
3935      indigo:[75,0,130],
3936      khaki:[240,230,140],
3937      lightblue:[173,216,230],
3938      lightcyan:[224,255,255],
3939      lightgreen:[144,238,144],
3940      lightgrey:[211,211,211],
3941      lightpink:[255,182,193],
3942      lightyellow:[255,255,224],
3943      lime:[0,255,0],
3944      magenta:[255,0,255],
3945      maroon:[128,0,0],
3946      navy:[0,0,128],
3947      olive:[128,128,0],
3948      orange:[255,165,0],
3949      pink:[255,192,203],
3950      purple:[128,0,128],
3951      violet:[128,0,128],
3952      red:[255,0,0],
3953      silver:[192,192,192],
3954      white:[255,255,255],
3955      yellow:[255,255,0],
3956      transparent: [255,255,255]
3957  };
3958  
3959  /*

3960   * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/

3961   *

3962   * Uses the built in easing capabilities added In jQuery 1.1

3963   * to offer multiple easing options

3964   *

3965   * TERMS OF USE - jQuery Easing

3966   *

3967   * Open source under the BSD License.

3968   *

3969   * Copyright © 2008 George McGinley Smith

3970   * All rights reserved.

3971   *

3972   * Redistribution and use in source and binary forms, with or without modification,

3973   * are permitted provided that the following conditions are met:

3974   *

3975   * Redistributions of source code must retain the above copyright notice, this list of

3976   * conditions and the following disclaimer.

3977   * Redistributions in binary form must reproduce the above copyright notice, this list

3978   * of conditions and the following disclaimer in the documentation and/or other materials

3979   * provided with the distribution.

3980   *

3981   * Neither the name of the author nor the names of contributors may be used to endorse

3982   * or promote products derived from this software without specific prior written permission.

3983   *

3984   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY

3985   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

3986   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

3987   * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

3988   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

3989   * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED

3990   * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

3991   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

3992   * OF THE POSSIBILITY OF SUCH DAMAGE.

3993   *

3994  */
3995  
3996  // t: current time, b: begInnIng value, c: change In value, d: duration

3997  $.easing.jswing = $.easing.swing;
3998  
3999  $.extend($.easing,
4000  {
4001      def: 'easeOutQuad',
4002      swing: function (x, t, b, c, d) {
4003          //alert($.easing.default);

4004          return $.easing[$.easing.def](x, t, b, c, d);
4005      },
4006      easeInQuad: function (x, t, b, c, d) {
4007          return c*(t/=d)*t + b;
4008      },
4009      easeOutQuad: function (x, t, b, c, d) {
4010          return -c *(t/=d)*(t-2) + b;
4011      },
4012      easeInOutQuad: function (x, t, b, c, d) {
4013          if ((t/=d/2) < 1) return c/2*t*t + b;
4014          return -c/2 * ((--t)*(t-2) - 1) + b;
4015      },
4016      easeInCubic: function (x, t, b, c, d) {
4017          return c*(t/=d)*t*t + b;
4018      },
4019      easeOutCubic: function (x, t, b, c, d) {
4020          return c*((t=t/d-1)*t*t + 1) + b;
4021      },
4022      easeInOutCubic: function (x, t, b, c, d) {
4023          if ((t/=d/2) < 1) return c/2*t*t*t + b;
4024          return c/2*((t-=2)*t*t + 2) + b;
4025      },
4026      easeInQuart: function (x, t, b, c, d) {
4027          return c*(t/=d)*t*t*t + b;
4028      },
4029      easeOutQuart: function (x, t, b, c, d) {
4030          return -c * ((t=t/d-1)*t*t*t - 1) + b;
4031      },
4032      easeInOutQuart: function (x, t, b, c, d) {
4033          if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
4034          return -c/2 * ((t-=2)*t*t*t - 2) + b;
4035      },
4036      easeInQuint: function (x, t, b, c, d) {
4037          return c*(t/=d)*t*t*t*t + b;
4038      },
4039      easeOutQuint: function (x, t, b, c, d) {
4040          return c*((t=t/d-1)*t*t*t*t + 1) + b;
4041      },
4042      easeInOutQuint: function (x, t, b, c, d) {
4043          if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
4044          return c/2*((t-=2)*t*t*t*t + 2) + b;
4045      },
4046      easeInSine: function (x, t, b, c, d) {
4047          return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
4048      },
4049      easeOutSine: function (x, t, b, c, d) {
4050          return c * Math.sin(t/d * (Math.PI/2)) + b;
4051      },
4052      easeInOutSine: function (x, t, b, c, d) {
4053          return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
4054      },
4055      easeInExpo: function (x, t, b, c, d) {
4056          return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
4057      },
4058      easeOutExpo: function (x, t, b, c, d) {
4059          return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
4060      },
4061      easeInOutExpo: function (x, t, b, c, d) {
4062          if (t==0) return b;
4063          if (t==d) return b+c;
4064          if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
4065          return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
4066      },
4067      easeInCirc: function (x, t, b, c, d) {
4068          return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
4069      },
4070      easeOutCirc: function (x, t, b, c, d) {
4071          return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
4072      },
4073      easeInOutCirc: function (x, t, b, c, d) {
4074          if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
4075          return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
4076      },
4077      easeInElastic: function (x, t, b, c, d) {
4078          var s=1.70158;var p=0;var a=c;
4079          if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
4080          if (a < Math.abs(c)) { a=c; var s=p/4; }
4081          else var s = p/(2*Math.PI) * Math.asin (c/a);
4082          return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4083      },
4084      easeOutElastic: function (x, t, b, c, d) {
4085          var s=1.70158;var p=0;var a=c;
4086          if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
4087          if (a < Math.abs(c)) { a=c; var s=p/4; }
4088          else var s = p/(2*Math.PI) * Math.asin (c/a);
4089          return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
4090      },
4091      easeInOutElastic: function (x, t, b, c, d) {
4092          var s=1.70158;var p=0;var a=c;
4093          if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
4094          if (a < Math.abs(c)) { a=c; var s=p/4; }
4095          else var s = p/(2*Math.PI) * Math.asin (c/a);
4096          if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4097          return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
4098      },
4099      easeInBack: function (x, t, b, c, d, s) {
4100          if (s == undefined) s = 1.70158;
4101          return c*(t/=d)*t*((s+1)*t - s) + b;
4102      },
4103      easeOutBack: function (x, t, b, c, d, s) {
4104          if (s == undefined) s = 1.70158;
4105          return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
4106      },
4107      easeInOutBack: function (x, t, b, c, d, s) {
4108          if (s == undefined) s = 1.70158;
4109          if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
4110          return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
4111      },
4112      easeInBounce: function (x, t, b, c, d) {
4113          return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
4114      },
4115      easeOutBounce: function (x, t, b, c, d) {
4116          if ((t/=d) < (1/2.75)) {
4117              return c*(7.5625*t*t) + b;
4118          } else if (t < (2/2.75)) {
4119              return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
4120          } else if (t < (2.5/2.75)) {
4121              return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
4122          } else {
4123              return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
4124          }
4125      },
4126      easeInOutBounce: function (x, t, b, c, d) {
4127          if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
4128          return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
4129      }
4130  });
4131  
4132  /*

4133   *

4134   * TERMS OF USE - EASING EQUATIONS

4135   *

4136   * Open source under the BSD License.

4137   *

4138   * Copyright © 2001 Robert Penner

4139   * All rights reserved.

4140   *

4141   * Redistribution and use in source and binary forms, with or without modification,

4142   * are permitted provided that the following conditions are met:

4143   *

4144   * Redistributions of source code must retain the above copyright notice, this list of

4145   * conditions and the following disclaimer.

4146   * Redistributions in binary form must reproduce the above copyright notice, this list

4147   * of conditions and the following disclaimer in the documentation and/or other materials

4148   * provided with the distribution.

4149   *

4150   * Neither the name of the author nor the names of contributors may be used to endorse

4151   * or promote products derived from this software without specific prior written permission.

4152   *

4153   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY

4154   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

4155   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE

4156   * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

4157   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE

4158   * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED

4159   * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

4160   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED

4161   * OF THE POSSIBILITY OF SUCH DAMAGE.

4162   *

4163   */
4164  
4165  })(jQuery);
4166  /*

4167   * jQuery UI Effects Blind 1.6

4168   *

4169   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4170   * Dual licensed under the MIT (MIT-LICENSE.txt)

4171   * and GPL (GPL-LICENSE.txt) licenses.

4172   *

4173   * http://docs.jquery.com/UI/Effects/Blind

4174   *

4175   * Depends:

4176   *    effects.core.js

4177   */
4178  (function($) {
4179  
4180  $.effects.blind = function(o) {
4181  
4182      return this.queue(function() {
4183  
4184          // Create element

4185          var el = $(this), props = ['position','top','left'];
4186  
4187          // Set options

4188          var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode

4189          var direction = o.options.direction || 'vertical'; // Default direction

4190  
4191          // Adjust

4192          $.effects.save(el, props); el.show(); // Save & Show

4193          var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper

4194          var ref = (direction == 'vertical') ? 'height' : 'width';
4195          var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
4196          if(mode == 'show') wrapper.css(ref, 0); // Shift

4197  
4198          // Animation

4199          var animation = {};
4200          animation[ref] = mode == 'show' ? distance : 0;
4201  
4202          // Animate

4203          wrapper.animate(animation, o.duration, o.options.easing, function() {
4204              if(mode == 'hide') el.hide(); // Hide

4205              $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore

4206              if(o.callback) o.callback.apply(el[0], arguments); // Callback

4207              el.dequeue();
4208          });
4209  
4210      });
4211  
4212  };
4213  
4214  })(jQuery);
4215  /*

4216   * jQuery UI Effects Bounce 1.6

4217   *

4218   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4219   * Dual licensed under the MIT (MIT-LICENSE.txt)

4220   * and GPL (GPL-LICENSE.txt) licenses.

4221   *

4222   * http://docs.jquery.com/UI/Effects/Bounce

4223   *

4224   * Depends:

4225   *    effects.core.js

4226   */
4227  (function($) {
4228  
4229  $.effects.bounce = function(o) {
4230  
4231      return this.queue(function() {
4232  
4233          // Create element

4234          var el = $(this), props = ['position','top','left'];
4235  
4236          // Set options

4237          var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode

4238          var direction = o.options.direction || 'up'; // Default direction

4239          var distance = o.options.distance || 20; // Default distance

4240          var times = o.options.times || 5; // Default # of times

4241          var speed = o.duration || 250; // Default speed per bounce

4242          if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE

4243  
4244          // Adjust

4245          $.effects.save(el, props); el.show(); // Save & Show

4246          $.effects.createWrapper(el); // Create Wrapper

4247          var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4248          var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4249          var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
4250          if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift

4251          if (mode == 'hide') distance = distance / (times * 2);
4252          if (mode != 'hide') times--;
4253  
4254          // Animate

4255          if (mode == 'show') { // Show Bounce
4256              var animation = {opacity: 1};
4257              animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4258              el.animate(animation, speed / 2, o.options.easing);
4259              distance = distance / 2;
4260              times--;
4261          };
4262          for (var i = 0; i < times; i++) { // Bounces
4263              var animation1 = {}, animation2 = {};
4264              animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4265              animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4266              el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
4267              distance = (mode == 'hide') ? distance * 2 : distance / 2;
4268          };
4269          if (mode == 'hide') { // Last Bounce
4270              var animation = {opacity: 0};
4271              animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
4272              el.animate(animation, speed / 2, o.options.easing, function(){
4273                  el.hide(); // Hide

4274                  $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore

4275                  if(o.callback) o.callback.apply(this, arguments); // Callback

4276              });
4277          } else {
4278              var animation1 = {}, animation2 = {};
4279              animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4280              animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4281              el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
4282                  $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore

4283                  if(o.callback) o.callback.apply(this, arguments); // Callback

4284              });
4285          };
4286          el.queue('fx', function() { el.dequeue(); });
4287          el.dequeue();
4288      });
4289  
4290  };
4291  
4292  })(jQuery);
4293  /*

4294   * jQuery UI Effects Clip 1.6

4295   *

4296   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4297   * Dual licensed under the MIT (MIT-LICENSE.txt)

4298   * and GPL (GPL-LICENSE.txt) licenses.

4299   *

4300   * http://docs.jquery.com/UI/Effects/Clip

4301   *

4302   * Depends:

4303   *    effects.core.js

4304   */
4305  (function($) {
4306  
4307  $.effects.clip = function(o) {
4308  
4309      return this.queue(function() {
4310  
4311          // Create element

4312          var el = $(this), props = ['position','top','left','height','width'];
4313  
4314          // Set options

4315          var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode

4316          var direction = o.options.direction || 'vertical'; // Default direction

4317  
4318          // Adjust

4319          $.effects.save(el, props); el.show(); // Save & Show

4320          var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper

4321          var animate = el[0].tagName == 'IMG' ? wrapper : el;
4322          var ref = {
4323              size: (direction == 'vertical') ? 'height' : 'width',
4324              position: (direction == 'vertical') ? 'top' : 'left'
4325          };
4326          var distance = (direction == 'vertical') ? animate.height() : animate.width();
4327          if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift

4328  
4329          // Animation

4330          var animation = {};
4331          animation[ref.size] = mode == 'show' ? distance : 0;
4332          animation[ref.position] = mode == 'show' ? 0 : distance / 2;
4333  
4334          // Animate

4335          animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4336              if(mode == 'hide') el.hide(); // Hide

4337              $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore

4338              if(o.callback) o.callback.apply(el[0], arguments); // Callback

4339              el.dequeue();
4340          }});
4341  
4342      });
4343  
4344  };
4345  
4346  })(jQuery);
4347  /*

4348   * jQuery UI Effects Drop 1.6

4349   *

4350   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4351   * Dual licensed under the MIT (MIT-LICENSE.txt)

4352   * and GPL (GPL-LICENSE.txt) licenses.

4353   *

4354   * http://docs.jquery.com/UI/Effects/Drop

4355   *

4356   * Depends:

4357   *    effects.core.js

4358   */
4359  (function($) {
4360  
4361  $.effects.drop = function(o) {
4362  
4363      return this.queue(function() {
4364  
4365          // Create element

4366          var el = $(this), props = ['position','top','left','opacity'];
4367  
4368          // Set options

4369          var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode

4370          var direction = o.options.direction || 'left'; // Default Direction

4371  
4372          // Adjust

4373          $.effects.save(el, props); el.show(); // Save & Show

4374          $.effects.createWrapper(el); // Create Wrapper

4375          var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4376          var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4377          var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
4378          if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift

4379  
4380          // Animation

4381          var animation = {opacity: mode == 'show' ? 1 : 0};
4382          animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
4383  
4384          // Animate

4385          el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4386              if(mode == 'hide') el.hide(); // Hide

4387              $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore

4388              if(o.callback) o.callback.apply(this, arguments); // Callback

4389              el.dequeue();
4390          }});
4391  
4392      });
4393  
4394  };
4395  
4396  })(jQuery);
4397  /*

4398   * jQuery UI Effects Explode 1.6

4399   *

4400   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4401   * Dual licensed under the MIT (MIT-LICENSE.txt)

4402   * and GPL (GPL-LICENSE.txt) licenses.

4403   *

4404   * http://docs.jquery.com/UI/Effects/Explode

4405   *

4406   * Depends:

4407   *    effects.core.js

4408   */
4409  (function($) {
4410  
4411  $.effects.explode = function(o) {
4412  
4413      return this.queue(function() {
4414  
4415      var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
4416      var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
4417  
4418      o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
4419      var el = $(this).show().css('visibility', 'hidden');
4420      var offset = el.offset();
4421  
4422      //Substract the margins - not fixing the problem yet.

4423      offset.top -= parseInt(el.css("marginTop")) || 0;
4424      offset.left -= parseInt(el.css("marginLeft")) || 0;
4425  
4426      var width = el.outerWidth(true);
4427      var height = el.outerHeight(true);
4428  
4429      for(var i=0;i<rows;i++) { // =
4430          for(var j=0;j<cells;j++) { // ||
4431              el
4432                  .clone()
4433                  .appendTo('body')
4434                  .wrap('<div></div>')
4435                  .css({
4436                      position: 'absolute',
4437                      visibility: 'visible',
4438                      left: -j*(width/cells),
4439                      top: -i*(height/rows)
4440                  })
4441                  .parent()
4442                  .addClass('effects-explode')
4443                  .css({
4444                      position: 'absolute',
4445                      overflow: 'hidden',
4446                      width: width/cells,
4447                      height: height/rows,
4448                      left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
4449                      top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
4450                      opacity: o.options.mode == 'show' ? 0 : 1
4451                  }).animate({
4452                      left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
4453                      top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
4454                      opacity: o.options.mode == 'show' ? 1 : 0
4455                  }, o.duration || 500);
4456          }
4457      }
4458  
4459      // Set a timeout, to call the callback approx. when the other animations have finished

4460      setTimeout(function() {
4461  
4462          o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
4463                  if(o.callback) o.callback.apply(el[0]); // Callback

4464                  el.dequeue();
4465  
4466                  $('.effects-explode').remove();
4467  
4468      }, o.duration || 500);
4469  
4470  
4471      });
4472  
4473  };
4474  
4475  })(jQuery);
4476  /*

4477   * jQuery UI Effects Fold 1.6

4478   *

4479   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4480   * Dual licensed under the MIT (MIT-LICENSE.txt)

4481   * and GPL (GPL-LICENSE.txt) licenses.

4482   *

4483   * http://docs.jquery.com/UI/Effects/Fold

4484   *

4485   * Depends:

4486   *    effects.core.js

4487   */
4488  (function($) {
4489  
4490  $.effects.fold = function(o) {
4491  
4492      return this.queue(function() {
4493  
4494          // Create element

4495          var el = $(this), props = ['position','top','left'];
4496  
4497          // Set options

4498          var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode

4499          var size = o.options.size || 15; // Default fold size

4500          var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value

4501  
4502          // Adjust

4503          $.effects.save(el, props); el.show(); // Save & Show

4504          var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper

4505          var widthFirst = ((mode == 'show') != horizFirst);
4506          var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
4507          var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
4508          var percent = /([0-9]+)%/.exec(size);
4509          if(percent) size = parseInt(percent[1]) / 100 * distance[mode == 'hide' ? 0 : 1];
4510          if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift

4511  
4512          // Animation

4513          var animation1 = {}, animation2 = {};
4514          animation1[ref[0]] = mode == 'show' ? distance[0] : size;
4515          animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
4516  
4517          // Animate

4518          wrapper.animate(animation1, o.duration / 2, o.options.easing)
4519          .animate(animation2, o.duration / 2, o.options.easing, function() {
4520              if(mode == 'hide') el.hide(); // Hide

4521              $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore

4522              if(o.callback) o.callback.apply(el[0], arguments); // Callback

4523              el.dequeue();
4524          });
4525  
4526      });
4527  
4528  };
4529  
4530  })(jQuery);
4531  /*

4532   * jQuery UI Effects Highlight 1.6

4533   *

4534   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4535   * Dual licensed under the MIT (MIT-LICENSE.txt)

4536   * and GPL (GPL-LICENSE.txt) licenses.

4537   *

4538   * http://docs.jquery.com/UI/Effects/Highlight

4539   *

4540   * Depends:

4541   *    effects.core.js

4542   */
4543  (function($) {
4544  
4545  $.effects.highlight = function(o) {
4546  
4547      return this.queue(function() {
4548  
4549          // Create element

4550          var el = $(this), props = ['backgroundImage','backgroundColor','opacity'];
4551  
4552          // Set options

4553          var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode

4554          var color = o.options.color || "#ffff99"; // Default highlight color

4555          var oldColor = el.css("backgroundColor");
4556  
4557          // Adjust

4558          $.effects.save(el, props); el.show(); // Save & Show

4559          el.css({backgroundImage: 'none', backgroundColor: color}); // Shift

4560  
4561          // Animation

4562          var animation = {backgroundColor: oldColor };
4563          if (mode == "hide") animation['opacity'] = 0;
4564  
4565          // Animate

4566          el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4567              if(mode == "hide") el.hide();
4568              $.effects.restore(el, props);
4569          if (mode == "show" && $.browser.msie) this.style.removeAttribute('filter');
4570              if(o.callback) o.callback.apply(this, arguments);
4571              el.dequeue();
4572          }});
4573  
4574      });
4575  
4576  };
4577  
4578  })(jQuery);
4579  /*

4580   * jQuery UI Effects Pulsate 1.6

4581   *

4582   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4583   * Dual licensed under the MIT (MIT-LICENSE.txt)

4584   * and GPL (GPL-LICENSE.txt) licenses.

4585   *

4586   * http://docs.jquery.com/UI/Effects/Pulsate

4587   *

4588   * Depends:

4589   *    effects.core.js

4590   */
4591  (function($) {
4592  
4593  $.effects.pulsate = function(o) {
4594  
4595      return this.queue(function() {
4596  
4597          // Create element

4598          var el = $(this);
4599  
4600          // Set options

4601          var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode

4602          var times = o.options.times || 5; // Default # of times

4603  
4604          // Adjust

4605          if (mode == 'hide') times--;
4606          if (el.is(':hidden')) { // Show fadeIn
4607              el.css('opacity', 0);
4608              el.show(); // Show

4609              el.animate({opacity: 1}, o.duration / 2, o.options.easing);
4610              times = times-2;
4611          }
4612  
4613          // Animate

4614          for (var i = 0; i < times; i++) { // Pulsate
4615              el.animate({opacity: 0}, o.duration / 2, o.options.easing).animate({opacity: 1}, o.duration / 2, o.options.easing);
4616          };
4617          if (mode == 'hide') { // Last Pulse
4618              el.animate({opacity: 0}, o.duration / 2, o.options.easing, function(){
4619                  el.hide(); // Hide

4620                  if(o.callback) o.callback.apply(this, arguments); // Callback

4621              });
4622          } else {
4623              el.animate({opacity: 0}, o.duration / 2, o.options.easing).animate({opacity: 1}, o.duration / 2, o.options.easing, function(){
4624                  if(o.callback) o.callback.apply(this, arguments); // Callback

4625              });
4626          };
4627          el.queue('fx', function() { el.dequeue(); });
4628          el.dequeue();
4629      });
4630  
4631  };
4632  
4633  })(jQuery);
4634  /*

4635   * jQuery UI Effects Scale 1.6

4636   *

4637   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4638   * Dual licensed under the MIT (MIT-LICENSE.txt)

4639   * and GPL (GPL-LICENSE.txt) licenses.

4640   *

4641   * http://docs.jquery.com/UI/Effects/Scale

4642   *

4643   * Depends:

4644   *    effects.core.js

4645   */
4646  (function($) {
4647  
4648  $.effects.puff = function(o) {
4649  
4650      return this.queue(function() {
4651  
4652          // Create element

4653          var el = $(this);
4654  
4655          // Set options

4656          var options = $.extend(true, {}, o.options);
4657          var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode

4658          var percent = parseInt(o.options.percent) || 150; // Set default puff percent

4659          options.fade = true; // It's not a puff if it doesn't fade! :)

4660          var original = {height: el.height(), width: el.width()}; // Save original

4661  
4662          // Adjust

4663          var factor = percent / 100;
4664          el.from = (mode == 'hide') ? original : {height: original.height * factor, width: original.width * factor};
4665  
4666          // Animation

4667          options.from = el.from;
4668          options.percent = (mode == 'hide') ? percent : 100;
4669          options.mode = mode;
4670  
4671          // Animate

4672          el.effect('scale', options, o.duration, o.callback);
4673          el.dequeue();
4674      });
4675  
4676  };
4677  
4678  $.effects.scale = function(o) {
4679  
4680      return this.queue(function() {
4681  
4682          // Create element

4683          var el = $(this);
4684  
4685          // Set options

4686          var options = $.extend(true, {}, o.options);
4687          var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode

4688          var percent = parseInt(o.options.percent) || (parseInt(o.options.percent) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent

4689          var direction = o.options.direction || 'both'; // Set default axis

4690          var origin = o.options.origin; // The origin of the scaling

4691          if (mode != 'effect') { // Set default origin and restore for show/hide
4692              options.origin = origin || ['middle','center'];
4693              options.restore = true;
4694          }
4695          var original = {height: el.height(), width: el.width()}; // Save original

4696          el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state

4697  
4698          // Adjust

4699          var factor = { // Set scaling factor
4700              y: direction != 'horizontal' ? (percent / 100) : 1,
4701              x: direction != 'vertical' ? (percent / 100) : 1
4702          };
4703          el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state

4704  
4705          if (o.options.fade) { // Fade option to support puff
4706              if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
4707              if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
4708          };
4709  
4710          // Animation

4711          options.from = el.from; options.to = el.to; options.mode = mode;
4712  
4713          // Animate

4714          el.effect('size', options, o.duration, o.callback);
4715          el.dequeue();
4716      });
4717  
4718  };
4719  
4720  $.effects.size = function(o) {
4721  
4722      return this.queue(function() {
4723  
4724          // Create element

4725          var el = $(this), props = ['position','top','left','width','height','overflow','opacity'];
4726          var props1 = ['position','top','left','overflow','opacity']; // Always restore

4727          var props2 = ['width','height','overflow']; // Copy for children

4728          var cProps = ['fontSize'];
4729          var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
4730          var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
4731  
4732          // Set options

4733          var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode

4734          var restore = o.options.restore || false; // Default restore

4735          var scale = o.options.scale || 'both'; // Default scale mode

4736          var origin = o.options.origin; // The origin of the sizing

4737          var original = {height: el.height(), width: el.width()}; // Save original

4738          el.from = o.options.from || original; // Default from state

4739          el.to = o.options.to || original; // Default to state

4740          // Adjust

4741          if (origin) { // Calculate baseline shifts
4742              var baseline = $.effects.getBaseline(origin, original);
4743              el.from.top = (original.height - el.from.height) * baseline.y;
4744              el.from.left = (original.width - el.from.width) * baseline.x;
4745              el.to.top = (original.height - el.to.height) * baseline.y;
4746              el.to.left = (original.width - el.to.width) * baseline.x;
4747          };
4748          var factor = { // Set scaling factor
4749              from: {y: el.from.height / original.height, x: el.from.width / original.width},
4750              to: {y: el.to.height / original.height, x: el.to.width / original.width}
4751          };
4752          if (scale == 'box' || scale == 'both') { // Scale the css box
4753              if (factor.from.y != factor.to.y) { // Vertical props scaling
4754                  props = props.concat(vProps);
4755                  el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
4756                  el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
4757              };
4758              if (factor.from.x != factor.to.x) { // Horizontal props scaling
4759                  props = props.concat(hProps);
4760                  el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
4761                  el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
4762              };
4763          };
4764          if (scale == 'content' || scale == 'both') { // Scale the content
4765              if (factor.from.y != factor.to.y) { // Vertical props scaling
4766                  props = props.concat(cProps);
4767                  el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
4768                  el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
4769              };
4770          };
4771          $.effects.save(el, restore ? props : props1); el.show(); // Save & Show

4772          $.effects.createWrapper(el); // Create Wrapper

4773          el.css('overflow','hidden').css(el.from); // Shift

4774  
4775          // Animate

4776          if (scale == 'content' || scale == 'both') { // Scale the children
4777              vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size

4778              hProps = hProps.concat(['marginLeft','marginRight']); // Add margins

4779              props2 = props.concat(vProps).concat(hProps); // Concat

4780              el.find("*[width]").each(function(){
4781                  child = $(this);
4782                  if (restore) $.effects.save(child, props2);
4783                  var c_original = {height: child.height(), width: child.width()}; // Save original

4784                  child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
4785                  child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
4786                  if (factor.from.y != factor.to.y) { // Vertical props scaling
4787                      child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
4788                      child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
4789                  };
4790                  if (factor.from.x != factor.to.x) { // Horizontal props scaling
4791                      child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
4792                      child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
4793                  };
4794                  child.css(child.from); // Shift children

4795                  child.animate(child.to, o.duration, o.options.easing, function(){
4796                      if (restore) $.effects.restore(child, props2); // Restore children

4797                  }); // Animate children

4798              });
4799          };
4800  
4801          // Animate

4802          el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4803              if(mode == 'hide') el.hide(); // Hide

4804              $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore

4805              if(o.callback) o.callback.apply(this, arguments); // Callback

4806              el.dequeue();
4807          }});
4808  
4809      });
4810  
4811  };
4812  
4813  })(jQuery);
4814  /*

4815   * jQuery UI Effects Shake 1.6

4816   *

4817   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4818   * Dual licensed under the MIT (MIT-LICENSE.txt)

4819   * and GPL (GPL-LICENSE.txt) licenses.

4820   *

4821   * http://docs.jquery.com/UI/Effects/Shake

4822   *

4823   * Depends:

4824   *    effects.core.js

4825   */
4826  (function($) {
4827  
4828  $.effects.shake = function(o) {
4829  
4830      return this.queue(function() {
4831  
4832          // Create element

4833          var el = $(this), props = ['position','top','left'];
4834  
4835          // Set options

4836          var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode

4837          var direction = o.options.direction || 'left'; // Default direction

4838          var distance = o.options.distance || 20; // Default distance

4839          var times = o.options.times || 3; // Default # of times

4840          var speed = o.duration || o.options.duration || 140; // Default speed per shake

4841  
4842          // Adjust

4843          $.effects.save(el, props); el.show(); // Save & Show

4844          $.effects.createWrapper(el); // Create Wrapper

4845          var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4846          var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4847  
4848          // Animation

4849          var animation = {}, animation1 = {}, animation2 = {};
4850          animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
4851          animation1[ref] = (motion == 'pos' ? '+=' : '-=')  + distance * 2;
4852          animation2[ref] = (motion == 'pos' ? '-=' : '+=')  + distance * 2;
4853  
4854          // Animate

4855          el.animate(animation, speed, o.options.easing);
4856          for (var i = 1; i < times; i++) { // Shakes
4857              el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
4858          };
4859          el.animate(animation1, speed, o.options.easing).
4860          animate(animation, speed / 2, o.options.easing, function(){ // Last shake
4861              $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore

4862              if(o.callback) o.callback.apply(this, arguments); // Callback

4863          });
4864          el.queue('fx', function() { el.dequeue(); });
4865          el.dequeue();
4866      });
4867  
4868  };
4869  
4870  })(jQuery);
4871  /*

4872   * jQuery UI Effects Slide 1.6

4873   *

4874   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4875   * Dual licensed under the MIT (MIT-LICENSE.txt)

4876   * and GPL (GPL-LICENSE.txt) licenses.

4877   *

4878   * http://docs.jquery.com/UI/Effects/Slide

4879   *

4880   * Depends:

4881   *    effects.core.js

4882   */
4883  (function($) {
4884  
4885  $.effects.slide = function(o) {
4886  
4887      return this.queue(function() {
4888  
4889          // Create element

4890          var el = $(this), props = ['position','top','left'];
4891  
4892          // Set options

4893          var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode

4894          var direction = o.options.direction || 'left'; // Default Direction

4895  
4896          // Adjust

4897          $.effects.save(el, props); el.show(); // Save & Show

4898          $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper

4899          var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4900          var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4901          var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
4902          if (mode == 'show') el.css(ref, motion == 'pos' ? -distance : distance); // Shift

4903  
4904          // Animation

4905          var animation = {};
4906          animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
4907  
4908          // Animate

4909          el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4910              if(mode == 'hide') el.hide(); // Hide

4911              $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore

4912              if(o.callback) o.callback.apply(this, arguments); // Callback

4913              el.dequeue();
4914          }});
4915  
4916      });
4917  
4918  };
4919  
4920  })(jQuery);
4921  /*

4922   * jQuery UI Effects Transfer 1.6

4923   *

4924   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4925   * Dual licensed under the MIT (MIT-LICENSE.txt)

4926   * and GPL (GPL-LICENSE.txt) licenses.

4927   *

4928   * http://docs.jquery.com/UI/Effects/Transfer

4929   *

4930   * Depends:

4931   *    effects.core.js

4932   */
4933  (function($) {
4934  
4935  $.effects.transfer = function(o) {
4936  
4937      return this.queue(function() {
4938  
4939          // Create element

4940          var el = $(this);
4941  
4942          // Set options

4943          var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode

4944          var target = $(o.options.to); // Find Target

4945          var position = el.offset();
4946          var transfer = $('<div class="ui-effects-transfer"></div>').appendTo(document.body);
4947          if(o.options.className) transfer.addClass(o.options.className);
4948  
4949          // Set target css

4950          transfer.addClass(o.options.className);
4951          transfer.css({
4952              top: position.top,
4953              left: position.left,
4954              height: el.outerHeight() - parseInt(transfer.css('borderTopWidth')) - parseInt(transfer.css('borderBottomWidth')),
4955              width: el.outerWidth() - parseInt(transfer.css('borderLeftWidth')) - parseInt(transfer.css('borderRightWidth')),
4956              position: 'absolute'
4957          });
4958  
4959          // Animation

4960          position = target.offset();
4961          animation = {
4962              top: position.top,
4963              left: position.left,
4964              height: target.outerHeight() - parseInt(transfer.css('borderTopWidth')) - parseInt(transfer.css('borderBottomWidth')),
4965              width: target.outerWidth() - parseInt(transfer.css('borderLeftWidth')) - parseInt(transfer.css('borderRightWidth'))
4966          };
4967  
4968          // Animate

4969          transfer.animate(animation, o.duration, o.options.easing, function() {
4970              transfer.remove(); // Remove div

4971              if(o.callback) o.callback.apply(el[0], arguments); // Callback

4972              el.dequeue();
4973          });
4974  
4975      });
4976  
4977  };
4978  
4979  })(jQuery);
4980  /*

4981   * jQuery UI Accordion 1.6

4982   *

4983   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

4984   * Dual licensed under the MIT (MIT-LICENSE.txt)

4985   * and GPL (GPL-LICENSE.txt) licenses.

4986   *

4987   * http://docs.jquery.com/UI/Accordion

4988   *

4989   * Depends:

4990   *    ui.core.js

4991   */
4992  (function($) {
4993  
4994  $.widget("ui.accordion", {
4995  
4996      _init: function() {
4997          var options = this.options;
4998  
4999          if ( options.navigation ) {
5000              var current = this.element.find("a").filter(options.navigationFilter);
5001              if ( current.length ) {
5002                  if ( current.filter(options.header).length ) {
5003                      options.active = current;
5004                  } else {
5005                      options.active = current.parent().parent().prev();
5006                      current.addClass("current");
5007                  }
5008              }
5009          }
5010  
5011          // calculate active if not specified, using the first header

5012          options.headers = this.element.find(options.header);
5013          options.active = findActive(options.headers, options.active);
5014  
5015          // IE7-/Win - Extra vertical space in Lists fixed

5016          if ($.browser.msie) {
5017              this.element.find('a').css('zoom', '1');
5018          }
5019  
5020          if (!this.element.hasClass("ui-accordion")) {
5021              this.element.addClass("ui-accordion");
5022              $('<span class="ui-accordion-left"></span>').insertBefore(options.headers);
5023              $('<span class="ui-accordion-right"></span>').appendTo(options.headers);
5024              options.headers.addClass("ui-accordion-header");
5025          }
5026  
5027          var maxHeight;
5028          if ( options.fillSpace ) {
5029              maxHeight = this.element.parent().height();
5030              options.headers.each(function() {
5031                  maxHeight -= $(this).outerHeight();
5032              });
5033              var maxPadding = 0;
5034              options.headers.next().each(function() {
5035                  maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height());
5036              }).height(maxHeight - maxPadding);
5037          } else if ( options.autoHeight ) {
5038              maxHeight = 0;
5039              options.headers.next().each(function() {
5040                  maxHeight = Math.max(maxHeight, $(this).outerHeight());
5041              }).height(maxHeight);
5042          }
5043  
5044          this.element.attr('role','tablist');
5045  
5046          var self=this;
5047          options.headers
5048              .attr('role','tab')
5049              .bind('keydown', function(event) { return self._keydown(event); })
5050              .next()
5051              .attr('role','tabpanel');
5052  
5053          options.headers
5054              .not(options.active || "")
5055              .attr('aria-expanded','false')
5056              .attr("tabIndex", "-1")
5057              .next()
5058              .hide();
5059  
5060          // make sure at least one header is in the tab order

5061          if (!options.active.length) {
5062              options.headers.eq(0).attr('tabIndex','0');
5063          } else {
5064              options.active
5065                  .attr('aria-expanded','true')
5066                  .attr("tabIndex", "0")
5067                  .parent().andSelf().addClass(options.selectedClass);
5068          }
5069  
5070          // only need links in taborder for Safari

5071          if (!$.browser.safari)
5072              options.headers.find('a').attr('tabIndex','-1');
5073  
5074          if (options.event) {
5075              this.element.bind((options.event) + ".accordion", clickHandler);
5076          }
5077      },
5078  
5079      destroy: function() {
5080          this.options.headers.parent().andSelf().removeClass(this.options.selectedClass);
5081          this.options.headers.prev(".ui-accordion-left").remove();
5082          this.options.headers.children(".ui-accordion-right").remove();
5083          this.options.headers.next().css("display", "");
5084          if ( this.options.fillSpace || this.options.autoHeight ) {
5085              this.options.headers.next().css("height", "");
5086          }
5087          $.removeData(this.element[0], "accordion");
5088  
5089          this.element.removeClass("ui-accordion").unbind(".accordion");
5090      },
5091  
5092      _keydown: function(event) {
5093          if (this.options.disabled || event.altKey || event.ctrlKey)
5094              return;
5095  
5096          var keyCode = $.ui.keyCode;
5097  
5098          var length = this.options.headers.length;
5099          var currentIndex = this.options.headers.index(event.target);
5100          var toFocus = false;
5101  
5102          switch(event.keyCode) {
5103              case keyCode.RIGHT:
5104              case keyCode.DOWN:
5105                  toFocus = this.options.headers[(currentIndex + 1) % length];
5106                  break;
5107              case keyCode.LEFT:
5108              case keyCode.UP:
5109                  toFocus = this.options.headers[(currentIndex - 1 + length) % length];
5110                  break;
5111              case keyCode.SPACE:
5112              case keyCode.ENTER:
5113                  return clickHandler.call(this.element[0], { target: event.target });
5114          }
5115  
5116          if (toFocus) {
5117              $(event.target).attr('tabIndex','-1');
5118              $(toFocus).attr('tabIndex','0');
5119              toFocus.focus();
5120              return false;
5121          }
5122  
5123          return true;
5124      },
5125  
5126      activate: function(index) {
5127          // call clickHandler with custom event

5128          clickHandler.call(this.element[0], {
5129              target: findActive( this.options.headers, index )[0]
5130          });
5131      }
5132  
5133  });
5134  
5135  function scopeCallback(callback, scope) {
5136      return function() {
5137          return callback.apply(scope, arguments);
5138      };
5139  };
5140  
5141  function completed(cancel) {
5142      // if removed while animated data can be empty

5143      if (!$.data(this, "accordion")) {
5144          return;
5145      }
5146  
5147      var instance = $.data(this, "accordion");
5148      var options = instance.options;
5149      options.running = cancel ? 0 : --options.running;
5150      if ( options.running ) {
5151          return;
5152      }
5153      if ( options.clearStyle ) {
5154          options.toShow.add(options.toHide).css({
5155              height: "",
5156              overflow: ""
5157          });
5158      }
5159      instance._trigger('change', null, options.data);
5160  }
5161  
5162  function toggle(toShow, toHide, data, clickedActive, down) {
5163      var options = $.data(this, "accordion").options;
5164      options.toShow = toShow;
5165      options.toHide = toHide;
5166      options.data = data;
5167      var complete = scopeCallback(completed, this);
5168  
5169      $.data(this, "accordion")._trigger("changestart", null, options.data);
5170  
5171      // count elements to animate

5172      options.running = toHide.size() === 0 ? toShow.size() : toHide.size();
5173  
5174      if ( options.animated ) {
5175          var animOptions = {};
5176  
5177          if ( !options.alwaysOpen && clickedActive ) {
5178              animOptions = {
5179                  toShow: $([]),
5180                  toHide: toHide,
5181                  complete: complete,
5182                  down: down,
5183                  autoHeight: options.autoHeight
5184              };
5185          } else {
5186              animOptions = {
5187                  toShow: toShow,
5188                  toHide: toHide,
5189                  complete: complete,
5190                  down: down,
5191                  autoHeight: options.autoHeight
5192              };
5193          }
5194  
5195          if (!options.proxied) {
5196              options.proxied = options.animated;
5197          }
5198  
5199          if (!options.proxiedDuration) {
5200              options.proxiedDuration = options.duration;
5201          }
5202  
5203          options.animated = $.isFunction(options.proxied) ?
5204              options.proxied(animOptions) : options.proxied;
5205  
5206          options.duration = $.isFunction(options.proxiedDuration) ?
5207              options.proxiedDuration(animOptions) : options.proxiedDuration;
5208  
5209          var animations = $.ui.accordion.animations,
5210              duration = options.duration,
5211              easing = options.animated;
5212  
5213          if (!animations[easing]) {
5214              animations[easing] = function(options) {
5215                  this.slide(options, {
5216                      easing: easing,
5217                      duration: duration || 700
5218                  });
5219              };
5220          }
5221  
5222          animations[easing](animOptions);
5223  
5224      } else {
5225          if ( !options.alwaysOpen && clickedActive ) {
5226              toShow.toggle();
5227          } else {
5228              toHide.hide();
5229              toShow.show();
5230          }
5231          complete(true);
5232      }
5233      toHide.prev().attr('aria-expanded','false').attr("tabIndex", "-1");
5234      toShow.prev().attr('aria-expanded','true').attr("tabIndex", "0").focus();;
5235  }
5236  
5237  function clickHandler(event) {
5238      var options = $.data(this, "accordion").options;
5239      if (options.disabled) {
5240          return false;
5241      }
5242  
5243      // called only when using activate(false) to close all parts programmatically

5244      if ( !event.target && !options.alwaysOpen ) {
5245          options.active.parent().andSelf().toggleClass(options.selectedClass);
5246          var toHide = options.active.next(),
5247              data = {
5248                  options: options,
5249                  newHeader: $([]),
5250                  oldHeader: options.active,
5251                  newContent: $([]),
5252                  oldContent: toHide
5253              },
5254              toShow = (options.active = $([]));
5255          toggle.call(this, toShow, toHide, data );
5256          return false;
5257      }
5258      // get the click target

5259      var clicked = $(event.target);
5260  
5261      // due to the event delegation model, we have to check if one

5262      // of the parent elements is our actual header, and find that

5263      // otherwise stick with the initial target

5264      clicked = $( clicked.parents(options.header)[0] || clicked );
5265  
5266      var clickedActive = clicked[0] == options.active[0];
5267  
5268      // if animations are still active, or the active header is the target, ignore click

5269      if (options.running || (options.alwaysOpen && clickedActive)) {
5270          return false;
5271      }
5272      if (!clicked.is(options.header)) {
5273          return;
5274      }
5275  
5276      // switch classes

5277      options.active.parent().andSelf().toggleClass(options.selectedClass);
5278      if ( !clickedActive ) {
5279          clicked.parent().andSelf().addClass(options.selectedClass);
5280      }
5281  
5282      // find elements to show and hide

5283      var toShow = clicked.next(),
5284          toHide = options.active.next(),
5285          data = {
5286              options: options,
5287              newHeader: clickedActive && !options.alwaysOpen ? $([]) : clicked,
5288              oldHeader: options.active,
5289              newContent: clickedActive && !options.alwaysOpen ? $([]) : toShow,
5290              oldContent: toHide
5291          },
5292          down = options.headers.index( options.active[0] ) > options.headers.index( clicked[0] );
5293  
5294      options.active = clickedActive ? $([]) : clicked;
5295      toggle.call(this, toShow, toHide, data, clickedActive, down );
5296  
5297      return false;
5298  };
5299  
5300  function findActive(headers, selector) {
5301      return selector
5302          ? typeof selector == "number"
5303              ? headers.filter(":eq(" + selector + ")")
5304              : headers.not(headers.not(selector))
5305          : selector === false
5306              ? $([])
5307              : headers.filter(":eq(0)");
5308  }
5309  
5310  $.extend($.ui.accordion, {
5311      version: "1.6",
5312      defaults: {
5313          autoHeight: true,
5314          alwaysOpen: true,
5315          animated: 'slide',
5316          event: "click",
5317          header: "a",
5318          navigationFilter: function() {
5319              return this.href.toLowerCase() == location.href.toLowerCase();
5320          },
5321          running: 0,
5322          selectedClass: "selected"
5323      },
5324      animations: {
5325          slide: function(options, additions) {
5326              options = $.extend({
5327                  easing: "swing",
5328                  duration: 300
5329              }, options, additions);
5330              if ( !options.toHide.size() ) {
5331                  options.toShow.animate({height: "show"}, options);
5332                  return;
5333              }
5334              var hideHeight = options.toHide.height(),
5335                  showHeight = options.toShow.height(),
5336                  difference = showHeight / hideHeight,
5337                  padding = options.toShow.outerHeight() - options.toShow.height(),
5338                  margin = options.toShow.css('marginBottom'),
5339                  overflow = options.toShow.css('overflow')
5340                  tmargin = options.toShow.css('marginTop');
5341              options.toShow.css({ height: 0, overflow: 'hidden', marginTop: 0, marginBottom: -padding }).show();
5342              options.toHide.filter(":hidden").each(options.complete).end().filter(":visible").animate({height:"hide"},{
5343                  step: function(now) {
5344                      var current = (hideHeight - now) * difference;
5345                      if ($.browser.msie || $.browser.opera) {
5346                          current = Math.ceil(current);
5347                      }
5348                      options.toShow.height( current );
5349                  },
5350                  duration: options.duration,
5351                  easing: options.easing,
5352                  complete: function() {
5353                      if ( !options.autoHeight ) {
5354                          options.toShow.css("height", "auto");
5355                      }
5356                      options.toShow.css({marginTop: tmargin, marginBottom: margin, overflow: overflow});
5357                      options.complete();
5358                  }
5359              });
5360          },
5361          bounceslide: function(options) {
5362              this.slide(options, {
5363                  easing: options.down ? "easeOutBounce" : "swing",
5364                  duration: options.down ? 1000 : 200
5365              });
5366          },
5367          easeslide: function(options) {
5368              this.slide(options, {
5369                  easing: "easeinout",
5370                  duration: 700
5371              });
5372          }
5373      }
5374  });
5375  
5376  })(jQuery);
5377  /*

5378   * jQuery UI Datepicker 1.6

5379   *

5380   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

5381   * Dual licensed under the MIT (MIT-LICENSE.txt)

5382   * and GPL (GPL-LICENSE.txt) licenses.

5383   *

5384   * http://docs.jquery.com/UI/Datepicker

5385   *

5386   * Depends:

5387   *    ui.core.js

5388   */
5389  
5390  (function($) { // hide the namespace
5391  
5392  $.extend($.ui, { datepicker: { version: "1.6" } });
5393  
5394  var PROP_NAME = 'datepicker';
5395  
5396  /* Date picker manager.

5397     Use the singleton instance of this class, $.datepicker, to interact with the date picker.

5398     Settings for (groups of) date pickers are maintained in an instance object,

5399     allowing multiple different settings on the same page. */
5400  
5401  function Datepicker() {
5402      this.debug = false; // Change this to true to start debugging

5403      this._curInst = null; // The current instance in use

5404      this._keyEvent = false; // If the last event was a key event

5405      this._disabledInputs = []; // List of date picker inputs that have been disabled

5406      this._datepickerShowing = false; // True if the popup picker is showing , false if not

5407      this._inDialog = false; // True if showing within a "dialog", false if not

5408      this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division

5409      this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class

5410      this._appendClass = 'ui-datepicker-append'; // The name of the append marker class

5411      this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class

5412      this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class

5413      this._promptClass = 'ui-datepicker-prompt'; // The name of the dialog prompt marker class

5414      this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class

5415      this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class

5416      this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class

5417      this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class

5418      this._weekOverClass = 'ui-datepicker-week-over'; // The name of the week hover marker class

5419      this.regional = []; // Available regional settings, indexed by language code

5420      this.regional[''] = { // Default regional settings
5421          clearText: 'Clear', // Display text for clear link
5422          clearStatus: 'Erase the current date', // Status text for clear link
5423          closeText: 'Close', // Display text for close link
5424          closeStatus: 'Close without change', // Status text for close link
5425          prevText: '&#x3c;Prev', // Display text for previous month link
5426          prevStatus: 'Show the previous month', // Status text for previous month link
5427          prevBigText: '&#x3c;&#x3c;', // Display text for previous year link
5428          prevBigStatus: 'Show the previous year', // Status text for previous year link
5429          nextText: 'Next&#x3e;', // Display text for next month link
5430          nextStatus: 'Show the next month', // Status text for next month link
5431          nextBigText: '&#x3e;&#x3e;', // Display text for next year link
5432          nextBigStatus: 'Show the next year', // Status text for next year link
5433          currentText: 'Today', // Display text for current month link
5434          currentStatus: 'Show the current month', // Status text for current month link
5435          monthNames: ['January','February','March','April','May','June',
5436              'July','August','September','October','November','December'], // Names of months for drop-down and formatting
5437          monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
5438          monthStatus: 'Show a different month', // Status text for selecting a month
5439          yearStatus: 'Show a different year', // Status text for selecting a year
5440          weekHeader: 'Wk', // Header for the week of the year column
5441          weekStatus: 'Week of the year', // Status text for the week of the year column
5442          dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
5443          dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
5444          dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
5445          dayStatus: 'Set DD as first week day', // Status text for the day of the week selection
5446          dateStatus: 'Select DD, M d', // Status text for the date selection
5447          dateFormat: 'mm/dd/yy', // See format options on parseDate
5448          firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
5449          initStatus: 'Select a date', // Initial Status text on opening
5450          isRTL: false // True if right-to-left language, false if left-to-right
5451      };
5452      this._defaults = { // Global defaults for all the date picker instances
5453          showOn: 'focus', // 'focus' for popup on focus,
5454              // 'button' for trigger button, or 'both' for either

5455          showAnim: 'show', // Name of jQuery animation for popup
5456          showOptions: {}, // Options for enhanced animations
5457          defaultDate: null, // Used when field is blank: actual date,
5458              // +/-number for offset from today, null for today

5459          appendText: '', // Display text following the input box, e.g. showing the format
5460          buttonText: '...', // Text for trigger button
5461          buttonImage: '', // URL for trigger button image
5462          buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
5463          closeAtTop: true, // True to have the clear/close at the top,
5464              // false to have them at the bottom

5465          mandatory: false, // True to hide the Clear link, false to include it
5466          hideIfNoPrevNext: false, // True to hide next/previous month links
5467              // if not applicable, false to just disable them

5468          navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
5469          showBigPrevNext: false, // True to show big prev/next links
5470          gotoCurrent: false, // True if today link goes back to current selection instead
5471          changeMonth: true, // True if month can be selected directly, false if only prev/next
5472          changeYear: true, // True if year can be selected directly, false if only prev/next
5473          showMonthAfterYear: false, // True if the year select precedes month, false for month then year
5474          yearRange: '-10:+10', // Range of years to display in drop-down,
5475              // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)

5476          changeFirstDay: true, // True to click on day name to change, false to remain as set
5477          highlightWeek: false, // True to highlight the selected week
5478          showOtherMonths: false, // True to show dates in other months, false to leave blank
5479          showWeeks: false, // True to show week of the year, false to omit
5480          calculateWeek: this.iso8601Week, // How to calculate the week of the year,
5481              // takes a Date and returns the number of the week for it

5482          shortYearCutoff: '+10', // Short year values < this are in the current century,
5483              // > this are in the previous century,

5484              // string value starting with '+' for current year + value

5485          showStatus: false, // True to show status bar at bottom, false to not show it
5486          statusForDate: this.dateStatus, // Function to provide status text for a date -
5487              // takes date and instance as parameters, returns display text

5488          minDate: null, // The earliest selectable date, or null for no limit
5489          maxDate: null, // The latest selectable date, or null for no limit
5490          duration: 'normal', // Duration of display/closure
5491          beforeShowDay: null, // Function that takes a date and returns an array with
5492              // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',

5493              // [2] = cell title (optional), e.g. $.datepicker.noWeekends

5494          beforeShow: null, // Function that takes an input field and
5495              // returns a set of custom settings for the date picker

5496          onSelect: null, // Define a callback function when a date is selected
5497          onChangeMonthYear: null, // Define a callback function when the month or year is changed
5498          onClose: null, // Define a callback function when the datepicker is closed
5499          numberOfMonths: 1, // Number of months to show at a time
5500          showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
5501          stepMonths: 1, // Number of months to step back/forward
5502          stepBigMonths: 12, // Number of months to step back/forward for the big links
5503          rangeSelect: false, // Allows for selecting a date range on one date picker
5504          rangeSeparator: ' - ', // Text between two dates in a range
5505          altField: '', // Selector for an alternate field to store selected dates into
5506          altFormat: '', // The date format to use for the alternate field
5507          constrainInput: true // The input is constrained by the current date format
5508      };
5509      $.extend(this._defaults, this.regional['']);
5510      this.dpDiv = $('<div id="' + this._mainDivId + '" style="display: none;"></div>');
5511  }
5512  
5513  $.extend(Datepicker.prototype, {
5514      /* Class name added to elements to indicate already configured with a date picker. */

5515      markerClassName: 'hasDatepicker',
5516  
5517      /* Debug logging (if enabled). */

5518      log: function () {
5519          if (this.debug)
5520              console.log.apply('', arguments);
5521      },
5522  
5523      /* Override the default settings for all instances of the date picker.

5524         @param  settings  object - the new settings to use as defaults (anonymous object)

5525         @return the manager object */
5526      setDefaults: function(settings) {
5527          extendRemove(this._defaults, settings || {});
5528          return this;
5529      },
5530  
5531      /* Attach the date picker to a jQuery selection.

5532         @param  target    element - the target input field or division or span

5533         @param  settings  object - the new settings to use for this date picker instance (anonymous) */
5534      _attachDatepicker: function(target, settings) {
5535          // check for settings on the control itself - in namespace 'date:'

5536          var inlineSettings = null;
5537          for (var attrName in this._defaults) {
5538              var attrValue = target.getAttribute('date:' + attrName);
5539              if (attrValue) {
5540                  inlineSettings = inlineSettings || {};
5541                  try {
5542                      inlineSettings[attrName] = eval(attrValue);
5543                  } catch (err) {
5544                      inlineSettings[attrName] = attrValue;
5545                  }
5546              }
5547          }
5548          var nodeName = target.nodeName.toLowerCase();
5549          var inline = (nodeName == 'div' || nodeName == 'span');
5550          if (!target.id)
5551              target.id = 'dp' + (++this.uuid);
5552          var inst = this._newInst($(target), inline);
5553          inst.settings = $.extend({}, settings || {}, inlineSettings || {});
5554          if (nodeName == 'input') {
5555              this._connectDatepicker(target, inst);
5556          } else if (inline) {
5557              this._inlineDatepicker(target, inst);
5558          }
5559      },
5560  
5561      /* Create a new instance object. */

5562      _newInst: function(target, inline) {
5563          var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars

5564          return {id: id, input: target, // associated target
5565              selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
5566              drawMonth: 0, drawYear: 0, // month being drawn
5567              inline: inline, // is datepicker inline or not
5568              dpDiv: (!inline ? this.dpDiv : // presentation div
5569              $('<div class="' + this._inlineClass + '"></div>'))};
5570      },
5571  
5572      /* Attach the date picker to an input field. */

5573      _connectDatepicker: function(target, inst) {
5574          var input = $(target);
5575          if (input.hasClass(this.markerClassName))
5576              return;
5577          var appendText = this._get(inst, 'appendText');
5578          var isRTL = this._get(inst, 'isRTL');
5579          if (appendText)
5580              input[isRTL ? 'before' : 'after']('<span class="' + this._appendClass + '">' + appendText + '</span>');
5581          var showOn = this._get(inst, 'showOn');
5582          if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
5583              input.focus(this._showDatepicker);
5584          if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
5585              var buttonText = this._get(inst, 'buttonText');
5586              var buttonImage = this._get(inst, 'buttonImage');
5587              var trigger = $(this._get(inst, 'buttonImageOnly') ?
5588                  $('<img/>').addClass(this._triggerClass).
5589                      attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
5590                  $('<button type="button"></button>').addClass(this._triggerClass).
5591                      html(buttonImage == '' ? buttonText : $('<img/>').attr(
5592                      { src:buttonImage, alt:buttonText, title:buttonText })));
5593              input[isRTL ? 'before' : 'after'](trigger);
5594              trigger.click(function() {
5595                  if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
5596                      $.datepicker._hideDatepicker();
5597                  else
5598                      $.datepicker._showDatepicker(target);
5599                  return false;
5600              });
5601          }
5602          input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).
5603              bind("setData.datepicker", function(event, key, value) {
5604                  inst.settings[key] = value;
5605              }).bind("getData.datepicker", function(event, key) {
5606                  return this._get(inst, key);
5607              });
5608          $.data(target, PROP_NAME, inst);
5609      },
5610  
5611      /* Attach an inline date picker to a div. */

5612      _inlineDatepicker: function(target, inst) {
5613          var divSpan = $(target);
5614          if (divSpan.hasClass(this.markerClassName))
5615              return;
5616          divSpan.addClass(this.markerClassName).append(inst.dpDiv).
5617              bind("setData.datepicker", function(event, key, value){
5618                  inst.settings[key] = value;
5619              }).bind("getData.datepicker", function(event, key){
5620                  return this._get(inst, key);
5621              });
5622          $.data(target, PROP_NAME, inst);
5623          this._setDate(inst, this._getDefaultDate(inst));
5624          this._updateDatepicker(inst);
5625          this._updateAlternate(inst);
5626      },
5627  
5628      /* Pop-up the date picker in a "dialog" box.

5629         @param  input     element - ignored

5630         @param  dateText  string - the initial date to display (in the current format)

5631         @param  onSelect  function - the function(dateText) to call when a date is selected

5632         @param  settings  object - update the dialog date picker instance's settings (anonymous object)

5633         @param  pos       int[2] - coordinates for the dialog's position within the screen or

5634                           event - with x/y coordinates or

5635                           leave empty for default (screen centre)

5636         @return the manager object */
5637      _dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
5638          var inst = this._dialogInst; // internal instance

5639          if (!inst) {
5640              var id = 'dp' + (++this.uuid);
5641              this._dialogInput = $('<input type="text" id="' + id +
5642                  '" size="1" style="position: absolute; top: -100px;"/>');
5643              this._dialogInput.keydown(this._doKeyDown);
5644              $('body').append(this._dialogInput);
5645              inst = this._dialogInst = this._newInst(this._dialogInput, false);
5646              inst.settings = {};
5647              $.data(this._dialogInput[0], PROP_NAME, inst);
5648          }
5649          extendRemove(inst.settings, settings || {});
5650          this._dialogInput.val(dateText);
5651  
5652          this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
5653          if (!this._pos) {
5654              var browserWidth = window.innerWidth || document.documentElement.clientWidth ||    document.body.clientWidth;
5655              var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
5656              var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
5657              var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
5658              this._pos = // should use actual width/height below
5659                  [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
5660          }
5661  
5662          // move input on screen for focus, but hidden behind dialog

5663          this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
5664          inst.settings.onSelect = onSelect;
5665          this._inDialog = true;
5666          this.dpDiv.addClass(this._dialogClass);
5667          this._showDatepicker(this._dialogInput[0]);
5668          if ($.blockUI)
5669              $.blockUI(this.dpDiv);
5670          $.data(this._dialogInput[0], PROP_NAME, inst);
5671          return this;
5672      },
5673  
5674      /* Detach a datepicker from its control.

5675         @param  target    element - the target input field or division or span */
5676      _destroyDatepicker: function(target) {
5677          var $target = $(target);
5678          if (!$target.hasClass(this.markerClassName)) {
5679              return;
5680          }
5681          var nodeName = target.nodeName.toLowerCase();
5682          $.removeData(target, PROP_NAME);
5683          if (nodeName == 'input') {
5684              $target.siblings('.' + this._appendClass).remove().end().
5685                  siblings('.' + this._triggerClass).remove().end().
5686                  removeClass(this.markerClassName).
5687                  unbind('focus', this._showDatepicker).
5688                  unbind('keydown', this._doKeyDown).
5689                  unbind('keypress', this._doKeyPress);
5690          } else if (nodeName == 'div' || nodeName == 'span')
5691              $target.removeClass(this.markerClassName).empty();
5692      },
5693  
5694      /* Enable the date picker to a jQuery selection.

5695         @param  target    element - the target input field or division or span */
5696      _enableDatepicker: function(target) {
5697          var $target = $(target);
5698          if (!$target.hasClass(this.markerClassName)) {
5699              return;
5700          }
5701          var nodeName = target.nodeName.toLowerCase();
5702          if (nodeName == 'input') {
5703          target.disabled = false;
5704              $target.siblings('button.' + this._triggerClass).
5705              each(function() { this.disabled = false; }).end().
5706                  siblings('img.' + this._triggerClass).
5707                  css({opacity: '1.0', cursor: ''});
5708          }
5709          else if (nodeName == 'div' || nodeName == 'span') {
5710              $target.children('.' + this._disableClass).remove();
5711          }
5712          this._disabledInputs = $.map(this._disabledInputs,
5713              function(value) { return (value == target ? null : value); }); // delete entry

5714      },
5715  
5716      /* Disable the date picker to a jQuery selection.

5717         @param  target    element - the target input field or division or span */
5718      _disableDatepicker: function(target) {
5719          var $target = $(target);
5720          if (!$target.hasClass(this.markerClassName)) {
5721              return;
5722          }
5723          var nodeName = target.nodeName.toLowerCase();
5724          if (nodeName == 'input') {
5725          target.disabled = true;
5726              $target.siblings('button.' + this._triggerClass).
5727              each(function() { this.disabled = true; }).end().
5728                  siblings('img.' + this._triggerClass).
5729                  css({opacity: '0.5', cursor: 'default'});
5730          }
5731          else if (nodeName == 'div' || nodeName == 'span') {
5732              var inline = $target.children('.' + this._inlineClass);
5733              var offset = inline.offset();
5734              var relOffset = {left: 0, top: 0};
5735              inline.parents().each(function() {
5736                  if ($(this).css('position') == 'relative') {
5737                      relOffset = $(this).offset();
5738                      return false;
5739                  }
5740              });
5741              $target.prepend('<div class="' + this._disableClass + '" style="' +
5742                  ($.browser.msie ? 'background-color: transparent; ' : '') +
5743                  'width: ' + inline.width() + 'px; height: ' + inline.height() +
5744                  'px; left: ' + (offset.left - relOffset.left) +
5745                  'px; top: ' + (offset.top - relOffset.top) + 'px;"></div>');
5746          }
5747          this._disabledInputs = $.map(this._disabledInputs,
5748              function(value) { return (value == target ? null : value); }); // delete entry

5749          this._disabledInputs[this._disabledInputs.length] = target;
5750      },
5751  
5752      /* Is the first field in a jQuery collection disabled as a datepicker?

5753         @param  target    element - the target input field or division or span

5754         @return boolean - true if disabled, false if enabled */
5755      _isDisabledDatepicker: function(target) {
5756          if (!target)
5757              return false;
5758          for (var i = 0; i < this._disabledInputs.length; i++) {
5759              if (this._disabledInputs[i] == target)
5760                  return true;
5761          }
5762          return false;
5763      },
5764  
5765      /* Retrieve the instance data for the target control.

5766         @param  target  element - the target input field or division or span

5767         @return  object - the associated instance data

5768         @throws  error if a jQuery problem getting data */
5769      _getInst: function(target) {
5770          try {
5771              return $.data(target, PROP_NAME);
5772          }
5773          catch (err) {
5774              throw 'Missing instance data for this datepicker';
5775          }
5776      },
5777  
5778      /* Update the settings for a date picker attached to an input field or division.

5779         @param  target  element - the target input field or division or span

5780         @param  name    object - the new settings to update or

5781                         string - the name of the setting to change or

5782         @param  value   any - the new value for the setting (omit if above is an object) */
5783      _optionDatepicker: function(target, name, value) {
5784          var settings = name || {};
5785          if (typeof name == 'string') {
5786              settings = {};
5787              settings[name] = value;
5788          }
5789          var inst = this._getInst(target);
5790          if (inst) {
5791              if (this._curInst == inst) {
5792                  this._hideDatepicker(null);
5793              }
5794              extendRemove(inst.settings, settings);
5795              var date = new Date();
5796              extendRemove(inst, {rangeStart: null, // start of range
5797                  endDay: null, endMonth: null, endYear: null, // end of range
5798                  selectedDay: date.getDate(), selectedMonth: date.getMonth(),
5799                  selectedYear: date.getFullYear(), // starting point
5800                  currentDay: date.getDate(), currentMonth: date.getMonth(),
5801                  currentYear: date.getFullYear(), // current selection
5802                  drawMonth: date.getMonth(), drawYear: date.getFullYear()}); // month being drawn

5803              this._updateDatepicker(inst);
5804          }
5805      },
5806  
5807      // change method deprecated

5808      _changeDatepicker: function(target, name, value) {
5809          this._optionDatepicker(target, name, value);
5810      },
5811  
5812      /* Redraw the date picker attached to an input field or division.

5813         @param  target  element - the target input field or division or span */
5814      _refreshDatepicker: function(target) {
5815          var inst = this._getInst(target);
5816          if (inst) {
5817              this._updateDatepicker(inst);
5818          }
5819      },
5820  
5821      /* Set the dates for a jQuery selection.

5822         @param  target   element - the target input field or division or span

5823         @param  date     Date - the new date

5824         @param  endDate  Date - the new end date for a range (optional) */
5825      _setDateDatepicker: function(target, date, endDate) {
5826          var inst = this._getInst(target);
5827          if (inst) {
5828              this._setDate(inst, date, endDate);
5829              this._updateDatepicker(inst);
5830              this._updateAlternate(inst);
5831          }
5832      },
5833  
5834      /* Get the date(s) for the first entry in a jQuery selection.

5835         @param  target  element - the target input field or division or span

5836         @return Date - the current date or

5837                 Date[2] - the current dates for a range */
5838      _getDateDatepicker: function(target) {
5839          var inst = this._getInst(target);
5840          if (inst && !inst.inline)
5841              this._setDateFromField(inst);
5842          return (inst ? this._getDate(inst) : null);
5843      },
5844  
5845      /* Handle keystrokes. */

5846      _doKeyDown: function(event) {
5847          var inst = $.datepicker._getInst(event.target);
5848          var handled = true;
5849          inst._keyEvent = true;
5850          if ($.datepicker._datepickerShowing)
5851              switch (event.keyCode) {
5852                  case 9:  $.datepicker._hideDatepicker(null, '');
5853                          break; // hide on tab out

5854                  case 13: var sel = $('td.' + $.datepicker._dayOverClass +
5855                              ', td.' + $.datepicker._currentClass, inst.dpDiv);
5856                          if (sel[0])
5857                              $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
5858                          else
5859                              $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
5860                          return false; // don't submit the form

5861                          break; // select the value on enter

5862                  case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
5863                          break; // hide on escape

5864                  case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
5865                              -$.datepicker._get(inst, 'stepBigMonths') :
5866                              -$.datepicker._get(inst, 'stepMonths')), 'M');
5867                          break; // previous month/year on page up/+ ctrl

5868                  case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
5869                              +$.datepicker._get(inst, 'stepBigMonths') :
5870                              +$.datepicker._get(inst, 'stepMonths')), 'M');
5871                          break; // next month/year on page down/+ ctrl

5872                  case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
5873                          handled = event.ctrlKey || event.metaKey;
5874                          break; // clear on ctrl or command +end

5875                  case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
5876                          handled = event.ctrlKey || event.metaKey;
5877                          break; // current on ctrl or command +home

5878                  case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -1, 'D');
5879                          handled = event.ctrlKey || event.metaKey;
5880                          // -1 day on ctrl or command +left

5881                          if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
5882                                      -$.datepicker._get(inst, 'stepBigMonths') :
5883                                      -$.datepicker._get(inst, 'stepMonths')), 'M');
5884                          // next month/year on alt +left on Mac

5885                          break;
5886                  case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
5887                          handled = event.ctrlKey || event.metaKey;
5888                          break; // -1 week on ctrl or command +up

5889                  case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +1, 'D');
5890                          handled = event.ctrlKey || event.metaKey;
5891                          // +1 day on ctrl or command +right

5892                          if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
5893                                      +$.datepicker._get(inst, 'stepBigMonths') :
5894                                      +$.datepicker._get(inst, 'stepMonths')), 'M');
5895                          // next month/year on alt +right

5896                          break;
5897                  case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
5898                          handled = event.ctrlKey || event.metaKey;
5899                          break; // +1 week on ctrl or command +down

5900                  default: handled = false;
5901              }
5902          else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
5903              $.datepicker._showDatepicker(this);
5904          else {
5905              handled = false;
5906          }
5907          if (handled) {
5908              event.preventDefault();
5909              event.stopPropagation();
5910          }
5911      },
5912  
5913      /* Filter entered characters - based on date format. */

5914      _doKeyPress: function(event) {
5915          var inst = $.datepicker._getInst(event.target);
5916          if ($.datepicker._get(inst, 'constrainInput')) {
5917              var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
5918              var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
5919              return event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
5920          }
5921      },
5922  
5923      /* Pop-up the date picker for a given input field.

5924         @param  input  element - the input field attached to the date picker or

5925                        event - if triggered by focus */
5926      _showDatepicker: function(input) {
5927          input = input.target || input;
5928          if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
5929              input = $('input', input.parentNode)[0];
5930          if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
5931              return;
5932          var inst = $.datepicker._getInst(input);
5933          var beforeShow = $.datepicker._get(inst, 'beforeShow');
5934          extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
5935          $.datepicker._hideDatepicker(null, '');
5936          $.datepicker._lastInput = input;
5937          $.datepicker._setDateFromField(inst);
5938          if ($.datepicker._inDialog) // hide cursor
5939              input.value = '';
5940          if (!$.datepicker._pos) { // position below input
5941              $.datepicker._pos = $.datepicker._findPos(input);
5942              $.datepicker._pos[1] += input.offsetHeight; // add the height

5943          }
5944          var isFixed = false;
5945          $(input).parents().each(function() {
5946              isFixed |= $(this).css('position') == 'fixed';
5947              return !isFixed;
5948          });
5949          if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
5950              $.datepicker._pos[0] -= document.documentElement.scrollLeft;
5951              $.datepicker._pos[1] -= document.documentElement.scrollTop;
5952          }
5953          var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
5954          $.datepicker._pos = null;
5955          inst.rangeStart = null;
5956          // determine sizing offscreen

5957          inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
5958          $.datepicker._updateDatepicker(inst);
5959          // fix width for dynamic number of date pickers

5960          inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1] *
5961              $('.ui-datepicker', inst.dpDiv[0])[0].offsetWidth);
5962          // and adjust position before showing

5963          offset = $.datepicker._checkOffset(inst, offset, isFixed);
5964          inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
5965              'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
5966              left: offset.left + 'px', top: offset.top + 'px'});
5967          if (!inst.inline) {
5968              var showAnim = $.datepicker._get(inst, 'showAnim') || 'show';
5969              var duration = $.datepicker._get(inst, 'duration');
5970              var postProcess = function() {
5971                  $.datepicker._datepickerShowing = true;
5972                  if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems
5973                      $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4,
5974                          height: inst.dpDiv.height() + 4});
5975              };
5976              if ($.effects && $.effects[showAnim])
5977                  inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
5978              else
5979                  inst.dpDiv[showAnim](duration, postProcess);
5980              if (duration == '')
5981                  postProcess();
5982              if (inst.input[0].type != 'hidden')
5983                  inst.input[0].focus();
5984              $.datepicker._curInst = inst;
5985          }
5986      },
5987  
5988      /* Generate the date picker content. */

5989      _updateDatepicker: function(inst) {
5990          var dims = {width: inst.dpDiv.width() + 4,
5991              height: inst.dpDiv.height() + 4};
5992          inst.dpDiv.empty().append(this._generateHTML(inst)).
5993              find('iframe.ui-datepicker-cover').
5994              css({width: dims.width, height: dims.height});
5995          var numMonths = this._getNumberOfMonths(inst);
5996          inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
5997              'Class']('ui-datepicker-multi');
5998          inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
5999              'Class']('ui-datepicker-rtl');
6000          if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst)
6001              $(inst.input[0]).focus();
6002      },
6003  
6004      /* Check positioning to remain on screen. */

6005      _checkOffset: function(inst, offset, isFixed) {
6006          var pos = inst.input ? this._findPos(inst.input[0]) : null;
6007          var browserWidth = window.innerWidth || (document.documentElement ?
6008              document.documentElement.clientWidth : document.body.clientWidth);
6009          var browserHeight = window.innerHeight || (document.documentElement ?
6010              document.documentElement.clientHeight : document.body.clientHeight);
6011          var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
6012          var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
6013          // reposition date picker horizontally if outside the browser window

6014          if (this._get(inst, 'isRTL') || (offset.left + inst.dpDiv.width() - scrollX) > browserWidth)
6015              offset.left = Math.max((isFixed ? 0 : scrollX),
6016                  pos[0] + (inst.input ? inst.input.width() : 0) - (isFixed ? scrollX : 0) - inst.dpDiv.width() -
6017                  (isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0));
6018          else
6019              offset.left -= (isFixed ? scrollX : 0);
6020          // reposition date picker vertically if outside the browser window

6021          if ((offset.top + inst.dpDiv.height() - scrollY) > browserHeight)
6022              offset.top = Math.max((isFixed ? 0 : scrollY),
6023                  pos[1] - (isFixed ? scrollY : 0) - (this._inDialog ? 0 : inst.dpDiv.height()) -
6024                  (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0));
6025          else
6026              offset.top -= (isFixed ? scrollY : 0);
6027          return offset;
6028      },
6029  
6030      /* Find an object's position on the screen. */

6031      _findPos: function(obj) {
6032          while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
6033              obj = obj.nextSibling;
6034          }
6035          var position = $(obj).offset();
6036          return [position.left, position.top];
6037      },
6038  
6039      /* Hide the date picker from view.

6040         @param  input  element - the input field attached to the date picker

6041         @param  duration  string - the duration over which to close the date picker */
6042      _hideDatepicker: function(input, duration) {
6043          var inst = this._curInst;
6044          if (!inst || (input && inst != $.data(input, PROP_NAME)))
6045              return;
6046          var rangeSelect = this._get(inst, 'rangeSelect');
6047          if (rangeSelect && inst.stayOpen)
6048              this._selectDate('#' + inst.id, this._formatDate(inst,
6049                  inst.currentDay, inst.currentMonth, inst.currentYear));
6050          inst.stayOpen = false;
6051          if (this._datepickerShowing) {
6052              duration = (duration != null ? duration : this._get(inst, 'duration'));
6053              var showAnim = this._get(inst, 'showAnim');
6054              var postProcess = function() {
6055                  $.datepicker._tidyDialog(inst);
6056              };
6057              if (duration != '' && $.effects && $.effects[showAnim])
6058                  inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'),
6059                      duration, postProcess);
6060              else
6061                  inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
6062                      (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);
6063              if (duration == '')
6064                  this._tidyDialog(inst);
6065              var onClose = this._get(inst, 'onClose');
6066              if (onClose)
6067                  onClose.apply((inst.input ? inst.input[0] : null),
6068                      [(inst.input ? inst.input.val() : ''), inst]);  // trigger custom callback

6069              this._datepickerShowing = false;
6070              this._lastInput = null;
6071              inst.settings.prompt = null;
6072              if (this._inDialog) {
6073                  this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
6074                  if ($.blockUI) {
6075                      $.unblockUI();
6076                      $('body').append(this.dpDiv);
6077                  }
6078              }
6079              this._inDialog = false;
6080          }
6081          this._curInst = null;
6082      },
6083  
6084      /* Tidy up after a dialog display. */

6085      _tidyDialog: function(inst) {
6086          inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker');
6087          $('.' + this._promptClass, inst.dpDiv).remove();
6088      },
6089  
6090      /* Close date picker if clicked elsewhere. */

6091      _checkExternalClick: function(event) {
6092          if (!$.datepicker._curInst)
6093              return;
6094          var $target = $(event.target);
6095          if (($target.parents('#' + $.datepicker._mainDivId).length == 0) &&
6096                  !$target.hasClass($.datepicker.markerClassName) &&
6097                  !$target.hasClass($.datepicker._triggerClass) &&
6098                  $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
6099              $.datepicker._hideDatepicker(null, '');
6100      },
6101  
6102      /* Adjust one of the date sub-fields. */

6103      _adjustDate: function(id, offset, period) {
6104          var target = $(id);
6105          var inst = this._getInst(target[0]);
6106          this._adjustInstDate(inst, offset, period);
6107          this._updateDatepicker(inst);
6108      },
6109  
6110      /* Action for current link. */

6111      _gotoToday: function(id) {
6112          var target = $(id);
6113          var inst = this._getInst(target[0]);
6114          if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
6115              inst.selectedDay = inst.currentDay;
6116              inst.drawMonth = inst.selectedMonth = inst.currentMonth;
6117              inst.drawYear = inst.selectedYear = inst.currentYear;
6118          }
6119          else {
6120          var date = new Date();
6121          inst.selectedDay = date.getDate();
6122          inst.drawMonth = inst.selectedMonth = date.getMonth();
6123          inst.drawYear = inst.selectedYear = date.getFullYear();
6124          }
6125          this._notifyChange(inst);
6126          this._adjustDate(target);
6127      },
6128  
6129      /* Action for selecting a new month/year. */

6130      _selectMonthYear: function(id, select, period) {
6131          var target = $(id);
6132          var inst = this._getInst(target[0]);
6133          inst._selectingMonthYear = false;
6134          inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
6135          inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
6136              parseInt(select.options[select.selectedIndex].value,10);
6137          this._notifyChange(inst);
6138          this._adjustDate(target);
6139      },
6140  
6141      /* Restore input focus after not changing month/year. */

6142      _clickMonthYear: function(id) {
6143          var target = $(id);
6144          var inst = this._getInst(target[0]);
6145          if (inst.input && inst._selectingMonthYear && !$.browser.msie)
6146              inst.input[0].focus();
6147          inst._selectingMonthYear = !inst._selectingMonthYear;
6148      },
6149  
6150      /* Action for changing the first week day. */

6151      _changeFirstDay: function(id, day) {
6152          var target = $(id);
6153          var inst = this._getInst(target[0]);
6154          inst.settings.firstDay = day;
6155          this._updateDatepicker(inst);
6156      },
6157  
6158      /* Action for selecting a day. */

6159      _selectDay: function(id, month, year, td) {
6160          if ($(td).hasClass(this._unselectableClass))
6161              return;
6162          var target = $(id);
6163          var inst = this._getInst(target[0]);
6164          var rangeSelect = this._get(inst, 'rangeSelect');
6165          if (rangeSelect) {
6166              inst.stayOpen = !inst.stayOpen;
6167              if (inst.stayOpen) {
6168                  $('.ui-datepicker td', inst.dpDiv).removeClass(this._currentClass);
6169                  $(td).addClass(this._currentClass);
6170              }
6171          }
6172          inst.selectedDay = inst.currentDay = $('a', td).html();
6173          inst.selectedMonth = inst.currentMonth = month;
6174          inst.selectedYear = inst.currentYear = year;
6175          if (inst.stayOpen) {
6176              inst.endDay = inst.endMonth = inst.endYear = null;
6177          }
6178          else if (rangeSelect) {
6179              inst.endDay = inst.currentDay;
6180              inst.endMonth = inst.currentMonth;
6181              inst.endYear = inst.currentYear;
6182          }
6183          this._selectDate(id, this._formatDate(inst,
6184              inst.currentDay, inst.currentMonth, inst.currentYear));
6185          if (inst.stayOpen) {
6186              inst.rangeStart = this._daylightSavingAdjust(
6187                  new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
6188              this._updateDatepicker(inst);
6189          }
6190          else if (rangeSelect) {
6191              inst.selectedDay = inst.currentDay = inst.rangeStart.getDate();
6192              inst.selectedMonth = inst.currentMonth = inst.rangeStart.getMonth();
6193              inst.selectedYear = inst.currentYear = inst.rangeStart.getFullYear();
6194              inst.rangeStart = null;
6195              if (inst.inline)
6196                  this._updateDatepicker(inst);
6197          }
6198      },
6199  
6200      /* Erase the input field and hide the date picker. */

6201      _clearDate: function(id) {
6202          var target = $(id);
6203          var inst = this._getInst(target[0]);
6204          if (this._get(inst, 'mandatory'))
6205              return;
6206          inst.stayOpen = false;
6207          inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;
6208          this._selectDate(target, '');
6209      },
6210  
6211      /* Update the input field with the selected date. */

6212      _selectDate: function(id, dateStr) {
6213          var target = $(id);
6214          var inst = this._getInst(target[0]);
6215          dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
6216          if (this._get(inst, 'rangeSelect') && dateStr)
6217              dateStr = (inst.rangeStart ? this._formatDate(inst, inst.rangeStart) :
6218                  dateStr) + this._get(inst, 'rangeSeparator') + dateStr;
6219          if (inst.input)
6220              inst.input.val(dateStr);
6221          this._updateAlternate(inst);
6222          var onSelect = this._get(inst, 'onSelect');
6223          if (onSelect)
6224              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback

6225          else if (inst.input)
6226              inst.input.trigger('change'); // fire the change event

6227          if (inst.inline)
6228              this._updateDatepicker(inst);
6229          else if (!inst.stayOpen) {
6230              this._hideDatepicker(null, this._get(inst, 'duration'));
6231              this._lastInput = inst.input[0];
6232              if (typeof(inst.input[0]) != 'object')
6233                  inst.input[0].focus(); // restore focus

6234              this._lastInput = null;
6235          }
6236      },
6237  
6238      /* Update any alternate field to synchronise with the main field. */

6239      _updateAlternate: function(inst) {
6240          var altField = this._get(inst, 'altField');
6241          if (altField) { // update alternate field too
6242              var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
6243              var date = this._getDate(inst);
6244              dateStr = (isArray(date) ? (!date[0] && !date[1] ? '' :
6245                  this.formatDate(altFormat, date[0], this._getFormatConfig(inst)) +
6246                  this._get(inst, 'rangeSeparator') + this.formatDate(
6247                  altFormat, date[1] || date[0], this._getFormatConfig(inst))) :
6248                  this.formatDate(altFormat, date, this._getFormatConfig(inst)));
6249              $(altField).each(function() { $(this).val(dateStr); });
6250          }
6251      },
6252  
6253      /* Set as beforeShowDay function to prevent selection of weekends.

6254         @param  date  Date - the date to customise

6255         @return [boolean, string] - is this date selectable?, what is its CSS class? */
6256      noWeekends: function(date) {
6257          var day = date.getDay();
6258          return [(day > 0 && day < 6), ''];
6259      },
6260  
6261      /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.

6262         @param  date  Date - the date to get the week for

6263         @return  number - the number of the week within the year that contains this date */
6264      iso8601Week: function(date) {
6265          var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
6266          var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan

6267          var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7

6268          firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday

6269          if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
6270              checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year

6271              return $.datepicker.iso8601Week(checkDate);
6272          } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
6273              firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
6274              if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
6275                  return 1;
6276              }
6277          }
6278          return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date

6279      },
6280  
6281      /* Provide status text for a particular date.

6282         @param  date  the date to get the status for

6283         @param  inst  the current datepicker instance

6284         @return  the status display text for this date */
6285      dateStatus: function(date, inst) {
6286          return $.datepicker.formatDate($.datepicker._get(inst, 'dateStatus'),
6287              date, $.datepicker._getFormatConfig(inst));
6288      },
6289  
6290      /* Parse a string value into a date object.

6291         See formatDate below for the possible formats.

6292  

6293         @param  format    string - the expected format of the date

6294         @param  value     string - the date in the above format

6295         @param  settings  Object - attributes include:

6296                           shortYearCutoff  number - the cutoff year for determining the century (optional)

6297                           dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)

6298                           dayNames         string[7] - names of the days from Sunday (optional)

6299                           monthNamesShort  string[12] - abbreviated names of the months (optional)

6300                           monthNames       string[12] - names of the months (optional)

6301         @return  Date - the extracted date value or null if value is blank */
6302      parseDate: function (format, value, settings) {
6303          if (format == null || value == null)
6304              throw 'Invalid arguments';
6305          value = (typeof value == 'object' ? value.toString() : value + '');
6306          if (value == '')
6307              return null;
6308          var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
6309          var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
6310          var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
6311          var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
6312          var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
6313          var year = -1;
6314          var month = -1;
6315          var day = -1;
6316          var doy = -1;
6317          var literal = false;
6318          // Check whether a format character is doubled

6319          var lookAhead = function(match) {
6320              var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
6321              if (matches)
6322                  iFormat++;
6323              return matches;
6324          };
6325          // Extract a number from the string value

6326          var getNumber = function(match) {
6327              lookAhead(match);
6328              var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)));
6329              var size = origSize;
6330              var num = 0;
6331              while (size > 0 && iValue < value.length &&
6332                      value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
6333                  num = num * 10 + parseInt(value.charAt(iValue++),10);
6334                  size--;
6335              }
6336              if (size == origSize)
6337                  throw 'Missing number at position ' + iValue;
6338              return num;
6339          };
6340          // Extract a name from the string value and convert to an index

6341          var getName = function(match, shortNames, longNames) {
6342              var names = (lookAhead(match) ? longNames : shortNames);
6343              var size = 0;
6344              for (var j = 0; j < names.length; j++)
6345                  size = Math.max(size, names[j].length);
6346              var name = '';
6347              var iInit = iValue;
6348              while (size > 0 && iValue < value.length) {
6349                  name += value.charAt(iValue++);
6350                  for (var i = 0; i < names.length; i++)
6351                      if (name == names[i])
6352                          return i + 1;
6353                  size--;
6354              }
6355              throw 'Unknown name at position ' + iInit;
6356          };
6357          // Confirm that a literal character matches the string value

6358          var checkLiteral = function() {
6359              if (value.charAt(iValue) != format.charAt(iFormat))
6360                  throw 'Unexpected literal at position ' + iValue;
6361              iValue++;
6362          };
6363          var iValue = 0;
6364          for (var iFormat = 0; iFormat < format.length; iFormat++) {
6365              if (literal)
6366                  if (format.charAt(iFormat) == "'" && !lookAhead("'"))
6367                      literal = false;
6368                  else
6369                      checkLiteral();
6370              else
6371                  switch (format.charAt(iFormat)) {
6372                      case 'd':
6373                          day = getNumber('d');
6374                          break;
6375                      case 'D':
6376                          getName('D', dayNamesShort, dayNames);
6377                          break;
6378                      case 'o':
6379                          doy = getNumber('o');
6380                          break;
6381                      case 'm':
6382                          month = getNumber('m');
6383                          break;
6384                      case 'M':
6385                          month = getName('M', monthNamesShort, monthNames);
6386                          break;
6387                      case 'y':
6388                          year = getNumber('y');
6389                          break;
6390                      case '@':
6391                          var date = new Date(getNumber('@'));
6392                          year = date.getFullYear();
6393                          month = date.getMonth() + 1;
6394                          day = date.getDate();
6395                          break;
6396                      case "'":
6397                          if (lookAhead("'"))
6398                              checkLiteral();
6399                          else
6400                              literal = true;
6401                          break;
6402                      default:
6403                          checkLiteral();
6404                  }
6405          }
6406          if (year == -1)
6407              year = new Date().getFullYear();
6408          else if (year < 100)
6409              year += new Date().getFullYear() - new Date().getFullYear() % 100 +
6410                  (year <= shortYearCutoff ? 0 : -100);
6411          if (doy > -1) {
6412              month = 1;
6413              day = doy;
6414              do {
6415                  var dim = this._getDaysInMonth(year, month - 1);
6416                  if (day <= dim)
6417                      break;
6418                  month++;
6419                  day -= dim;
6420              } while (true);
6421          }
6422          var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
6423          if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
6424              throw 'Invalid date'; // E.g. 31/02/*

6425          return date;

6426      },

6427  

6428      /* Standard date formats. */

6429      ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)

6430      COOKIE: 'D, dd M yy',

6431      ISO_8601: 'yy-mm-dd',

6432      RFC_822: 'D, d M y',

6433      RFC_850: 'DD, dd-M-y',

6434      RFC_1036: 'D, d M y',

6435      RFC_1123: 'D, d M yy',

6436      RFC_2822: 'D, d M yy',

6437      RSS: 'D, d M y', // RFC 822

6438      TIMESTAMP: '@',

6439      W3C: 'yy-mm-dd', // ISO 8601

6440  

6441      /* Format a date object into a string value.

6442         The format can be combinations of the following:

6443         d  - day of month (no leading zero)

6444         dd - day of month (two digit)

6445         o  - day of year (no leading zeros)

6446         oo - day of year (three digit)

6447         D  - day name short

6448         DD - day name long

6449         m  - month of year (no leading zero)

6450         mm - month of year (two digit)

6451         M  - month name short

6452         MM - month name long

6453         y  - year (two digit)

6454         yy - year (four digit)

6455         @ - Unix timestamp (ms since 01/01/1970)

6456         '...' - literal text

6457         '' - single quote

6458  

6459         @param  format    string - the desired format of the date

6460         @param  date      Date - the date value to format

6461         @param  settings  Object - attributes include:

6462                           dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)

6463                           dayNames         string[7] - names of the days from Sunday (optional)

6464                           monthNamesShort  string[12] - abbreviated names of the months (optional)

6465                           monthNames       string[12] - names of the months (optional)

6466         @return  string - the date in the above format */
6467      formatDate: function (format, date, settings) {
6468          if (!date)
6469              return '';
6470          var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
6471          var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
6472          var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
6473          var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
6474          // Check whether a format character is doubled

6475          var lookAhead = function(match) {
6476              var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
6477              if (matches)
6478                  iFormat++;
6479              return matches;
6480          };
6481          // Format a number, with leading zero if necessary

6482          var formatNumber = function(match, value, len) {
6483              var num = '' + value;
6484              if (lookAhead(match))
6485                  while (num.length < len)
6486                      num = '0' + num;
6487              return num;
6488          };
6489          // Format a name, short or long as requested

6490          var formatName = function(match, value, shortNames, longNames) {
6491              return (lookAhead(match) ? longNames[value] : shortNames[value]);
6492          };
6493          var output = '';
6494          var literal = false;
6495          if (date)
6496              for (var iFormat = 0; iFormat < format.length; iFormat++) {
6497                  if (literal)
6498                      if (format.charAt(iFormat) == "'" && !lookAhead("'"))
6499                          literal = false;
6500                      else
6501                          output += format.charAt(iFormat);
6502                  else
6503                      switch (format.charAt(iFormat)) {
6504                          case 'd':
6505                              output += formatNumber('d', date.getDate(), 2);
6506                              break;
6507                          case 'D':
6508                              output += formatName('D', date.getDay(), dayNamesShort, dayNames);
6509                              break;
6510                          case 'o':
6511                              var doy = date.getDate();
6512                              for (var m = date.getMonth() - 1; m >= 0; m--)
6513                                  doy += this._getDaysInMonth(date.getFullYear(), m);
6514                              output += formatNumber('o', doy, 3);
6515                              break;
6516                          case 'm':
6517                              output += formatNumber('m', date.getMonth() + 1, 2);
6518                              break;
6519                          case 'M':
6520                              output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
6521                              break;
6522                          case 'y':
6523                              output += (lookAhead('y') ? date.getFullYear() :
6524                                  (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
6525                              break;
6526                          case '@':
6527                              output += date.getTime();
6528                              break;
6529                          case "'":
6530                              if (lookAhead("'"))
6531                                  output += "'";
6532                              else
6533                                  literal = true;
6534                              break;
6535                          default:
6536                              output += format.charAt(iFormat);
6537                      }
6538              }
6539          return output;
6540      },
6541  
6542      /* Extract all possible characters from the date format. */

6543      _possibleChars: function (format) {
6544          var chars = '';
6545          var literal = false;
6546          for (var iFormat = 0; iFormat < format.length; iFormat++)
6547              if (literal)
6548                  if (format.charAt(iFormat) == "'" && !lookAhead("'"))
6549                      literal = false;
6550                  else
6551                      chars += format.charAt(iFormat);
6552              else
6553                  switch (format.charAt(iFormat)) {
6554                      case 'd': case 'm': case 'y': case '@':
6555                          chars += '0123456789';
6556                          break;
6557                      case 'D': case 'M':
6558                          return null; // Accept anything

6559                      case "'":
6560                          if (lookAhead("'"))
6561                              chars += "'";
6562                          else
6563                              literal = true;
6564                          break;
6565                      default:
6566                          chars += format.charAt(iFormat);
6567                  }
6568          return chars;
6569      },
6570  
6571      /* Get a setting value, defaulting if necessary. */

6572      _get: function(inst, name) {
6573          return inst.settings[name] !== undefined ?
6574              inst.settings[name] : this._defaults[name];
6575      },
6576  
6577      /* Parse existing date and initialise date picker. */

6578      _setDateFromField: function(inst) {
6579          var dateFormat = this._get(inst, 'dateFormat');
6580          var dates = inst.input ? inst.input.val().split(this._get(inst, 'rangeSeparator')) : null;
6581          inst.endDay = inst.endMonth = inst.endYear = null;
6582          var date = defaultDate = this._getDefaultDate(inst);
6583          if (dates.length > 0) {
6584              var settings = this._getFormatConfig(inst);
6585              if (dates.length > 1) {
6586                  date = this.parseDate(dateFormat, dates[1], settings) || defaultDate;
6587                  inst.endDay = date.getDate();
6588                  inst.endMonth = date.getMonth();
6589                  inst.endYear = date.getFullYear();
6590              }
6591              try {
6592                  date = this.parseDate(dateFormat, dates[0], settings) || defaultDate;
6593              } catch (event) {
6594                  this.log(event);
6595                  date = defaultDate;
6596              }
6597          }
6598          inst.selectedDay = date.getDate();
6599          inst.drawMonth = inst.selectedMonth = date.getMonth();
6600          inst.drawYear = inst.selectedYear = date.getFullYear();
6601          inst.currentDay = (dates[0] ? date.getDate() : 0);
6602          inst.currentMonth = (dates[0] ? date.getMonth() : 0);
6603          inst.currentYear = (dates[0] ? date.getFullYear() : 0);
6604          this._adjustInstDate(inst);
6605      },
6606  
6607      /* Retrieve the default date shown on opening. */

6608      _getDefaultDate: function(inst) {
6609          var date = this._determineDate(this._get(inst, 'defaultDate'), new Date());
6610          var minDate = this._getMinMaxDate(inst, 'min', true);
6611          var maxDate = this._getMinMaxDate(inst, 'max');
6612          date = (minDate && date < minDate ? minDate : date);
6613          date = (maxDate && date > maxDate ? maxDate : date);
6614          return date;
6615      },
6616  
6617      /* A date may be specified as an exact value or a relative one. */

6618      _determineDate: function(date, defaultDate) {
6619          var offsetNumeric = function(offset) {
6620              var date = new Date();
6621              date.setDate(date.getDate() + offset);
6622              return date;
6623          };
6624          var offsetString = function(offset, getDaysInMonth) {
6625              var date = new Date();
6626              var year = date.getFullYear();
6627              var month = date.getMonth();
6628              var day = date.getDate();
6629              var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
6630              var matches = pattern.exec(offset);
6631              while (matches) {
6632                  switch (matches[2] || 'd') {
6633                      case 'd' : case 'D' :
6634                          day += parseInt(matches[1],10); break;
6635                      case 'w' : case 'W' :
6636                          day += parseInt(matches[1],10) * 7; break;
6637                      case 'm' : case 'M' :
6638                          month += parseInt(matches[1],10);
6639                          day = Math.min(day, getDaysInMonth(year, month));
6640                          break;
6641                      case 'y': case 'Y' :
6642                          year += parseInt(matches[1],10);
6643                          day = Math.min(day, getDaysInMonth(year, month));
6644                          break;
6645                  }
6646                  matches = pattern.exec(offset);
6647              }
6648              return new Date(year, month, day);
6649          };
6650          date = (date == null ? defaultDate :
6651              (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :
6652              (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date)));
6653          date = (date && date.toString() == 'Invalid Date' ? defaultDate : date);
6654          if (date) {
6655              date.setHours(0);
6656              date.setMinutes(0);
6657              date.setSeconds(0);
6658              date.setMilliseconds(0);
6659          }
6660          return this._daylightSavingAdjust(date);
6661      },
6662  
6663      /* Handle switch to/from daylight saving.

6664         Hours may be non-zero on daylight saving cut-over:

6665         > 12 when midnight changeover, but then cannot generate

6666         midnight datetime, so jump to 1AM, otherwise reset.

6667         @param  date  (Date) the date to check

6668         @return  (Date) the corrected date */
6669      _daylightSavingAdjust: function(date) {
6670          if (!date) return null;
6671          date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
6672          return date;
6673      },
6674  
6675      /* Set the date(s) directly. */

6676      _setDate: function(inst, date, endDate) {
6677          var clear = !(date);
6678          var origMonth = inst.selectedMonth;
6679          var origYear = inst.selectedYear;
6680          date = this._determineDate(date, new Date());
6681          inst.selectedDay = inst.currentDay = date.getDate();
6682          inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
6683          inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
6684          if (this._get(inst, 'rangeSelect')) {
6685              if (endDate) {
6686                  endDate = this._determineDate(endDate, null);
6687                  inst.endDay = endDate.getDate();
6688                  inst.endMonth = endDate.getMonth();
6689                  inst.endYear = endDate.getFullYear();
6690              } else {
6691                  inst.endDay = inst.currentDay;
6692                  inst.endMonth = inst.currentMonth;
6693                  inst.endYear = inst.currentYear;
6694              }
6695          }
6696          if (origMonth != inst.selectedMonth || origYear != inst.selectedYear)
6697              this._notifyChange(inst);
6698          this._adjustInstDate(inst);
6699          if (inst.input)
6700              inst.input.val(clear ? '' : this._formatDate(inst) +
6701                  (!this._get(inst, 'rangeSelect') ? '' : this._get(inst, 'rangeSeparator') +
6702                  this._formatDate(inst, inst.endDay, inst.endMonth, inst.endYear)));
6703      },
6704  
6705      /* Retrieve the date(s) directly. */

6706      _getDate: function(inst) {
6707          var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
6708              this._daylightSavingAdjust(new Date(
6709              inst.currentYear, inst.currentMonth, inst.currentDay)));
6710          if (this._get(inst, 'rangeSelect')) {
6711              return [inst.rangeStart || startDate,
6712                  (!inst.endYear ? inst.rangeStart || startDate :
6713                  this._daylightSavingAdjust(new Date(inst.endYear, inst.endMonth, inst.endDay)))];
6714          } else
6715              return startDate;
6716      },
6717  
6718      /* Generate the HTML for the current state of the date picker. */

6719      _generateHTML: function(inst) {
6720          var today = new Date();
6721          today = this._daylightSavingAdjust(
6722              new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time

6723          var showStatus = this._get(inst, 'showStatus');
6724          var initStatus = this._get(inst, 'initStatus') || '&#xa0;';
6725          var isRTL = this._get(inst, 'isRTL');
6726          // build the date picker HTML

6727          var clear = (this._get(inst, 'mandatory') ? '' :
6728              '<div class="ui-datepicker-clear"><a onclick="jQuery.datepicker._clearDate(\'#' + inst.id + '\');"' +
6729              this._addStatus(showStatus, inst.id, this._get(inst, 'clearStatus'), initStatus) + '>' +
6730              this._get(inst, 'clearText') + '</a></div>');
6731          var controls = '<div class="ui-datepicker-control">' + (isRTL ? '' : clear) +
6732              '<div class="ui-datepicker-close"><a onclick="jQuery.datepicker._hideDatepicker();"' +
6733              this._addStatus(showStatus, inst.id, this._get(inst, 'closeStatus'), initStatus) + '>' +
6734              this._get(inst, 'closeText') + '</a></div>' + (isRTL ? clear : '')  + '</div>';
6735          var prompt = this._get(inst, 'prompt');
6736          var closeAtTop = this._get(inst, 'closeAtTop');
6737          var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
6738          var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
6739          var showBigPrevNext = this._get(inst, 'showBigPrevNext');
6740          var numMonths = this._getNumberOfMonths(inst);
6741          var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
6742          var stepMonths = this._get(inst, 'stepMonths');
6743          var stepBigMonths = this._get(inst, 'stepBigMonths');
6744          var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
6745          var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
6746              new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
6747          var minDate = this._getMinMaxDate(inst, 'min', true);
6748          var maxDate = this._getMinMaxDate(inst, 'max');
6749          var drawMonth = inst.drawMonth - showCurrentAtPos;
6750          var drawYear = inst.drawYear;
6751          if (drawMonth < 0) {
6752              drawMonth += 12;
6753              drawYear--;
6754          }
6755          if (maxDate) {
6756              var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
6757                  maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate()));
6758              maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
6759              while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
6760                  drawMonth--;
6761                  if (drawMonth < 0) {
6762                      drawMonth = 11;
6763                      drawYear--;
6764                  }
6765              }
6766          }
6767          // controls and links

6768          var prevText = this._get(inst, 'prevText');
6769          prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
6770              this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
6771              this._getFormatConfig(inst)));
6772          var prevBigText = (showBigPrevNext ? this._get(inst, 'prevBigText') : '');
6773          prevBigText = (!navigationAsDateFormat ? prevBigText : this.formatDate(prevBigText,
6774              this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepBigMonths, 1)),
6775              this._getFormatConfig(inst)));
6776          var prev = '<div class="ui-datepicker-prev">' + (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
6777              (showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepBigMonths + ', \'M\');"' +
6778              this._addStatus(showStatus, inst.id, this._get(inst, 'prevBigStatus'), initStatus) + '>' + prevBigText + '</a>' : '') +
6779              '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
6780              this._addStatus(showStatus, inst.id, this._get(inst, 'prevStatus'), initStatus) + '>' + prevText + '</a>' :
6781              (hideIfNoPrevNext ? '' : (showBigPrevNext ? '<label>' + prevBigText + '</label>' : '') +
6782              '<label>' + prevText + '</label>')) + '</div>';
6783          var nextText = this._get(inst, 'nextText');
6784          nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
6785              this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
6786              this._getFormatConfig(inst)));
6787          var nextBigText = (showBigPrevNext ? this._get(inst, 'nextBigText') : '');
6788          nextBigText = (!navigationAsDateFormat ? nextBigText : this.formatDate(nextBigText,
6789              this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepBigMonths, 1)),
6790              this._getFormatConfig(inst)));
6791          var next = '<div class="ui-datepicker-next">' + (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
6792              '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
6793              this._addStatus(showStatus, inst.id, this._get(inst, 'nextStatus'), initStatus) + '>' + nextText + '</a>' +
6794              (showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepBigMonths + ', \'M\');"' +
6795              this._addStatus(showStatus, inst.id, this._get(inst, 'nextBigStatus'), initStatus) + '>' + nextBigText + '</a>' : '') :
6796              (hideIfNoPrevNext ? '' : '<label>' + nextText + '</label>' +
6797              (showBigPrevNext ? '<label>' + nextBigText + '</label>' : ''))) + '</div>';
6798          var currentText = this._get(inst, 'currentText');
6799          var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
6800          currentText = (!navigationAsDateFormat ? currentText :
6801              this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
6802          var html = (closeAtTop && !inst.inline ? controls : '') +
6803              '<div class="ui-datepicker-links">' + (isRTL ? next : prev) +
6804              (this._isInRange(inst, gotoDate) ? '<div class="ui-datepicker-current">' +
6805              '<a onclick="jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' +
6806              this._addStatus(showStatus, inst.id, this._get(inst, 'currentStatus'), initStatus) + '>' +
6807              currentText + '</a></div>' : '') + (isRTL ? prev : next) + '</div>' +
6808              (prompt ? '<div class="' + this._promptClass + '"><span>' + prompt + '</span></div>' : '');
6809          var firstDay = parseInt(this._get(inst, 'firstDay'));
6810          firstDay = (isNaN(firstDay) ? 0 : firstDay);
6811          var changeFirstDay = this._get(inst, 'changeFirstDay');
6812          var dayNames = this._get(inst, 'dayNames');
6813          var dayNamesShort = this._get(inst, 'dayNamesShort');
6814          var dayNamesMin = this._get(inst, 'dayNamesMin');
6815          var monthNames = this._get(inst, 'monthNames');
6816          var beforeShowDay = this._get(inst, 'beforeShowDay');
6817          var highlightWeek = this._get(inst, 'highlightWeek');
6818          var showOtherMonths = this._get(inst, 'showOtherMonths');
6819          var showWeeks = this._get(inst, 'showWeeks');
6820          var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
6821          var weekStatus = this._get(inst, 'weekStatus');
6822          var status = (showStatus ? this._get(inst, 'dayStatus') || initStatus : '');
6823          var dateStatus = this._get(inst, 'statusForDate') || this.dateStatus;
6824          var endDate = inst.endDay ? this._daylightSavingAdjust(
6825              new Date(inst.endYear, inst.endMonth, inst.endDay)) : currentDate;
6826          var defaultDate = this._getDefaultDate(inst);
6827          for (var row = 0; row < numMonths[0]; row++)
6828              for (var col = 0; col < numMonths[1]; col++) {
6829                  var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
6830                  html += '<div class="ui-datepicker-one-month' + (col == 0 ? ' ui-datepicker-new-row' : '') + '">' +
6831                      this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
6832                      selectedDate, row > 0 || col > 0, showStatus, initStatus, monthNames) + // draw month headers
6833                      '<table class="ui-datepicker" cellpadding="0" cellspacing="0"><thead>' +
6834                      '<tr class="ui-datepicker-title-row">' +
6835                      (showWeeks ? '<td' + this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' +
6836                      this._get(inst, 'weekHeader') + '</td>' : '');
6837                  for (var dow = 0; dow < 7; dow++) { // days of the week
6838                      var day = (dow + firstDay) % 7;
6839                      var dayStatus = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) :
6840                          status.replace(/D/, dayNamesShort[day]));
6841                      html += '<td' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end-cell"' : '') + '>' +
6842                          (!changeFirstDay ? '<span' :
6843                          '<a onclick="jQuery.datepicker._changeFirstDay(\'#' + inst.id + '\', ' + day + ');"') +
6844                          this._addStatus(showStatus, inst.id, dayStatus, initStatus) + ' title="' + dayNames[day] + '">' +
6845                          dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>';
6846                  }
6847                  html += '</tr></thead><tbody>';
6848                  var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
6849                  if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
6850                      inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
6851                  var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
6852                  var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate

6853                  var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
6854                  for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
6855                      html += '<tr class="ui-datepicker-days-row">' +
6856                          (showWeeks ? '<td class="ui-datepicker-week-col"' +
6857                          this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' +
6858                          calculateWeek(printDate) + '</td>' : '');
6859                      for (var dow = 0; dow < 7; dow++) { // create date picker days
6860                          var daySettings = (beforeShowDay ?
6861                              beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
6862                          var otherMonth = (printDate.getMonth() != drawMonth);
6863                          var unselectable = otherMonth || !daySettings[0] ||
6864                              (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
6865                          html += '<td class="ui-datepicker-days-cell' +
6866                              ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end-cell' : '') + // highlight weekends
6867                              (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
6868                              ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
6869                              (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
6870                              // or defaultDate is current printedDate and defaultDate is selectedDate

6871                              ' ' + $.datepicker._dayOverClass : '') + // highlight selected day
6872                              (unselectable ? ' ' + this._unselectableClass : '') +  // highlight unselectable days
6873                              (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
6874                              (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
6875                              ' ' + this._currentClass : '') + // highlight selected day
6876                              (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
6877                              ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
6878                              (unselectable ? (highlightWeek ? ' onmouseover="jQuery(this).parent().addClass(\'' + this._weekOverClass + '\');"' + // highlight selection week
6879                              ' onmouseout="jQuery(this).parent().removeClass(\'' + this._weekOverClass + '\');"' : '') : // unhighlight selection week
6880                              ' onmouseover="jQuery(this).addClass(\'' + this._dayOverClass + '\')' + // highlight selection
6881                              (highlightWeek ? '.parent().addClass(\'' + this._weekOverClass + '\')' : '') + ';' + // highlight selection week
6882                              (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
6883                              inst.id + '\').html(\'' + (dateStatus.apply((inst.input ? inst.input[0] : null),
6884                              [printDate, inst]) || initStatus) +'\');') + '"' +
6885                              ' onmouseout="jQuery(this).removeClass(\'' + this._dayOverClass + '\')' + // unhighlight selection
6886                              (highlightWeek ? '.parent().removeClass(\'' + this._weekOverClass + '\')' : '') + ';' + // unhighlight selection week
6887                              (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
6888                              inst.id + '\').html(\'' + initStatus + '\');') + '" onclick="jQuery.datepicker._selectDay(\'#' +
6889                              inst.id + '\',' + drawMonth + ',' + drawYear + ', this);"') + '>' + // actions
6890                              (otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
6891                              (unselectable ? printDate.getDate() : '<a>' + printDate.getDate() + '</a>')) + '</td>'; // display for this month

6892                          printDate.setDate(printDate.getDate() + 1);
6893                          printDate = this._daylightSavingAdjust(printDate);
6894                      }
6895                      html += '</tr>';
6896                  }
6897                  drawMonth++;
6898                  if (drawMonth > 11) {
6899                      drawMonth = 0;
6900                      drawYear++;
6901                  }
6902                  html += '</tbody></table></div>';
6903              }
6904          html += (showStatus ? '<div style="clear: both;"></div><div id="ui-datepicker-status-' + inst.id +
6905              '" class="ui-datepicker-status">' + initStatus + '</div>' : '') +
6906              (!closeAtTop && !inst.inline ? controls : '') +
6907              '<div style="clear: both;"></div>' +
6908              ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
6909              '<iframe src="javascript:false;" class="ui-datepicker-cover"></iframe>' : '');
6910          inst._keyEvent = false;
6911          return html;
6912      },
6913  
6914      /* Generate the month and year header. */

6915      _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
6916              selectedDate, secondary, showStatus, initStatus, monthNames) {
6917          minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
6918          var changeMonth = this._get(inst, 'changeMonth');
6919          var changeYear = this._get(inst, 'changeYear');
6920          var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
6921          var html = '<div class="ui-datepicker-header">';
6922          var monthHtml = '';
6923          // month selection

6924          if (secondary || !changeMonth)
6925              monthHtml += monthNames[drawMonth];
6926          else {
6927              var inMinYear = (minDate && minDate.getFullYear() == drawYear);
6928              var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
6929              monthHtml += '<select class="ui-datepicker-new-month" ' +
6930                  'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
6931                  'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
6932                  this._addStatus(showStatus, inst.id, this._get(inst, 'monthStatus'), initStatus) + '>';
6933              for (var month = 0; month < 12; month++) {
6934                  if ((!inMinYear || month >= minDate.getMonth()) &&
6935                          (!inMaxYear || month <= maxDate.getMonth()))
6936                      monthHtml += '<option value="' + month + '"' +
6937                          (month == drawMonth ? ' selected="selected"' : '') +
6938                          '>' + monthNames[month] + '</option>';
6939              }
6940              monthHtml += '</select>';
6941          }
6942          if (!showMonthAfterYear)
6943              html += monthHtml + (secondary || changeMonth || changeYear ? '&#xa0;' : '');
6944          // year selection

6945          if (secondary || !changeYear)
6946              html += drawYear;
6947          else {
6948              // determine range of years to display

6949              var years = this._get(inst, 'yearRange').split(':');
6950              var year = 0;
6951              var endYear = 0;
6952              if (years.length != 2) {
6953                  year = drawYear - 10;
6954                  endYear = drawYear + 10;
6955              } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
6956                  year = endYear = new Date().getFullYear();
6957                  year += parseInt(years[0], 10);
6958                  endYear += parseInt(years[1], 10);
6959              } else {
6960                  year = parseInt(years[0], 10);
6961                  endYear = parseInt(years[1], 10);
6962              }
6963              year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
6964              endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
6965              html += '<select class="ui-datepicker-new-year" ' +
6966                  'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
6967                  'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
6968                  this._addStatus(showStatus, inst.id, this._get(inst, 'yearStatus'), initStatus) + '>';
6969              for (; year <= endYear; year++) {
6970                  html += '<option value="' + year + '"' +
6971                      (year == drawYear ? ' selected="selected"' : '') +
6972                      '>' + year + '</option>';
6973              }
6974              html += '</select>';
6975          }
6976          if (showMonthAfterYear)
6977              html += (secondary || changeMonth || changeYear ? '&#xa0;' : '') + monthHtml;
6978          html += '</div>'; // Close datepicker_header

6979          return html;
6980      },
6981  
6982      /* Provide code to set and clear the status panel. */

6983      _addStatus: function(showStatus, id, text, initStatus) {
6984          return (showStatus ? ' onmouseover="jQuery(\'#ui-datepicker-status-' + id +
6985              '\').html(\'' + (text || initStatus) + '\');" ' +
6986              'onmouseout="jQuery(\'#ui-datepicker-status-' + id +
6987              '\').html(\'' + initStatus + '\');"' : '');
6988      },
6989  
6990      /* Adjust one of the date sub-fields. */

6991      _adjustInstDate: function(inst, offset, period) {
6992          var year = inst.drawYear + (period == 'Y' ? offset : 0);
6993          var month = inst.drawMonth + (period == 'M' ? offset : 0);
6994          var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
6995              (period == 'D' ? offset : 0);
6996          var date = this._daylightSavingAdjust(new Date(year, month, day));
6997          // ensure it is within the bounds set

6998          var minDate = this._getMinMaxDate(inst, 'min', true);
6999          var maxDate = this._getMinMaxDate(inst, 'max');
7000          date = (minDate && date < minDate ? minDate : date);
7001          date = (maxDate && date > maxDate ? maxDate : date);
7002          inst.selectedDay = date.getDate();
7003          inst.drawMonth = inst.selectedMonth = date.getMonth();
7004          inst.drawYear = inst.selectedYear = date.getFullYear();
7005          if (period == 'M' || period == 'Y')
7006              this._notifyChange(inst);
7007      },
7008  
7009      /* Notify change of month/year. */

7010      _notifyChange: function(inst) {
7011          var onChange = this._get(inst, 'onChangeMonthYear');
7012          if (onChange)
7013              onChange.apply((inst.input ? inst.input[0] : null),
7014                  [inst.selectedYear, inst.selectedMonth + 1, inst]);
7015      },
7016  
7017      /* Determine the number of months to show. */

7018      _getNumberOfMonths: function(inst) {
7019          var numMonths = this._get(inst, 'numberOfMonths');
7020          return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
7021      },
7022  
7023      /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */

7024      _getMinMaxDate: function(inst, minMax, checkRange) {
7025          var date = this._determineDate(this._get(inst, minMax + 'Date'), null);
7026          return (!checkRange || !inst.rangeStart ? date :
7027              (!date || inst.rangeStart > date ? inst.rangeStart : date));
7028      },
7029  
7030      /* Find the number of days in a given month. */

7031      _getDaysInMonth: function(year, month) {
7032          return 32 - new Date(year, month, 32).getDate();
7033      },
7034  
7035      /* Find the day of the week of the first of a month. */

7036      _getFirstDayOfMonth: function(year, month) {
7037          return new Date(year, month, 1).getDay();
7038      },
7039  
7040      /* Determines if we should allow a "next/prev" month display change. */

7041      _canAdjustMonth: function(inst, offset, curYear, curMonth) {
7042          var numMonths = this._getNumberOfMonths(inst);
7043          var date = this._daylightSavingAdjust(new Date(
7044              curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1));
7045          if (offset < 0)
7046              date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
7047          return this._isInRange(inst, date);
7048      },
7049  
7050      /* Is the given date in the accepted range? */

7051      _isInRange: function(inst, date) {
7052          // during range selection, use minimum of selected date and range start

7053          var newMinDate = (!inst.rangeStart ? null : this._daylightSavingAdjust(
7054              new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay)));
7055          newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate);
7056          var minDate = newMinDate || this._getMinMaxDate(inst, 'min');
7057          var maxDate = this._getMinMaxDate(inst, 'max');
7058          return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
7059      },
7060  
7061      /* Provide the configuration settings for formatting/parsing. */

7062      _getFormatConfig: function(inst) {
7063          var shortYearCutoff = this._get(inst, 'shortYearCutoff');
7064          shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
7065              new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
7066          return {shortYearCutoff: shortYearCutoff,
7067              dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
7068              monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
7069      },
7070  
7071      /* Format the given date for display. */

7072      _formatDate: function(inst, day, month, year) {
7073          if (!day) {
7074              inst.currentDay = inst.selectedDay;
7075              inst.currentMonth = inst.selectedMonth;
7076              inst.currentYear = inst.selectedYear;
7077          }
7078          var date = (day ? (typeof day == 'object' ? day :
7079              this._daylightSavingAdjust(new Date(year, month, day))) :
7080              this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
7081          return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
7082      }
7083  });
7084  
7085  /* jQuery extend now ignores nulls! */

7086  function extendRemove(target, props) {
7087      $.extend(target, props);
7088      for (var name in props)
7089          if (props[name] == null || props[name] == undefined)
7090              target[name] = props[name];
7091      return target;
7092  };
7093  
7094  /* Determine whether an object is an array. */

7095  function isArray(a) {
7096      return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
7097          (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
7098  };
7099  
7100  /* Invoke the datepicker functionality.

7101     @param  options  string - a command, optionally followed by additional parameters or

7102                      Object - settings for attaching new datepicker functionality

7103     @return  jQuery object */
7104  $.fn.datepicker = function(options){
7105  
7106      /* Initialise the date picker. */

7107      if (!$.datepicker.initialized) {
7108          $(document.body).append($.datepicker.dpDiv).
7109              mousedown($.datepicker._checkExternalClick);
7110          $.datepicker.initialized = true;
7111      }
7112  
7113      var otherArgs = Array.prototype.slice.call(arguments, 1);
7114      if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate'))
7115          return $.datepicker['_' + options + 'Datepicker'].
7116              apply($.datepicker, [this[0]].concat(otherArgs));
7117      return this.each(function() {
7118          typeof options == 'string' ?
7119              $.datepicker['_' + options + 'Datepicker'].
7120                  apply($.datepicker, [this].concat(otherArgs)) :
7121              $.datepicker._attachDatepicker(this, options);
7122      });
7123  };
7124  
7125  $.datepicker = new Datepicker(); // singleton instance

7126  $.datepicker.initialized = false;
7127  $.datepicker.uuid = new Date().getTime();
7128  $.datepicker.version = "1.6";
7129  
7130  })(jQuery);
7131  /*

7132   * jQuery UI Dialog 1.6

7133   *

7134   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

7135   * Dual licensed under the MIT (MIT-LICENSE.txt)

7136   * and GPL (GPL-LICENSE.txt) licenses.

7137   *

7138   * http://docs.jquery.com/UI/Dialog

7139   *

7140   * Depends:

7141   *    ui.core.js

7142   *    ui.draggable.js

7143   *    ui.resizable.js

7144   */
7145  (function($) {
7146  
7147  var setDataSwitch = {
7148      dragStart: "start.draggable",
7149      drag: "drag.draggable",
7150      dragStop: "stop.draggable",
7151      maxHeight: "maxHeight.resizable",
7152      minHeight: "minHeight.resizable",
7153      maxWidth: "maxWidth.resizable",
7154      minWidth: "minWidth.resizable",
7155      resizeStart: "start.resizable",
7156      resize: "drag.resizable",
7157      resizeStop: "stop.resizable"
7158  };
7159  
7160  $.widget("ui.dialog", {
7161  
7162      _init: function() {
7163          this.originalTitle = this.element.attr('title');
7164          this.options.title = this.options.title || this.originalTitle;
7165  
7166          var self = this,
7167              options = this.options,
7168  
7169              uiDialogContent = this.element
7170                  .removeAttr('title')
7171                  .addClass('ui-dialog-content')
7172                  .wrap('<div></div>')
7173                  .wrap('<div></div>'),
7174  
7175              uiDialogContainer = (this.uiDialogContainer = uiDialogContent.parent())
7176                  .addClass('ui-dialog-container')
7177                  .css({
7178                      position: 'relative',
7179                      width: '100%',
7180                      height: '100%'
7181                  }),
7182  
7183              uiDialogTitlebar = (this.uiDialogTitlebar = $('<div></div>'))
7184                  .addClass('ui-dialog-titlebar')
7185                  .mousedown(function() {
7186                      self.moveToTop();
7187                  })
7188                  .prependTo(uiDialogContainer),
7189  
7190              uiDialogTitlebarClose = $('<a href="#"/>')
7191                  .addClass('ui-dialog-titlebar-close')
7192                  .attr('role', 'button')
7193                  .appendTo(uiDialogTitlebar),
7194  
7195              uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>'))
7196                  .text(options.closeText)
7197                  .appendTo(uiDialogTitlebarClose),
7198  
7199              title = options.title || '&nbsp;',
7200              titleId = $.ui.dialog.getTitleId(this.element),
7201              uiDialogTitle = $('<span/>')
7202                  .addClass('ui-dialog-title')
7203                  .attr('id', titleId)
7204                  .html(title)
7205                  .prependTo(uiDialogTitlebar),
7206  
7207              uiDialog = (this.uiDialog = uiDialogContainer.parent())
7208                  .appendTo(document.body)
7209                  .hide()
7210                  .addClass('ui-dialog')
7211                  .addClass(options.dialogClass)
7212                  .css({
7213                      position: 'absolute',
7214                      width: options.width,
7215                      height: options.height,
7216                      overflow: 'hidden',
7217                      zIndex: options.zIndex
7218                  })
7219                  // setting tabIndex makes the div focusable

7220                  // setting outline to 0 prevents a border on focus in Mozilla

7221                  .attr('tabIndex', -1).css('outline', 0).keydown(function(ev) {
7222                      (options.closeOnEscape && ev.keyCode
7223                          && ev.keyCode == $.ui.keyCode.ESCAPE && self.close());
7224                  })
7225                  .attr({
7226                      role: 'dialog',
7227                      'aria-labelledby': titleId
7228                  })
7229                  .mouseup(function() {
7230                      self.moveToTop();
7231                  }),
7232  
7233              uiDialogButtonPane = (this.uiDialogButtonPane = $('<div></div>'))
7234                  .addClass('ui-dialog-buttonpane')
7235                  .css({
7236                      position: 'absolute',
7237                      bottom: 0
7238                  })
7239                  .appendTo(uiDialog),
7240  
7241              uiDialogTitlebarClose = $('.ui-dialog-titlebar-close', uiDialogTitlebar)
7242                  .hover(
7243                      function() {
7244                          $(this).addClass('ui-dialog-titlebar-close-hover');
7245                      },
7246                      function() {
7247                          $(this).removeClass('ui-dialog-titlebar-close-hover');
7248                      }
7249                  )
7250                  .mousedown(function(ev) {
7251                      ev.stopPropagation();
7252                  })
7253                  .click(function() {
7254                      self.close();
7255                      return false;
7256                  });
7257  
7258          uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
7259  
7260          (options.draggable && $.fn.draggable && this._makeDraggable());
7261          (options.resizable && $.fn.resizable && this._makeResizable());
7262  
7263          this._createButtons(options.buttons);
7264          this._isOpen = false;
7265  
7266          (options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe());
7267          (options.autoOpen && this.open());
7268      },
7269  
7270      destroy: function() {
7271          (this.overlay && this.overlay.destroy());
7272          this.uiDialog.hide();
7273          this.element
7274              .unbind('.dialog')
7275              .removeData('dialog')
7276              .removeClass('ui-dialog-content')
7277              .hide().appendTo('body');
7278          this.uiDialog.remove();
7279  
7280          (this.originalTitle && this.element.attr('title', this.originalTitle));
7281      },
7282  
7283      close: function() {
7284          if (false === this._trigger('beforeclose', null, { options: this.options })) {
7285              return;
7286          }
7287  
7288          (this.overlay && this.overlay.destroy());
7289          this.uiDialog
7290              .hide(this.options.hide)
7291              .unbind('keypress.ui-dialog');
7292  
7293          this._trigger('close', null, { options: this.options });
7294          $.ui.dialog.overlay.resize();
7295  
7296          this._isOpen = false;
7297      },
7298  
7299      isOpen: function() {
7300          return this._isOpen;
7301      },
7302  
7303      // the force parameter allows us to move modal dialogs to their correct

7304      // position on open

7305      moveToTop: function(force) {
7306  
7307          if ((this.options.modal && !force)
7308              || (!this.options.stack && !this.options.modal)) {
7309              return this._trigger('focus', null, { options: this.options });
7310          }
7311  
7312          var maxZ = this.options.zIndex, options = this.options;
7313          $('.ui-dialog:visible').each(function() {
7314              maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10) || options.zIndex);
7315          });
7316          (this.overlay && this.overlay.$el.css('z-index', ++maxZ));
7317  
7318          //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.

7319          //  http://ui.jquery.com/bugs/ticket/3193

7320          var saveScroll = { scrollTop: this.element.attr('scrollTop'), scrollLeft: this.element.attr('scrollLeft') };
7321          this.uiDialog.css('z-index', ++maxZ);
7322          this.element.attr(saveScroll);
7323          this._trigger('focus', null, { options: this.options });
7324      },
7325  
7326      open: function() {
7327          if (this._isOpen) { return; }
7328  
7329          this.overlay = this.options.modal ? new $.ui.dialog.overlay(this) : null;
7330          (this.uiDialog.next().length && this.uiDialog.appendTo('body'));
7331          this._position(this.options.position);
7332          this.uiDialog.show(this.options.show);
7333          (this.options.autoResize && this._size());
7334          this.moveToTop(true);
7335  
7336          // prevent tabbing out of modal dialogs

7337          (this.options.modal && this.uiDialog.bind('keypress.ui-dialog', function(event) {
7338              if (event.keyCode != $.ui.keyCode.TAB) {
7339                  return;
7340              }
7341  
7342              var tabbables = $(':tabbable', this),
7343                  first = tabbables.filter(':first')[0],
7344                  last  = tabbables.filter(':last')[0];
7345  
7346              if (event.target == last && !event.shiftKey) {
7347                  setTimeout(function() {
7348                      first.focus();
7349                  }, 1);
7350              } else if (event.target == first && event.shiftKey) {
7351                  setTimeout(function() {
7352                      last.focus();
7353                  }, 1);
7354              }
7355          }));
7356  
7357          this.uiDialog.find(':tabbable:first').focus();
7358          this._trigger('open', null, { options: this.options });
7359          this._isOpen = true;
7360      },
7361  
7362      _createButtons: function(buttons) {
7363          var self = this,
7364              hasButtons = false,
7365              uiDialogButtonPane = this.uiDialogButtonPane;
7366  
7367          // remove any existing buttons

7368          uiDialogButtonPane.empty().hide();
7369  
7370          $.each(buttons, function() { return !(hasButtons = true); });
7371          if (hasButtons) {
7372              uiDialogButtonPane.show();
7373              $.each(buttons, function(name, fn) {
7374                  $('<button type="button"></button>')
7375                      .text(name)
7376                      .click(function() { fn.apply(self.element[0], arguments); })
7377                      .appendTo(uiDialogButtonPane);
7378              });
7379          }
7380      },
7381  
7382      _makeDraggable: function() {
7383          var self = this,
7384              options = this.options;
7385  
7386          this.uiDialog.draggable({
7387              cancel: '.ui-dialog-content',
7388              helper: options.dragHelper,
7389              handle: '.ui-dialog-titlebar',
7390              start: function() {
7391                  self.moveToTop();
7392                  (options.dragStart && options.dragStart.apply(self.element[0], arguments));
7393              },
7394              drag: function() {
7395                  (options.drag && options.drag.apply(self.element[0], arguments));
7396              },
7397              stop: function() {
7398                  (options.dragStop && options.dragStop.apply(self.element[0], arguments));
7399                  $.ui.dialog.overlay.resize();
7400              }
7401          });
7402      },
7403  
7404      _makeResizable: function(handles) {
7405          handles = (handles === undefined ? this.options.resizable : handles);
7406          var self = this,
7407              options = this.options,
7408              resizeHandles = typeof handles == 'string'
7409                  ? handles
7410                  : 'n,e,s,w,se,sw,ne,nw';
7411  
7412          this.uiDialog.resizable({
7413              cancel: '.ui-dialog-content',
7414              helper: options.resizeHelper,
7415              maxWidth: options.maxWidth,
7416              maxHeight: options.maxHeight,
7417              minWidth: options.minWidth,
7418              minHeight: options.minHeight,
7419              start: function() {
7420                  (options.resizeStart && options.resizeStart.apply(self.element[0], arguments));
7421              },
7422              resize: function() {
7423                  (options.autoResize && self._size.apply(self));
7424                  (options.resize && options.resize.apply(self.element[0], arguments));
7425              },
7426              handles: resizeHandles,
7427              stop: function() {
7428                  (options.autoResize && self._size.apply(self));
7429                  (options.resizeStop && options.resizeStop.apply(self.element[0], arguments));
7430                  $.ui.dialog.overlay.resize();
7431              }
7432          });
7433      },
7434  
7435      _position: function(pos) {
7436          var wnd = $(window), doc = $(document),
7437              pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
7438              minTop = pTop;
7439  
7440          if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
7441              pos = [
7442                  pos == 'right' || pos == 'left' ? pos : 'center',
7443                  pos == 'top' || pos == 'bottom' ? pos : 'middle'
7444              ];
7445          }
7446          if (pos.constructor != Array) {
7447              pos = ['center', 'middle'];
7448          }
7449          if (pos[0].constructor == Number) {
7450              pLeft += pos[0];
7451          } else {
7452              switch (pos[0]) {
7453                  case 'left':
7454                      pLeft += 0;
7455                      break;
7456                  case 'right':
7457                      pLeft += wnd.width() - this.uiDialog.outerWidth();
7458                      break;
7459                  default:
7460                  case 'center':
7461                      pLeft += (wnd.width() - this.uiDialog.outerWidth()) / 2;
7462              }
7463          }
7464          if (pos[1].constructor == Number) {
7465              pTop += pos[1];
7466          } else {
7467              switch (pos[1]) {
7468                  case 'top':
7469                      pTop += 0;
7470                      break;
7471                  case 'bottom':
7472                      // Opera check fixes #3564, can go away with jQuery 1.3

7473                      pTop += ($.browser.opera ? window.innerHeight : wnd.height()) - this.uiDialog.outerHeight();
7474                      break;
7475                  default:
7476                  case 'middle':
7477                      // Opera check fixes #3564, can go away with jQuery 1.3

7478                      pTop += (($.browser.opera ? window.innerHeight : wnd.height()) - this.uiDialog.outerHeight()) / 2;
7479              }
7480          }
7481  
7482          // prevent the dialog from being too high (make sure the titlebar

7483          // is accessible)

7484          pTop = Math.max(pTop, minTop);
7485          this.uiDialog.css({top: pTop, left: pLeft});
7486      },
7487  
7488      _setData: function(key, value){
7489          (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
7490          switch (key) {
7491              case "buttons":
7492                  this._createButtons(value);
7493                  break;
7494              case "closeText":
7495                  this.uiDialogTitlebarCloseText.text(value);
7496                  break;
7497              case "draggable":
7498                  (value
7499                      ? this._makeDraggable()
7500                      : this.uiDialog.draggable('destroy'));
7501                  break;
7502              case "height":
7503                  this.uiDialog.height(value);
7504                  break;
7505              case "position":
7506                  this._position(value);
7507                  break;
7508              case "resizable":
7509                  var uiDialog = this.uiDialog,
7510                      isResizable = this.uiDialog.is(':data(resizable)');
7511  
7512                  // currently resizable, becoming non-resizable

7513                  (isResizable && !value && uiDialog.resizable('destroy'));
7514  
7515                  // currently resizable, changing handles

7516                  (isResizable && typeof value == 'string' &&
7517                      uiDialog.resizable('option', 'handles', value));
7518  
7519                  // currently non-resizable, becoming resizable

7520                  (isResizable || this._makeResizable(value));
7521  
7522                  break;
7523              case "title":
7524                  $(".ui-dialog-title", this.uiDialogTitlebar).html(value || '&nbsp;');
7525                  break;
7526              case "width":
7527                  this.uiDialog.width(value);
7528                  break;
7529          }
7530  
7531          $.widget.prototype._setData.apply(this, arguments);
7532      },
7533  
7534      _size: function() {
7535          var container = this.uiDialogContainer,
7536              titlebar = this.uiDialogTitlebar,
7537              content = this.element,
7538              tbMargin = (parseInt(content.css('margin-top'), 10) || 0)
7539                  + (parseInt(content.css('margin-bottom'), 10) || 0),
7540              lrMargin = (parseInt(content.css('margin-left'), 10) || 0)
7541                  + (parseInt(content.css('margin-right'), 10) || 0);
7542          content.height(container.height() - titlebar.outerHeight() - tbMargin);
7543          content.width(container.width() - lrMargin);
7544      }
7545  
7546  });
7547  
7548  $.extend($.ui.dialog, {
7549      version: "1.6",
7550      defaults: {
7551          autoOpen: true,
7552          autoResize: true,
7553          bgiframe: false,
7554          buttons: {},
7555          closeOnEscape: true,
7556          closeText: 'close',
7557          draggable: true,
7558          height: 200,
7559          minHeight: 100,
7560          minWidth: 150,
7561          modal: false,
7562          overlay: {},
7563          position: 'center',
7564          resizable: true,
7565          stack: true,
7566          width: 300,
7567          zIndex: 1000
7568      },
7569  
7570      getter: 'isOpen',
7571  
7572      uuid: 0,
7573  
7574      getTitleId: function($el) {
7575          return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid);
7576      },
7577  
7578      overlay: function(dialog) {
7579          this.$el = $.ui.dialog.overlay.create(dialog);
7580      }
7581  });
7582  
7583  $.extend($.ui.dialog.overlay, {
7584      instances: [],
7585      events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
7586          function(event) { return event + '.dialog-overlay'; }).join(' '),
7587      create: function(dialog) {
7588          if (this.instances.length === 0) {
7589              // prevent use of anchors and inputs

7590              // we use a setTimeout in case the overlay is created from an

7591              // event that we're going to be cancelling (see #2804)

7592              setTimeout(function() {
7593                  $('a, :input').bind($.ui.dialog.overlay.events, function() {
7594                      // allow use of the element if inside a dialog and

7595                      // - there are no modal dialogs

7596                      // - there are modal dialogs, but we are in front of the topmost modal

7597                      var allow = false;
7598                      var $dialog = $(this).parents('.ui-dialog');
7599                      if ($dialog.length) {
7600                          var $overlays = $('.ui-dialog-overlay');
7601                          if ($overlays.length) {
7602                              var maxZ = parseInt($overlays.css('z-index'), 10);
7603                              $overlays.each(function() {
7604                                  maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10));
7605                              });
7606                              allow = parseInt($dialog.css('z-index'), 10) > maxZ;
7607                          } else {
7608                              allow = true;
7609                          }
7610                      }
7611                      return allow;
7612                  });
7613              }, 1);
7614  
7615              // allow closing by pressing the escape key

7616              $(document).bind('keydown.dialog-overlay', function(event) {
7617                  (dialog.options.closeOnEscape && event.keyCode
7618                          && event.keyCode == $.ui.keyCode.ESCAPE && dialog.close());
7619              });
7620  
7621              // handle window resize

7622              $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
7623          }
7624  
7625          var $el = $('<div></div>').appendTo(document.body)
7626              .addClass('ui-dialog-overlay').css($.extend({
7627                  borderWidth: 0, margin: 0, padding: 0,
7628                  position: 'absolute', top: 0, left: 0,
7629                  width: this.width(),
7630                  height: this.height()
7631              }, dialog.options.overlay));
7632  
7633          (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());
7634  
7635          this.instances.push($el);
7636          return $el;
7637      },
7638  
7639      destroy: function($el) {
7640          this.instances.splice($.inArray(this.instances, $el), 1);
7641  
7642          if (this.instances.length === 0) {
7643              $('a, :input').add([document, window]).unbind('.dialog-overlay');
7644          }
7645  
7646          $el.remove();
7647      },
7648  
7649      height: function() {
7650          // handle IE 6

7651          if ($.browser.msie && $.browser.version < 7) {
7652              var scrollHeight = Math.max(
7653                  document.documentElement.scrollHeight,
7654                  document.body.scrollHeight
7655              );
7656              var offsetHeight = Math.max(
7657                  document.documentElement.offsetHeight,
7658                  document.body.offsetHeight
7659              );
7660  
7661              if (scrollHeight < offsetHeight) {
7662                  return $(window).height() + 'px';
7663              } else {
7664                  return scrollHeight + 'px';
7665              }
7666          // handle Opera

7667          } else if ($.browser.opera) {
7668              return Math.max(
7669                  window.innerHeight,
7670                  $(document).height()
7671              ) + 'px';
7672          // handle "good" browsers

7673          } else {
7674              return $(document).height() + 'px';
7675          }
7676      },
7677  
7678      width: function() {
7679          // handle IE 6

7680          if ($.browser.msie && $.browser.version < 7) {
7681              var scrollWidth = Math.max(
7682                  document.documentElement.scrollWidth,
7683                  document.body.scrollWidth
7684              );
7685              var offsetWidth = Math.max(
7686                  document.documentElement.offsetWidth,
7687                  document.body.offsetWidth
7688              );
7689  
7690              if (scrollWidth < offsetWidth) {
7691                  return $(window).width() + 'px';
7692              } else {
7693                  return scrollWidth + 'px';
7694              }
7695          // handle Opera

7696          } else if ($.browser.opera) {
7697              return Math.max(
7698                  window.innerWidth,
7699                  $(document).width()
7700              ) + 'px';
7701          // handle "good" browsers

7702          } else {
7703              return $(document).width() + 'px';
7704          }
7705      },
7706  
7707      resize: function() {
7708          /* If the dialog is draggable and the user drags it past the

7709           * right edge of the window, the document becomes wider so we

7710           * need to stretch the overlay. If the user then drags the

7711           * dialog back to the left, the document will become narrower,

7712           * so we need to shrink the overlay to the appropriate size.

7713           * This is handled by shrinking the overlay before setting it

7714           * to the full document size.

7715           */
7716          var $overlays = $([]);
7717          $.each($.ui.dialog.overlay.instances, function() {
7718              $overlays = $overlays.add(this);
7719          });
7720  
7721          $overlays.css({
7722              width: 0,
7723              height: 0
7724          }).css({
7725              width: $.ui.dialog.overlay.width(),
7726              height: $.ui.dialog.overlay.height()
7727          });
7728      }
7729  });
7730  
7731  $.extend($.ui.dialog.overlay.prototype, {
7732      destroy: function() {
7733          $.ui.dialog.overlay.destroy(this.$el);
7734      }
7735  });
7736  
7737  })(jQuery);
7738  /*

7739   * jQuery UI Slider 1.6

7740   *

7741   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

7742   * Dual licensed under the MIT (MIT-LICENSE.txt)

7743   * and GPL (GPL-LICENSE.txt) licenses.

7744   *

7745   * http://docs.jquery.com/UI/Slider

7746   *

7747   * Depends:

7748   *    ui.core.js

7749   */
7750  (function($) {
7751  
7752  $.fn.unwrap = $.fn.unwrap || function(expr) {
7753    return this.each(function(){
7754       $(this).parents(expr).eq(0).after(this).remove();
7755    });
7756  };
7757  
7758  $.widget("ui.slider", {
7759  
7760      _init: function() {
7761  
7762          var self = this;
7763          this.element.addClass("ui-slider");
7764          this._initBoundaries();
7765  
7766          // Initialize mouse and key events for interaction

7767          this.handle = $(this.options.handle, this.element);
7768          if (!this.handle.length) {
7769              self.handle = self.generated = $(self.options.handles || [0]).map(function() {
7770                  var handle = $("<div/>").addClass("ui-slider-handle").appendTo(self.element);
7771                  if (this.id)
7772                      handle.attr("id", this.id);
7773                  return handle[0];
7774              });
7775          }
7776  
7777          var handleclass = function(el) {
7778              this.element = $(el);
7779              this.element.data("mouse", this);
7780              this.options = self.options;
7781  
7782              this.element.bind("mousedown", function() {
7783                  if(self.currentHandle) this.blur(self.currentHandle);
7784                  self._focus(this, true);
7785              });
7786  
7787              this._mouseInit();
7788          };
7789  
7790          $.extend(handleclass.prototype, $.ui.mouse, {
7791              _mouseCapture: function() { return true; },
7792              _mouseStart: function(event) { return self._start.call(self, event, this.element[0]); },
7793              _mouseDrag: function(event) { return self._drag.call(self, event, this.element[0]); },
7794              _mouseStop: function(event) { return self._stop.call(self, event, this.element[0]); },
7795              trigger: function(event) { this._mouseDown(event); }
7796          });
7797  
7798          $(this.handle)
7799              .each(function() {
7800                  new handleclass(this);
7801              })
7802              .wrap('<a href="#" style="outline:none;border:none;"></a>')
7803              .parent()
7804                  .bind('click', function() { return false; })
7805                  .bind('focus', function(event) { self._focus(this.firstChild); })
7806                  .bind('blur', function(event) { self._blur(this.firstChild); })
7807                  .bind('keydown', function(event) { if(!self.options.noKeyboard) return self._keydown(event.keyCode, this.firstChild); })
7808          ;
7809  
7810          // Bind the click to the slider itself

7811          this.element.bind('mousedown.slider', function(event) {
7812  
7813              if($(event.target).is('.ui-slider-handle')) return;
7814  
7815              //Go to the actual clicked posiion, apply a click

7816              self._click.apply(self, [event]);
7817  
7818              //initiate a handle drag, so we can click+drag somewhere

7819               self.currentHandle.data("mouse").trigger(event);
7820  
7821               //This is for always triggering the change event

7822              self.firstValue = self.firstValue + 1;
7823  
7824          });
7825  
7826          // Move the first handle to the startValue

7827          $.each(this.options.handles || [], function(index, handle) {
7828              self.moveTo(handle.start, index, true);
7829          });
7830          if (!isNaN(this.options.startValue))
7831              this.moveTo(this.options.startValue, 0, true);
7832  
7833          this.previousHandle = $(this.handle[0]); //set the previous handle to the first to allow clicking before selecting the handle

7834          if(this.handle.length == 2 && this.options.range) this._createRange();
7835  
7836      },
7837  
7838      destroy: function() {
7839  
7840          this.element
7841              .removeClass("ui-slider ui-slider-disabled")
7842              .removeData("slider")
7843              .unbind(".slider");
7844  
7845          if(this.handle && this.handle.length) {
7846              this.handle
7847                  .unwrap("a");
7848              this.handle.each(function() {
7849                  var mouse = $(this).data("mouse");
7850                  mouse && mouse._mouseDestroy();
7851              });
7852          }
7853  
7854          this.generated && this.generated.remove();
7855  
7856      },
7857  
7858      _start: function(event, handle) {
7859  
7860          var o = this.options;
7861          if(o.disabled) return false;
7862  
7863          // Prepare the outer size

7864          this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
7865  
7866          // This is a especially ugly fix for strange blur events happening on mousemove events

7867          if (!this.currentHandle)
7868              this._focus(this.previousHandle, true);
7869  
7870          this.offset = this.element.offset();
7871  
7872          this.handleOffset = this.currentHandle.offset();
7873          this.clickOffset = { top: event.pageY - this.handleOffset.top, left: event.pageX - this.handleOffset.left };
7874  
7875          this.firstValue = this.value();
7876  
7877          this._propagate('start', event);
7878          this._drag(event, handle);
7879          return true;
7880  
7881      },
7882  
7883      _drag: function(event, handle) {
7884  
7885          var o = this.options;
7886  
7887          var position = { top: event.pageY - this.offset.top - this.clickOffset.top, left: event.pageX - this.offset.left - this.clickOffset.left};
7888          if(!this.currentHandle) this._focus(this.previousHandle, true); //This is a especially ugly fix for strange blur events happening on mousemove events

7889  
7890          position.left = this._translateLimits(position.left, "x");
7891          position.top = this._translateLimits(position.top, "y");
7892  
7893          if (o.stepping.x) {
7894              var value = this._convertValue(position.left, "x");
7895              value = this._round(value / o.stepping.x) * o.stepping.x;
7896              position.left = this._translateValue(value, "x");
7897          }
7898          if (o.stepping.y) {
7899              var value = this._convertValue(position.top, "y");
7900              value = this._round(value / o.stepping.y) * o.stepping.y;
7901              position.top = this._translateValue(value, "y");
7902          }
7903  
7904          position.left = this._translateRange(position.left, "x");
7905          position.top = this._translateRange(position.top, "y");
7906  
7907          if(o.axis != "vertical") this.currentHandle.css({ left: position.left });
7908          if(o.axis != "horizontal") this.currentHandle.css({ top: position.top });
7909  
7910          //Store the slider's value

7911          this.currentHandle.data("mouse").sliderValue = {
7912              x: this._round(this._convertValue(position.left, "x")) || 0,
7913              y: this._round(this._convertValue(position.top, "y")) || 0
7914          };
7915  
7916          if (this.rangeElement)
7917              this._updateRange();
7918          this._propagate('slide', event);
7919          return false;
7920  
7921      },
7922  
7923      _stop: function(event) {
7924  
7925          this._propagate('stop', event);
7926  
7927          if (this.firstValue != this.value())
7928              this._propagate('change', event);
7929  
7930          // This is a especially ugly fix for strange blur events happening on mousemove events

7931          this._focus(this.currentHandle, true);
7932  
7933          return false;
7934  
7935      },
7936  
7937      _round: function(value) {
7938  
7939          return this.options.round ? parseInt(value,10) : parseFloat(value);
7940  
7941      },
7942  
7943      _setData: function(key, value) {
7944  
7945          $.widget.prototype._setData.apply(this, arguments);
7946  
7947          if (/min|max|steps/.test(key)) {
7948              this._initBoundaries();
7949          }
7950  
7951          if(key == "range") {
7952              value ? this.handle.length == 2 && this._createRange() : this._removeRange();
7953          }
7954  
7955      },
7956  
7957      _initBoundaries: function() {
7958  
7959          var element = this.element[0], o = this.options;
7960          this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
7961  
7962          $.extend(o, {
7963              axis: o.axis || (element.offsetWidth < element.offsetHeight ? 'vertical' : 'horizontal'),
7964              max: !isNaN(parseInt(o.max,10)) ? { x: parseInt(o.max, 10), y: parseInt(o.max, 10) } : ({ x: o.max && o.max.x || 100, y: o.max && o.max.y || 100 }),
7965              min: !isNaN(parseInt(o.min,10)) ? { x: parseInt(o.min, 10), y: parseInt(o.min, 10) } : ({ x: o.min && o.min.x || 0, y: o.min && o.min.y || 0 })
7966          });
7967          //Prepare the real maxValue

7968          o.realMax = {
7969              x: o.max.x - o.min.x,
7970              y: o.max.y - o.min.y
7971          };
7972          //Calculate stepping based on steps

7973          o.stepping = {
7974              x: o.stepping && o.stepping.x || parseInt(o.stepping, 10) || (o.steps ? o.realMax.x/(o.steps.x || parseInt(o.steps, 10) || o.realMax.x) : 0),
7975              y: o.stepping && o.stepping.y || parseInt(o.stepping, 10) || (o.steps ? o.realMax.y/(o.steps.y || parseInt(o.steps, 10) || o.realMax.y) : 0)
7976          };
7977  
7978      },
7979  
7980      _keydown: function(keyCode, handle) {
7981  
7982          if (this.options.disabled)
7983              return;
7984  
7985          var k = keyCode;
7986          if(/(33|34|35|36|37|38|39|40)/.test(k)) {
7987              var o = this.options, xpos, ypos;
7988              if (/(35|36)/.test(k)) {
7989                  xpos = (k == 35) ? o.max.x : o.min.x;
7990                  ypos = (k == 35) ? o.max.y : o.min.y;
7991              } else {
7992                  var oper = /(34|37|40)/.test(k) ? "-=" : "+=";
7993                  var step = /(37|38|39|40)/.test(k) ? "_oneStep" : "_pageStep";
7994                  xpos = oper + this[step]("x");
7995                  ypos = oper + this[step]("y");
7996              }
7997              this.moveTo({
7998                  x: xpos,
7999                  y: ypos
8000              }, handle);
8001              return false;
8002          }
8003          return true;
8004  
8005      },
8006  
8007      _focus: function(handle,hard) {
8008  
8009          this.currentHandle = $(handle).addClass('ui-slider-handle-active');
8010  
8011          if (hard)
8012              this.currentHandle.parent()[0].focus();
8013  
8014      },
8015  
8016      _blur: function(handle) {
8017  
8018          $(handle).removeClass('ui-slider-handle-active');
8019  
8020          if(this.currentHandle && this.currentHandle[0] == handle) {
8021              this.previousHandle = this.currentHandle;
8022              this.currentHandle = null;
8023          };
8024  
8025      },
8026  
8027      _click: function(event) {
8028  
8029          // This method is only used if:

8030          // - The user didn't click a handle

8031          // - The Slider is not disabled

8032          // - There is a current, or previous selected handle (otherwise we wouldn't know which one to move)

8033  
8034          var pointer = [event.pageX, event.pageY];
8035  
8036          var clickedHandle = false;
8037          this.handle.each(function() {
8038              if(this == event.target)
8039                  clickedHandle = true;
8040          });
8041          if (clickedHandle || this.options.disabled || !(this.currentHandle || this.previousHandle))
8042              return;
8043  
8044          // If a previous handle was focussed, focus it again

8045          if (!this.currentHandle && this.previousHandle)
8046              this._focus(this.previousHandle, true);
8047  
8048          // propagate only for distance > 0, otherwise propagation is done my drag

8049          this.offset = this.element.offset();
8050  
8051          this.moveTo({
8052              y: this._convertValue(event.pageY - this.offset.top - this.currentHandle[0].offsetHeight/2, "y"),
8053              x: this._convertValue(event.pageX - this.offset.left - this.currentHandle[0].offsetWidth/2, "x")
8054          }, null, !this.options.distance);
8055  
8056      },
8057  
8058      _createRange: function() {
8059  
8060          if(this.rangeElement) return;
8061          this.rangeElement = $('<div></div>')
8062              .addClass('ui-slider-range')
8063              .css({ position: 'absolute' })
8064              .appendTo(this.element);
8065          this._updateRange();
8066  
8067      },
8068  
8069      _removeRange: function() {
8070  
8071          this.rangeElement.remove();
8072          this.rangeElement = null;
8073  
8074      },
8075  
8076      _updateRange: function() {
8077  
8078          var prop = this.options.axis == "vertical" ? "top" : "left";
8079          var size = this.options.axis == "vertical" ? "height" : "width";
8080  
8081          this.rangeElement.css(prop, (this._round($(this.handle[0]).css(prop)) || 0) + this._handleSize(0, this.options.axis == "vertical" ? "y" : "x")/2);
8082          this.rangeElement.css(size, (this._round($(this.handle[1]).css(prop)) || 0) - (this._round($(this.handle[0]).css(prop)) || 0));
8083  
8084      },
8085  
8086      _getRange: function() {
8087  
8088          return this.rangeElement ? this._convertValue(this._round(this.rangeElement.css(this.options.axis == "vertical" ? "height" : "width")), this.options.axis == "vertical" ? "y" : "x") : null;
8089  
8090      },
8091  
8092      _handleIndex: function() {
8093  
8094          return this.handle.index(this.currentHandle[0]);
8095  
8096      },
8097  
8098      value: function(handle, axis) {
8099  
8100          if(this.handle.length == 1) this.currentHandle = this.handle;
8101          if(!axis) axis = this.options.axis == "vertical" ? "y" : "x";
8102  
8103          var curHandle = $(handle != undefined && handle !== null ? this.handle[handle] || handle : this.currentHandle);
8104  
8105          if(curHandle.data("mouse").sliderValue) {
8106              return this._round(curHandle.data("mouse").sliderValue[axis]);
8107          } else {
8108              return this._round(((this._round(curHandle.css(axis == "x" ? "left" : "top")) / (this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(handle,axis))) * this.options.realMax[axis]) + this.options.min[axis]);
8109          }
8110  
8111      },
8112  
8113      _convertValue: function(value,axis) {
8114  
8115          return this.options.min[axis] + (value / (this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis))) * this.options.realMax[axis];
8116  
8117      },
8118  
8119      _translateValue: function(value,axis) {
8120  
8121          return ((value - this.options.min[axis]) / this.options.realMax[axis]) * (this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis));
8122  
8123      },
8124  
8125      _translateRange: function(value,axis) {
8126  
8127          if (this.rangeElement) {
8128              if (this.currentHandle[0] == this.handle[0] && value >= this._translateValue(this.value(1),axis))
8129                  value = this._translateValue(this.value(1,axis) - this._oneStep(axis), axis);
8130              if (this.currentHandle[0] == this.handle[1] && value <= this._translateValue(this.value(0),axis))
8131                  value = this._translateValue(this.value(0,axis) + this._oneStep(axis), axis);
8132          }
8133  
8134          if (this.options.handles) {
8135              var handle = this.options.handles[this._handleIndex()];
8136              if (value < this._translateValue(handle.min,axis)) {
8137                  value = this._translateValue(handle.min,axis);
8138              } else if (value > this._translateValue(handle.max,axis)) {
8139                  value = this._translateValue(handle.max,axis);
8140              }
8141          }
8142  
8143          return value;
8144  
8145      },
8146  
8147      _translateLimits: function(value,axis) {
8148  
8149          if (value >= this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis))
8150              value = this.actualSize[axis == "x" ? "width" : "height"] - this._handleSize(null,axis);
8151  
8152          if (value <= 0)
8153              value = 0;
8154  
8155          return value;
8156  
8157      },
8158  
8159      _handleSize: function(handle,axis) {
8160  
8161          return $(handle != undefined && handle !== null ? this.handle[handle] : this.currentHandle)[0]["offset"+(axis == "x" ? "Width" : "Height")];
8162  
8163      },
8164  
8165      _oneStep: function(axis) {
8166  
8167          return this.options.stepping[axis] || 1;
8168  
8169      },
8170  
8171      _pageStep: function(axis) {
8172  
8173          return /* this.options.paging[axis] ||*/ 10;
8174  
8175      },
8176  
8177      moveTo: function(value, handle, noPropagation) {
8178  
8179          var o = this.options;
8180  
8181          // Prepare the outer size

8182          this.actualSize = { width: this.element.outerWidth() , height: this.element.outerHeight() };
8183  
8184          //If no handle has been passed, no current handle is available and we have multiple handles, return false

8185          if (handle == undefined && !this.currentHandle && this.handle.length != 1)
8186              return false;
8187  
8188          //If only one handle is available, use it

8189          if (handle == undefined && !this.currentHandle)
8190              handle = 0;
8191  
8192          if (handle != undefined)
8193              this.currentHandle = this.previousHandle = $(this.handle[handle] || handle);
8194  
8195          if(value.x !== undefined && value.y !== undefined) {
8196              var x = value.x, y = value.y;
8197          } else {
8198              var x = value, y = value;
8199          }
8200  
8201          if(x !== undefined && x.constructor != Number) {
8202              var me = /^\-\=/.test(x), pe = /^\+\=/.test(x);
8203              if(me || pe) {
8204                  x = this.value(null, "x") + this._round(x.replace(me ? '=' : '+=', ''));
8205              } else {
8206                  x = isNaN(this._round(x)) ? undefined : this._round(x);
8207              }
8208          }
8209  
8210          if(y !== undefined && y.constructor != Number) {
8211              var me = /^\-\=/.test(y), pe = /^\+\=/.test(y);
8212              if(me || pe) {
8213                  y = this.value(null, "y") + this._round(y.replace(me ? '=' : '+=', ''));
8214              } else {
8215                  y = isNaN(this._round(y)) ? undefined : this._round(y);
8216              }
8217          }
8218  
8219          if(o.axis != "vertical" && x !== undefined) {
8220              if(o.stepping.x) x = this._round(x / o.stepping.x) * o.stepping.x;
8221              x = this._translateValue(x, "x");
8222              x = this._translateLimits(x, "x");
8223              x = this._translateRange(x, "x");
8224  
8225              o.animate ? this.currentHandle.stop().animate({ left: x }, (Math.abs(parseInt(this.currentHandle.css("left"),10) - x)) * (!isNaN(parseInt(o.animate,10)) ? o.animate : 5)) : this.currentHandle.css({ left: x });
8226          }
8227  
8228          if(o.axis != "horizontal" && y !== undefined) {
8229              if(o.stepping.y) y = this._round(y / o.stepping.y) * o.stepping.y;
8230              y = this._translateValue(y, "y");
8231              y = this._translateLimits(y, "y");
8232              y = this._translateRange(y, "y");
8233              o.animate ? this.currentHandle.stop().animate({ top: y }, (Math.abs(parseInt(this.currentHandle.css("top"),10) - y)) * (!isNaN(parseInt(o.animate,10)) ? o.animate : 5)) : this.currentHandle.css({ top: y });
8234          }
8235  
8236          if (this.rangeElement)
8237              this._updateRange();
8238  
8239          //Store the slider's value

8240          this.currentHandle.data("mouse").sliderValue = {
8241              x: this._round(this._convertValue(x, "x")) || 0,
8242              y: this._round(this._convertValue(y, "y")) || 0
8243          };
8244  
8245          if (!noPropagation) {
8246              this._propagate('start', null);
8247              this._propagate("slide", null);
8248              this._propagate('stop', null);
8249              this._propagate('change', null);
8250          }
8251  
8252      },
8253  
8254      _propagate: function(n, event) {
8255  
8256          $.ui.plugin.call(this, n, [event, this.ui()]);
8257          this.element.triggerHandler(n == "slide" ? n : "slide"+n, [event, this.ui()], this.options[n]);
8258  
8259      },
8260  
8261      plugins: {},
8262  
8263      ui: function(event) {
8264          return {
8265              options: this.options,
8266              handle: this.currentHandle,
8267              value: this.options.axis != "both" || !this.options.axis ?
8268                  this._round(this.value(null, this.options.axis == "vertical" ? "y" : "x")) :
8269                  {
8270                      x: this._round(this.value(null, "x")),
8271                      y: this._round(this.value(null, "y"))
8272                  },
8273              range: this._getRange()
8274          };
8275      }
8276  
8277  });
8278  
8279  $.extend($.ui.slider, {
8280      getter: "value",
8281      version: "1.6",
8282      defaults: {
8283          animate: false,
8284          distance: 1,
8285          handle: ".ui-slider-handle",
8286          round: true
8287      }
8288  });
8289  
8290  })(jQuery);
8291  /*

8292   * jQuery UI Tabs 1.6

8293   *

8294   * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)

8295   * Dual licensed under the MIT (MIT-LICENSE.txt)

8296   * and GPL (GPL-LICENSE.txt) licenses.

8297   *

8298   * http://docs.jquery.com/UI/Tabs

8299   *

8300   * Depends:

8301   *    ui.core.js

8302   */
8303  (function($) {
8304  
8305  $.widget("ui.tabs", {
8306  
8307      _init: function() {
8308          // create tabs

8309          this._tabify(true);
8310      },
8311  
8312      destroy: function() {
8313          var o = this.options;
8314          this.element.unbind('.tabs')
8315              .removeClass(o.navClass).removeData('tabs');
8316          this.$tabs.each(function() {
8317              var href = $.data(this, 'href.tabs');
8318              if (href)
8319                  this.href = href;
8320              var $this = $(this).unbind('.tabs');
8321              $.each(['href', 'load', 'cache'], function(i, prefix) {
8322                  $this.removeData(prefix + '.tabs');
8323              });
8324          });
8325          this.$lis.add(this.$panels).each(function() {
8326              if ($.data(this, 'destroy.tabs'))
8327                  $(this).remove();
8328              else
8329                  $(this).removeClass([o.selectedClass, o.deselectableClass,
8330                      o.disabledClass, o.panelClass, o.hideClass].join(' '));
8331          });
8332          if (o.cookie)
8333              this._cookie(null, o.cookie);
8334      },
8335  
8336      _setData: function(key, value) {
8337          if ((/^selected/).test(key))
8338              this.select(value);
8339          else {
8340              this.options[key] = value;
8341              this._tabify();
8342          }
8343      },
8344  
8345      length: function() {
8346          return this.$tabs.length;
8347      },
8348  
8349      _tabId: function(a) {
8350          return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '')
8351              || this.options.idPrefix + $.data(a);
8352      },
8353  
8354      _sanitizeSelector: function(hash) {
8355          return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":"

8356      },
8357  
8358      _cookie: function() {
8359          var cookie = this.cookie || (this.cookie = 'ui-tabs-' + $.data(this.element[0]));
8360          return $.cookie.apply(null, [cookie].concat($.makeArray(arguments)));
8361      },
8362  
8363      _tabify: function(init) {
8364  
8365          this.$lis = $('li:has(a[href])', this.element);
8366          this.$tabs = this.$lis.map(function() { return $('a', this)[0]; });
8367          this.$panels = $([]);
8368  
8369          var self = this, o = this.options;
8370  
8371          this.$tabs.each(function(i, a) {
8372              // inline tab

8373              if (a.hash && a.hash.replace('#', '')) // Safari 2 reports '#' for an empty hash
8374                  self.$panels = self.$panels.add(self._sanitizeSelector(a.hash));
8375              // remote tab

8376              else if ($(a).attr('href') != '#') { // prevent loading the page itself if href is just "#"
8377                  $.data(a, 'href.tabs', a.href); // required for restore on destroy

8378                  $.data(a, 'load.tabs', a.href); // mutable

8379                  var id = self._tabId(a);
8380                  a.href = '#' + id;
8381                  var $panel = $('#' + id);
8382                  if (!$panel.length) {
8383                      $panel = $(o.panelTemplate).attr('id', id).addClass(o.panelClass)
8384                          .insertAfter(self.$panels[i - 1] || self.element);
8385                      $panel.data('destroy.tabs', true);
8386                  }
8387                  self.$panels = self.$panels.add($panel);
8388              }
8389              // invalid tab href

8390              else
8391                  o.disabled.push(i + 1);
8392          });
8393  
8394          // initialization from scratch

8395          if (init) {
8396  
8397              // attach necessary classes for styling if not present

8398              this.element.addClass(o.navClass);
8399              this.$panels.addClass(o.panelClass);
8400  
8401              // Selected tab

8402              // use "selected" option or try to retrieve:

8403              // 1. from fragment identifier in url

8404              // 2. from cookie

8405              // 3. from selected class attribute on <li>

8406              if (o.selected === undefined) {
8407                  if (location.hash) {
8408                      this.$tabs.each(function(i, a) {
8409                          if (a.hash == location.hash) {
8410                              o.selected = i;
8411                              return false; // break

8412                          }
8413                      });
8414                  }
8415                  else if (o.cookie) {
8416                      var index = parseInt(self._cookie(), 10);
8417                      if (index && self.$tabs[index]) o.selected = index;
8418                  }
8419                  else if (self.$lis.filter('.' + o.selectedClass).length)
8420                      o.selected = self.$lis.index( self.$lis.filter('.' + o.selectedClass)[0] );
8421              }
8422              o.selected = o.selected === null || o.selected !== undefined ? o.selected : 0; // first tab selected by default

8423  
8424              // Take disabling tabs via class attribute from HTML

8425              // into account and update option properly.

8426              // A selected tab cannot become disabled.

8427              o.disabled = $.unique(o.disabled.concat(
8428                  $.map(this.$lis.filter('.' + o.disabledClass),
8429                      function(n, i) { return self.$lis.index(n); } )
8430              )).sort();
8431              if ($.inArray(o.selected, o.disabled) != -1)
8432                  o.disabled.splice($.inArray(o.selected, o.disabled), 1);
8433  
8434              // highlight selected tab

8435              this.$panels.addClass(o.hideClass);
8436              this.$lis.removeClass(o.selectedClass);
8437              if (o.selected !== null) {
8438                  this.$panels.eq(o.selected).removeClass(o.hideClass);
8439                  var classes = [o.selectedClass];
8440                  if (o.deselectable) classes.push(o.deselectableClass);
8441                  this.$lis.eq(o.selected).addClass(classes.join(' '));
8442  
8443                  // seems to be expected behavior that the show callback is fired

8444                  var onShow = function() {
8445                      self._trigger('show', null,
8446                          self.ui(self.$tabs[o.selected], self.$panels[o.selected]));
8447                  };
8448  
8449                  // load if remote tab

8450                  if ($.data(this.$tabs[o.selected], 'load.tabs'))
8451                      this.load(o.selected, onShow);
8452                  // just trigger show event

8453                  else onShow();
8454              }
8455  
8456              // clean up to avoid memory leaks in certain versions of IE 6

8457              $(window).bind('unload', function() {
8458                  self.$tabs.unbind('.tabs');
8459                  self.$lis = self.$tabs = self.$panels = null;
8460              });
8461  
8462          }
8463          // update selected after add/remove

8464          else
8465              o.selected = this.$lis.index( this.$lis.filter('.' + o.selectedClass)[0] );
8466  
8467          // set or update cookie after init and add/remove respectively

8468          if (o.cookie) this._cookie(o.selected, o.cookie);
8469  
8470          // disable tabs

8471          for (var i = 0, li; li = this.$lis[i]; i++)
8472              $(li)[$.inArray(i, o.disabled) != -1 && !$(li).hasClass(o.selectedClass) ? 'addClass' : 'removeClass'](o.disabledClass);
8473  
8474          // reset cache if switching from cached to not cached

8475          if (o.cache === false) this.$tabs.removeData('cache.tabs');
8476  
8477          // set up animations

8478          var hideFx, showFx;
8479          if (o.fx) {
8480              if (o.fx.constructor == Array) {
8481                  hideFx = o.fx[0];
8482                  showFx = o.fx[1];
8483              }
8484              else hideFx = showFx = o.fx;
8485          }
8486  
8487          // Reset certain styles left over from animation

8488          // and prevent IE's ClearType bug...

8489  		function resetStyle($el, fx) {
8490              $el.css({ display: '' });
8491              if ($.browser.msie && fx.opacity) $el[0].style.removeAttribute('filter');
8492          }
8493  
8494          // Show a tab...

8495          var showTab = showFx ?
8496              function(clicked, $show) {
8497                  $show.animate(showFx, showFx.duration || 'normal', function() {
8498                      $show.removeClass(o.hideClass);
8499                      resetStyle($show, showFx);
8500                      self._trigger('show', null, self.ui(clicked, $show[0]));
8501                  });
8502              } :
8503              function(clicked, $show) {
8504                  $show.removeClass(o.hideClass);
8505                  self._trigger('show', null, self.ui(clicked, $show[0]));
8506              };
8507  
8508          // Hide a tab, $show is optional...

8509          var hideTab = hideFx ?
8510              function(clicked, $hide, $show) {
8511                  $hide.animate(hideFx, hideFx.duration || 'normal', function() {
8512                      $hide.addClass(o.hideClass);
8513                      resetStyle($hide, hideFx);
8514                      if ($show) showTab(clicked, $show, $hide);
8515                  });
8516              } :
8517              function(clicked, $hide, $show) {
8518                  $hide.addClass(o.hideClass);
8519                  if ($show) showTab(clicked, $show);
8520              };
8521  
8522          // Switch a tab...

8523  		function switchTab(clicked, $li, $hide, $show) {
8524              var classes = [o.selectedClass];
8525              if (o.deselectable) classes.push(o.deselectableClass);
8526              $li.addClass(classes.join(' ')).siblings().removeClass(classes.join(' '));
8527              hideTab(clicked, $hide, $show);
8528          }
8529  
8530          // attach tab event handler, unbind to avoid duplicates from former tabifying...

8531          this.$tabs.unbind('.tabs').bind(o.event + '.tabs', function() {
8532  
8533              //var trueClick = event.clientX; // add to history only if true click occured, not a triggered click

8534              var $li = $(this).parents('li:eq(0)'),
8535                  $hide = self.$panels.filter(':visible'),
8536                  $show = $(self._sanitizeSelector(this.hash));
8537  
8538              // If tab is already selected and not deselectable or tab disabled or

8539              // or is already loading or click callback returns false stop here.

8540              // Check if click handler returns false last so that it is not executed

8541              // for a disabled or loading tab!

8542              if (($li.hasClass(o.selectedClass) && !o.deselectable)
8543                  || $li.hasClass(o.disabledClass)
8544                  || $(this).hasClass(o.loadingClass)
8545                  || self._trigger('select', null, self.ui(this, $show[0])) === false
8546                  ) {
8547                  this.blur();
8548                  return false;
8549              }
8550  
8551              o.selected = self.$tabs.index(this);
8552  
8553              // if tab may be closed

8554              if (o.deselectable) {
8555                  if ($li.hasClass(o.selectedClass)) {
8556                      self.options.selected = null;
8557                      $li.removeClass([o.selectedClass, o.deselectableClass].join(' '));
8558                      self.$panels.stop();
8559                      hideTab(this, $hide);
8560                      this.blur();
8561                      return false;
8562                  } else if (!$hide.length) {
8563                      self.$panels.stop();
8564                      var a = this;
8565                      self.load(self.$tabs.index(this), function() {
8566                          $li.addClass([o.selectedClass, o.deselectableClass].join(' '));
8567                          showTab(a, $show);
8568                      });
8569                      this.blur();
8570                      return false;
8571                  }
8572              }
8573  
8574              if (o.cookie) self._cookie(o.selected, o.cookie);
8575  
8576              // stop possibly running animations

8577              self.$panels.stop();
8578  
8579              // show new tab

8580              if ($show.length) {
8581                  var a = this;
8582                  self.load(self.$tabs.index(this), $hide.length ?
8583                      function() {
8584                          switchTab(a, $li, $hide, $show);
8585                      } :
8586                      function() {
8587                          $li.addClass(o.selectedClass);
8588                          showTab(a, $show);
8589                      }
8590                  );
8591              } else
8592                  throw 'jQuery UI Tabs: Mismatching fragment identifier.';
8593  
8594              // Prevent IE from keeping other link focussed when using the back button

8595              // and remove dotted border from clicked link. This is controlled via CSS

8596              // in modern browsers; blur() removes focus from address bar in Firefox

8597              // which can become a usability and annoying problem with tabs('rotate').

8598              if ($.browser.msie) this.blur();
8599  
8600              return false;
8601  
8602          });
8603  
8604          // disable click if event is configured to something else

8605          if (o.event != 'click') this.$tabs.bind('click.tabs', function(){return false;});
8606  
8607      },
8608  
8609      add: function(url, label, index) {
8610          if (index == undefined)
8611              index = this.$tabs.length; // append by default

8612  
8613          var o = this.options;
8614          var $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label));
8615          $li.data('destroy.tabs', true);
8616  
8617          var id = url.indexOf('#') == 0 ? url.replace('#', '') : this._tabId( $('a:first-child', $li)[0] );
8618  
8619          // try to find an existing element before creating a new one

8620          var $panel = $('#' + id);
8621          if (!$panel.length) {
8622              $panel = $(o.panelTemplate).attr('id', id)
8623                  .addClass(o.hideClass)
8624                  .data('destroy.tabs', true);
8625          }
8626          $panel.addClass(o.panelClass);
8627          if (index >= this.$lis.length) {
8628              $li.appendTo(this.element);
8629              $panel.appendTo(this.element[0].parentNode);
8630          } else {
8631              $li.insertBefore(this.$lis[index]);
8632              $panel.insertBefore(this.$panels[index]);
8633          }
8634  
8635          o.disabled = $.map(o.disabled,
8636              function(n, i) { return n >= index ? ++n : n });
8637  
8638          this._tabify();
8639  
8640          if (this.$tabs.length == 1) {
8641              $li.addClass(o.selectedClass);
8642              $panel.removeClass(o.hideClass);
8643              var href = $.data(this.$tabs[0], 'load.tabs');
8644              if (href)
8645                  this.load(index, href);
8646          }
8647  
8648          // callback

8649          this._trigger('add', null, this.ui(this.$tabs[index], this.$panels[index]));
8650      },
8651  
8652      remove: function(index) {
8653          var o = this.options, $li = this.$lis.eq(index).remove(),
8654              $panel = this.$panels.eq(index).remove();
8655  
8656          // If selected tab was removed focus tab to the right or

8657          // in case the last tab was removed the tab to the left.

8658          if ($li.hasClass(o.selectedClass) && this.$tabs.length > 1)
8659              this.select(index + (index + 1 < this.$tabs.length ? 1 : -1));
8660  
8661          o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
8662              function(n, i) { return n >= index ? --n : n });
8663  
8664          this._tabify();
8665  
8666          // callback

8667          this._trigger('remove', null, this.ui($li.find('a')[0], $panel[0]));
8668      },
8669  
8670      enable: function(index) {
8671          var o = this.options;
8672          if ($.inArray(index, o.disabled) == -1)
8673              return;
8674  
8675          var $li = this.$lis.eq(index).removeClass(o.disabledClass);
8676          if ($.browser.safari) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2...
8677              $li.css('display', 'inline-block');
8678              setTimeout(function() {
8679                  $li.css('display', 'block');
8680              }, 0);
8681          }
8682  
8683          o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });
8684  
8685          // callback

8686          this._trigger('enable', null, this.ui(this.$tabs[index], this.$panels[index]));
8687      },
8688  
8689      disable: function(index) {
8690          var self = this, o = this.options;
8691          if (index != o.selected) { // cannot disable already selected tab
8692              this.$lis.eq(index).addClass(o.disabledClass);
8693  
8694              o.disabled.push(index);
8695              o.disabled.sort();
8696  
8697              // callback

8698              this._trigger('disable', null, this.ui(this.$tabs[index], this.$panels[index]));
8699          }
8700      },
8701  
8702      select: function(index) {
8703          // TODO make null as argument work

8704          if (typeof index == 'string')
8705              index = this.$tabs.index( this.$tabs.filter('[href$=' + index + ']')[0] );
8706          this.$tabs.eq(index).trigger(this.options.event + '.tabs');
8707      },
8708  
8709      load: function(index, callback) { // callback is for internal usage only
8710  
8711          var self = this, o = this.options, $a = this.$tabs.eq(index), a = $a[0],
8712                  bypassCache = callback == undefined || callback === false, url = $a.data('load.tabs');
8713  
8714          callback = callback || function() {};
8715  
8716          // no remote or from cache - just finish with callback

8717          if (!url || !bypassCache && $.data(a, 'cache.tabs')) {
8718              callback();
8719              return;
8720          }
8721  
8722          // load remote from here on

8723  
8724          var inner = function(parent) {
8725              var $parent = $(parent), $inner = $parent.find('*:last');
8726              return $inner.length && $inner.is(':not(img)') && $inner || $parent;
8727          };
8728          var cleanup = function() {
8729              self.$tabs.filter('.' + o.loadingClass).removeClass(o.loadingClass)
8730                      .each(function() {
8731                          if (o.spinner)
8732                              inner(this).parent().html(inner(this).data('label.tabs'));
8733                      });
8734              self.xhr = null;
8735          };
8736  
8737          if (o.spinner) {
8738              var label = inner(a).html();
8739              inner(a).wrapInner('<em></em>')
8740                  .find('em').data('label.tabs', label).html(o.spinner);
8741          }
8742  
8743          var ajaxOptions = $.extend({}, o.ajaxOptions, {
8744              url: url,
8745              success: function(r, s) {
8746                  $(self._sanitizeSelector(a.hash)).html(r);
8747                  cleanup();
8748  
8749                  if (o.cache)
8750                      $.data(a, 'cache.tabs', true); // if loaded once do not load them again

8751  
8752                  // callbacks

8753                  self._trigger('load', null, self.ui(self.$tabs[index], self.$panels[index]));
8754                  try {
8755                      o.ajaxOptions.success(r, s);
8756                  }
8757                  catch (event) {}
8758  
8759                  // This callback is required because the switch has to take

8760                  // place after loading has completed. Call last in order to

8761                  // fire load before show callback...

8762                  callback();
8763              }
8764          });
8765          if (this.xhr) {
8766              // terminate pending requests from other tabs and restore tab label

8767              this.xhr.abort();
8768              cleanup();
8769          }
8770          $a.addClass(o.loadingClass);
8771          self.xhr = $.ajax(ajaxOptions);
8772      },
8773  
8774      url: function(index, url) {
8775          this.$tabs.eq(index).removeData('cache.tabs').data('load.tabs', url);
8776      },
8777  
8778      ui: function(tab, panel) {
8779          return {
8780              options: this.options,
8781              tab: tab,
8782              panel: panel,
8783              index: this.$tabs.index(tab)
8784          };
8785      }
8786  
8787  });
8788  
8789  $.extend($.ui.tabs, {
8790      version: '1.6',
8791      getter: 'length',
8792      defaults: {
8793          ajaxOptions: null,
8794          cache: false,
8795          cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
8796          deselectable: false,
8797          deselectableClass: 'ui-tabs-deselectable',
8798          disabled: [],
8799          disabledClass: 'ui-tabs-disabled',
8800          event: 'click',
8801          fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
8802          hideClass: 'ui-tabs-hide',
8803          idPrefix: 'ui-tabs-',
8804          loadingClass: 'ui-tabs-loading',
8805          navClass: 'ui-tabs-nav',
8806          panelClass: 'ui-tabs-panel',
8807          panelTemplate: '<div></div>',
8808          selectedClass: 'ui-tabs-selected',
8809          spinner: 'Loading&#8230;',
8810          tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>'
8811      }
8812  });
8813  
8814  /*

8815   * Tabs Extensions

8816   */
8817  
8818  /*

8819   * Rotate

8820   */
8821  $.extend($.ui.tabs.prototype, {
8822      rotation: null,
8823      rotate: function(ms, continuing) {
8824  
8825          continuing = continuing || false;
8826  
8827          var self = this, t = this.options.selected;
8828  
8829  		function start() {
8830              self.rotation = setInterval(function() {
8831                  t = ++t < self.$tabs.length ? t : 0;
8832                  self.select(t);
8833              }, ms);
8834          }
8835  
8836  		function stop(event) {
8837              if (!event || event.clientX) { // only in case of a true click
8838                  clearInterval(self.rotation);
8839              }
8840          }
8841  
8842          // start interval

8843          if (ms) {
8844              start();
8845              if (!continuing)
8846                  this.$tabs.bind(this.options.event + '.tabs', stop);
8847              else
8848                  this.$tabs.bind(this.options.event + '.tabs', function() {
8849                      stop();
8850                      t = self.options.selected;
8851                      start();
8852                  });
8853          }
8854          // stop interval

8855          else {
8856              stop();
8857              this.$tabs.unbind(this.options.event + '.tabs', stop);
8858          }
8859      }
8860  });
8861  
8862  })(jQuery);


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7