PageSourceSearch

https://www.iqconsultancy.cz/bitrix/cache/js/iq/main_new/template_…38b0f4619ad2d4a9a1ee1a9.js?1721641856519778

js iqconsultancy.cz collected 2026-09-29 18:09:01 UTC 519,778 bytes, 17,876 lines download raw bytes

1
2; /* Start:"a:4:{s:4:"full";s:29:"/js/script.js?172122556711515";s:6:"source";s:13:"/js/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
3$(function() {
4		var thisTex;
5		var regionSelectTex;
6		var regionName;
7		
8		$('.vibor select ').change(function(){
9			window.location.href = $(this).find('option:selected').val();
10		});
11		
12	/******************************************************
13	CITY CHANGE
14	*********************************************************/
15		$(document).on('click', '.select span', function(){
16			
17			//показыает/убираем панельку переключения языка на УКР
18			if ( $(this).html() == "Киев" ) $('#lang').addClass('active');
19			if ( $(this).html() != "Киев" ) $('#lang').removeClass('active');
20
21			thisTex = $(this).closest('.select').html();
22			regionSelectTex = $('.region-select').clone().removeClass('region-select').addClass('select');
23			regionName = $(this).closest('.select').text();
24			$(this).closest('.select').detach();
25			$('.region-select').html(thisTex);
26			$('.point .hidden').prepend(regionSelectTex);
27			
28			
29		$.ajax({
30		type: 'POST',
31		url: '/include/phone-ajax.php',
32		data: { name: regionName },
33		cache: false,
34		dataType: 'json',
35		success: function(data) {
36			$('.phone-block .phone, .bottom-block .phone').html(data[0]);
37			$('.bottom-block .adress').html(data[1]);
38			$('a.contacts').attr('href',data[2]);
39			$('.icon-item .number').html(data[3]);
40			//new
41			$('.phoneNumber .number').html(data[3]);
42			$('.footer-form-office-mail').html(data[8]);
43			$(".footer-form-office-mail").attr("href", "mailto:"+data[8]);
44			
45			if(data[4]){
46			$('.review-block .name-block').html(data[4]);
47			$('.motivation-block .form-name').val(data[5]);
48			$('.motivation-block .form-address').val(data[6]);
49			$('#publicid').val(data[7]);
50
51			}
52		},
53		});
54			
55			
56		});
57	
58	/******************************************************
59	LEFT MENU
60	*********************************************************/		
61	
62	$('.menu-sidebar a, .sidebar-title a').each(function(){
63		if ($(this).attr('href')==window.location.pathname + window.location.search)
64		{
65		$(this).closest('li').addClass('parent');
66		$(this).before('<span>' + $(this).html() +'</span>');
67		$(this).detach();
68		}
69	});	
70	
71	/***********************************************************
72	SLIDER
73	***********************************************************/
74	function mycarousel_initCallback(carousel)
75	{
76		// Disable autoscrolling if the user clicks the prev or next button.
77		carousel.buttonNext.bind('click', function() {
78			carousel.startAuto(0);
79		});
80
81		carousel.buttonPrev.bind('click', function() {
82			carousel.startAuto(0);
83		});
84
85		// Pause autoscrolling if the user moves with the cursor over the clip.
86		carousel.clip.hover(function() {
87			carousel.stopAuto();
88		}, function() {
89			carousel.startAuto();
90		});
91	};
92	
93	
94	function photocarousel_initCallback(carousel)
95	{
96	
97	}
98	var numberC;
99	var numbers;
100	$('.calc-wrap .jcarousel-next ').on('click', function() {
101	
102			numberC = $(this).closest('.calc-wrap').find('#item-number').text();
103			numbers = $(this).closest('.calc-wrap').find('#count').text();
104			if(numberC == numbers)
105			{
106			$(this).closest('.calc-wrap').find('#item-number').text('1');
107			}
108			else
109			{
110			
111			$(this).closest('.calc-wrap').find('#item-number').text(numberC*1 + 1);
112			}
113	});
114	
115	$('.calc-wrap .jcarousel-prev').on('click', function() {
116	
117			numberC = $(this).closest('.calc-wrap').find('#item-number').text();
118			numbers = $(this).closest('.calc-wrap').find('#count').text();
119			if(numberC == 1)
120			{
121				$(this).closest('.calc-wrap').find('#item-number').text(numbers);
122			}
123			else
124			{
125			
126				$(this).closest('.calc-wrap').find('#item-number').text(numberC*1 - 1);
127			}
128	});
129	
130	jQuery('.photo-jcarousel').jcarousel({
131    	wrap: 'circular',
132		scroll : 1,
133		//auto: 4, // Сколько секунд держиться картинка 
134		initCallback: photocarousel_initCallback,
135		//animation : "slow",
136		buttonNextHTML: null,
137        buttonPrevHTML: null
138    });
139	
140 	jQuery('.photo-jcarousel-universities').jcarousel({
141    	wrap: 'circular',
142		scroll : 1,
143		initCallback: photocarousel_initCallback,
144		buttonNextHTML: null,
145        buttonPrevHTML: null
146    });
147	
148	
149
150	/***********************************************************
151	SLIDER
152	***********************************************************/
153	jQuery('#mycarousel').jcarousel({
154    	wrap: 'circular',
155		scroll : 1,
156		auto: 6, // Сколько секунд держиться картинка 
157		initCallback: mycarousel_initCallback,
158		animation : "slow"
159    });
160	
161	/******************************************************
162	FEEDBACK
163	*********************************************************/		
164	$('a.popup').fancybox({
165		'overlayShow': false, // значения параметров можно посмотреть на сайте разработчика
166		'padding': 0,
167		'margin' : 0,
168		'scrolling' : 'no',
169		'titleShow': false,
170		'type': 'ajax' // описание скрипта будет дано ниже по тексту:)
171	});
172	
173	/******************************************************
174	FEEDBACK
175	*********************************************************/		
176
177
178	
179	$('a.callback').fancybox({
180		'overlayShow': false, // значения параметров можно посмотреть на сайте разработчика
181		'padding': 0,
182		'margin' : 0,
183		'scrolling' : 'no',
184		'titleShow': false,
185		'type': 'ajax',
186		'href': '/include/callback.php', // описание скрипта будет дано ниже по тексту:)
187
188		'afterShow': function(){
189		
190		var ManagerName;
191		var id = this.element.attr('id');
192		if (id == "anna")
193		{
194			ManagerName = "Анны Гуляевой";
195			mailq = "[email protected]";
196			vtiger_id = "d0b9aa437a1905d43423c8de943b7459";
197		}
198		if (id == "daria")
199		{
200			ManagerName = "Дарьи Милько";
201			mailq = "[email protected]";
202			vtiger_id = "41643998ca611cc5f7ba3aacf9ee03f7";
203		}
204		if (id == "vikaf")
205		{
206			ManagerName = "Виктории Фрид";
207			mailq = "[email protected]";
208			vtiger_id = "ab1cb1c649d75242e86aa3e549530cca";
209		}
210		if (id == "yuliab")
211		{
212			ManagerName = "Юлии Бочковой";
213			mailq = "[email protected]";
214			vtiger_id = "acc797172ded0a11f7ebd93f03dac7ea";
215		}
216		if (id == "tatyanad")
217		{
218			ManagerName = "Татьяны Даутовой";
219			mailq = "[email protected]";
220			vtiger_id = "b382fcb5dcd5b72876ec14d4fe680086";
221		}
222		if (id == "elenab")
223		{
224			ManagerName = "Елены Блиман";
225			mailq = "[email protected]";
226			vtiger_id = "c417a16a70cad5b72ef63cf5da54d57d";
227		}
228		if (id == "marina")
229		{
230			ManagerName = "Марины Елецкой";
231			mailq = "[email protected]";
232			vtiger_id = "41643998ca611cc5f7ba3aacf9ee03f7";
233		}
234		if (id == "tetiana")
235		{
236			ManagerName = "Тетяны Яцковой";
237			mailq = "[email protected]";
238			vtiger_id = "c5896998788c431280d05057df0d54fe";
239		}
240		if (id == "cons")
241		{
242			ManagerName = "консультанта IQ Consultancy";
243			mailq = "[email protected]";
244			vtiger_id = "41643998ca611cc5f7ba3aacf9ee03f7";
245		}
246		$('#for').html(ManagerName);
247		$('#publicid_expert').val(vtiger_id);
248		$( "#callback-q input[name='form_text_44']" ).val(ManagerName);
249		$( "#callback-q input[name='form_text_45']" ).val(mailq);
250		
251		}
252		
253		});
254		
255	});
256	
257	/******************************************************
258	ДОБАВИТЬ GET ПАРАМЕТР К URL
259	*********************************************************/	
260	function setAttr(prmName,val){
261		var res = '';
262		var d = location.href.split("#")[0].split("?");  
263		var base = d[0];
264		var query = d[1];
265		if(query) {
266			var params = query.split("&");  
267			for(var i = 0; i < params.length; i++) {  
268				var keyval = params[i].split("=");  
269				if(keyval[0] != prmName) {  
270					res += params[i] + '&';
271				}
272			}
273		}
274		res += prmName + '=' + val;
275		window.location.href = base + '?' + res;
276		return false;
277	} 
278	
279	/******************************************************
280	TABS UNIVERSITY DETAIL
281	*********************************************************/	
282	$(function () {
283	    var tabContainers = $('div.tab-wrapper'); // получаем массив контейнеров
284	    tabContainers.css({'left':'-1000%' , 'position':'absolute'}).filter(':first').css({'left':'0' , 'position':'static'}); // прячем все, кроме первого
285	    // далее обрабатывается клик по вкладке
286	    $('div.type-tubs ul.tabNavigation a').click(function () {
287
288	        tabContainers.css({'left':'-1000%' , 'position':'absolute'}); // прячем все табы
289	        tabContainers.filter(this.hash).css({'left':'0' , 'position':'static'}); // показываем содержимое текущего
290	        $('div.type-tubs ul.tabNavigation li').removeClass('selected'); // у всех убираем класс 'selected'
291	        $(this).parent().addClass('selected'); // текушей вкладке добавляем класс 'selected'
292	        return false;
293	    }).filter(':first').click();
294	});
295	
296	/******************************************************
297	LOG FUNCTION
298	*********************************************************/	
299	function writeLog(responseData, textStatus, errorThrown) {
300		jQuery.ajax({
301	        type: 'POST',
302	        url: '/log/js_client_side_logging.php',
303	        data: {
304	        	responseData: responseData,
305	        	textStatus: textStatus,
306	        	errorThrown: errorThrown,
307	        },
308	        success: function() {
309	            if (console && console.log) {
310	                //console.log('JS error report successful.');
311	            }
312	        },
313	        error: function() {
314	            if (console && console.error) {
315	                //console.error('JS error report submission failed!');
316	            }
317	        }
318	    });
319	}
320	
321	/******************************************************
322	ГАЛОЧКИ НА LP СОБЫТИЯХ
323	*********************************************************/	
324	$(function () {
325		$('#events_checklists .event_checkbox').change(function(){
326			try {
327				var $this = $( this );
328				if( $this.prop('checked') ) {
329					if ( $('#events_reg').val() == "" ) {
330						$('#events_reg').val( $this.attr('event_name') );
331					} else {
332						$('#events_reg').val( $('#events_reg').val() + ", " + $this.attr('event_name') );
333					}
334				} else {
335					var val = $('#events_reg').val();
336					$('#events_reg').val( val.replace( $this.attr('event_name'), "") );
337				}
338			} catch (e) {
339				writeLog(e.name, e.message, e.stack);
340			}
341		});
342	});
343	
344	/******************************************************
345	Убирает прокрутку google карт
346	*********************************************************/	
347
348	var onMapMouseleaveHandler = function (event) {
349        var that = $(this);
350    
351        that.on('click', onMapClickHandler);
352        that.off('mouseleave', onMapMouseleaveHandler);
353        that.find('iframe').css("pointer-events", "none");
354      }
355    
356      var onMapClickHandler = function (event) {
357        var that = $(this);
358    
359        // Disable the click handler until the user leaves the map area
360        that.off('click', onMapClickHandler);
361    
362        // Enable scrolling zoom
363        that.find('iframe').css("pointer-events", "auto");
364    
365        // Handle the mouse leave event
366        that.on('mouseleave', onMapMouseleaveHandler);
367      }
368    
369      // Enable map zooming with mouse scroll when the user clicks the map
370      $('.maps.embed-container').on('click', onMapClickHandler);
371
372/* End */
373;
374; /* Start:"a:4:{s:4:"full";s:38:"/js/jquery.fancybox.js?172122556748706";s:6:"source";s:22:"/js/jquery.fancybox.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
375/*!
376 * fancyBox - jQuery Plugin
377 * version: 2.1.5 (Fri, 14 Jun 2013)
378 * @requires jQuery v1.6 or later
379 *
380 * Examples at http://fancyapps.com/fancybox/
381 * License: www.fancyapps.com/fancybox/#license
382 *
383 * Copyright 2012 Janis Skarnelis - [email protected]
384 *
385 */
386
387(function (window, document, $, undefined) {
388	"use strict";
389
390	var H = $("html"),
391		W = $(window),
392		D = $(document),
393		F = $.fancybox = function () {
394			F.open.apply( this, arguments );
395		},
396		IE =  navigator.userAgent.match(/msie/i),
397		didUpdate	= null,
398		isTouch		= document.createTouch !== undefined,
399
400		isQuery	= function(obj) {
401			return obj && obj.hasOwnProperty && obj instanceof $;
402		},
403		isString = function(str) {
404			return str && $.type(str) === "string";
405		},
406		isPercentage = function(str) {
407			return isString(str) && str.indexOf('%') > 0;
408		},
409		isScrollable = function(el) {
410			return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight)));
411		},
412		getScalar = function(orig, dim) {
413			var value = parseInt(orig, 10) || 0;
414
415			if (dim && isPercentage(orig)) {
416				value = F.getViewport()[ dim ] / 100 * value;
417			}
418
419			return Math.ceil(value);
420		},
421		getValue = function(value, dim) {
422			return getScalar(value, dim) + 'px';
423		};
424
425	$.extend(F, {
426		// The current version of fancyBox
427		version: '2.1.5',
428
429		defaults: {
430			padding : 15,
431			margin  : 20,
432
433			width     : 800,
434			height    : 600,
435			minWidth  : 100,
436			minHeight : 100,
437			maxWidth  : 9999,
438			maxHeight : 9999,
vendor: 16,174 bytes, lines 439-1135
439			pixelRatio: 1, // Set to 2 for retina display support
440
441			autoSize   : true,
442			autoHeight : false,
443			autoWidth  : false,
444
445			autoResize  : true,
446			autoCenter  : !isTouch,
447			fitToView   : true,
448			aspectRatio : false,
449			topRatio    : 0.5,
450			leftRatio   : 0.5,
451
452			scrolling : 'auto', // 'auto', 'yes' or 'no'
453			wrapCSS   : '',
454
455			arrows     : true,
456			closeBtn   : true,
457			closeClick : false,
458			nextClick  : false,
459			mouseWheel : true,
460			autoPlay   : false,
461			playSpeed  : 3000,
462			preload    : 3,
463			modal      : false,
464			loop       : true,
465
466			ajax  : {
467				dataType : 'html',
468				headers  : { 'X-fancyBox': true }
469			},
470			iframe : {
471				scrolling : 'auto',
472				preload   : true
473			},
474			swf : {
475				wmode: 'transparent',
476				allowfullscreen   : 'true',
477				allowscriptaccess : 'always'
478			},
479
480			keys  : {
481				next : {
482					13 : 'left', // enter
483					34 : 'up',   // page down
484					39 : 'left', // right arrow
485					40 : 'up'    // down arrow
486				},
487				prev : {
488					8  : 'right',  // backspace
489					33 : 'down',   // page up
490					37 : 'right',  // left arrow
491					38 : 'down'    // up arrow
492				},
493				close  : [27], // escape key
494				play   : [32], // space - start/stop slideshow
495				toggle : [70]  // letter "f" - toggle fullscreen
496			},
497
498			direction : {
499				next : 'left',
500				prev : 'right'
501			},
502
503			scrollOutside  : true,
504
505			// Override some properties
506			index   : 0,
507			type    : null,
508			href    : null,
509			content : null,
510			title   : null,
511
512			// HTML templates
513			tpl: {
514				wrap     : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
515				image    : '<img class="fancybox-image" src="{href}" alt="" />',
516				iframe   : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>',
517				error    : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
518				closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
519				next     : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
520				prev     : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
521			},
522
523			// Properties for each animation type
524			// Opening fancyBox
525			openEffect  : 'fade', // 'elastic', 'fade' or 'none'
526			openSpeed   : 250,
527			openEasing  : 'swing',
528			openOpacity : true,
529			openMethod  : 'zoomIn',
530
531			// Closing fancyBox
532			closeEffect  : 'fade', // 'elastic', 'fade' or 'none'
533			closeSpeed   : 250,
534			closeEasing  : 'swing',
535			closeOpacity : true,
536			closeMethod  : 'zoomOut',
537
538			// Changing next gallery item
539			nextEffect : 'elastic', // 'elastic', 'fade' or 'none'
540			nextSpeed  : 250,
541			nextEasing : 'swing',
542			nextMethod : 'changeIn',
543
544			// Changing previous gallery item
545			prevEffect : 'elastic', // 'elastic', 'fade' or 'none'
546			prevSpeed  : 250,
547			prevEasing : 'swing',
548			prevMethod : 'changeOut',
549
550			// Enable default helpers
551			helpers : {
552				overlay : true,
553				title   : true
554			},
555
556			// Callbacks
557			onCancel     : $.noop, // If canceling
558			beforeLoad   : $.noop, // Before loading
559			afterLoad    : $.noop, // After loading
560			beforeShow   : $.noop, // Before changing in current item
561			afterShow    : $.noop, // After opening
562			beforeChange : $.noop, // Before changing gallery item
563			beforeClose  : $.noop, // Before closing
564			afterClose   : $.noop  // After closing
565		},
566
567		//Current state
568		group    : {}, // Selected group
569		opts     : {}, // Group options
570		previous : null,  // Previous element
571		coming   : null,  // Element being loaded
572		current  : null,  // Currently loaded element
573		isActive : false, // Is activated
574		isOpen   : false, // Is currently open
575		isOpened : false, // Have been fully opened at least once
576
577		wrap  : null,
578		skin  : null,
579		outer : null,
580		inner : null,
581
582		player : {
583			timer    : null,
584			isActive : false
585		},
586
587		// Loaders
588		ajaxLoad   : null,
589		imgPreload : null,
590
591		// Some collections
592		transitions : {},
593		helpers     : {},
594
595		/*
596		 *	Static methods
597		 */
598
599		open: function (group, opts) {
600			if (!group) {
601				return;
602			}
603
604			if (!$.isPlainObject(opts)) {
605				opts = {};
606			}
607
608			// Close if already active
609			if (false === F.close(true)) {
610				return;
611			}
612
613			// Normalize group
614			if (!$.isArray(group)) {
615				group = isQuery(group) ? $(group).get() : [group];
616			}
617
618			// Recheck if the type of each element is `object` and set content type (image, ajax, etc)
619			$.each(group, function(i, element) {
620				var obj = {},
621					href,
622					title,
623					content,
624					type,
625					rez,
626					hrefParts,
627					selector;
628
629				if ($.type(element) === "object") {
630					// Check if is DOM element
631					if (element.nodeType) {
632						element = $(element);
633					}
634
635					if (isQuery(element)) {
636						obj = {
637							href    : element.data('fancybox-href') || element.attr('href'),
638							title   : element.data('fancybox-title') || element.attr('title'),
639							isDom   : true,
640							element : element
641						};
642
643						if ($.metadata) {
644							$.extend(true, obj, element.metadata());
645						}
646
647					} else {
648						obj = element;
649					}
650				}
651
652				href  = opts.href  || obj.href || (isString(element) ? element : null);
653				title = opts.title !== undefined ? opts.title : obj.title || '';
654
655				content = opts.content || obj.content;
656				type    = content ? 'html' : (opts.type  || obj.type);
657
658				if (!type && obj.isDom) {
659					type = element.data('fancybox-type');
660
661					if (!type) {
662						rez  = element.prop('class').match(/fancybox\.(\w+)/);
663						type = rez ? rez[1] : null;
664					}
665				}
666
667				if (isString(href)) {
668					// Try to guess the content type
669					if (!type) {
670						if (F.isImage(href)) {
671							type = 'image';
672
673						} else if (F.isSWF(href)) {
674							type = 'swf';
675
676						} else if (href.charAt(0) === '#') {
677							type = 'inline';
678
679						} else if (isString(element)) {
680							type    = 'html';
681							content = element;
682						}
683					}
684
685					// Split url into two pieces with source url and content selector, e.g,
686					// "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id"
687					if (type === 'ajax') {
688						hrefParts = href.split(/\s+/, 2);
689						href      = hrefParts.shift();
690						selector  = hrefParts.shift();
691					}
692				}
693
694				if (!content) {
695					if (type === 'inline') {
696						if (href) {
697							content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7
698
699						} else if (obj.isDom) {
700							content = element;
701						}
702
703					} else if (type === 'html') {
704						content = href;
705
706					} else if (!type && !href && obj.isDom) {
707						type    = 'inline';
708						content = element;
709					}
710				}
711
712				$.extend(obj, {
713					href     : href,
714					type     : type,
715					content  : content,
716					title    : title,
717					selector : selector
718				});
719
720				group[ i ] = obj;
721			});
722
723			// Extend the defaults
724			F.opts = $.extend(true, {}, F.defaults, opts);
725
726			// All options are merged recursive except keys
727			if (opts.keys !== undefined) {
728				F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;
729			}
730
731			F.group = group;
732
733			return F._start(F.opts.index);
734		},
735
736		// Cancel image loading or abort ajax request
737		cancel: function () {
738			var coming = F.coming;
739
740			if (!coming || false === F.trigger('onCancel')) {
741				return;
742			}
743
744			F.hideLoading();
745
746			if (F.ajaxLoad) {
747				F.ajaxLoad.abort();
748			}
749
750			F.ajaxLoad = null;
751
752			if (F.imgPreload) {
753				F.imgPreload.onload = F.imgPreload.onerror = null;
754			}
755
756			if (coming.wrap) {
757				coming.wrap.stop(true, true).trigger('onReset').remove();
758			}
759
760			F.coming = null;
761
762			// If the first item has been canceled, then clear everything
763			if (!F.current) {
764				F._afterZoomOut( coming );
765			}
766		},
767
768		// Start closing animation if is open; remove immediately if opening/closing
769		close: function (event) {
770			F.cancel();
771
772			if (false === F.trigger('beforeClose')) {
773				return;
774			}
775
776			F.unbindEvents();
777
778			if (!F.isActive) {
779				return;
780			}
781
782			if (!F.isOpen || event === true) {
783				$('.fancybox-wrap').stop(true).trigger('onReset').remove();
784
785				F._afterZoomOut();
786
787			} else {
788				F.isOpen = F.isOpened = false;
789				F.isClosing = true;
790
791				$('.fancybox-item, .fancybox-nav').remove();
792
793				F.wrap.stop(true, true).removeClass('fancybox-opened');
794
795				F.transitions[ F.current.closeMethod ]();
796			}
797		},
798
799		// Manage slideshow:
800		//   $.fancybox.play(); - toggle slideshow
801		//   $.fancybox.play( true ); - start
802		//   $.fancybox.play( false ); - stop
803		play: function ( action ) {
804			var clear = function () {
805					clearTimeout(F.player.timer);
806				},
807				set = function () {
808					clear();
809
810					if (F.current && F.player.isActive) {
811						F.player.timer = setTimeout(F.next, F.current.playSpeed);
812					}
813				},
814				stop = function () {
815					clear();
816
817					D.unbind('.player');
818
819					F.player.isActive = false;
820
821					F.trigger('onPlayEnd');
822				},
823				start = function () {
824					if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
825						F.player.isActive = true;
826
827						D.bind({
828							'onCancel.player beforeClose.player' : stop,
829							'onUpdate.player'   : set,
830							'beforeLoad.player' : clear
831						});
832
833						set();
834
835						F.trigger('onPlayStart');
836					}
837				};
838
839			if (action === true || (!F.player.isActive && action !== false)) {
840				start();
841			} else {
842				stop();
843			}
844		},
845
846		// Navigate to next gallery item
847		next: function ( direction ) {
848			var current = F.current;
849
850			if (current) {
851				if (!isString(direction)) {
852					direction = current.direction.next;
853				}
854
855				F.jumpto(current.index + 1, direction, 'next');
856			}
857		},
858
859		// Navigate to previous gallery item
860		prev: function ( direction ) {
861			var current = F.current;
862
863			if (current) {
864				if (!isString(direction)) {
865					direction = current.direction.prev;
866				}
867
868				F.jumpto(current.index - 1, direction, 'prev');
869			}
870		},
871
872		// Navigate to gallery item by index
873		jumpto: function ( index, direction, router ) {
874			var current = F.current;
875
876			if (!current) {
877				return;
878			}
879
880			index = getScalar(index);
881
882			F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ];
883			F.router    = router || 'jumpto';
884
885			if (current.loop) {
886				if (index < 0) {
887					index = current.group.length + (index % current.group.length);
888				}
889
890				index = index % current.group.length;
891			}
892
893			if (current.group[ index ] !== undefined) {
894				F.cancel();
895
896				F._start(index);
897			}
898		},
899
900		// Center inside viewport and toggle position type to fixed or absolute if needed
901		reposition: function (e, onlyAbsolute) {
902			var current = F.current,
903				wrap    = current ? current.wrap : null,
904				pos;
905
906			if (wrap) {
907				pos = F._getPosition(onlyAbsolute);
908
909				if (e && e.type === 'scroll') {
910					delete pos.position;
911
912					wrap.stop(true, true).animate(pos, 200);
913
914				} else {
915					wrap.css(pos);
916
917					current.pos = $.extend({}, current.dim, pos);
918				}
919			}
920		},
921
922		update: function (e) {
923			var type = (e && e.type),
924				anyway = !type || type === 'orientationchange';
925
926			if (anyway) {
927				clearTimeout(didUpdate);
928
929				didUpdate = null;
930			}
931
932			if (!F.isOpen || didUpdate) {
933				return;
934			}
935
936			didUpdate = setTimeout(function() {
937				var current = F.current;
938
939				if (!current || F.isClosing) {
940					return;
941				}
942
943				F.wrap.removeClass('fancybox-tmp');
944
945				if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) {
946					F._setDimension();
947				}
948
949				if (!(type === 'scroll' && current.canShrink)) {
950					F.reposition(e);
951				}
952
953				F.trigger('onUpdate');
954
955				didUpdate = null;
956
957			}, (anyway && !isTouch ? 0 : 300));
958		},
959
960		// Shrink content to fit inside viewport or restore if resized
961		toggle: function ( action ) {
962			if (F.isOpen) {
963				F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView;
964
965				// Help browser to restore document dimensions
966				if (isTouch) {
967					F.wrap.removeAttr('style').addClass('fancybox-tmp');
968
969					F.trigger('onUpdate');
970				}
971
972				F.update();
973			}
974		},
975
976		hideLoading: function () {
977			D.unbind('.loading');
978
979			$('#fancybox-loading').remove();
980		},
981
982		showLoading: function () {
983			var el, viewport;
984
985			F.hideLoading();
986
987			el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body');
988
989			// If user will press the escape-button, the request will be canceled
990			D.bind('keydown.loading', function(e) {
991				if ((e.which || e.keyCode) === 27) {
992					e.preventDefault();
993
994					F.cancel();
995				}
996			});
997
998			if (!F.defaults.fixed) {
999				viewport = F.getViewport();
1000
1001				el.css({
1002					position : 'absolute',
1003					top  : (viewport.h * 0.5) + viewport.y,
1004					left : (viewport.w * 0.5) + viewport.x
1005				});
1006			}
1007		},
1008
1009		getViewport: function () {
1010			var locked = (F.current && F.current.locked) || false,
1011				rez    = {
1012					x: W.scrollLeft(),
1013					y: W.scrollTop()
1014				};
1015
1016			if (locked) {
1017				rez.w = locked[0].clientWidth;
1018				rez.h = locked[0].clientHeight;
1019
1020			} else {
1021				// See http://bugs.jquery.com/ticket/6724
1022				rez.w = isTouch && window.innerWidth  ? window.innerWidth  : W.width();
1023				rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height();
1024			}
1025
1026			return rez;
1027		},
1028
1029		// Unbind the keyboard / clicking actions
1030		unbindEvents: function () {
1031			if (F.wrap && isQuery(F.wrap)) {
1032				F.wrap.unbind('.fb');
1033			}
1034
1035			D.unbind('.fb');
1036			W.unbind('.fb');
1037		},
1038
1039		bindEvents: function () {
1040			var current = F.current,
1041				keys;
1042
1043			if (!current) {
1044				return;
1045			}
1046
1047			// Changing document height on iOS devices triggers a 'resize' event,
1048			// that can change document height... repeating infinitely
1049			W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update);
1050
1051			keys = current.keys;
1052
1053			if (keys) {
1054				D.bind('keydown.fb', function (e) {
1055					var code   = e.which || e.keyCode,
1056						target = e.target || e.srcElement;
1057
1058					// Skip esc key if loading, because showLoading will cancel preloading
1059					if (code === 27 && F.coming) {
1060						return false;
1061					}
1062
1063					// Ignore key combinations and key events within form elements
1064					if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {
1065						$.each(keys, function(i, val) {
1066							if (current.group.length > 1 && val[ code ] !== undefined) {
1067								F[ i ]( val[ code ] );
1068
1069								e.preventDefault();
1070								return false;
1071							}
1072
1073							if ($.inArray(code, val) > -1) {
1074								F[ i ] ();
1075
1076								e.preventDefault();
1077								return false;
1078							}
1079						});
1080					}
1081				});
1082			}
1083
1084			if ($.fn.mousewheel && current.mouseWheel) {
1085				F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) {
1086					var target = e.target || null,
1087						parent = $(target),
1088						canScroll = false;
1089
1090					while (parent.length) {
1091						if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) {
1092							break;
1093						}
1094
1095						canScroll = isScrollable( parent[0] );
1096						parent    = $(parent).parent();
1097					}
1098
1099					if (delta !== 0 && !canScroll) {
1100						if (F.group.length > 1 && !current.canShrink) {
1101							if (deltaY > 0 || deltaX > 0) {
1102								F.prev( deltaY > 0 ? 'down' : 'left' );
1103
1104							} else if (deltaY < 0 || deltaX < 0) {
1105								F.next( deltaY < 0 ? 'up' : 'right' );
1106							}
1107
1108							e.preventDefault();
1109						}
1110					}
1111				});
1112			}
1113		},
1114
1115		trigger: function (event, o) {
1116			var ret, obj = o || F.coming || F.current;
1117
1118			if (!obj) {
1119				return;
1120			}
1121
1122			if ($.isFunction( obj[event] )) {
1123				ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));
1124			}
1125
1126			if (ret === false) {
1127				return false;
1128			}
1129
1130			if (obj.helpers) {
1131				$.each(obj.helpers, function (helper, opts) {
1132					if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) {
1133						F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj);
1134					}
1135				});
vendor: 8,050 bytes, lines 1135-1494
1135
1136			}
1137
1138			D.trigger(event);
1139		},
1140
1141		isImage: function (str) {
1142			return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
1143		},
1144
1145		isSWF: function (str) {
1146			return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i);
1147		},
1148
1149		_start: function (index) {
1150			var coming = {},
1151				obj,
1152				href,
1153				type,
1154				margin,
1155				padding;
1156
1157			index = getScalar( index );
1158			obj   = F.group[ index ] || null;
1159
1160			if (!obj) {
1161				return false;
1162			}
1163
1164			coming = $.extend(true, {}, F.opts, obj);
1165
1166			// Convert margin and padding properties to array - top, right, bottom, left
1167			margin  = coming.margin;
1168			padding = coming.padding;
1169
1170			if ($.type(margin) === 'number') {
1171				coming.margin = [margin, margin, margin, margin];
1172			}
1173
1174			if ($.type(padding) === 'number') {
1175				coming.padding = [padding, padding, padding, padding];
1176			}
1177
1178			// 'modal' propery is just a shortcut
1179			if (coming.modal) {
1180				$.extend(true, coming, {
1181					closeBtn   : false,
1182					closeClick : false,
1183					nextClick  : false,
1184					arrows     : false,
1185					mouseWheel : false,
1186					keys       : null,
1187					helpers: {
1188						overlay : {
1189							closeClick : false
1190						}
1191					}
1192				});
1193			}
1194
1195			// 'autoSize' property is a shortcut, too
1196			if (coming.autoSize) {
1197				coming.autoWidth = coming.autoHeight = true;
1198			}
1199
1200			if (coming.width === 'auto') {
1201				coming.autoWidth = true;
1202			}
1203
1204			if (coming.height === 'auto') {
1205				coming.autoHeight = true;
1206			}
1207
1208			/*
1209			 * Add reference to the group, so it`s possible to access from callbacks, example:
1210			 * afterLoad : function() {
1211			 *     this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
1212			 * }
1213			 */
1214
1215			coming.group  = F.group;
1216			coming.index  = index;
1217
1218			// Give a chance for callback or helpers to update coming item (type, title, etc)
1219			F.coming = coming;
1220
1221			if (false === F.trigger('beforeLoad')) {
1222				F.coming = null;
1223
1224				return;
1225			}
1226
1227			type = coming.type;
1228			href = coming.href;
1229
1230			if (!type) {
1231				F.coming = null;
1232
1233				//If we can not determine content type then drop silently or display next/prev item if looping through gallery
1234				if (F.current && F.router && F.router !== 'jumpto') {
1235					F.current.index = index;
1236
1237					return F[ F.router ]( F.direction );
1238				}
1239
1240				return false;
1241			}
1242
1243			F.isActive = true;
1244
1245			if (type === 'image' || type === 'swf') {
1246				coming.autoHeight = coming.autoWidth = false;
1247				coming.scrolling  = 'visible';
1248			}
1249
1250			if (type === 'image') {
1251				coming.aspectRatio = true;
1252			}
1253
1254			if (type === 'iframe' && isTouch) {
1255				coming.scrolling = 'scroll';
1256			}
1257
1258			// Build the neccessary markup
1259			coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' );
1260
1261			$.extend(coming, {
1262				skin  : $('.fancybox-skin',  coming.wrap),
1263				outer : $('.fancybox-outer', coming.wrap),
1264				inner : $('.fancybox-inner', coming.wrap)
1265			});
1266
1267			$.each(["Top", "Right", "Bottom", "Left"], function(i, v) {
1268				coming.skin.css('padding' + v, getValue(coming.padding[ i ]));
1269			});
1270
1271			F.trigger('onReady');
1272
1273			// Check before try to load; 'inline' and 'html' types need content, others - href
1274			if (type === 'inline' || type === 'html') {
1275				if (!coming.content || !coming.content.length) {
1276					return F._error( 'content' );
1277				}
1278
1279			} else if (!href) {
1280				return F._error( 'href' );
1281			}
1282
1283			if (type === 'image') {
1284				F._loadImage();
1285
1286			} else if (type === 'ajax') {
1287				F._loadAjax();
1288
1289			} else if (type === 'iframe') {
1290				F._loadIframe();
1291
1292			} else {
1293				F._afterLoad();
1294			}
1295		},
1296
1297		_error: function ( type ) {
1298			$.extend(F.coming, {
1299				type       : 'html',
1300				autoWidth  : true,
1301				autoHeight : true,
1302				minWidth   : 0,
1303				minHeight  : 0,
1304				scrolling  : 'no',
1305				hasError   : type,
1306				content    : F.coming.tpl.error
1307			});
1308
1309			F._afterLoad();
1310		},
1311
1312		_loadImage: function () {
1313			// Reset preload image so it is later possible to check "complete" property
1314			var img = F.imgPreload = new Image();
1315
1316			img.onload = function () {
1317				this.onload = this.onerror = null;
1318
1319				F.coming.width  = this.width / F.opts.pixelRatio;
1320				F.coming.height = this.height / F.opts.pixelRatio;
1321
1322				F._afterLoad();
1323			};
1324
1325			img.onerror = function () {
1326				this.onload = this.onerror = null;
1327
1328				F._error( 'image' );
1329			};
1330
1331			img.src = F.coming.href;
1332
1333			if (img.complete !== true) {
1334				F.showLoading();
1335			}
1336		},
1337
1338		_loadAjax: function () {
1339			var coming = F.coming;
1340
1341			F.showLoading();
1342
1343			F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {
1344				url: coming.href,
1345				error: function (jqXHR, textStatus) {
1346					if (F.coming && textStatus !== 'abort') {
1347						F._error( 'ajax', jqXHR );
1348
1349					} else {
1350						F.hideLoading();
1351					}
1352				},
1353				success: function (data, textStatus) {
1354					if (textStatus === 'success') {
1355						coming.content = data;
1356
1357						F._afterLoad();
1358					}
1359				}
1360			}));
1361		},
1362
1363		_loadIframe: function() {
1364			var coming = F.coming,
1365				iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime()))
1366					.attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling)
1367					.attr('src', coming.href);
1368
1369			// This helps IE
1370			$(coming.wrap).bind('onReset', function () {
1371				try {
1372					$(this).find('iframe').hide().attr('src', '//about:blank').end().empty();
1373				} catch (e) {}
1374			});
1375
1376			if (coming.iframe.preload) {
1377				F.showLoading();
1378
1379				iframe.one('load', function() {
1380					$(this).data('ready', 1);
1381
1382					// iOS will lose scrolling if we resize
1383					if (!isTouch) {
1384						$(this).bind('load.fb', F.update);
1385					}
1386
1387					// Without this trick:
1388					//   - iframe won't scroll on iOS devices
1389					//   - IE7 sometimes displays empty iframe
1390					$(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show();
1391
1392					F._afterLoad();
1393				});
1394			}
1395
1396			coming.content = iframe.appendTo( coming.inner );
1397
1398			if (!coming.iframe.preload) {
1399				F._afterLoad();
1400			}
1401		},
1402
1403		_preloadImages: function() {
1404			var group   = F.group,
1405				current = F.current,
1406				len     = group.length,
1407				cnt     = current.preload ? Math.min(current.preload, len - 1) : 0,
1408				item,
1409				i;
1410
1411			for (i = 1; i <= cnt; i += 1) {
1412				item = group[ (current.index + i ) % len ];
1413
1414				if (item.type === 'image' && item.href) {
1415					new Image().src = item.href;
1416				}
1417			}
1418		},
1419
1420		_afterLoad: function () {
1421			var coming   = F.coming,
1422				previous = F.current,
1423				placeholder = 'fancybox-placeholder',
1424				current,
1425				content,
1426				type,
1427				scrolling,
1428				href,
1429				embed;
1430
1431			F.hideLoading();
1432
1433			if (!coming || F.isActive === false) {
1434				return;
1435			}
1436
1437			if (false === F.trigger('afterLoad', coming, previous)) {
1438				coming.wrap.stop(true).trigger('onReset').remove();
1439
1440				F.coming = null;
1441
1442				return;
1443			}
1444
1445			if (previous) {
1446				F.trigger('beforeChange', previous);
1447
1448				previous.wrap.stop(true).removeClass('fancybox-opened')
1449					.find('.fancybox-item, .fancybox-nav')
1450					.remove();
1451			}
1452
1453			F.unbindEvents();
1454
1455			current   = coming;
1456			content   = coming.content;
1457			type      = coming.type;
1458			scrolling = coming.scrolling;
1459
1460			$.extend(F, {
1461				wrap  : current.wrap,
1462				skin  : current.skin,
1463				outer : current.outer,
1464				inner : current.inner,
1465				current  : current,
1466				previous : previous
1467			});
1468
1469			href = current.href;
1470
1471			switch (type) {
1472				case 'inline':
1473				case 'ajax':
1474				case 'html':
1475					if (current.selector) {
1476						content = $('<div>').html(content).find(current.selector);
1477
1478					} else if (isQuery(content)) {
1479						if (!content.data(placeholder)) {
1480							content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() );
1481						}
1482
1483						content = content.show().detach();
1484
1485						current.wrap.bind('onReset', function () {
1486							if ($(this).find(content).length) {
1487								content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false);
1488							}
1489						});
1490					}
1491				break;
1492
1493				case 'image':
1494					content = current.tpl.image.replace(
vendor: 14,919 bytes, lines 1494-2063
1494'{href}', href);
1495				break;
1496
1497				case 'swf':
1498					content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';
1499					embed   = '';
1500
1501					$.each(current.swf, function(name, val) {
1502						content += '<param name="' + name + '" value="' + val + '"></param>';
1503						embed   += ' ' + name + '="' + val + '"';
1504					});
1505
1506					content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>';
1507				break;
1508			}
1509
1510			if (!(isQuery(content) && content.parent().is(current.inner))) {
1511				current.inner.append( content );
1512			}
1513
1514			// Give a chance for helpers or callbacks to update elements
1515			F.trigger('beforeShow');
1516
1517			// Set scrolling before calculating dimensions
1518			current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
1519
1520			// Set initial dimensions and start position
1521			F._setDimension();
1522
1523			F.reposition();
1524
1525			F.isOpen = false;
1526			F.coming = null;
1527
1528			F.bindEvents();
1529
1530			if (!F.isOpened) {
1531				$('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove();
1532
1533			} else if (previous.prevMethod) {
1534				F.transitions[ previous.prevMethod ]();
1535			}
1536
1537			F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();
1538
1539			F._preloadImages();
1540		},
1541
1542		_setDimension: function () {
1543			var viewport   = F.getViewport(),
1544				steps      = 0,
1545				canShrink  = false,
1546				canExpand  = false,
1547				wrap       = F.wrap,
1548				skin       = F.skin,
1549				inner      = F.inner,
1550				current    = F.current,
1551				width      = current.width,
1552				height     = current.height,
1553				minWidth   = current.minWidth,
1554				minHeight  = current.minHeight,
1555				maxWidth   = current.maxWidth,
1556				maxHeight  = current.maxHeight,
1557				scrolling  = current.scrolling,
1558				scrollOut  = current.scrollOutside ? current.scrollbarWidth : 0,
1559				margin     = current.margin,
1560				wMargin    = getScalar(margin[1] + margin[3]),
1561				hMargin    = getScalar(margin[0] + margin[2]),
1562				wPadding,
1563				hPadding,
1564				wSpace,
1565				hSpace,
1566				origWidth,
1567				origHeight,
1568				origMaxWidth,
1569				origMaxHeight,
1570				ratio,
1571				width_,
1572				height_,
1573				maxWidth_,
1574				maxHeight_,
1575				iframe,
1576				body;
1577
1578			// Reset dimensions so we could re-check actual size
1579			wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp');
1580
1581			wPadding = getScalar(skin.outerWidth(true)  - skin.width());
1582			hPadding = getScalar(skin.outerHeight(true) - skin.height());
1583
1584			// Any space between content and viewport (margin, padding, border, title)
1585			wSpace = wMargin + wPadding;
1586			hSpace = hMargin + hPadding;
1587
1588			origWidth  = isPercentage(width)  ? (viewport.w - wSpace) * getScalar(width)  / 100 : width;
1589			origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;
1590
1591			if (current.type === 'iframe') {
1592				iframe = current.content;
1593
1594				if (current.autoHeight && iframe.data('ready') === 1) {
1595					try {
1596						if (iframe[0].contentWindow.document.location) {
1597							inner.width( origWidth ).height(9999);
1598
1599							body = iframe.contents().find('body');
1600
1601							if (scrollOut) {
1602								body.css('overflow-x', 'hidden');
1603							}
1604
1605							origHeight = body.outerHeight(true);
1606						}
1607
1608					} catch (e) {}
1609				}
1610
1611			} else if (current.autoWidth || current.autoHeight) {
1612				inner.addClass( 'fancybox-tmp' );
1613
1614				// Set width or height in case we need to calculate only one dimension
1615				if (!current.autoWidth) {
1616					inner.width( origWidth );
1617				}
1618
1619				if (!current.autoHeight) {
1620					inner.height( origHeight );
1621				}
1622
1623				if (current.autoWidth) {
1624					origWidth = inner.width();
1625				}
1626
1627				if (current.autoHeight) {
1628					origHeight = inner.height();
1629				}
1630
1631				inner.removeClass( 'fancybox-tmp' );
1632			}
1633
1634			width  = getScalar( origWidth );
1635			height = getScalar( origHeight );
1636
1637			ratio  = origWidth / origHeight;
1638
1639			// Calculations for the content
1640			minWidth  = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth);
1641			maxWidth  = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth);
1642
1643			minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight);
1644			maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight);
1645
1646			// These will be used to determine if wrap can fit in the viewport
1647			origMaxWidth  = maxWidth;
1648			origMaxHeight = maxHeight;
1649
1650			if (current.fitToView) {
1651				maxWidth  = Math.min(viewport.w - wSpace, maxWidth);
1652				maxHeight = Math.min(viewport.h - hSpace, maxHeight);
1653			}
1654
1655			maxWidth_  = viewport.w - wMargin;
1656			maxHeight_ = viewport.h - hMargin;
1657
1658			if (current.aspectRatio) {
1659				if (width > maxWidth) {
1660					width  = maxWidth;
1661					height = getScalar(width / ratio);
1662				}
1663
1664				if (height > maxHeight) {
1665					height = maxHeight;
1666					width  = getScalar(height * ratio);
1667				}
1668
1669				if (width < minWidth) {
1670					width  = minWidth;
1671					height = getScalar(width / ratio);
1672				}
1673
1674				if (height < minHeight) {
1675					height = minHeight;
1676					width  = getScalar(height * ratio);
1677				}
1678
1679			} else {
1680				width = Math.max(minWidth, Math.min(width, maxWidth));
1681
1682				if (current.autoHeight && current.type !== 'iframe') {
1683					inner.width( width );
1684
1685					height = inner.height();
1686				}
1687
1688				height = Math.max(minHeight, Math.min(height, maxHeight));
1689			}
1690
1691			// Try to fit inside viewport (including the title)
1692			if (current.fitToView) {
1693				inner.width( width ).height( height );
1694
1695				wrap.width( width + wPadding );
1696
1697				// Real wrap dimensions
1698				width_  = wrap.width();
1699				height_ = wrap.height();
1700
1701				if (current.aspectRatio) {
1702					while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
1703						if (steps++ > 19) {
1704							break;
1705						}
1706
1707						height = Math.max(minHeight, Math.min(maxHeight, height - 10));
1708						width  = getScalar(height * ratio);
1709
1710						if (width < minWidth) {
1711							width  = minWidth;
1712							height = getScalar(width / ratio);
1713						}
1714
1715						if (width > maxWidth) {
1716							width  = maxWidth;
1717							height = getScalar(width / ratio);
1718						}
1719
1720						inner.width( width ).height( height );
1721
1722						wrap.width( width + wPadding );
1723
1724						width_  = wrap.width();
1725						height_ = wrap.height();
1726					}
1727
1728				} else {
1729					width  = Math.max(minWidth,  Math.min(width,  width  - (width_  - maxWidth_)));
1730					height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)));
1731				}
1732			}
1733
1734			if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) {
1735				width += scrollOut;
1736			}
1737
1738			inner.width( width ).height( height );
1739
1740			wrap.width( width + wPadding );
1741
1742			width_  = wrap.width();
1743			height_ = wrap.height();
1744
1745			canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
1746			canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight));
1747
1748			$.extend(current, {
1749				dim : {
1750					width	: getValue( width_ ),
1751					height	: getValue( height_ )
1752				},
1753				origWidth  : origWidth,
1754				origHeight : origHeight,
1755				canShrink  : canShrink,
1756				canExpand  : canExpand,
1757				wPadding   : wPadding,
1758				hPadding   : hPadding,
1759				wrapSpace  : height_ - skin.outerHeight(true),
1760				skinSpace  : skin.height() - height
1761			});
1762
1763			if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
1764				inner.height('auto');
1765			}
1766		},
1767
1768		_getPosition: function (onlyAbsolute) {
1769			var current  = F.current,
1770				viewport = F.getViewport(),
1771				margin   = current.margin,
1772				width    = F.wrap.width()  + margin[1] + margin[3],
1773				height   = F.wrap.height() + margin[0] + margin[2],
1774				rez      = {
1775					position: 'absolute',
1776					top  : margin[0],
1777					left : margin[3]
1778				};
1779
1780			if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
1781				rez.position = 'fixed';
1782
1783			} else if (!current.locked) {
1784				rez.top  += viewport.y;
1785				rez.left += viewport.x;
1786			}
1787
1788			rez.top  = getValue(Math.max(rez.top,  rez.top  + ((viewport.h - height) * current.topRatio)));
1789			rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width)  * current.leftRatio)));
1790
1791			return rez;
1792		},
1793
1794		_afterZoomIn: function () {
1795			var current = F.current;
1796
1797			if (!current) {
1798				return;
1799			}
1800
1801			F.isOpen = F.isOpened = true;
1802
1803			F.wrap.css('overflow', 'visible').addClass('fancybox-opened');
1804
1805			F.update();
1806
1807			// Assign a click event
1808			if ( current.closeClick || (current.nextClick && F.group.length > 1) ) {
1809				F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
1810					if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
1811						e.preventDefault();
1812
1813						F[ current.closeClick ? 'close' : 'next' ]();
1814					}
1815				});
1816			}
1817
1818			// Create a close button
1819			if (current.closeBtn) {
1820				$(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) {
1821					e.preventDefault();
1822
1823					F.close();
1824				});
1825			}
1826
1827			// Create navigation arrows
1828			if (current.arrows && F.group.length > 1) {
1829				if (current.loop || current.index > 0) {
1830					$(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev);
1831				}
1832
1833				if (current.loop || current.index < F.group.length - 1) {
1834					$(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next);
1835				}
1836			}
1837
1838			F.trigger('afterShow');
1839
1840			// Stop the slideshow if this is the last item
1841			if (!current.loop && current.index === current.group.length - 1) {
1842				F.play( false );
1843
1844			} else if (F.opts.autoPlay && !F.player.isActive) {
1845				F.opts.autoPlay = false;
1846
1847				F.play();
1848			}
1849		},
1850
1851		_afterZoomOut: function ( obj ) {
1852			obj = obj || F.current;
1853
1854			$('.fancybox-wrap').trigger('onReset').remove();
1855
1856			$.extend(F, {
1857				group  : {},
1858				opts   : {},
1859				router : false,
1860				current   : null,
1861				isActive  : false,
1862				isOpened  : false,
1863				isOpen    : false,
1864				isClosing : false,
1865				wrap   : null,
1866				skin   : null,
1867				outer  : null,
1868				inner  : null
1869			});
1870
1871			F.trigger('afterClose', obj);
1872		}
1873	});
1874
1875	/*
1876	 *	Default transitions
1877	 */
1878
1879	F.transitions = {
1880		getOrigPosition: function () {
1881			var current  = F.current,
1882				element  = current.element,
1883				orig     = current.orig,
1884				pos      = {},
1885				width    = 50,
1886				height   = 50,
1887				hPadding = current.hPadding,
1888				wPadding = current.wPadding,
1889				viewport = F.getViewport();
1890
1891			if (!orig && current.isDom && element.is(':visible')) {
1892				orig = element.find('img:first');
1893
1894				if (!orig.length) {
1895					orig = element;
1896				}
1897			}
1898
1899			if (isQuery(orig)) {
1900				pos = orig.offset();
1901
1902				if (orig.is('img')) {
1903					width  = orig.outerWidth();
1904					height = orig.outerHeight();
1905				}
1906
1907			} else {
1908				pos.top  = viewport.y + (viewport.h - height) * current.topRatio;
1909				pos.left = viewport.x + (viewport.w - width)  * current.leftRatio;
1910			}
1911
1912			if (F.wrap.css('position') === 'fixed' || current.locked) {
1913				pos.top  -= viewport.y;
1914				pos.left -= viewport.x;
1915			}
1916
1917			pos = {
1918				top     : getValue(pos.top  - hPadding * current.topRatio),
1919				left    : getValue(pos.left - wPadding * current.leftRatio),
1920				width   : getValue(width  + wPadding),
1921				height  : getValue(height + hPadding)
1922			};
1923
1924			return pos;
1925		},
1926
1927		step: function (now, fx) {
1928			var ratio,
1929				padding,
1930				value,
1931				prop       = fx.prop,
1932				current    = F.current,
1933				wrapSpace  = current.wrapSpace,
1934				skinSpace  = current.skinSpace;
1935
1936			if (prop === 'width' || prop === 'height') {
1937				ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);
1938
1939				if (F.isClosing) {
1940					ratio = 1 - ratio;
1941				}
1942
1943				padding = prop === 'width' ? current.wPadding : current.hPadding;
1944				value   = now - padding;
1945
1946				F.skin[ prop ](  getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) ) );
1947				F.inner[ prop ]( getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );
1948			}
1949		},
1950
1951		zoomIn: function () {
1952			var current  = F.current,
1953				startPos = current.pos,
1954				effect   = current.openEffect,
1955				elastic  = effect === 'elastic',
1956				endPos   = $.extend({opacity : 1}, startPos);
1957
1958			// Remove "position" property that breaks older IE
1959			delete endPos.position;
1960
1961			if (elastic) {
1962				startPos = this.getOrigPosition();
1963
1964				if (current.openOpacity) {
1965					startPos.opacity = 0.1;
1966				}
1967
1968			} else if (effect === 'fade') {
1969				startPos.opacity = 0.1;
1970			}
1971
1972			F.wrap.css(startPos).animate(endPos, {
1973				duration : effect === 'none' ? 0 : current.openSpeed,
1974				easing   : current.openEasing,
1975				step     : elastic ? this.step : null,
1976				complete : F._afterZoomIn
1977			});
1978		},
1979
1980		zoomOut: function () {
1981			var current  = F.current,
1982				effect   = current.closeEffect,
1983				elastic  = effect === 'elastic',
1984				endPos   = {opacity : 0.1};
1985
1986			if (elastic) {
1987				endPos = this.getOrigPosition();
1988
1989				if (current.closeOpacity) {
1990					endPos.opacity = 0.1;
1991				}
1992			}
1993
1994			F.wrap.animate(endPos, {
1995				duration : effect === 'none' ? 0 : current.closeSpeed,
1996				easing   : current.closeEasing,
1997				step     : elastic ? this.step : null,
1998				complete : F._afterZoomOut
1999			});
2000		},
2001
2002		changeIn: function () {
2003			var current   = F.current,
2004				effect    = current.nextEffect,
2005				startPos  = current.pos,
2006				endPos    = { opacity : 1 },
2007				direction = F.direction,
2008				distance  = 200,
2009				field;
2010
2011			startPos.opacity = 0.1;
2012
2013			if (effect === 'elastic') {
2014				field = direction === 'down' || direction === 'up' ? 'top' : 'left';
2015
2016				if (direction === 'down' || direction === 'right') {
2017					startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance);
2018					endPos[ field ]   = '+=' + distance + 'px';
2019
2020				} else {
2021					startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance);
2022					endPos[ field ]   = '-=' + distance + 'px';
2023				}
2024			}
2025
2026			// Workaround for http://bugs.jquery.com/ticket/12273
2027			if (effect === 'none') {
2028				F._afterZoomIn();
2029
2030			} else {
2031				F.wrap.css(startPos).animate(endPos, {
2032					duration : current.nextSpeed,
2033					easing   : current.nextEasing,
2034					complete : F._afterZoomIn
2035				});
2036			}
2037		},
2038
2039		changeOut: function () {
2040			var previous  = F.previous,
2041				effect    = previous.prevEffect,
2042				endPos    = { opacity : 0.1 },
2043				direction = F.direction,
2044				distance  = 200;
2045
2046			if (effect === 'elastic') {
2047				endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';
2048			}
2049
2050			previous.wrap.animate(endPos, {
2051				duration : effect === 'none' ? 0 : previous.prevSpeed,
2052				easing   : previous.prevEasing,
2053				complete : function () {
2054					$(this).trigger('onReset').remove();
2055				}
2056			});
2057		}
2058	};
2059
2060	/*
2061	 *	Overlay helper
2062	 */
2063
2064	F.helpers.overlay = {
2065		defaults : {
2066			closeClick : true,      // if true, fancyBox will be closed when user clicks on the overlay
2067			speedOut   : 200,       // duration of fadeOut animation
2068			showEarly  : true,      // indicates if should be opened immediately or wait until the content is ready
2069			css        : {},        // custom CSS properties
2070			locked     : !isTouch,  // if true, the content will be locked into overlay
2071			fixed      : true       // if false, the overlay CSS position property will not be set to "fixed"
2072		},
2073
2074		overlay : null,      // current handle
2075		fixed   : false,     // indicates if the overlay has position "fixed"
2076		el      : $('html'), // element that contains "the lock"
2077
2078		// Public methods
2079		create : function(opts) {
2080			opts = $.extend({}, this.defaults, opts);
2081
2082			if (this.overlay) {
2083				this.close();
2084			}
2085
2086			this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( F.coming ? F.coming.parent : opts.parent );
2087			this.fixed   = false;
2088
2089			if (opts.fixed && F.defaults.fixed) {
2090				this.overlay.addClass('fancybox-overlay-fixed');
2091
2092				this.fixed = true;
2093			}
2094		},
2095
2096		open : function(opts) {
2097			var that = this;
2098
2099			opts = $.extend({}, this.defaults, opts);
2100
2101			if (this.overlay) {
2102				this.overlay.unbind('.overlay').width('auto').height('auto');
2103
2104			} else {
2105				this.create(opts);
2106			}
2107
2108			if (!this.fixed) {
2109				W.bind('resize.overlay', $.proxy( this.update, this) );
2110
2111				this.update();
2112			}
2113
2114			if (opts.closeClick) {
2115				this.overlay.bind('click.overlay', function(e) {
2116					if ($(e.target).hasClass('fancybox-overlay')) {
2117						if (F.isActive) {
2118							F.close();
2119						} else {
2120							that.close();
2121						}
2122
2123						return false;
2124					}
2125				});
2126			}
2127
2128			this.overlay.css( opts.css ).show();
2129		},
2130
2131		close : function() {
2132			var scrollV, scrollH;
2133
2134			W.unbind('resize.overlay');
2135
2136			if (this.el.hasClass('fancybox-lock')) {
2137				$('.fancybox-margin').removeClass('fancybox-margin');
2138
2139				scrollV = W.scrollTop();
2140				scrollH = W.scrollLeft();
2141
2142				this.el.removeClass('fancybox-lock');
2143
2144				W.scrollTop( scrollV ).scrollLeft( scrollH );
2145			}
2146
2147			$('.fancybox-overlay').remove().hide();
2148
2149			$.extend(this, {
2150				overlay : null,
2151				fixed   : false
2152			});
2153		},
2154
2155		// Private, callbacks
2156
2157		update : function () {
2158			var width = '100%', offsetWidth;
2159
2160			// Reset width/height so it will not mess
2161			this.overlay.width(width).height('100%');
2162
2163			// jQuery does not return reliable result for IE
2164			if (IE) {
2165				offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
2166
2167				if (D.width() > offsetWidth) {
2168					width = D.width();
2169				}
2170
2171			} else if (D.width() > W.width()) {
2172				width = D.width();
2173			}
2174
2175			this.overlay.width(width).height(D.height());
2176		},
2177
2178		// This is where we can manipulate DOM, because later it would cause iframes to reload
2179		onReady : function (opts, obj) {
2180			var overlay = this.overlay;
2181
2182			$('.fancybox-overlay').stop(true, true);
2183
2184			if (!overlay) {
2185				this.create(opts);
2186			}
2187
2188			if (opts.locked && this.fixed && obj.fixed) {
2189				if (!overlay) {
2190					this.margin = D.height() > W.height() ? $('html').css('margin-right').replace("px", "") : false;
2191				}
2192
2193				obj.locked = this.overlay.append( obj.wrap );
2194				obj.fixed  = false;
2195			}
2196
2197			if (opts.showEarly === true) {
2198				this.beforeShow.apply(this, arguments);
2199			}
2200		},
2201
2202		beforeShow : function(opts, obj) {
2203			var scrollV, scrollH;
2204
2205			if (obj.locked) {
2206				if (this.margin !== false) {
2207					$('*').filter(function(){
2208						return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") );
2209					}).addClass('fancybox-margin');
2210
2211					this.el.addClass('fancybox-margin');
2212				}
2213
2214				scrollV = W.scrollTop();
2215				scrollH = W.scrollLeft();
2216
2217				this.el.addClass('fancybox-lock');
2218
2219				W.scrollTop( scrollV ).scrollLeft( scrollH );
2220			}
2221
2222			this.open(opts);
2223		},
2224
2225		onUpdate : function() {
2226			if (!this.fixed) {
2227				this.update();
2228			}
2229		},
2230
2231		afterClose: function (opts) {
2232			// Remove overlay if exists and fancyBox is not opening
2233			// (e.g., it is not being open using afterClose callback)
2234			//if (this.overlay && !F.isActive) {
2235			if (this.overlay && !F.coming) {
2236				this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this ));
2237			}
2238		}
2239	};
2240
2241	/*
2242	 *	Title helper
2243	 */
2244
2245	F.helpers.title = {
2246		defaults : {
2247			type     : 'float', // 'float', 'inside', 'outside' or 'over',
2248			position : 'bottom' // 'top' or 'bottom'
2249		},
2250
2251		beforeShow: function (opts) {
2252			var current = F.current,
2253				text    = current.title,
2254				type    = opts.type,
2255				title,
2256				target;
2257
2258			if ($.isFunction(text)) {
2259				text = text.call(current.element, current);
2260			}
2261
2262			if (!isString(text) || $.trim(text) === '') {
2263				return;
2264			}
2265
2266			title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">
vendor: 4,223 bytes, lines 2266-2430
2266' + text + '</div>');
2267
2268			switch (type) {
2269				case 'inside':
2270					target = F.skin;
2271				break;
2272
2273				case 'outside':
2274					target = F.wrap;
2275				break;
2276
2277				case 'over':
2278					target = F.inner;
2279				break;
2280
2281				default: // 'float'
2282					target = F.skin;
2283
2284					title.appendTo('body');
2285
2286					if (IE) {
2287						title.width( title.width() );
2288					}
2289
2290					title.wrapInner('<span class="child"></span>');
2291
2292					//Increase bottom margin so this title will also fit into viewport
2293					F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) );
2294				break;
2295			}
2296
2297			title[ (opts.position === 'top' ? 'prependTo'  : 'appendTo') ](target);
2298		}
2299	};
2300
2301	// jQuery plugin initialization
2302	$.fn.fancybox = function (options) {
2303		var index,
2304			that     = $(this),
2305			selector = this.selector || '',
2306			run      = function(e) {
2307				var what = $(this).blur(), idx = index, relType, relVal;
2308
2309				if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) {
2310					relType = options.groupAttr || 'data-fancybox-group';
2311					relVal  = what.attr(relType);
2312
2313					if (!relVal) {
2314						relType = 'rel';
2315						relVal  = what.get(0)[ relType ];
2316					}
2317
2318					if (relVal && relVal !== '' && relVal !== 'nofollow') {
2319						what = selector.length ? $(selector) : that;
2320						what = what.filter('[' + relType + '="' + relVal + '"]');
2321						idx  = what.index(this);
2322					}
2323
2324					options.index = idx;
2325
2326					// Stop an event from bubbling if everything is fine
2327					if (F.open(what, options) !== false) {
2328						e.preventDefault();
2329					}
2330				}
2331			};
2332
2333		options = options || {};
2334		index   = options.index || 0;
2335
2336		if (!selector || options.live === false) {
2337			that.unbind('click.fb-start').bind('click.fb-start', run);
2338
2339		} else {
2340			D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run);
2341		}
2342
2343		this.filter('[data-fancybox-start=1]').trigger('click');
2344
2345		return this;
2346	};
2347
2348	// Tests that need a body at doc ready
2349	D.ready(function() {
2350		var w1, w2;
2351
2352		if ( $.scrollbarWidth === undefined ) {
2353			// http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
2354			$.scrollbarWidth = function() {
2355				var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'),
2356					child  = parent.children(),
2357					width  = child.innerWidth() - child.height( 99 ).innerWidth();
2358
2359				parent.remove();
2360
2361				return width;
2362			};
2363		}
2364
2365		if ( $.support.fixedPosition === undefined ) {
2366			$.support.fixedPosition = (function() {
2367				var elem  = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'),
2368					fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 );
2369
2370				elem.remove();
2371
2372				return fixed;
2373			}());
2374		}
2375
2376		$.extend(F.defaults, {
2377			scrollbarWidth : $.scrollbarWidth(),
2378			fixed  : $.support.fixedPosition,
2379			parent : $('body')
2380		});
2381
2382		//Get real width of page scroll-bar
2383		w1 = $(window).width();
2384
2385		H.addClass('fancybox-lock-test');
2386
2387		w2 = $(window).width();
2388
2389		H.removeClass('fancybox-lock-test');
2390
2391		$("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head");
2392	});
2393
2394}(window, document, jQuery));
2395/* End */
2396;
2397; /* Start:"a:4:{s:4:"full";s:39:"/js/jquery.jcarousel.js?172122556736009";s:6:"source";s:23:"/js/jquery.jcarousel.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
2398/*!
2399 * jCarousel - Riding carousels with jQuery
2400 *   http://sorgalla.com/jcarousel/
2401 *
2402 * Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com)
2403 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
2404 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
2405 *
2406 * Built on top of the jQuery library
2407 *   http://jquery.com
2408 *
2409 * Inspired by the "Carousel Component" by Bill Scott
2410 *   http://billwscott.com/carousel/
2411 */
2412
2413/*global window, jQuery */
2414(function($) {
2415    // Default configuration properties.
2416    var defaults = {
2417        vertical: false,
2418        rtl: false,
2419        start: 1,
2420        offset: 1,
2421        size: null,
2422        scroll: 3,
2423        visible: null,
2424        animation: 'normal',
2425        easing: 'swing',
2426        auto: 0,
2427        wrap: null,
2428        initCallback: null,
2429        setupCallback: null,
2430        reloadCallback: null,
2431        itemLoadCallback: null,
2432        itemFirstInCallback: null,
2433        itemFirstOutCallback: null,
2434        itemLastInCallback: null,
2435        itemLastOutCallback: null,
2436        itemVisibleInCallback: null,
2437        itemVisibleOutCallback: null,
2438        animationStepCallback: null,
2439        buttonNextHTML: '<div></div>',
2440        buttonPrevHTML: '<div></div>',
2441        buttonNextEvent: 'click',
2442        buttonPrevEvent: 'click',
2443        buttonNextCallback: null,
2444        buttonPrevCallback: null,
2445        itemFallbackDimension: null
2446    }, windowLoaded = false;
2447
2448    $(window).bind('load.jcarousel', function() { windowLoaded = true; });
2449
2450    /**
2451     * The jCarousel object.
2452     *
2453     * @constructor
2454     * @class jcarousel
2455     * @param e {HTMLElement} The element to create the carousel for.
2456     * @param o {Object} A set of key/value pairs to set as configuration properties.
2457     * @cat Plugins/jCarousel
2458     */
2459    $.jcarousel = function(e, o) {
2460        this.options    = $.extend({}, defaults, o || {});
2461
2462        this.locked          = false;
2463        this.autoStopped     = false;
2464
2465        this.container       = null;
2466        this.clip            = null;
2467        this.list            = null;
2468        this.buttonNext      = null;
2469        this.buttonPrev      = null;
2470        this.buttonNextState = null;
2471        this.buttonPrevState = null;
2472
2473        // Only set if not explicitly passed as option
2474        if (!o || o.rtl === undefined) {
2475            this.options.rtl = ($(e).attr('dir') || $('html').attr('dir') || '').toLowerCase() == 'rtl';
2476        }
2477
2478        this.wh = !this.options.vertical ? 'width' : 'height';
2479        this.lt = !this.options.vertical ? (this.options.rtl ? 'right' : 'left') : 'top';
2480
2481        // Extract skin class
2482        var skin = '', split = e.className.split(' ');
2483
2484        for (var i = 0; i < split.length; i++) {
2485            if (split[i].indexOf('jcarousel-skin') != -1) {
2486                $(e).removeClass(split[i]);
2487                skin = split[i];
2488                break;
2489            }
2490        }
2491
2492        if (e.nodeName.toUpperCase() == 'UL' || e.nodeName.toUpperCase() == 'OL') {
2493            this.list      = $(e);
2494            this.clip      = this.list.parents('.jcarousel-clip');
2495            this.container = this.list.parents('.jcarousel-container');
2496        } else {
2497            this.container = $(e);
2498            this.list      = this.container.find('ul,ol').eq(0);
2499            this.clip      = this.container.find('.jcarousel-clip');
2500        }
2501
2502        if (this.clip.size() === 0) {
2503            this.clip = this.list.wrap('<div></div>').parent();
2504        }
2505
2506        if (this.container.size() === 0) {
2507            this.container = this.clip.wrap('<div></div>').parent();
2508        }
2509
2510        if (skin !== '' && this.container.parent()[0].className.indexOf('jcarousel-skin') == -1) {
2511            this.container.wrap('<div class=" '+ skin + '"></div>');
2512        }
2513
2514        this.buttonPrev = $('.jcarousel-prev', this.container);
2515
2516        if (this.buttonPrev.size() === 0 && this.options.buttonPrevHTML !== null) {
2517            this.buttonPrev = $(this.options.buttonPrevHTML).appendTo(this.container);
2518        }
2519
2520        this.buttonPrev.addClass(this.className('jcarousel-prev'));
2521
2522        this.buttonNext = $('.jcarousel-next', this.container);
2523
2524        if (this.buttonNext.size() === 0 && this.options.buttonNextHTML !== null) {
2525            this.buttonNext = $(this.options.buttonNextHTML).appendTo(this.container);
2526        }
2527
2528        this.buttonNext.addClass(this.className('jcarousel-next'));
2529
2530        this.clip.addClass(this.className('jcarousel-clip')).css({
2531            position: 'relative'
2532        });
2533
2534        this.list.addClass(this.className('jcarousel-list')).css({
2535            overflow: 'hidden',
2536            position: 'relative',
2537            top: 0,
2538            margin: 0,
2539            padding: 0
2540        }).css((this.options.rtl ? 'right' : 'left'), 0);
2541
2542        this.container.addClass(this.className('jcarousel-container')).css({
2543            position: 'relative'
2544        });
2545
2546        if (!this.options.vertical && this.options.rtl) {
2547            this.container.addClass('jcarousel-direction-rtl').attr('dir', 'rtl');
2548        }
2549
2550        var di = this.options.visible !== null ? Math.ceil(this.clipping() / this.options.visible) : null;
2551        var li = this.list.children('li');
2552
2553        var self = this;
2554
2555        if (li.size() > 0) {
2556            var wh = 0, j = this.options.offset;
2557            li.each(function() {
2558                self.format(this, j++);
2559                wh += self.dimension(this, di);
2560            });
2561
2562            this.list.css(this.wh, (wh + 100) + 'px');
2563
2564            // Only set if not explicitly passed as option
2565            if (!o || o.size === undefined) {
2566                this.options.size = li.size();
2567            }
2568        }
2569
2570        // For whatever reason, .show() does not work in Safari...
2571        this.container.css('display', 'block');
2572        this.buttonNext.css('display', 'block');
2573        this.buttonPrev.css('display', 'block');
2574
2575        this.funcNext   = function() { self.next(); return false; };
2576        this.funcPrev   = function() { self.prev(); return false; };
2577        this.funcResize = function() {
2578            if (self.resizeTimer) {
2579                clearTimeout(self.resizeTimer);
2580            }
2581
2582            self.resizeTimer = setTimeout(function() {
2583                self.reload();
2584            }, 100);
2585        };
2586
2587        if (this.options.initCallback !== null) {
2588            this.options.initCallback(this, 'init');
2589        }
2590
2591        if (!windowLoaded && $jc.isSafari()) {
2592            this.buttons(false, false);
2593            $(window).bind('load.jcarousel', function() { self.setup(); });
2594        } else {
2595            this.setup();
2596        }
2597    };
2598
2599    // Create shortcut for internal use
2600    var $jc = $.jcarousel;
2601
2602    $jc.fn = $jc.prototype = {
2603        jcarousel: '0.2.9'
2604    };
2605
2606    $jc.fn.extend = $jc.extend = $.extend;
2607
2608    $jc.fn.extend({
2609        /**
2610         * Setups the carousel.
2611         *
2612         * @method setup
2613         * @return undefined
2614         */
2615        setup: function() {
2616            this.first       = null;
2617            this.last        = null;
2618            this.prevFirst   = null;
2619            this.prevLast    = null;
2620            this.animating   = false;
2621            this.timer       = null;
2622            this.resizeTimer = null;
2623            this.tail        = null;
2624            this.inTail      = false;
2625
2626            if (this.locked) {
2627                return;
2628            }
2629
2630            this.list.css(this.lt, this.pos(this.options.offset) + 'px');
2631            var p = this.pos(this.options.start, true);
2632            this.prevFirst = this.prevLast = null;
2633            this.animate(p, false);
2634
2635            $(window).unbind('resize.jcarousel', this.funcResize).bind('resize.jcarousel', this.funcResize);
2636
2637            if (this.options.setupCallback !== null) {
2638                this.options.setupCallback(this);
2639            }
2640        },
2641
2642        /**
2643         * Clears the list and resets the carousel.
2644         *
2645         * @method reset
2646         * @return undefined
2647         */
2648        reset: function() {
2649            this.list.empty();
2650
2651            this.list.css(this.lt, '0px');
2652            this.list.css(this.wh, '10px');
2653
2654            if (this.options.initCallback !== null) {
2655                this.options.initCallback(this, 'reset');
2656            }
2657
2658            this.setup();
2659        },
2660
2661        /**
2662         * Reloads the carousel and adjusts positions.
2663         *
2664         * @method reload
2665         * @return undefined
2666         */
2667        reload: function() {
2668            if (this.tail !== null && this.inTail) {
2669                this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + this.tail);
2670            }
2671
2672            this.tail   = null;
2673            this.inTail = false;
2674
2675            if (this.options.reloadCallback !== null) {
2676                this.options.reloadCallback(this);
2677            }
2678
2679            if (this.options.visible !== null) {
2680                var self = this;
2681                var di = Math.ceil(this.clipping() / this.options.visible), wh = 0, lt = 0;
2682                this.list.children('li').each(function(i) {
2683                    wh += self.dimension(this, di);
2684                    if (i + 1 < self.first) {
2685                        lt = wh;
2686                    }
2687                });
2688
2689                this.list.css(this.wh, wh + 'px');
2690                this.list.css(this.lt, -lt + 'px');
2691            }
2692
2693            this.scroll(this.first, false);
2694        },
2695
2696        /**
2697         * Locks the carousel.
2698         *
2699         * @method lock
2700         * @return undefined
2701         */
2702        lock: function() {
2703            this.locked = true;
2704            this.buttons();
2705        },
2706
2707        /**
2708         * Unlocks the carousel.
2709         *
2710         * @method unlock
2711         * @return undefined
2712         */
2713        unlock: function() {
2714            this.locked = false;
2715            this.buttons();
2716        },
2717
2718        /**
2719         * Sets the size of the carousel.
2720         *
2721         * @method size
2722         * @return undefined
2723         * @param s {Number} The size of the carousel.
2724         */
2725        size: function(s) {
2726            if (s !== undefined) {
2727                this.options.size = s;
2728                if (!this.locked) {
2729                    this.buttons();
2730                }
2731            }
2732
2733            return this.options.size;
2734        },
2735
2736        /**
2737         * Checks whether a list element exists for the given index (or index range).
2738         *
2739         * @method get
2740         * @return bool
2741         * @param i {Number} The index of the (first) element.
2742         * @param i2 {Number} The index of the last element.
2743         */
2744        has: function(i, i2) {
2745            if (i2 === undefined || !i2) {
2746                i2 = i;
2747            }
2748
2749            if (this.options.size !== null && i2 > this.options.size) {
2750                i2 = this.options.size;
2751            }
2752
2753            for (var j = i; j <= i2; j++) {
2754                var e = this.get(j);
2755                if (!e.length || e.hasClass('jcarousel-item-placeholder')) {
2756                    return false;
2757                }
2758            }
2759
2760            return true;
2761        },
2762
2763        /**
2764         * Returns a jQuery object with list element for the given index.
2765         *
2766         * @method get
2767         * @return jQuery
2768         * @param i {Number} The index of the element.
2769         */
2770        get: function(i) {
2771            return $('>.jcarousel-item-' + i, this.list);
2772        },
2773
2774        /**
2775         * Adds an element for the given index to the list.
2776         * If the element already exists, it updates the inner html.
2777         * Returns the created element as jQuery object.
2778         *
2779         * @method add
2780         * @return jQuery
2781         * @param i {Number} The index of the element.
2782         * @param s {String} The innerHTML of the element.
2783         */
2784        add: function(i, s) {
2785            var e = this.get(i), old = 0, n = $(s);
2786
2787            if (e.length === 0) {
2788                var c, j = $jc.intval(i);
2789                e = this.create(i);
2790                while (true) {
2791                    c = this.get(--j);
2792                    if (j <= 0 || c.length) {
2793                        if (j <= 0) {
2794                            this.list.prepend(e);
2795                        } else {
2796                            c.after(e);
2797                        }
2798                        break;
2799                    }
2800                }
2801            } else {
2802                old = this.dimension(e);
2803            }
2804
2805            if (n.get(0).nodeName.toUpperCase() == 'LI') {
2806                e.replaceWith(n);
2807                e = n;
2808            } else {
2809                e.empty().append(s);
2810            }
2811
2812            this.format(e.removeClass(this.className('jcarousel-item-placeholder')), i);
2813
2814            var di = this.options.visible !== null ? Math.ceil(this.clipping() / this.options.visible) : null;
2815            var wh = this.dimension(e, di) - old;
2816
2817            if (i > 0 && i < this.first) {
2818                this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - wh + 'px');
2819            }
2820
2821            this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) + wh + 'px');
2822
2823            return e;
2824        },
2825
2826        /**
2827         * Removes an element for the given index from the list.
2828         *
2829         * @method remove
2830         * @return undefined
2831         * @param i {Number} The index of the element.
2832         */
2833        remove: function(i) {
2834            var e = this.get(i);
2835
2836            // Check if item exists and is not currently visible
2837            if (!e.length || (i >= this.first && i <= this.last)) {
2838                return;
2839            }
2840
2841            var d = this.dimension(e);
2842
2843            if (i < this.first) {
2844                this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) + d + 'px');
2845            }
2846
2847            e.remove();
2848
2849            this.list.css(this.wh, $jc.intval(this.list.css(this.wh)) - d + 'px');
2850        },
2851
2852        /**
2853         * Moves the carousel forwards.
2854         *
2855         * @method next
2856         * @return undefined
2857         */
2858        next: function() {
2859            if (this.tail !== null && !this.inTail) {
2860                this.scrollTail(false);
2861            } else {
2862                this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'last') && this.options.size !== null && this.last == this.options.size) ? 1 : this.first + this.options.scroll);
2863            }
2864        },
2865
2866        /**
2867         * Moves the carousel backwards.
2868         *
2869         * @method prev
2870         * @return undefined
2871         */
2872        prev: function() {
2873            if (this.tail !== null && this.inTail) {
2874                this.scrollTail(true);
2875            } else {
2876                this.scroll(((this.options.wrap == 'both' || this.options.wrap == 'first') && this.options.size !== null && this.first == 1) ? this.options.size : this.first - this.options.scroll);
2877            }
2878        },
2879
2880        /**
2881         * Scrolls the tail of the carousel.
2882         *
2883         * @method scrollTail
2884         * @return undefined
2885         * @param b {Boolean} Whether scroll the tail back or forward.
2886         */
2887        scrollTail: function(b) {
2888            if (this.locked || this.animating || !this.tail) {
2889                return;
2890            }
2891
2892            this.pauseAuto();
2893
2894            var pos  = $jc.intval(this.list.css(this.lt));
2895
2896            pos = !b ? pos - this.tail : pos + this.tail;
2897            this.inTail = !b;
2898
2899            // Save for callbacks
2900            this.prevFirst = this.first;
2901            this.prevLast  = this.last;
2902
2903            this.animate(pos);
2904        },
2905
2906        /**
2907         * Scrolls the carousel to a certain position.
2908         *
2909         * @method scroll
2910         * @return undefined
2911         * @param i {Number} The index of the element to scoll to.
2912         * @param a {Boolean} Flag indicating whether to perform animation.
2913         */
2914        scroll: function(i, a) {
2915            if (this.locked || this.animating) {
2916                return;
2917            }
2918
2919            this.pauseAuto();
2920            this.animate(this.pos(i), a);
2921        },
2922
2923        /**
2924         * Prepares the carousel and return the position for a certian index.
2925         *
2926         * @method pos
2927         * @return {Number}
2928         * @param i {Number} The index of the element to scoll to.
2929         * @param fv {Boolean} Whether to force last item to be visible.
2930         */
2931        pos: function(i, fv) {
2932            var pos  = $jc.intval(this.list.css(this.lt));
2933
2934            if (this.locked || this.animating) {
2935                return pos;
2936            }
2937
2938            if (this.options.wrap != 'circular') {
2939                i = i < 1 ? 1 : (this.options.size && i > this.options.size ? this.options.size : i);
2940            }
2941
2942            var back = this.first > i;
2943
2944            // Create placeholders, new list width/height
2945            // and new list position
2946            var f = this.options.wrap != 'circular' && this.first <= 1 ? 1 : this.first;
2947            var c = back ? this.get(f) : this.get(this.last);
2948            var j = back ? f : f - 1;
2949            var e = null, l = 0, p = false, d = 0, g;
2950
2951            while (back ? --j >= i : ++j < i) {
2952                e = this.get(j);
2953                p = !e.length;
2954                if (e.length === 0) {
2955                    e = this.create(j).addClass(this.className('jcarousel-item-placeholder'));
2956                    c[back ? 'before' : 'after' ](e);
2957
2958                    if (this.first !== null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) {
2959                        g = this.get(this.index(j));
2960                        if (g.length) {
2961                            e = this.add(j, g.clone(true));
2962                        }
2963                    }
2964                }
2965
2966                c = e;
2967                d = this.dimension(e);
2968
2969                if (p) {
2970                    l += d;
2971                }
2972
2973                if (this.first !== null && (this.options.wrap == 'circular' || (j >= 1 && (this.options.size === null || j <= this.options.size)))) {
2974                    pos = back ? pos + d : pos - d;
2975                }
2976            }
2977
2978            // Calculate visible items
2979            var clipping = this.clipping(), cache = [], visible = 0, v = 0;
2980            c = this.get(i - 1);
2981            j = i;
2982
2983            while (++visible) {
2984                e = this.get(j);
2985                p = !e.length;
2986                if (e.length === 0) {
2987                    e = this.create(j).addClass(this.className('jcarousel-item-placeholder'));
2988                    // This should only happen on a next scroll
2989                    if (c.length === 0) {
2990                        this.list.prepend(e);
2991                    } else {
2992                        c[back ? 'before' : 'after' ](e);
2993                    }
2994
2995                    if (this.first !== null && this.options.wrap == 'circular' && this.options.size !== null && (j <= 0 || j > this.options.size)) {
2996                        g = this.get(this.index(j));
2997                        if (g.length) {
2998                            e = this.add(j, g.clone(true));
2999                        }
3000                    }
3001                }
3002
3003                c = e;
3004                d = this.dimension(e);
3005                if (d === 0) {
3006                    throw new Error('jCarousel: No width/height set for items. This will cause an infinite loop. Aborting...');
3007                }
3008
3009                if (this.options.wrap != 'circular' && this.options.size !== null && j > this.options.size) {
3010                    cache.push(e);
3011                } else if (p) {
3012                    l += d;
3013                }
3014
3015                v += d;
3016
3017                if (v >= clipping) {
3018                    break;
3019                }
3020
3021                j++;
3022            }
3023
3024             // Remove out-of-range placeholders
3025            for (var x = 0; x < cache.length; x++) {
3026                cache[x].remove();
3027            }
3028
3029            // Resize list
3030            if (l > 0) {
3031                this.list.css(this.wh, this.dimension(this.list) + l + 'px');
3032
3033                if (back) {
3034                    pos -= l;
3035                    this.list.css(this.lt, $jc.intval(this.list.css(this.lt)) - l + 'px');
3036                }
3037            }
3038
3039            // Calculate first and last item
3040            var last = i + visible - 1;
3041            if (this.options.wrap != 'circular' && this.options.size && last > this.options.size) {
3042                last = this.options.size;
3043            }
3044
3045            if (j > last) {
3046                visible = 0;
3047                j = last;
3048                v = 0;
3049                while (++visible) {
3050                    e = this.get(j--);
3051                    if (!e.length) {
3052                        break;
3053                    }
3054                    v += this.dimension(e);
3055                    if (v >= clipping) {
3056                        break;
3057                    }
3058                }
3059            }
3060
3061            var first = last - visible + 1;
3062            if (this.options.wrap != 'circular' && first < 1) {
3063                first = 1;
3064            }
3065
3066            if (this.inTail && back) {
3067                pos += this.tail;
3068                this.inTail = false;
3069            }
3070
3071            this.tail = null;
3072            if (this.options.wrap != 'circular' && last == this.options.size && (last - visible + 1) >= 1) {
3073                var m = $jc.intval(this.get(last).css(!this.options.vertical ? 'marginRight' : 'marginBottom'));
3074                if ((v - m) > clipping) {
3075                    this.tail = v - clipping - m;
3076                }
3077            }
3078
3079            if (fv && i === this.options.size && this.tail) {
3080                pos -= this.tail;
3081                this.inTail = true;
3082            }
3083
3084            // Adjust position
3085            while (i-- > first) {
3086                pos += this.dimension(this.get(i));
3087            }
3088
3089            // Save visible item range
3090            this.prevFirst = this.first;
3091            this.prevLast  = this.last;
3092            this.first     = first;
3093            this.last      = last;
3094
3095            return pos;
3096        },
3097
3098        /**
3099         * Animates the carousel to a certain position.
3100         *
3101         * @method animate
3102         * @return undefined
3103         * @param p {Number} Position to scroll to.
3104         * @param a {Boolean} Flag indicating whether to perform animation.
3105         */
3106        animate: function(p, a) {
3107            if (this.locked || this.animating) {
3108                return;
3109            }
3110
3111            this.animating = true;
3112
3113            var self = this;
3114            var scrolled = function() {
3115                self.animating = false;
3116
3117                if (p === 0) {
3118                    self.list.css(self.lt,  0);
3119                }
3120
3121                if (!self.autoStopped && (self.options.wrap == 'circular' || self.options.wrap == 'both' || self.options.wrap == 'last' || self.options.size === null || self.last < self.options.size || (self.last == self.options.size && self.tail !== null && !self.inTail))) {
3122                    self.startAuto();
3123                }
3124
3125                self.buttons();
3126                self.notify('onAfterAnimation');
3127
3128                // This function removes items which are appended automatically for circulation.
3129                // This prevents the list from growing infinitely.
3130                if (self.options.wrap == 'circular' && self.options.size !== null) {
3131                    for (var i = self.prevFirst; i <= self.prevLast; i++) {
3132                        if (i !== null && !(i >= self.first && i <= self.last) && (i < 1 || i > self.options.size)) {
3133                            self.remove(i);
3134                        }
3135                    }
3136                }
3137            };
3138
3139            this.notify('onBeforeAnimation');
3140
3141            // Animate
3142            if (!this.options.animation || a === false) {
3143                this.list.css(this.lt, p + 'px');
3144                scrolled();
3145            } else {
3146                var o = !this.options.vertical ? (this.options.rtl ? {'right': p} : {'left': p}) : {'top': p};
3147                // Define animation settings.
3148                var settings = {
3149                    duration: this.options.animation,
3150                    easing:   this.options.easing,
3151                    complete: scrolled
3152                };
3153                // If we have a step callback, specify it as well.
3154                if ($.isFunction(this.options.animationStepCallback)) {
3155                    settings.step = this.options.animationStepCallback;
3156                }
3157                // Start the animation.
3158                this.list.animate(o, settings);
3159            }
3160        },
3161
3162        /**
3163         * Starts autoscrolling.
3164         *
3165         * @method auto
3166         * @return undefined
3167         * @param s {Number} Seconds to periodically autoscroll the content.
3168         */
3169        startAuto: function(s) {
3170            if (s !== undefined) {
3171                this.options.auto = s;
3172            }
3173
3174            if (this.options.auto === 0) {
3175                return this.stopAuto();
3176            }
3177
3178            if (this.timer !== null) {
3179                return;
3180            }
3181
3182            this.autoStopped = false;
3183
3184            var self = this;
3185            this.timer = window.setTimeout(function() { self.next(); }, this.options.auto * 1000);
3186        },
3187
3188        /**
3189         * Stops autoscrolling.
3190         *
3191         * @method stopAuto
3192         * @return undefined
3193         */
3194        stopAuto: function() {
3195            this.pauseAuto();
3196            this.autoStopped = true;
3197        },
3198
3199        /**
3200         * Pauses autoscrolling.
3201         *
3202         * @method pauseAuto
3203         * @return undefined
3204         */
3205        pauseAuto: function() {
3206            if (this.timer === null) {
3207                return;
3208            }
3209
3210            window.clearTimeout(this.timer);
3211            this.timer = null;
3212        },
3213
3214        /**
3215         * Sets the states of the prev/next buttons.
3216         *
3217         * @method buttons
3218         * @return undefined
3219         */
3220        buttons: function(n, p) {
3221            if (n == null) {
3222                n = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'first') || this.options.size === null || this.last < this.options.size);
3223                if (!this.locked && (!this.options.wrap || this.options.wrap == 'first') && this.options.size !== null && this.last >= this.options.size) {
3224                    n = this.tail !== null && !this.inTail;
3225                }
3226            }
3227
3228            if (p == null) {
3229                p = !this.locked && this.options.size !== 0 && ((this.options.wrap && this.options.wrap != 'last') || this.first > 1);
3230                if (!this.locked && (!this.options.wrap || this.options.wrap == 'last') && this.options.size !== null && this.first == 1) {
3231                    p = this.tail !== null && this.inTail;
3232                }
3233            }
3234
3235            var self = this;
3236
3237            if (this.buttonNext.size() > 0) {
3238                this.buttonNext.unbind(this.options.buttonNextEvent + '.jcarousel', this.funcNext);
3239
3240                if (n) {
3241                    this.buttonNext.bind(this.options.buttonNextEvent + '.jcarousel', this.funcNext);
3242                }
3243
3244                this.buttonNext[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
3245
3246                if (this.options.buttonNextCallback !== null && this.buttonNext.data('jcarou
3246selstate') != n) {
3247                    this.buttonNext.each(function() { self.options.buttonNextCallback(self, this, n); }).data('jcarouselstate', n);
3248                }
3249            } else {
3250                if (this.options.buttonNextCallback !== null && this.buttonNextState != n) {
3251                    this.options.buttonNextCallback(self, null, n);
3252                }
3253            }
3254
3255            if (this.buttonPrev.size() > 0) {
3256                this.buttonPrev.unbind(this.options.buttonPrevEvent + '.jcarousel', this.funcPrev);
3257
3258                if (p) {
3259                    this.buttonPrev.bind(this.options.buttonPrevEvent + '.jcarousel', this.funcPrev);
3260                }
3261
3262                this.buttonPrev[p ? 'removeClass' : 'addClass'](this.className('jcarousel-prev-disabled')).attr('disabled', p ? false : true);
3263
3264                if (this.options.buttonPrevCallback !== null && this.buttonPrev.data('jcarouselstate') != p) {
3265                    this.buttonPrev.each(function() { self.options.buttonPrevCallback(self, this, p); }).data('jcarouselstate', p);
3266                }
3267            } else {
3268                if (this.options.buttonPrevCallback !== null && this.buttonPrevState != p) {
3269                    this.options.buttonPrevCallback(self, null, p);
3270                }
3271            }
3272
3273            this.buttonNextState = n;
3274            this.buttonPrevState = p;
3275        },
3276
3277        /**
3278         * Notify callback of a specified event.
3279         *
3280         * @method notify
3281         * @return undefined
3282         * @param evt {String} The event name
3283         */
3284        notify: function(evt) {
3285            var state = this.prevFirst === null ? 'init' : (this.prevFirst < this.first ? 'next' : 'prev');
3286
3287            // Load items
3288            this.callback('itemLoadCallback', evt, state);
3289
3290            if (this.prevFirst !== this.first) {
3291                this.callback('itemFirstInCallback', evt, state, this.first);
3292                this.callback('itemFirstOutCallback', evt, state, this.prevFirst);
3293            }
3294
3295            if (this.prevLast !== this.last) {
3296                this.callback('itemLastInCallback', evt, state, this.last);
3297                this.callback('itemLastOutCallback', evt, state, this.prevLast);
3298            }
3299
3300            this.callback('itemVisibleInCallback', evt, state, this.first, this.last, this.prevFirst, this.prevLast);
3301            this.callback('itemVisibleOutCallback', evt, state, this.prevFirst, this.prevLast, this.first, this.last);
3302        },
3303
3304        callback: function(cb, evt, state, i1, i2, i3, i4) {
3305            if (this.options[cb] == null || (typeof this.options[cb] != 'object' && evt != 'onAfterAnimation')) {
3306                return;
3307            }
3308
3309            var callback = typeof this.options[cb] == 'object' ? this.options[cb][evt] : this.options[cb];
3310
3311            if (!$.isFunction(callback)) {
3312                return;
3313            }
3314
3315            var self = this;
3316
3317            if (i1 === undefined) {
3318                callback(self, state, evt);
3319            } else if (i2 === undefined) {
3320                this.get(i1).each(function() { callback(self, this, i1, state, evt); });
3321            } else {
3322                var call = function(i) {
3323                    self.get(i).each(function() { callback(self, this, i, state, evt); });
3324                };
3325                for (var i = i1; i <= i2; i++) {
3326                    if (i !== null && !(i >= i3 && i <= i4)) {
3327                        call(i);
3328                    }
3329                }
3330            }
3331        },
3332
3333        create: function(i) {
3334            return this.format('<li></li>', i);
3335        },
3336
3337        format: function(e, i) {
3338            e = $(e);
3339            var split = e.get(0).className.split(' ');
3340            for (var j = 0; j < split.length; j++) {
3341                if (split[j].indexOf('jcarousel-') != -1) {
3342                    e.removeClass(split[j]);
3343                }
3344            }
3345            e.addClass(this.className('jcarousel-item')).addClass(this.className('jcarousel-item-' + i)).css({
3346                'float': (this.options.rtl ? 'right' : 'left'),
3347                'list-style': 'none'
3348            }).attr('jcarouselindex', i);
3349            return e;
3350        },
3351
3352        className: function(c) {
3353            return c + ' ' + c + (!this.options.vertical ? '-horizontal' : '-vertical');
3354        },
3355
3356        dimension: function(e, d) {
3357            var el = $(e);
3358
3359            if (d == null) {
3360                return !this.options.vertical ?
3361                    ((el.innerWidth() +
3362                        $jc.intval(el.css('margin-left')) +
3363                        $jc.intval(el.css('margin-right')) +
3364                        $jc.intval(el.css('border-left-width')) +
3365                        $jc.intval(el.css('border-right-width'))) || $jc.intval(this.options.itemFallbackDimension)) :
3366                    ((el.innerHeight() +
3367                        $jc.intval(el.css('margin-top')) +
3368                        $jc.intval(el.css('margin-bottom')) +
3369                        $jc.intval(el.css('border-top-width')) +
3370                        $jc.intval(el.css('border-bottom-width'))) || $jc.intval(this.options.itemFallbackDimension));
3371            } else {
3372                var w = !this.options.vertical ?
3373                    d - $jc.intval(el.css('marginLeft')) - $jc.intval(el.css('marginRight')) :
3374                    d - $jc.intval(el.css('marginTop')) - $jc.intval(el.css('marginBottom'));
3375
3376                $(el).css(this.wh, w + 'px');
3377
3378                return this.dimension(el);
3379            }
3380        },
3381
3382        clipping: function() {
3383            return !this.options.vertical ?
3384                this.clip[0].offsetWidth - $jc.intval(this.clip.css('borderLeftWidth')) - $jc.intval(this.clip.css('borderRightWidth')) :
3385                this.clip[0].offsetHeight - $jc.intval(this.clip.css('borderTopWidth')) - $jc.intval(this.clip.css('borderBottomWidth'));
3386        },
3387
3388        index: function(i, s) {
3389            if (s == null) {
3390                s = this.options.size;
3391            }
3392
3393            return Math.round((((i-1) / s) - Math.floor((i-1) / s)) * s) + 1;
3394        }
3395    });
3396
3397    $jc.extend({
3398        /**
3399         * Gets/Sets the global default configuration properties.
3400         *
3401         * @method defaults
3402         * @return {Object}
3403         * @param d {Object} A set of key/value pairs to set as configuration properties.
3404         */
3405        defaults: function(d) {
3406            return $.extend(defaults, d || {});
3407        },
3408
3409        intval: function(v) {
3410            v = parseInt(v, 10);
3411            return isNaN(v) ? 0 : v;
3412        },
3413
3414        windowLoaded: function() {
3415            windowLoaded = true;
3416        },
3417
3418        isSafari: function() {
3419            var ua = navigator.userAgent.toLowerCase(),
3420                match = /(chrome)[ \/]([\w.]+)/.exec(ua) || /(webkit)[ \/]([\w.]+)/.exec(ua) || [],
3421                browser = match[1] || "";
3422
3423            return browser === 'webkit';
3424        }
3425    });
3426
3427    /**
3428     * Creates a carousel for all matched elements.
3429     *
3430     * @example $("#mycarousel").jcarousel();
3431     * @before <ul id="mycarousel" class="jcarousel-skin-name"><li>First item</li><li>Second item</li></ul>
3432     * @result
3433     *
3434     * <div class="jcarousel-skin-name">
3435     *   <div class="jcarousel-container">
3436     *     <div class="jcarousel-clip">
3437     *       <ul class="jcarousel-list">
3438     *         <li class="jcarousel-item-1">First item</li>
3439     *         <li class="jcarousel-item-2">Second item</li>
3440     *       </ul>
3441     *     </div>
3442     *     <div disabled="disabled" class="jcarousel-prev jcarousel-prev-disabled"></div>
3443     *     <div class="jcarousel-next"></div>
3444     *   </div>
3445     * </div>
3446     *
3447     * @method jcarousel
3448     * @return jQuery
3449     * @param o {Hash|String} A set of key/value pairs to set as configuration properties or a method name to call on a formerly created instance.
3450     */
3451    $.fn.jcarousel = function(o) {
3452        if (typeof o == 'string') {
3453            var instance = $(this).data('jcarousel'), args = Array.prototype.slice.call(arguments, 1);
3454            return instance[o].apply(instance, args);
3455        } else {
3456            return this.each(function() {
3457                var instance = $(this).data('jcarousel');
3458                if (instance) {
3459                    if (o) {
3460                        $.extend(instance.options, o);
3461                    }
3462                    instance.reload();
3463                } else {
3464                    $(this).data('jcarousel', new $jc(this, o));
3465                }
3466            });
3467        }
3468    };
3469
3470})(jQuery);
3471
3472/* End */
3473;
3474; /* Start:"a:4:{s:4:"full";s:47:"/js/jquery-ui-1.10.3.custom.js?1721225567416213";s:6:"source";s:30:"/js/jquery-ui-1.10.3.custom.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
3475/*! jQuery UI - v1.10.3 - 2013-09-01
3476* http://jqueryui.com
3477* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
3478* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
3479
3480(function( $, undefined ) {
3481
3482var uuid = 0,
3483	runiqueId = /^ui-id-\d+$/;
3484
vendor: 5,040 bytes, lines 3485-3672
3485// $.ui might exist from components with no dependencies, e.g., $.ui.position
3486$.ui = $.ui || {};
3487
3488$.extend( $.ui, {
3489	version: "1.10.3",
3490
3491	keyCode: {
3492		BACKSPACE: 8,
3493		COMMA: 188,
3494		DELETE: 46,
3495		DOWN: 40,
3496		END: 35,
3497		ENTER: 13,
3498		ESCAPE: 27,
3499		HOME: 36,
3500		LEFT: 37,
3501		NUMPAD_ADD: 107,
3502		NUMPAD_DECIMAL: 110,
3503		NUMPAD_DIVIDE: 111,
3504		NUMPAD_ENTER: 108,
3505		NUMPAD_MULTIPLY: 106,
3506		NUMPAD_SUBTRACT: 109,
3507		PAGE_DOWN: 34,
3508		PAGE_UP: 33,
3509		PERIOD: 190,
3510		RIGHT: 39,
3511		SPACE: 32,
3512		TAB: 9,
3513		UP: 38
3514	}
3515});
3516
3517// plugins
3518$.fn.extend({
3519	focus: (function( orig ) {
3520		return function( delay, fn ) {
3521			return typeof delay === "number" ?
3522				this.each(function() {
3523					var elem = this;
3524					setTimeout(function() {
3525						$( elem ).focus();
3526						if ( fn ) {
3527							fn.call( elem );
3528						}
3529					}, delay );
3530				}) :
3531				orig.apply( this, arguments );
3532		};
3533	})( $.fn.focus ),
3534
3535	scrollParent: function() {
3536		var scrollParent;
3537		if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
3538			scrollParent = this.parents().filter(function() {
3539				return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
3540			}).eq(0);
3541		} else {
3542			scrollParent = this.parents().filter(function() {
3543				return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
3544			}).eq(0);
3545		}
3546
3547		return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
3548	},
3549
3550	zIndex: function( zIndex ) {
3551		if ( zIndex !== undefined ) {
3552			return this.css( "zIndex", zIndex );
3553		}
3554
3555		if ( this.length ) {
3556			var elem = $( this[ 0 ] ), position, value;
3557			while ( elem.length && elem[ 0 ] !== document ) {
3558				// Ignore z-index if position is set to a value where z-index is ignored by the browser
3559				// This makes behavior of this function consistent across browsers
3560				// WebKit always returns auto if the element is positioned
3561				position = elem.css( "position" );
3562				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
3563					// IE returns 0 when zIndex is not specified
3564					// other browsers return a string
3565					// we ignore the case of nested elements with an explicit value of 0
3566					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
3567					value = parseInt( elem.css( "zIndex" ), 10 );
3568					if ( !isNaN( value ) && value !== 0 ) {
3569						return value;
3570					}
3571				}
3572				elem = elem.parent();
3573			}
3574		}
3575
3576		return 0;
3577	},
3578
3579	uniqueId: function() {
3580		return this.each(function() {
3581			if ( !this.id ) {
3582				this.id = "ui-id-" + (++uuid);
3583			}
3584		});
3585	},
3586
3587	removeUniqueId: function() {
3588		return this.each(function() {
3589			if ( runiqueId.test( this.id ) ) {
3590				$( this ).removeAttr( "id" );
3591			}
3592		});
3593	}
3594});
3595
3596// selectors
3597function focusable( element, isTabIndexNotNaN ) {
3598	var map, mapName, img,
3599		nodeName = element.nodeName.toLowerCase();
3600	if ( "area" === nodeName ) {
3601		map = element.parentNode;
3602		mapName = map.name;
3603		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3604			return false;
3605		}
3606		img = $( "img[usemap=#" + mapName + "]" )[0];
3607		return !!img && visible( img );
3608	}
3609	return ( /input|select|textarea|button|object/.test( nodeName ) ?
3610		!element.disabled :
3611		"a" === nodeName ?
3612			element.href || isTabIndexNotNaN :
3613			isTabIndexNotNaN) &&
3614		// the element and all of its ancestors must be visible
3615		visible( element );
3616}
3617
3618function visible( element ) {
3619	return $.expr.filters.visible( element ) &&
3620		!$( element ).parents().addBack().filter(function() {
3621			return $.css( this, "visibility" ) === "hidden";
3622		}).length;
3623}
3624
3625$.extend( $.expr[ ":" ], {
3626	data: $.expr.createPseudo ?
3627		$.expr.createPseudo(function( dataName ) {
3628			return function( elem ) {
3629				return !!$.data( elem, dataName );
3630			};
3631		}) :
3632		// support: jQuery <1.8
3633		function( elem, i, match ) {
3634			return !!$.data( elem, match[ 3 ] );
3635		},
3636
3637	focusable: function( element ) {
3638		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
3639	},
3640
3641	tabbable: function( element ) {
3642		var tabIndex = $.attr( element, "tabindex" ),
3643			isTabIndexNaN = isNaN( tabIndex );
3644		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
3645	}
3646});
3647
3648// support: jQuery <1.8
3649if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
3650	$.each( [ "Width", "Height" ], function( i, name ) {
3651		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
3652			type = name.toLowerCase(),
3653			orig = {
3654				innerWidth: $.fn.innerWidth,
3655				innerHeight: $.fn.innerHeight,
3656				outerWidth: $.fn.outerWidth,
3657				outerHeight: $.fn.outerHeight
3658			};
3659
3660		function reduce( elem, size, border, margin ) {
3661			$.each( side, function() {
3662				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
3663				if ( border ) {
3664					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
3665				}
3666				if ( margin ) {
3667					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
3668				}
3669			});
3670			return size;
3671		}
3672
3673		$.fn[ "inner" + name ] = function( size ) {
3674			if ( size === undefined ) {
3675				return orig[ "inner" + name ].call( this );
3676			}
3677
3678			return this.each(function() {
3679				$( this ).css( type, reduce( this, size ) + "px" );
3680			});
3681		};
3682
3683		$.fn[ "outer" + name] = function( size, margin ) {
3684			if ( typeof size !== "number" ) {
3685				return orig[ "outer" + name ].call( this, size );
3686			}
3687
3688			return this.each(function() {
3689				$( this).css( type, reduce( this, size, true, margin ) + "px" );
3690			});
3691		};
3692	});
3693}
3694
3695// support: jQuery <1.8
3696if ( !$.fn.addBack ) {
3697	$.fn.addBack = function( selector ) {
3698		return this.add( selector == null ?
3699			this.prevObject : this.prevObject.filter( selector )
3700		);
3701	};
3702}
3703
3704// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
3705if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
3706	$.fn.removeData = (function( removeData ) {
3707		return function( key ) {
3708			if ( arguments.length ) {
3709				return removeData.call( this, $.camelCase( key ) );
3710			} else {
3711				return removeData.call( this );
3712			}
3713		};
3714	})( $.fn.removeData );
3715}
3716
3717
3718
3719
3720
3721// deprecated
3722$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
3723
3724$.support.selectstart = "onselectstart" in document.createElement( "div" );
3725$.fn.extend({
3726	disableSelection: function() {
3727		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
3728			".ui-disableSelection", function( event ) {
3729				event.preventDefault();
3730			});
3731	},
3732
3733	enableSelection: function() {
3734		return this.unbind( ".ui-disableSelection" );
3735	}
3736});
3737
3738$.extend( $.ui, {
3739	// $.ui.plugin is deprecated. Use $.widget() extensions instead.
3740	plugin: {
3741		add: function( module, option, set ) {
3742			var i,
3743				proto = $.ui[ module ].prototype;
3744			for ( i in set ) {
3745				proto.plugins[ i ] = proto.plugins[ i ] || [];
3746				proto.plugins[ i ].push( [ option, set[ i ] ] );
3747			}
3748		},
3749		call: function( instance, name, args ) {
3750			var i,
3751				set = instance.plugins[ name ];
3752			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
3753				return;
3754			}
3755
3756			for ( i = 0; i < set.length; i++ ) {
3757				if ( instance.options[ set[ i ][ 0 ] ] ) {
3758					set[ i ][ 1 ].apply( instance.element, args );
3759				}
3760			}
3761		}
3762	},
3763
3764	// only used by resizable
3765	hasScroll: function( el, a ) {
3766
3767		//If overflow is hidden, the element might have extra content, but the user wants to hide it
3768		if ( $( el ).css( "overflow" ) === "hidden") {
3769			return false;
3770		}
3771
3772		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3773			has = false;
3774
3775		if ( el[ scroll ] > 0 ) {
3776			return true;
3777		}
3778
3779		// TODO: determine which cases actually cause this to happen
3780		// if the element doesn't have the scroll set, see if it's possible to
3781		// set the scroll
3782		el[ scroll ] = 1;
3783		has = ( el[ scroll ] > 0 );
3784		el[ scroll ] = 0;
3785		return has;
3786	}
3787});
3788
3789})( jQuery );
3790(function( $, undefined ) {
3791
3792var uuid = 0,
3793	slice = Array.prototype.slice,
3794	_cleanData = $.cleanData;
3795$.cleanData = function( elems ) {
3796	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
3797		try {
3798			$( elem ).triggerHandler( "remove" );
3799		// http://bugs.jquery.com/ticket/8235
3800		} catch( e ) {}
3801	}
3802	_cleanData( elems );
3803};
3804
3805$.widget = function( name, base, prototype ) {
3806	var fullName, existingConstructor, constructor, basePrototype,
3807		// proxiedPrototype allows the provided prototype to remain unmodified
3808		// so that it can be used as a mixin for multiple widgets (#8876)
3809		proxiedPrototype = {},
3810		namespace = name.split( "." )[ 0 ];
3811
3812	name = name.split( "." )[ 1 ];
3813	fullName = namespace + "-" + name;
3814
3815	if ( !prototype ) {
3816		prototype = base;
3817		base = $.Widget;
3818	}
3819
3820	// create selector for plugin
3821	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
3822		return !!$.data( elem, fullName );
3823	};
3824
3825	$[ namespace ] = $[ namespace ] || {};
3826	existingConstructor = $[ namespace ][ name ];
3827	constructor = $[ namespace ][ name ] = function( options, element ) {
3828		// allow instantiation without "new" keyword
3829		if ( !this._createWidget ) {
3830			return new constructor( options, element );
3831		}
3832
3833		// allow instantiation without initializing for simple inheritance
3834		// must use "new" keyword (the code above always passes args)
3835		if ( arguments.length ) {
3836			this._createWidget( options, element );
3837		}
3838	};
3839	// extend with the existing constructor to carry over any static properties
3840	$.extend( constructor, existingConstructor, {
3841		version: prototype.version,
3842		// copy the object used to create the prototype in case we need to
3843		// redefine the widget later
3844		_proto: $.extend( {}, prototype ),
3845		// track widgets that inherit from this widget in case this widget is
3846		// redefined after a widget inherits from it
3847		_childConstructors: []
3848	});
3849
3850	basePrototype = new base();
3851	// we need to make the options hash a property directly on the new instance
3852	// otherwise we'll modify the options hash on the prototype that we're
3853	// inheriting from
3854	basePrototype.options = $.widget.extend( {}, basePrototype.options );
3855	$.each( prototype, function( prop, value ) {
3856		if ( !$.isFunction( value ) ) {
3857			proxiedPrototype[ prop ] = value;
3858			return;
3859		}
3860		proxiedPrototype[ prop ] = (function() {
3861			var _super = function() {
3862					return base.prototype[ prop ].apply( this, arguments );
3863				},
3864				_superApply = function( args ) {
3865					return base.prototype[ prop ].apply( this, args );
3866				};
3867			return function() {
3868				var __super = this._super,
3869					__superApply = this._superApply,
3870					returnValue;
3871
3872				this._super = _super;
3873				this._superApply = _superApply;
3874
vendor: 11,913 bytes, lines 3875-4286
3875				returnValue = value.apply( this, arguments );
3876
3877				this._super = __super;
3878				this._superApply = __superApply;
3879
3880				return returnValue;
3881			};
3882		})();
3883	});
3884	constructor.prototype = $.widget.extend( basePrototype, {
3885		// TODO: remove support for widgetEventPrefix
3886		// always use the name + a colon as the prefix, e.g., draggable:start
3887		// don't prefix for widgets that aren't DOM-based
3888		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
3889	}, proxiedPrototype, {
3890		constructor: constructor,
3891		namespace: namespace,
3892		widgetName: name,
3893		widgetFullName: fullName
3894	});
3895
3896	// If this widget is being redefined then we need to find all widgets that
3897	// are inheriting from it and redefine all of them so that they inherit from
3898	// the new version of this widget. We're essentially trying to replace one
3899	// level in the prototype chain.
3900	if ( existingConstructor ) {
3901		$.each( existingConstructor._childConstructors, function( i, child ) {
3902			var childPrototype = child.prototype;
3903
3904			// redefine the child widget using the same prototype that was
3905			// originally used, but inherit from the new version of the base
3906			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
3907		});
3908		// remove the list of existing child constructors from the old constructor
3909		// so the old child constructors can be garbage collected
3910		delete existingConstructor._childConstructors;
3911	} else {
3912		base._childConstructors.push( constructor );
3913	}
3914
3915	$.widget.bridge( name, constructor );
3916};
3917
3918$.widget.extend = function( target ) {
3919	var input = slice.call( arguments, 1 ),
3920		inputIndex = 0,
3921		inputLength = input.length,
3922		key,
3923		value;
3924	for ( ; inputIndex < inputLength; inputIndex++ ) {
3925		for ( key in input[ inputIndex ] ) {
3926			value = input[ inputIndex ][ key ];
3927			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
3928				// Clone objects
3929				if ( $.isPlainObject( value ) ) {
3930					target[ key ] = $.isPlainObject( target[ key ] ) ?
3931						$.widget.extend( {}, target[ key ], value ) :
3932						// Don't extend strings, arrays, etc. with objects
3933						$.widget.extend( {}, value );
3934				// Copy everything else by reference
3935				} else {
3936					target[ key ] = value;
3937				}
3938			}
3939		}
3940	}
3941	return target;
3942};
3943
3944$.widget.bridge = function( name, object ) {
3945	var fullName = object.prototype.widgetFullName || name;
3946	$.fn[ name ] = function( options ) {
3947		var isMethodCall = typeof options === "string",
3948			args = slice.call( arguments, 1 ),
3949			returnValue = this;
3950
3951		// allow multiple hashes to be passed on init
3952		options = !isMethodCall && args.length ?
3953			$.widget.extend.apply( null, [ options ].concat(args) ) :
3954			options;
3955
3956		if ( isMethodCall ) {
3957			this.each(function() {
3958				var methodValue,
3959					instance = $.data( this, fullName );
3960				if ( !instance ) {
3961					return $.error( "cannot call methods on " + name + " prior to initialization; " +
3962						"attempted to call method '" + options + "'" );
3963				}
3964				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
3965					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
3966				}
3967				methodValue = instance[ options ].apply( instance, args );
3968				if ( methodValue !== instance && methodValue !== undefined ) {
3969					returnValue = methodValue && methodValue.jquery ?
3970						returnValue.pushStack( methodValue.get() ) :
3971						methodValue;
3972					return false;
3973				}
3974			});
3975		} else {
3976			this.each(function() {
3977				var instance = $.data( this, fullName );
3978				if ( instance ) {
3979					instance.option( options || {} )._init();
3980				} else {
3981					$.data( this, fullName, new object( options, this ) );
3982				}
3983			});
3984		}
3985
3986		return returnValue;
3987	};
3988};
3989
3990$.Widget = function( /* options, element */ ) {};
3991$.Widget._childConstructors = [];
3992
3993$.Widget.prototype = {
3994	widgetName: "widget",
3995	widgetEventPrefix: "",
3996	defaultElement: "<div>",
3997	options: {
3998		disabled: false,
3999
4000		// callbacks
4001		create: null
4002	},
4003	_createWidget: function( options, element ) {
4004		element = $( element || this.defaultElement || this )[ 0 ];
4005		this.element = $( element );
4006		this.uuid = uuid++;
4007		this.eventNamespace = "." + this.widgetName + this.uuid;
4008		this.options = $.widget.extend( {},
4009			this.options,
4010			this._getCreateOptions(),
4011			options );
4012
4013		this.bindings = $();
4014		this.hoverable = $();
4015		this.focusable = $();
4016
4017		if ( element !== this ) {
4018			$.data( element, this.widgetFullName, this );
4019			this._on( true, this.element, {
4020				remove: function( event ) {
4021					if ( event.target === element ) {
4022						this.destroy();
4023					}
4024				}
4025			});
4026			this.document = $( element.style ?
4027				// element within the document
4028				element.ownerDocument :
4029				// element is window or document
4030				element.document || element );
4031			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
4032		}
4033
4034		this._create();
4035		this._trigger( "create", null, this._getCreateEventData() );
4036		this._init();
4037	},
4038	_getCreateOptions: $.noop,
4039	_getCreateEventData: $.noop,
4040	_create: $.noop,
4041	_init: $.noop,
4042
4043	destroy: function() {
4044		this._destroy();
4045		// we can probably remove the unbind calls in 2.0
4046		// all event bindings should go through this._on()
4047		this.element
4048			.unbind( this.eventNamespace )
4049			// 1.9 BC for #7810
4050			// TODO remove dual storage
4051			.removeData( this.widgetName )
4052			.removeData( this.widgetFullName )
4053			// support: jquery <1.6.3
4054			// http://bugs.jquery.com/ticket/9413
4055			.removeData( $.camelCase( this.widgetFullName ) );
4056		this.widget()
4057			.unbind( this.eventNamespace )
4058			.removeAttr( "aria-disabled" )
4059			.removeClass(
4060				this.widgetFullName + "-disabled " +
4061				"ui-state-disabled" );
4062
4063		// clean up events and states
4064		this.bindings.unbind( this.eventNamespace );
4065		this.hoverable.removeClass( "ui-state-hover" );
4066		this.focusable.removeClass( "ui-state-focus" );
4067	},
4068	_destroy: $.noop,
4069
4070	widget: function() {
4071		return this.element;
4072	},
4073
4074	option: function( key, value ) {
4075		var options = key,
4076			parts,
4077			curOption,
4078			i;
4079
4080		if ( arguments.length === 0 ) {
4081			// don't return a reference to the internal hash
4082			return $.widget.extend( {}, this.options );
4083		}
4084
4085		if ( typeof key === "string" ) {
4086			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
4087			options = {};
4088			parts = key.split( "." );
4089			key = parts.shift();
4090			if ( parts.length ) {
4091				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
4092				for ( i = 0; i < parts.length - 1; i++ ) {
4093					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
4094					curOption = curOption[ parts[ i ] ];
4095				}
4096				key = parts.pop();
4097				if ( value === undefined ) {
4098					return curOption[ key ] === undefined ? null : curOption[ key ];
4099				}
4100				curOption[ key ] = value;
4101			} else {
4102				if ( value === undefined ) {
4103					return this.options[ key ] === undefined ? null : this.options[ key ];
4104				}
4105				options[ key ] = value;
4106			}
4107		}
4108
4109		this._setOptions( options );
4110
4111		return this;
4112	},
4113	_setOptions: function( options ) {
4114		var key;
4115
4116		for ( key in options ) {
4117			this._setOption( key, options[ key ] );
4118		}
4119
4120		return this;
4121	},
4122	_setOption: function( key, value ) {
4123		this.options[ key ] = value;
4124
4125		if ( key === "disabled" ) {
4126			this.widget()
4127				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
4128				.attr( "aria-disabled", value );
4129			this.hoverable.removeClass( "ui-state-hover" );
4130			this.focusable.removeClass( "ui-state-focus" );
4131		}
4132
4133		return this;
4134	},
4135
4136	enable: function() {
4137		return this._setOption( "disabled", false );
4138	},
4139	disable: function() {
4140		return this._setOption( "disabled", true );
4141	},
4142
4143	_on: function( suppressDisabledCheck, element, handlers ) {
4144		var delegateElement,
4145			instance = this;
4146
4147		// no suppressDisabledCheck flag, shuffle arguments
4148		if ( typeof suppressDisabledCheck !== "boolean" ) {
4149			handlers = element;
4150			element = suppressDisabledCheck;
4151			suppressDisabledCheck = false;
4152		}
4153
4154		// no element argument, shuffle and use this.element
4155		if ( !handlers ) {
4156			handlers = element;
4157			element = this.element;
4158			delegateElement = this.widget();
4159		} else {
4160			// accept selectors, DOM elements
4161			element = delegateElement = $( element );
4162			this.bindings = this.bindings.add( element );
4163		}
4164
4165		$.each( handlers, function( event, handler ) {
4166			function handlerProxy() {
4167				// allow widgets to customize the disabled handling
4168				// - disabled as an array instead of boolean
4169				// - disabled class as method for disabling individual parts
4170				if ( !suppressDisabledCheck &&
4171						( instance.options.disabled === true ||
4172							$( this ).hasClass( "ui-state-disabled" ) ) ) {
4173					return;
4174				}
4175				return ( typeof handler === "string" ? instance[ handler ] : handler )
4176					.apply( instance, arguments );
4177			}
4178
4179			// copy the guid so direct unbinding works
4180			if ( typeof handler !== "string" ) {
4181				handlerProxy.guid = handler.guid =
4182					handler.guid || handlerProxy.guid || $.guid++;
4183			}
4184
4185			var match = event.match( /^(\w+)\s*(.*)$/ ),
4186				eventName = match[1] + instance.eventNamespace,
4187				selector = match[2];
4188			if ( selector ) {
4189				delegateElement.delegate( selector, eventName, handlerProxy );
4190			} else {
4191				element.bind( eventName, handlerProxy );
4192			}
4193		});
4194	},
4195
4196	_off: function( element, eventName ) {
4197		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
4198		element.unbind( eventName ).undelegate( eventName );
4199	},
4200
4201	_delay: function( handler, delay ) {
4202		function handlerProxy() {
4203			return ( typeof handler === "string" ? instance[ handler ] : handler )
4204				.apply( instance, arguments );
4205		}
4206		var instance = this;
4207		return setTimeout( handlerProxy, delay || 0 );
4208	},
4209
4210	_hoverable: function( element ) {
4211		this.hoverable = this.hoverable.add( element );
4212		this._on( element, {
4213			mouseenter: function( event ) {
4214				$( event.currentTarget ).addClass( "ui-state-hover" );
4215			},
4216			mouseleave: function( event ) {
4217				$( event.currentTarget ).removeClass( "ui-state-hover" );
4218			}
4219		});
4220	},
4221
4222	_focusable: function( element ) {
4223		this.focusable = this.focusable.add( element );
4224		this._on( element, {
4225			focusin: function( event ) {
4226				$( event.currentTarget ).addClass( "ui-state-focus" );
4227			},
4228			focusout: function( event ) {
4229				$( event.currentTarget ).removeClass( "ui-state-focus" );
4230			}
4231		});
4232	},
4233
4234	_trigger: function( type, event, data ) {
4235		var prop, orig,
4236			callback = this.options[ type ];
4237
4238		data = data || {};
4239		event = $.Event( event );
4240		event.type = ( type === this.widgetEventPrefix ?
4241			type :
4242			this.widgetEventPrefix + type ).toLowerCase();
4243		// the original event may come from any element
4244		// so we need to reset the target on the new event
4245		event.target = this.element[ 0 ];
4246
4247		// copy original event properties over to the new event
4248		orig = event.originalEvent;
4249		if ( orig ) {
4250			for ( prop in orig ) {
4251				if ( !( prop in event ) ) {
4252					event[ prop ] = orig[ prop ];
4253				}
4254			}
4255		}
4256
4257		this.element.trigger( event, data );
4258		return !( $.isFunction( callback ) &&
4259			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
4260			event.isDefaultPrevented() );
4261	}
4262};
4263
4264$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
4265	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
4266		if ( typeof options === "string" ) {
4267			options = { effect: options };
4268		}
4269		var hasOptions,
4270			effectName = !options ?
4271				method :
4272				options === true || typeof options === "number" ?
4273					defaultEffect :
4274					options.effect || defaultEffect;
4275		options = options || {};
4276		if ( typeof options === "number" ) {
4277			options = { duration: options };
4278		}
4279		hasOptions = !$.isEmptyObject( options );
4280		options.complete = callback;
4281		if ( options.delay ) {
4282			element.delay( options.delay );
4283		}
4284		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
4285			element[ method ]( options );
4286		} else if ( effectName !== method && element[ effectName ] ) {
vendor: 54,147 bytes, lines 4287-6017
4287			element[ effectName ]( options.duration, options.easing, callback );
4288		} else {
4289			element.queue(function( next ) {
4290				$( this )[ method ]();
4291				if ( callback ) {
4292					callback.call( element[ 0 ] );
4293				}
4294				next();
4295			});
4296		}
4297	};
4298});
4299
4300})( jQuery );
4301(function( $, undefined ) {
4302
4303var mouseHandled = false;
4304$( document ).mouseup( function() {
4305	mouseHandled = false;
4306});
4307
4308$.widget("ui.mouse", {
4309	version: "1.10.3",
4310	options: {
4311		cancel: "input,textarea,button,select,option",
4312		distance: 1,
4313		delay: 0
4314	},
4315	_mouseInit: function() {
4316		var that = this;
4317
4318		this.element
4319			.bind("mousedown."+this.widgetName, function(event) {
4320				return that._mouseDown(event);
4321			})
4322			.bind("click."+this.widgetName, function(event) {
4323				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
4324					$.removeData(event.target, that.widgetName + ".preventClickEvent");
4325					event.stopImmediatePropagation();
4326					return false;
4327				}
4328			});
4329
4330		this.started = false;
4331	},
4332
4333	// TODO: make sure destroying one instance of mouse doesn't mess with
4334	// other instances of mouse
4335	_mouseDestroy: function() {
4336		this.element.unbind("."+this.widgetName);
4337		if ( this._mouseMoveDelegate ) {
4338			$(document)
4339				.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
4340				.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
4341		}
4342	},
4343
4344	_mouseDown: function(event) {
4345		// don't let more than one widget handle mouseStart
4346		if( mouseHandled ) { return; }
4347
4348		// we may have missed mouseup (out of window)
4349		(this._mouseStarted && this._mouseUp(event));
4350
4351		this._mouseDownEvent = event;
4352
4353		var that = this,
4354			btnIsLeft = (event.which === 1),
4355			// event.target.nodeName works around a bug in IE 8 with
4356			// disabled inputs (#7620)
4357			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
4358		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
4359			return true;
4360		}
4361
4362		this.mouseDelayMet = !this.options.delay;
4363		if (!this.mouseDelayMet) {
4364			this._mouseDelayTimer = setTimeout(function() {
4365				that.mouseDelayMet = true;
4366			}, this.options.delay);
4367		}
4368
4369		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
4370			this._mouseStarted = (this._mouseStart(event) !== false);
4371			if (!this._mouseStarted) {
4372				event.preventDefault();
4373				return true;
4374			}
4375		}
4376
4377		// Click event may never have fired (Gecko & Opera)
4378		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
4379			$.removeData(event.target, this.widgetName + ".preventClickEvent");
4380		}
4381
4382		// these delegates are required to keep context
4383		this._mouseMoveDelegate = function(event) {
4384			return that._mouseMove(event);
4385		};
4386		this._mouseUpDelegate = function(event) {
4387			return that._mouseUp(event);
4388		};
4389		$(document)
4390			.bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
4391			.bind("mouseup."+this.widgetName, this._mouseUpDelegate);
4392
4393		event.preventDefault();
4394
4395		mouseHandled = true;
4396		return true;
4397	},
4398
4399	_mouseMove: function(event) {
4400		// IE mouseup check - mouseup happened when mouse was out of window
4401		if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
4402			return this._mouseUp(event);
4403		}
4404
4405		if (this._mouseStarted) {
4406			this._mouseDrag(event);
4407			return event.preventDefault();
4408		}
4409
4410		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
4411			this._mouseStarted =
4412				(this._mouseStart(this._mouseDownEvent, event) !== false);
4413			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
4414		}
4415
4416		return !this._mouseStarted;
4417	},
4418
4419	_mouseUp: function(event) {
4420		$(document)
4421			.unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
4422			.unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
4423
4424		if (this._mouseStarted) {
4425			this._mouseStarted = false;
4426
4427			if (event.target === this._mouseDownEvent.target) {
4428				$.data(event.target, this.widgetName + ".preventClickEvent", true);
4429			}
4430
4431			this._mouseStop(event);
4432		}
4433
4434		return false;
4435	},
4436
4437	_mouseDistanceMet: function(event) {
4438		return (Math.max(
4439				Math.abs(this._mouseDownEvent.pageX - event.pageX),
4440				Math.abs(this._mouseDownEvent.pageY - event.pageY)
4441			) >= this.options.distance
4442		);
4443	},
4444
4445	_mouseDelayMet: function(/* event */) {
4446		return this.mouseDelayMet;
4447	},
4448
4449	// These are placeholder methods, to be overriden by extending plugin
4450	_mouseStart: function(/* event */) {},
4451	_mouseDrag: function(/* event */) {},
4452	_mouseStop: function(/* event */) {},
4453	_mouseCapture: function(/* event */) { return true; }
4454});
4455
4456})(jQuery);
4457(function( $, undefined ) {
4458
4459$.ui = $.ui || {};
4460
4461var cachedScrollbarWidth,
4462	max = Math.max,
4463	abs = Math.abs,
4464	round = Math.round,
4465	rhorizontal = /left|center|right/,
4466	rvertical = /top|center|bottom/,
4467	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
4468	rposition = /^\w+/,
4469	rpercent = /%$/,
4470	_position = $.fn.position;
4471
4472function getOffsets( offsets, width, height ) {
4473	return [
4474		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
4475		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
4476	];
4477}
4478
4479function parseCss( element, property ) {
4480	return parseInt( $.css( element, property ), 10 ) || 0;
4481}
4482
4483function getDimensions( elem ) {
4484	var raw = elem[0];
4485	if ( raw.nodeType === 9 ) {
4486		return {
4487			width: elem.width(),
4488			height: elem.height(),
4489			offset: { top: 0, left: 0 }
4490		};
4491	}
4492	if ( $.isWindow( raw ) ) {
4493		return {
4494			width: elem.width(),
4495			height: elem.height(),
4496			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
4497		};
4498	}
4499	if ( raw.preventDefault ) {
4500		return {
4501			width: 0,
4502			height: 0,
4503			offset: { top: raw.pageY, left: raw.pageX }
4504		};
4505	}
4506	return {
4507		width: elem.outerWidth(),
4508		height: elem.outerHeight(),
4509		offset: elem.offset()
4510	};
4511}
4512
4513$.position = {
4514	scrollbarWidth: function() {
4515		if ( cachedScrollbarWidth !== undefined ) {
4516			return cachedScrollbarWidth;
4517		}
4518		var w1, w2,
4519			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
4520			innerDiv = div.children()[0];
4521
4522		$( "body" ).append( div );
4523		w1 = innerDiv.offsetWidth;
4524		div.css( "overflow", "scroll" );
4525
4526		w2 = innerDiv.offsetWidth;
4527
4528		if ( w1 === w2 ) {
4529			w2 = div[0].clientWidth;
4530		}
4531
4532		div.remove();
4533
4534		return (cachedScrollbarWidth = w1 - w2);
4535	},
4536	getScrollInfo: function( within ) {
4537		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
4538			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
4539			hasOverflowX = overflowX === "scroll" ||
4540				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
4541			hasOverflowY = overflowY === "scroll" ||
4542				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
4543		return {
4544			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
4545			height: hasOverflowX ? $.position.scrollbarWidth() : 0
4546		};
4547	},
4548	getWithinInfo: function( element ) {
4549		var withinElement = $( element || window ),
4550			isWindow = $.isWindow( withinElement[0] );
4551		return {
4552			element: withinElement,
4553			isWindow: isWindow,
4554			offset: withinElement.offset() || { left: 0, top: 0 },
4555			scrollLeft: withinElement.scrollLeft(),
4556			scrollTop: withinElement.scrollTop(),
4557			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
4558			height: isWindow ? withinElement.height() : withinElement.outerHeight()
4559		};
4560	}
4561};
4562
4563$.fn.position = function( options ) {
4564	if ( !options || !options.of ) {
4565		return _position.apply( this, arguments );
4566	}
4567
4568	// make a copy, we don't want to modify arguments
4569	options = $.extend( {}, options );
4570
4571	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
4572		target = $( options.of ),
4573		within = $.position.getWithinInfo( options.within ),
4574		scrollInfo = $.position.getScrollInfo( within ),
4575		collision = ( options.collision || "flip" ).split( " " ),
4576		offsets = {};
4577
4578	dimensions = getDimensions( target );
4579	if ( target[0].preventDefault ) {
4580		// force left top to allow flipping
4581		options.at = "left top";
4582	}
4583	targetWidth = dimensions.width;
4584	targetHeight = dimensions.height;
4585	targetOffset = dimensions.offset;
4586	// clone to reuse original targetOffset later
4587	basePosition = $.extend( {}, targetOffset );
4588
4589	// force my and at to have valid horizontal and vertical positions
4590	// if a value is missing or invalid, it will be converted to center
4591	$.each( [ "my", "at" ], function() {
4592		var pos = ( options[ this ] || "" ).split( " " ),
4593			horizontalOffset,
4594			verticalOffset;
4595
4596		if ( pos.length === 1) {
4597			pos = rhorizontal.test( pos[ 0 ] ) ?
4598				pos.concat( [ "center" ] ) :
4599				rvertical.test( pos[ 0 ] ) ?
4600					[ "center" ].concat( pos ) :
4601					[ "center", "center" ];
4602		}
4603		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
4604		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
4605
4606		// calculate offsets
4607		horizontalOffset = roffset.exec( pos[ 0 ] );
4608		verticalOffset = roffset.exec( pos[ 1 ] );
4609		offsets[ this ] = [
4610			horizontalOffset ? horizontalOffset[ 0 ] : 0,
4611			verticalOffset ? verticalOffset[ 0 ] : 0
4612		];
4613
4614		// reduce to just the positions without the offsets
4615		options[ this ] = [
4616			rposition.exec( pos[ 0 ] )[ 0 ],
4617			rposition.exec( pos[ 1 ] )[ 0 ]
4618		];
4619	});
4620
4621	// normalize collision option
4622	if ( collision.length === 1 ) {
4623		collision[ 1 ] = collision[ 0 ];
4624	}
4625
4626	if ( options.at[ 0 ] === "right" ) {
4627		basePosition.left += targetWidth;
4628	} else if ( options.at[ 0 ] === "center" ) {
4629		basePosition.left += targetWidth / 2;
4630	}
4631
4632	if ( options.at[ 1 ] === "bottom" ) {
4633		basePosition.top += targetHeight;
4634	} else if ( options.at[ 1 ] === "center" ) {
4635		basePosition.top += targetHeight / 2;
4636	}
4637
4638	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
4639	basePosition.left += atOffset[ 0 ];
4640	basePosition.top += atOffset[ 1 ];
4641
4642	return this.each(function() {
4643		var collisionPosition, using,
4644			elem = $( this ),
4645			elemWidth = elem.outerWidth(),
4646			elemHeight = elem.outerHeight(),
4647			marginLeft = parseCss( this, "marginLeft" ),
4648			marginTop = parseCss( this, "marginTop" ),
4649			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
4650			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
4651			position = $.extend( {}, basePosition ),
4652			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
4653
4654		if ( options.my[ 0 ] === "right" ) {
4655			position.left -= elemWidth;
4656		} else if ( options.my[ 0 ] === "center" ) {
4657			position.left -= elemWidth / 2;
4658		}
4659
4660		if ( options.my[ 1 ] === "bottom" ) {
4661			position.top -= elemHeight;
4662		} else if ( options.my[ 1 ] === "center" ) {
4663			position.top -= elemHeight / 2;
4664		}
4665
4666		position.left += myOffset[ 0 ];
4667		position.top += myOffset[ 1 ];
4668
4669		// if the browser doesn't support fractions, then round for consistent results
4670		if ( !$.support.offsetFractions ) {
4671			position.left = round( position.left );
4672			position.top = round( position.top );
4673		}
4674
4675		collisionPosition = {
4676			marginLeft: marginLeft,
4677			marginTop: marginTop
4678		};
4679
4680		$.each( [ "left", "top" ], function( i, dir ) {
4681			if ( $.ui.position[ collision[ i ] ] ) {
4682				$.ui.position[ collision[ i ] ][ dir ]( position, {
4683					targetWidth: targetWidth,
4684					targetHeight: targetHeight,
4685					elemWidth: elemWidth,
4686					elemHeight: elemHeight,
4687					collisionPosition: collisionPosition,
4688					collisionWidth: collisionWidth,
4689					collisionHeight: collisionHeight,
4690					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
4691					my: options.my,
4692					at: options.at,
4693					within: within,
4694					elem : elem
4695				});
4696			}
4697		});
4698
4699		if ( options.using ) {
4700			// adds feedback as second argument to using callback, if present
4701			using = function( props ) {
4702				var left = targetOffset.left - position.left,
4703					right = left + targetWidth - elemWidth,
4704					top = targetOffset.top - position.top,
4705					bottom = top + targetHeight - elemHeight,
4706					feedback = {
4707						target: {
4708							element: target,
4709							left: targetOffset.left,
4710							top: targetOffset.top,
4711							width: targetWidth,
4712							height: targetHeight
4713						},
4714						element: {
4715							element: elem,
4716							left: position.left,
4717							top: position.top,
4718							width: elemWidth,
4719							height: elemHeight
4720						},
4721						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
4722						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
4723					};
4724				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
4725					feedback.horizontal = "center";
4726				}
4727				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
4728					feedback.vertical = "middle";
4729				}
4730				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
4731					feedback.important = "horizontal";
4732				} else {
4733					feedback.important = "vertical";
4734				}
4735				options.using.call( this, props, feedback );
4736			};
4737		}
4738
4739		elem.offset( $.extend( position, { using: using } ) );
4740	});
4741};
4742
4743$.ui.position = {
4744	fit: {
4745		left: function( position, data ) {
4746			var within = data.within,
4747				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
4748				outerWidth = within.width,
4749				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
4750				overLeft = withinOffset - collisionPosLeft,
4751				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
4752				newOverRight;
4753
4754			// element is wider than within
4755			if ( data.collisionWidth > outerWidth ) {
4756				// element is initially over the left side of within
4757				if ( overLeft > 0 && overRight <= 0 ) {
4758					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
4759					position.left += overLeft - newOverRight;
4760				// element is initially over right side of within
4761				} else if ( overRight > 0 && overLeft <= 0 ) {
4762					position.left = withinOffset;
4763				// element is initially over both left and right sides of within
4764				} else {
4765					if ( overLeft > overRight ) {
4766						position.left = withinOffset + outerWidth - data.collisionWidth;
4767					} else {
4768						position.left = withinOffset;
4769					}
4770				}
4771			// too far left -> align with left edge
4772			} else if ( overLeft > 0 ) {
4773				position.left += overLeft;
4774			// too far right -> align with right edge
4775			} else if ( overRight > 0 ) {
4776				position.left -= overRight;
4777			// adjust based on position and margin
4778			} else {
4779				position.left = max( position.left - collisionPosLeft, position.left );
4780			}
4781		},
4782		top: function( position, data ) {
4783			var within = data.within,
4784				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
4785				outerHeight = data.within.height,
4786				collisionPosTop = position.top - data.collisionPosition.marginTop,
4787				overTop = withinOffset - collisionPosTop,
4788				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
4789				newOverBottom;
4790
4791			// element is taller than within
4792			if ( data.collisionHeight > outerHeight ) {
4793				// element is initially over the top of within
4794				if ( overTop > 0 && overBottom <= 0 ) {
4795					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
4796					position.top += overTop - newOverBottom;
4797				// element is initially over bottom of within
4798				} else if ( overBottom > 0 && overTop <= 0 ) {
4799					position.top = withinOffset;
4800				// element is initially over both top and bottom of within
4801				} else {
4802					if ( overTop > overBottom ) {
4803						position.top = withinOffset + outerHeight - data.collisionHeight;
4804					} else {
4805						position.top = withinOffset;
4806					}
4807				}
4808			// too far up -> align with top
4809			} else if ( overTop > 0 ) {
4810				position.top += overTop;
4811			// too far down -> align with bottom edge
4812			} else if ( overBottom > 0 ) {
4813				position.top -= overBottom;
4814			// adjust based on position and margin
4815			} else {
4816				position.top = max( position.top - collisionPosTop, position.top );
4817			}
4818		}
4819	},
4820	flip: {
4821		left: function( position, data ) {
4822			var within = data.within,
4823				withinOffset = within.offset.left + within.scrollLeft,
4824				outerWidth = within.width,
4825				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
4826				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
4827				overLeft = collisionPosLeft - offsetLeft,
4828				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
4829				myOffset = data.my[ 0 ] === "left" ?
4830					-data.elemWidth :
4831					data.my[ 0 ] === "right" ?
4832						data.elemWidth :
4833						0,
4834				atOffset = data.at[ 0 ] === "left" ?
4835					data.targetWidth :
4836					data.at[ 0 ] === "right" ?
4837						-data.targetWidth :
4838						0,
4839				offset = -2 * data.offset[ 0 ],
4840				newOverRight,
4841				newOverLeft;
4842
4843			if ( overLeft < 0 ) {
4844				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
4845				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
4846					position.left += myOffset + atOffset + offset;
4847				}
4848			}
4849			else if ( overRight > 0 ) {
4850				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
4851				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
4852					position.left += myOffset + atOffset + offset;
4853				}
4854			}
4855		},
4856		top: function( position, data ) {
4857			var within = data.within,
4858				withinOffset = within.offset.top + within.scrollTop,
4859				outerHeight = within.height,
4860				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
4861				collisionPosTop = position.top - data.collisionPosition.marginTop,
4862				overTop = collisionPosTop - offsetTop,
4863				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
4864				top = data.my[ 1 ] === "top",
4865				myOffset = top ?
4866					-data.elemHeight :
4867					data.my[ 1 ] === "bottom" ?
4868						data.elemHeight :
4869						0,
4870				atOffset = data.at[ 1 ] === "top" ?
4871					data.targetHeight :
4872					data.at[ 1 ] === "bottom" ?
4873						-data.targetHeight :
4874						0,
4875				offset = -2 * data.offset[ 1 ],
4876				newOverTop,
4877				newOverBottom;
4878			if ( overTop < 0 ) {
4879				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
4880				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
4881					position.top += myOffset + atOffset + offset;
4882				}
4883			}
4884			else if ( overBottom > 0 ) {
4885				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
4886				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
4887					position.top += myOffset + atOffset + offset;
4888				}
4889			}
4890		}
4891	},
4892	flipfit: {
4893		left: function() {
4894			$.ui.position.flip.left.apply( this, arguments );
4895			$.ui.position.fit.left.apply( this, arguments );
4896		},
4897		top: function() {
4898			$.ui.position.flip.top.apply( this, arguments );
4899			$.ui.position.fit.top.apply( this, arguments );
4900		}
4901	}
4902};
4903
4904// fraction support test
4905(function () {
4906	var testElement, testElementParent, testElementStyle, offsetLeft, i,
4907		body = document.getElementsByTagName( "body" )[ 0 ],
4908		div = document.createElement( "div" );
4909
4910	//Create a "fake body" for testing based on method used in jQuery.support
4911	testElement = document.createElement( body ? "div" : "body" );
4912	testElementStyle = {
4913		visibility: "hidden",
4914		width: 0,
4915		height: 0,
4916		border: 0,
4917		margin: 0,
4918		background: "none"
4919	};
4920	if ( body ) {
4921		$.extend( testElementStyle, {
4922			position: "absolute",
4923			left: "-1000px",
4924			top: "-1000px"
4925		});
4926	}
4927	for ( i in testElementStyle ) {
4928		testElement.style[ i ] = testElementStyle[ i ];
4929	}
4930	testElement.appendChild( div );
4931	testElementParent = body || document.documentElement;
4932	testElementParent.insertBefore( testElement, testElementParent.firstChild );
4933
4934	div.style.cssText = "position: absolute; left: 10.7432222px;";
4935
4936	offsetLeft = $( div ).offset().left;
4937	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
4938
4939	testElement.innerHTML = "";
4940	testElementParent.removeChild( testElement );
4941})();
4942
4943}( jQuery ) );
4944(function( $, undefined ) {
4945
4946$.widget("ui.draggable", $.ui.mouse, {
4947	version: "1.10.3",
4948	widgetEventPrefix: "drag",
4949	options: {
4950		addClasses: true,
4951		appendTo: "parent",
4952		axis: false,
4953		connectToSortable: false,
4954		containment: false,
4955		cursor: "auto",
4956		cursorAt: false,
4957		grid: false,
4958		handle: false,
4959		helper: "original",
4960		iframeFix: false,
4961		opacity: false,
4962		refreshPositions: false,
4963		revert: false,
4964		revertDuration: 500,
4965		scope: "default",
4966		scroll: true,
4967		scrollSensitivity: 20,
4968		scrollSpeed: 20,
4969		snap: false,
4970		snapMode: "both",
4971		snapTolerance: 20,
4972		stack: false,
4973		zIndex: false,
4974
4975		// callbacks
4976		drag: null,
4977		start: null,
4978		stop: null
4979	},
4980	_create: function() {
4981
4982		if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
4983			this.element[0].style.position = "relative";
4984		}
4985		if (this.options.addClasses){
4986			this.element.addClass("ui-draggable");
4987		}
4988		if (this.options.disabled){
4989			this.element.addClass("ui-draggable-disabled");
4990		}
4991
4992		this._mouseInit();
4993
4994	},
4995
4996	_destroy: function() {
4997		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
4998		this._mouseDestroy();
4999	},
5000
5001	_mouseCapture: function(event) {
5002
5003		var o = this.options;
5004
5005		// among others, prevent a drag on a resizable-handle
5006		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
5007			return false;
5008		}
5009
5010		//Quit if we're not on a valid handle
5011		this.handle = this._getHandle(event);
5012		if (!this.handle) {
5013			return false;
5014		}
5015
5016		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
5017			$("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
5018			.css({
5019				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
5020				position: "absolute", opacity: "0.001", zIndex: 1000
5021			})
5022			.css($(this).offset())
5023			.appendTo("body");
5024		});
5025
5026		return true;
5027
5028	},
5029
5030	_mouseStart: function(event) {
5031
5032		var o = this.options;
5033
5034		//Create and append the visible helper
5035		this.helper = this._createHelper(event);
5036
5037		this.helper.addClass("ui-draggable-dragging");
5038
5039		//Cache the helper size
5040		this._cacheHelperProportions();
5041
5042		//If ddmanager is used for droppables, set the global draggable
5043		if($.ui.ddmanager) {
5044			$.ui.ddmanager.current = this;
5045		}
5046
5047		/*
5048		 * - Position generation -
5049		 * This block generates everything position related - it's the core of draggables.
5050		 */
5051
5052		//Cache the margins of the original element
5053		this._cacheMargins();
5054
5055		//Store the helper's css position
5056		this.cssPosition = this.helper.css( "position" );
5057		this.scrollParent = this.helper.scrollParent();
5058		this.offsetParent = this.helper.offsetParent();
5059		this.offsetParentCssPosition = this.offsetParent.css( "position" );
5060
5061		//The element's absolute position on the page minus margins
5062		this.offset = this.positionAbs = this.element.offset();
5063		this.offset = {
5064			top: this.offset.top - this.margins.top,
5065			left: this.offset.left - this.margins.left
5066		};
5067
5068		//Reset scroll cache
5069		this.offset.scroll = false;
5070
5071		$.extend(this.offset, {
5072			click: { //Where the click happened, relative to the element
5073				left: event.pageX - this.offset.left,
5074				top: event.pageY - this.offset.top
5075			},
5076			parent: this._getParentOffset(),
5077			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
5078		});
5079
5080		//Generate the original position
5081		this.originalPosition = this.position = this._generatePosition(event);
5082		this.originalPageX = event.pageX;
5083		this.originalPageY = event.pageY;
5084
5085		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
5086		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
5087
5088		//Set a containment if given in the options
5089		this._setContainment();
5090
5091		//Trigger event + callbacks
5092		if(this._trigger("start", event) === false) {
5093			this._clear();
5094			return false;
5095		}
5096
5097		//Recache the helper size
5098		this._cacheHelperProportions();
5099
5100		//Prepare the droppable offsets
5101		if ($.ui.ddmanager && !o.dropBehaviour) {
5102			$.ui.ddmanager.prepareOffsets(this, event);
5103		}
5104
5105
5106		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
5107
5108		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
5109		if ( $.ui.ddmanager ) {
5110			$.ui.ddmanager.dragStart(this, event);
5111		}
5112
5113		return true;
5114	},
5115
5116	_mouseDrag: function(event, noPropagation) {
5117		// reset any necessary cached properties (see #5009)
5118		if ( this.offsetParentCssPosition === "fixed" ) {
5119			this.offset.parent = this._getParentOffset();
5120		}
5121
5122		//Compute the helpers position
5123		this.position = this._generatePosition(event);
5124		this.positionAbs = this._convertPositionTo("absolute");
5125
5126		//Call plugins and callbacks and use the resulting position if something is returned
5127		if (!noPropagation) {
5128			var ui = this._uiHash();
5129			if(this._trigger("drag", event, ui) === false) {
5130				this._mouseUp({});
5131				return false;
5132			}
5133			this.position = ui.position;
5134		}
5135
5136		if(!this.options.axis || this.options.axis !== "y") {
5137			this.helper[0].style.left = this.position.left+"px";
5138		}
5139		if(!this.options.axis || this.options.axis !== "x") {
5140			this.helper[0].style.top = this.position.top+"px";
5141		}
5142		if($.ui.ddmanager) {
5143			$.ui.ddmanager.drag(this, event);
5144		}
5145
5146		return false;
5147	},
5148
5149	_mouseStop: function(event) {
5150
5151		//If we are using droppables, inform the manager about the drop
5152		var that = this,
5153			dropped = false;
5154		if ($.ui.ddmanager && !this.options.dropBehaviour) {
5155			dropped = $.ui.ddmanager.drop(this, event);
5156		}
5157
5158		//if a drop comes from outside (a sortable)
5159		if(this.dropped) {
5160			dropped = this.dropped;
5161			this.dropped = false;
5162		}
5163
5164		//if the original element is no longer in the DOM don't bother to continue (see #8269)
5165		if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
5166			return false;
5167		}
5168
5169		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))) {
5170			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
5171				if(that._trigger("stop", event) !== false) {
5172					that._clear();
5173				}
5174			});
5175		} else {
5176			if(this._trigger("stop", event) !== false) {
5177				this._clear();
5178			}
5179		}
5180
5181		return false;
5182	},
5183
5184	_mouseUp: function(event) {
5185		//Remove frame helpers
5186		$("div.ui-draggable-iframeFix").each(function() {
5187			this.parentNode.removeChild(this);
5188		});
5189
5190		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
5191		if( $.ui.ddmanager ) {
5192			$.ui.ddmanager.dragStop(this, event);
5193		}
5194
5195		return $.ui.mouse.prototype._mouseUp.call(this, event);
5196	},
5197
5198	cancel: function() {
5199
5200		if(this.helper.is(".ui-draggable-dragging")) {
5201			this._mouseUp({});
5202		} else {
5203			this._clear();
5204		}
5205
5206		return this;
5207
5208	},
5209
5210	_getHandle: function(event) {
5211		return this.options.handle ?
5212			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
5213			true;
5214	},
5215
5216	_createHelper: function(event) {
5217
5218		var o = this.options,
5219			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
5220
5221		if(!helper.parents("body").length) {
5222			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
5223		}
5224
5225		if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
5226			helper.css("position", "absolute");
5227		}
5228
5229		return helper;
5230
5231	},
5232
5233	_adjustOffsetFromHelper: function(obj) {
5234		if (typeof obj === "string") {
5235			obj = obj.split(" ");
5236		}
5237		if ($.isArray(obj)) {
5238			obj = {left: +obj[0], top: +obj[1] || 0};
5239		}
5240		if ("left" in obj) {
5241			this.offset.click.left = obj.left + this.margins.left;
5242		}
5243		if ("right" in obj) {
5244			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5245		}
5246		if ("top" in obj) {
5247			this.offset.click.top = obj.top + this.margins.top;
5248		}
5249		if ("bottom" in obj) {
5250			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5251		}
5252	},
5253
5254	_getParentOffset: function() {
5255
5256		//Get the offsetParent and cache its position
5257		var po = this.offsetParent.offset();
5258
5259		// This is a special case where we need to modify a offset calculated on start, since the following happened:
5260		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
5261		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
5262		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
5263		if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
5264			po.left += this.scrollParent.scrollLeft();
5265			po.top += this.scrollParent.scrollTop();
5266		}
5267
5268		//This needs to be actually done for all browsers, since pageX/pageY includes this information
5269		//Ugly IE fix
5270		if((this.offsetParent[0] === document.body) ||
5271			(this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
5272			po = { top: 0, left: 0 };
5273		}
5274
5275		return {
5276			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
5277			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
5278		};
5279
5280	},
5281
5282	_getRelativeOffset: function() {
5283
5284		if(this.cssPosition === "relative") {
5285			var p = this.element.position();
5286			return {
5287				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
5288				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
5289			};
5290		} else {
5291			return { top: 0, left: 0 };
5292		}
5293
5294	},
5295
5296	_cacheMargins: function() {
5297		this.margins = {
5298			left: (parseInt(this.element.css("marginLeft"),10) || 0),
5299			top: (parseInt(this.element.css("marginTop"),10) || 0),
5300			right: (parseInt(this.element.css("marginRight"),10) || 0),
5301			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
5302		};
5303	},
5304
5305	_cacheHelperProportions: function() {
5306		this.helperProportions = {
5307			width: this.helper.outerWidth(),
5308			height: this.helper.outerHeight()
5309		};
5310	},
5311
5312	_setContainment: function() {
5313
5314		var over, c, ce,
5315			o = this.options;
5316
5317		if ( !o.containment ) {
5318			this.containment = null;
5319			return;
5320		}
5321
5322		if ( o.containment === "window" ) {
5323			this.containment = [
5324				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
5325				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
5326				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
5327				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
5328			];
5329			return;
5330		}
5331
5332		if ( o.containment === "document") {
5333			this.containment = [
5334				0,
5335				0,
5336				$( document ).width() - this.helperProportions.width - this.margins.left,
5337				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
5338			];
5339			return;
5340		}
5341
5342		if ( o.containment.constructor === Array ) {
5343			this.containment = o.containment;
5344			return;
5345		}
5346
5347		if ( o.containment === "parent" ) {
5348			o.containment = this.helper[ 0 ].parentNode;
5349		}
5350
5351		c = $( o.containment );
5352		ce = c[ 0 ];
5353
5354		if( !ce ) {
5355			return;
5356		}
5357
5358		over = c.css( "overflow" ) !== "hidden";
5359
5360		this.containment = [
5361			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
5362			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
5363			( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
5364			( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom
5365		];
5366		this.relative_container = c;
5367	},
5368
5369	_convertPositionTo: function(d, pos) {
5370
5371		if(!pos) {
5372			pos = this.position;
5373		}
5374
5375		var mod = d === "absolute" ? 1 : -1,
5376			scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
5377
5378		//Cache the scroll
5379		if (!this.offset.scroll) {
5380			this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
5381		}
5382
5383		return {
5384			top: (
5385				pos.top	+																// The absolute mouse position
5386				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
5387				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
5388				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
5389			),
5390			left: (
5391				pos.left +																// The absolute mouse position
5392				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
5393				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
5394				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
5395			)
5396		};
5397
5398	},
5399
5400	_generatePosition: function(event) {
5401
5402		var containment, co, top, left,
5403			o = this.options,
5404			scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
5405			pageX = event.pageX,
5406			pageY = event.pageY;
5407
5408		//Cache the scroll
5409		if (!this.offset.scroll) {
5410			this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
5411		}
5412
5413		/*
5414		 * - Position constraining -
5415		 * Constrain the position to a mix of grid, containment.
5416		 */
5417
5418		// If we are not dragging yet, we won't check for options
5419		if ( this.originalPosition ) {
5420			if ( this.containment ) {
5421				if ( this.relative_container ){
5422					co = this.relative_container.offset();
5423					containment = [
5424						this.containment[ 0 ] + co.left,
5425						this.containment[ 1 ] + co.top,
5426						this.containment[ 2 ] + co.left,
5427						this.containment[ 3 ] + co.top
5428					];
5429				}
5430				else {
5431					containment = this.containment;
5432				}
5433
5434				if(event.pageX - this.offset.click.left < containment[0]) {
5435					pageX = containment[0] + this.offset.click.left;
5436				}
5437				if(event.pageY - this.offset.click.top < containment[1]) {
5438					pageY = containment[1] + this.offset.click.top;
5439				}
5440				if(event.pageX - this.offset.click.left > containment[2]) {
5441					pageX = containment[2] + this.offset.click.left;
5442				}
5443				if(event.pageY - this.offset.click.top > containment[3]) {
5444					pageY = containment[3] + this.offset.click.top;
5445				}
5446			}
5447
5448			if(o.grid) {
5449				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
5450				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
5451				pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
5452
5453				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
5454				pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
5455			}
5456
5457		}
5458
5459		return {
5460			top: (
5461				pageY -																	// The absolute mouse position
5462				this.offset.click.top	-												// Click offset (relative to the element)
5463				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
5464				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
5465				( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
5466			),
5467			left: (
5468				pageX -																	// The absolute mouse position
5469				this.offset.click.left -												// Click offset (relative to the element)
5470				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
5471				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
5472				( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
5473			)
5474		};
5475
5476	},
5477
5478	_clear: function() {
5479		this.helper.removeClass("ui-draggable-dragging");
5480		if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
5481			this.helper.remove();
5482		}
5483		this.helper = null;
5484		this.cancelHelperRemoval = false;
5485	},
5486
5487	// From now on bulk stuff - mainly helpers
5488
5489	_trigger: function(type, event, ui) {
5490		ui = ui || this._uiHash();
5491		$.ui.plugin.call(this, type, [event, ui]);
5492		//The absolute position has to be recalculated after plugins
5493		if(type === "drag") {
5494			this.positionAbs = this._convertPositionTo("absolute");
5495		}
5496		return $.Widget.prototype._trigger.call(this, type, event, ui);
5497	},
5498
5499	plugins: {},
5500
5501	_uiHash: function() {
5502		return {
5503			helper: this.helper,
5504			position: this.position,
5505			originalPosition: this.originalPosition,
5506			offset: this.positionAbs
5507		};
5508	}
5509
5510});
5511
5512$.ui.plugin.add("draggable", "connectToSortable", {
5513	start: function(event, ui) {
5514
5515		var inst = $(this).data("ui-draggable"), o = inst.options,
5516			uiSortable = $.extend({}, ui, { item: inst.element });
5517		inst.sortables = [];
5518		$(o.connectToSortable).each(function() {
5519			var sortable = $.data(this, "ui-sortable");
5520			if (sortable && !sortable.options.disabled) {
5521				inst.sortables.push({
5522					instance: sortable,
5523					shouldRevert: sortable.options.revert
5524				});
5525				sortable.refreshPositions();	// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
5526				sortable._trigger("activate", event, uiSortable);
5527			}
5528		});
5529
5530	},
5531	stop: function(event, ui) {
5532
5533		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
5534		var inst = $(this).data("ui-draggable"),
5535			uiSortable = $.extend({}, ui, { item: inst.element });
5536
5537		$.each(inst.sortables, function() {
5538			if(this.instance.isOver) {
5539
5540				this.instance.isOver = 0;
5541
5542				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
5543				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
5544
5545				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
5546				if(this.shouldRevert) {
5547					this.instance.options.revert = this.shouldRevert;
5548				}
5549
5550				//Trigger the stop of the sortable
5551				this.instance._mouseStop(event);
5552
5553				this.instance.options.helper = this.instance.options._helper;
5554
5555				//If the helper has been the original item, restore properties in the sortable
5556				if(inst.options.helper === "original") {
5557					this.instance.currentItem.css({ top: "auto", left: "auto" });
5558				}
5559
5560			} else {
5561				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
5562				this.instance._trigger("deactivate", event, uiSortable);
5563			}
5564
5565		});
5566
5567	},
5568	drag: function(event, ui) {
5569
5570		var inst = $(this).data("ui-draggable"), that = this;
5571
5572		$.each(inst.sortables, function() {
5573
5574			var innermostIntersecting = false,
5575				thisSortable = this;
5576
5577			//Copy over some variables to allow calling the sortable's native _intersectsWith
5578			this.instance.positionAbs = inst.positionAbs;
5579			this.instance.helperProportions = inst.helperProportions;
5580			this.instance.offset.click = inst.offset.click;
5581
5582			if(this.instance._intersectsWith(this.instance.containerCache)) {
5583				innermostIntersecting = true;
5584				$.each(inst.sortables, function () {
5585					this.instance.positionAbs = inst.positionAbs;
5586					this.instance.helperProportions = inst.helperProportions;
5587					this.instance.offset.click = inst.offset.click;
5588					if (this !== thisSortable &&
5589						this.instance._intersectsWith(this.instance.containerCache) &&
5590						$.contains(thisSortable.instance.element[0], this.instance.element[0])
5591					) {
5592						innermostIntersecting = false;
5593					}
5594					return innermostIntersecting;
5595				});
5596			}
5597
5598
5599			if(innermostIntersecting) {
5600				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
5601				if(!this.instance.isOver) {
5602
5603					this.instance.isOver = 1;
5604					//Now we fake the start of dragging for the sortable instance,
5605					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
5606					//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)
5607					this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
5608					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
5609					this.instance.options.helper = function() { return ui.helper[0]; };
5610
5611					event.target = this.instance.currentItem[0];
5612					this.instance._mouseCapture(event, true);
5613					this.instance._mouseStart(event, true, true);
5614
5615					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
5616					this.instance.offset.click.top = inst.offset.click.top;
5617					this.instance.offset.click.left = inst.offset.click.left;
5618					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
5619					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
5620
5621					inst._trigger("toSortable", event);
5622					inst.dropped = this.instance.element; //draggable revert needs that
5623					//hack so receive/update callbacks work (mostly)
5624					inst.currentItem = inst.element;
5625					this.instance.fromOutside = inst;
5626
5627				}
5628
5629				//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
5630				if(this.instance.currentItem) {
5631					this.instance._mouseDrag(event);
5632				}
5633
5634			} else {
5635
5636				//If it doesn't intersect with the sortable, and it intersected before,
5637				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
5638				if(this.instance.isOver) {
5639
5640					this.instance.isOver = 0;
5641					this.instance.cancelHelperRemoval = true;
5642
5643					//Prevent reverting on this forced stop
5644					this.instance.options.revert = false;
5645
5646					// The out event needs to be triggered independently
5647					this.instance._trigger("out", event, this.instance._uiHash(this.instance));
5648
5649					this.instance._mouseStop(event, true);
5650					this.instance.options.helper = this.instance.options._helper;
5651
5652					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
5653					this.instance.currentItem.remove();
5654					if(this.instance.placeholder) {
5655						this.instance.placeholder.remove();
5656					}
5657
5658					inst._trigger("fromSortable", event);
5659					inst.dropped = false; //draggable revert needs that
5660				}
5661
5662			}
5663
5664		});
5665
5666	}
5667});
5668
5669$.ui.plugin.add("draggable", "cursor", {
5670	start: function() {
5671		var t = $("body"), o = $(this).data("ui-draggable").options;
5672		if (t.css("cursor")) {
5673			o._cursor = t.css("cursor");
5674		}
5675		t.css("cursor", o.cursor);
5676	},
5677	stop: function() {
5678		var o = $(this).data("ui-draggable").options;
5679		if (o._cursor) {
5680			$("body").css("cursor", o._cursor);
5681		}
5682	}
5683});
5684
5685$.ui.plugin.add("draggable", "opacity", {
5686	start: function(event, ui) {
5687		var t = $(ui.helper), o = $(this).data("ui-draggable").options;
5688		if(t.css("opacity")) {
5689			o._opacity = t.css("opacity");
5690		}
5691		t.css("opacity", o.opacity);
5692	},
5693	stop: function(event, ui) {
5694		var o = $(this).data("ui-draggable").options;
5695		if(o._opacity) {
5696			$(ui.helper).css("opacity", o._opacity);
5697		}
5698	}
5699});
5700
5701$.ui.plugin.add("draggable", "scroll", {
5702	start: function() {
5703		var i = $(this).data("ui-draggable");
5704		if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
5705			i.overflowOffset = i.scrollParent.offset();
5706		}
5707	},
5708	drag: function( event ) {
5709
5710		var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
5711
5712		if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
5713
5714			if(!o.axis || o.axis !== "x") {
5715				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
5716					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
5717				} else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
5718					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
5719				}
5720			}
5721
5722			if(!o.axis || o.axis !== "y") {
5723				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
5724					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
5725				} else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
5726					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
5727				}
5728			}
5729
5730		} else {
5731
5732			if(!o.axis || o.axis !== "x") {
5733				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
5734					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
5735				} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
5736					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
5737				}
5738			}
5739
5740			if(!o.axis || o.axis !== "y") {
5741				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
5742					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
5743				} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
5744					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
5745				}
5746			}
5747
5748		}
5749
5750		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
5751			$.ui.ddmanager.prepareOffsets(i, event);
5752		}
5753
5754	}
5755});
5756
5757$.ui.plugin.add("draggable", "snap", {
5758	start: function() {
5759
5760		var i = $(this).data("ui-draggable"),
5761			o = i.options;
5762
5763		i.snapElements = [];
5764
5765		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
5766			var $t = $(this),
5767				$o = $t.offset();
5768			if(this !== i.element[0]) {
5769				i.snapElements.push({
5770					item: this,
5771					width: $t.outerWidth(), height: $t.outerHeight(),
5772					top: $o.top, left: $o.left
5773				});
5774			}
5775		});
5776
5777	},
5778	drag: function(event, ui) {
5779
5780		var ts, bs, ls, rs, l, r, t, b, i, first,
5781			inst = $(this).data("ui-draggable"),
5782			o = inst.options,
5783			d = o.snapTolerance,
5784			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
5785			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
5786
5787		for (i = inst.snapElements.length - 1; i >= 0; i--){
5788
5789			l = inst.snapElements[i].left;
5790			r = l + inst.snapElements[i].width;
5791			t = inst.snapElements[i].top;
5792			b = t + inst.snapElements[i].height;
5793
5794			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
5795				if(inst.snapElements[i].snapping) {
5796					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
5797				}
5798				inst.snapElements[i].snapping = false;
5799				continue;
5800			}
5801
5802			if(o.snapMode !== "inner") {
5803				ts = Math.abs(t - y2) <= d;
5804				bs = Math.abs(b - y1) <= d;
5805				ls = Math.abs(l - x2) <= d;
5806				rs = Math.abs(r - x1) <= d;
5807				if(ts) {
5808					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
5809				}
5810				if(bs) {
5811					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
5812				}
5813				if(ls) {
5814					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
5815				}
5816				if(rs) {
5817					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
5818				}
5819			}
5820
5821			first = (ts || bs || ls || rs);
5822
5823			if(o.snapMode !== "outer") {
5824				ts = Math.abs(t - y1) <= d;
5825				bs = Math.abs(b - y2) <= d;
5826				ls = Math.abs(l - x1) <= d;
5827				rs = Math.abs(r - x2) <= d;
5828				if(ts) {
5829					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
5830				}
5831				if(bs) {
5832					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
5833				}
5834				if(ls) {
5835					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
5836				}
5837				if(rs) {
5838					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
5839				}
5840			}
5841
5842			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
5843				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
5844			}
5845			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
5846
5847		}
5848
5849	}
5850});
5851
5852$.ui.plugin.add("draggable", "stack", {
5853	start: function() {
5854		var min,
5855			o = this.data("ui-draggable").options,
5856			group = $.makeArray($(o.stack)).sort(function(a,b) {
5857				return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
5858			});
5859
5860		if (!group.length) { return; }
5861
5862		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
5863		$(group).each(function(i) {
5864			$(this).css("zIndex", min + i);
5865		});
5866		this.css("zIndex", (min + group.length));
5867	}
5868});
5869
5870$.ui.plugin.add("draggable", "zIndex", {
5871	start: function(event, ui) {
5872		var t = $(ui.helper), o = $(this).data("ui-draggable").options;
5873		if(t.css("zIndex")) {
5874			o._zIndex = t.css("zIndex");
5875		}
5876		t.css("zIndex", o.zIndex);
5877	},
5878	stop: function(event, ui) {
5879		var o = $(this).data("ui-draggable").options;
5880		if(o._zIndex) {
5881			$(ui.helper).css("zIndex", o._zIndex);
5882		}
5883	}
5884});
5885
5886})(jQuery);
5887(function( $, undefined ) {
5888
5889function isOverAxis( x, reference, size ) {
5890	return ( x > reference ) && ( x < ( reference + size ) );
5891}
5892
5893$.widget("ui.droppable", {
5894	version: "1.10.3",
5895	widgetEventPrefix: "drop",
5896	options: {
5897		accept: "*",
5898		activeClass: false,
5899		addClasses: true,
5900		greedy: false,
5901		hoverClass: false,
5902		scope: "default",
5903		tolerance: "intersect",
5904
5905		// callbacks
5906		activate: null,
5907		deactivate: null,
5908		drop: null,
5909		out: null,
5910		over: null
5911	},
5912	_create: function() {
5913
5914		var o = this.options,
5915			accept = o.accept;
5916
5917		this.isover = false;
5918		this.isout = true;
5919
5920		this.accept = $.isFunction(accept) ? accept : function(d) {
5921			return d.is(accept);
5922		};
5923
5924		//Store the droppable's proportions
5925		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
5926
5927		// Add the reference and positions to the manager
5928		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
5929		$.ui.ddmanager.droppables[o.scope].push(this);
5930
5931		(o.addClasses && this.element.addClass("ui-droppable"));
5932
5933	},
5934
5935	_destroy: function() {
5936		var i = 0,
5937			drop = $.ui.ddmanager.droppables[this.options.scope];
5938
5939		for ( ; i < drop.length; i++ ) {
5940			if ( drop[i] === this ) {
5941				drop.splice(i, 1);
5942			}
5943		}
5944
5945		this.element.removeClass("ui-droppable ui-droppable-disabled");
5946	},
5947
5948	_setOption: function(key, value) {
5949
5950		if(key === "accept") {
5951			this.accept = $.isFunction(value) ? value : function(d) {
5952				return d.is(value);
5953			};
5954		}
5955		$.Widget.prototype._setOption.apply(this, arguments);
5956	},
5957
5958	_activate: function(event) {
5959		var draggable = $.ui.ddmanager.current;
5960		if(this.options.activeClass) {
5961			this.element.addClass(this.options.activeClass);
5962		}
5963		if(draggable){
5964			this._trigger("activate", event, this.ui(draggable));
5965		}
5966	},
5967
5968	_deactivate: function(event) {
5969		var draggable = $.ui.ddmanager.current;
5970		if(this.options.activeClass) {
5971			this.element.removeClass(this.options.activeClass);
5972		}
5973		if(draggable){
5974			this._trigger("deactivate", event, this.ui(draggable));
5975		}
5976	},
5977
5978	_over: function(event) {
5979
5980		var draggable = $.ui.ddmanager.current;
5981
5982		// Bail if draggable and droppable are same element
5983		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
5984			return;
5985		}
5986
5987		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
5988			if(this.options.hoverClass) {
5989				this.element.addClass(this.options.hoverClass);
5990			}
5991			this._trigger("over", event, this.ui(draggable));
5992		}
5993
5994	},
5995
5996	_out: function(event) {
5997
5998		var draggable = $.ui.ddmanager.current;
5999
6000		// Bail if draggable and droppable are same element
6001		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
6002			return;
6003		}
6004
6005		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
6006			if(this.options.hoverClass) {
6007				this.element.removeClass(this.options.hoverClass);
6008			}
6009			this._trigger("out", event, this.ui(draggable));
6010		}
6011
6012	},
6013
6014	_drop: function(event,custom) {
6015
6016		var draggable = custom || $.ui.ddmanager.current,
6017			childrenIntersection = false;
6018
6019		// Bail if draggable and droppable are same element
6020		if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
6021			return false;
6022		}
6023
6024		this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
6025			var inst = $.data(this, "ui-droppable");
6026			if(
6027				inst.options.greedy &&
6028				!inst.options.disabled &&
6029				inst.options.scope === draggable.options.scope &&
6030				inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
6031				$.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
6032			) { childrenIntersection = true; return false; }
6033		});
6034		if(childrenIntersection) {
6035			return false;
6036		}
6037
6038		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
6039			if(this.options.activeClass) {
6040				this.element.removeClass(this.options.activeClass);
6041			}
6042			if(this.options.hoverClass) {
6043				this.element.removeClass(this.options.hoverClass);
6044			}
6045			this._trigger("drop", event, this.ui(draggable));
6046			return this.element;
6047		}
6048
6049		return false;
6050
6051	},
6052
6053	ui: function(c) {
6054		return {
6055			draggable: (c.currentItem || c.element),
6056			helper: c.helper,
6057			position: c.position,
6058			offset: c.positionAbs
6059		};
6060	}
6061
6062});
6063
6064$.ui.intersect = function(draggable, droppable, toleranceMode) {
6065
6066	if (!droppable.offset) {
6067		return false;
6068	}
6069
6070	var draggableLeft, draggableTop,
6071		x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
6072		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
6073		l = droppable.offset.left, r = l + droppable.proportions.width,
6074		t = droppable.offset.top, b = t + droppable.proportions.height;
6075
6076	switch (toleranceMode) {
6077		case "fit":
6078			return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
6079		case "intersect":
6080			return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
6081				x2 - (draggable.helperProportions.width / 2) < r && // Left Half
6082				t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
6083				y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
6084		case "pointer":
6085			draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
6086			draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
6087			return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
6088		case "touch":
6089			return (
6090				(y1 >= t && y1 <= b) ||	// Top edge touching
6091				(y2 >= t && y2 <= b) ||	// Bottom edge touching
6092				(y1 < t && y2 > b)		// Surrounded vertically
6093			) && (
6094				(x1 >= l && x1 <= r) ||	// Left edge touching
6095				(x2 >= l && x2 <= r) ||	// Right edge touching
6096				(x1 < l && x2 > r)		// Surrounded horizontally
6097			);
6098		default:
6099			return false;
6100		}
6101
6102};
6103
6104/*
6105	This manager tracks offsets of draggables and droppables
6106*/
6107$.ui.ddmanager = {
6108	current: null,
6109	droppables: { "default": [] },
6110	prepareOffsets: function(t, event) {
6111
6112		var i, j,
6113			m = $.ui.ddmanager.droppables[t.options.scope] || [],
6114			type = event ? event.type : null, // workaround for #2317
6115			list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
6116
6117		droppablesLoop: for (i = 0; i < m.length; i++) {
6118
6119			//No disabled and non-accepted
6120			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
6121				continue;
6122			}
6123
6124			// Filter out elements in the current dragged item
6125			for (j=0; j < list.length; j++) {
6126				if(list[j] === m[i].element[0]) {
6127					m[i].proportions.height = 0;
6128					continue droppablesLoop;
6129				}
6130			}
6131
6132			m[i].visible = m[i].element.css("display") !== "none";
6133			if(!m[i].visible) {
6134				continue;
6135			}
6136
6137			//Activate the droppable if used directly from draggables
6138			if(type === "mousedown") {
6139				m[i]._activate.call(m[i], event);
6140			}
6141
6142			m[i].offset = m[i].element.offset();
6143			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
6144
6145		}
6146
6147	},
6148	drop: function(draggable, event) {
6149
6150		var dropped = false;
vendor: 22,517 bytes, lines 6151-6939
6151		// Create a copy of the droppables in case the list changes during the drop (#9116)
6152		$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
6153
6154			if(!this.options) {
6155				return;
6156			}
6157			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
6158				dropped = this._drop.call(this, event) || dropped;
6159			}
6160
6161			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
6162				this.isout = true;
6163				this.isover = false;
6164				this._deactivate.call(this, event);
6165			}
6166
6167		});
6168		return dropped;
6169
6170	},
6171	dragStart: function( draggable, event ) {
6172		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
6173		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
6174			if( !draggable.options.refreshPositions ) {
6175				$.ui.ddmanager.prepareOffsets( draggable, event );
6176			}
6177		});
6178	},
6179	drag: function(draggable, event) {
6180
6181		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
6182		if(draggable.options.refreshPositions) {
6183			$.ui.ddmanager.prepareOffsets(draggable, event);
6184		}
6185
6186		//Run through all droppables and check their positions based on specific tolerance options
6187		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
6188
6189			if(this.options.disabled || this.greedyChild || !this.visible) {
6190				return;
6191			}
6192
6193			var parentInstance, scope, parent,
6194				intersects = $.ui.intersect(draggable, this, this.options.tolerance),
6195				c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
6196			if(!c) {
6197				return;
6198			}
6199
6200			if (this.options.greedy) {
6201				// find droppable parents with same scope
6202				scope = this.options.scope;
6203				parent = this.element.parents(":data(ui-droppable)").filter(function () {
6204					return $.data(this, "ui-droppable").options.scope === scope;
6205				});
6206
6207				if (parent.length) {
6208					parentInstance = $.data(parent[0], "ui-droppable");
6209					parentInstance.greedyChild = (c === "isover");
6210				}
6211			}
6212
6213			// we just moved into a greedy child
6214			if (parentInstance && c === "isover") {
6215				parentInstance.isover = false;
6216				parentInstance.isout = true;
6217				parentInstance._out.call(parentInstance, event);
6218			}
6219
6220			this[c] = true;
6221			this[c === "isout" ? "isover" : "isout"] = false;
6222			this[c === "isover" ? "_over" : "_out"].call(this, event);
6223
6224			// we just moved out of a greedy child
6225			if (parentInstance && c === "isout") {
6226				parentInstance.isout = false;
6227				parentInstance.isover = true;
6228				parentInstance._over.call(parentInstance, event);
6229			}
6230		});
6231
6232	},
6233	dragStop: function( draggable, event ) {
6234		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
6235		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
6236		if( !draggable.options.refreshPositions ) {
6237			$.ui.ddmanager.prepareOffsets( draggable, event );
6238		}
6239	}
6240};
6241
6242})(jQuery);
6243(function( $, undefined ) {
6244
6245function num(v) {
6246	return parseInt(v, 10) || 0;
6247}
6248
6249function isNumber(value) {
6250	return !isNaN(parseInt(value, 10));
6251}
6252
6253$.widget("ui.resizable", $.ui.mouse, {
6254	version: "1.10.3",
6255	widgetEventPrefix: "resize",
6256	options: {
6257		alsoResize: false,
6258		animate: false,
6259		animateDuration: "slow",
6260		animateEasing: "swing",
6261		aspectRatio: false,
6262		autoHide: false,
6263		containment: false,
6264		ghost: false,
6265		grid: false,
6266		handles: "e,s,se",
6267		helper: false,
6268		maxHeight: null,
6269		maxWidth: null,
6270		minHeight: 10,
6271		minWidth: 10,
6272		// See #7960
6273		zIndex: 90,
6274
6275		// callbacks
6276		resize: null,
6277		start: null,
6278		stop: null
6279	},
6280	_create: function() {
6281
6282		var n, i, handle, axis, hname,
6283			that = this,
6284			o = this.options;
6285		this.element.addClass("ui-resizable");
6286
6287		$.extend(this, {
6288			_aspectRatio: !!(o.aspectRatio),
6289			aspectRatio: o.aspectRatio,
6290			originalElement: this.element,
6291			_proportionallyResizeElements: [],
6292			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
6293		});
6294
6295		//Wrap the element if it cannot hold child nodes
6296		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
6297
6298			//Create a wrapper element and set the wrapper to the new current internal element
6299			this.element.wrap(
6300				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
6301					position: this.element.css("position"),
6302					width: this.element.outerWidth(),
6303					height: this.element.outerHeight(),
6304					top: this.element.css("top"),
6305					left: this.element.css("left")
6306				})
6307			);
6308
6309			//Overwrite the original this.element
6310			this.element = this.element.parent().data(
6311				"ui-resizable", this.element.data("ui-resizable")
6312			);
6313
6314			this.elementIsWrapper = true;
6315
6316			//Move margins to the wrapper
6317			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
6318			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
6319
6320			//Prevent Safari textarea resize
6321			this.originalResizeStyle = this.originalElement.css("resize");
6322			this.originalElement.css("resize", "none");
6323
6324			//Push the actual element to our proportionallyResize internal array
6325			this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
6326
6327			// avoid IE jump (hard set the margin)
6328			this.originalElement.css({ margin: this.originalElement.css("margin") });
6329
6330			// fix handlers offset
6331			this._proportionallyResize();
6332
6333		}
6334
6335		this.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" });
6336		if(this.handles.constructor === String) {
6337
6338			if ( this.handles === "all") {
6339				this.handles = "n,e,s,w,se,sw,ne,nw";
6340			}
6341
6342			n = this.handles.split(",");
6343			this.handles = {};
6344
6345			for(i = 0; i < n.length; i++) {
6346
6347				handle = $.trim(n[i]);
6348				hname = "ui-resizable-"+handle;
6349				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
6350
6351				// Apply zIndex to all handles - see #7960
6352				axis.css({ zIndex: o.zIndex });
6353
6354				//TODO : What's going on here?
6355				if ("se" === handle) {
6356					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
6357				}
6358
6359				//Insert into internal handles object and append to element
6360				this.handles[handle] = ".ui-resizable-"+handle;
6361				this.element.append(axis);
6362			}
6363
6364		}
6365
6366		this._renderAxis = function(target) {
6367
6368			var i, axis, padPos, padWrapper;
6369
6370			target = target || this.element;
6371
6372			for(i in this.handles) {
6373
6374				if(this.handles[i].constructor === String) {
6375					this.handles[i] = $(this.handles[i], this.element).show();
6376				}
6377
6378				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
6379				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
6380
6381					axis = $(this.handles[i], this.element);
6382
6383					//Checking the correct pad and border
6384					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
6385
6386					//The padding type i have to apply...
6387					padPos = [ "padding",
6388						/ne|nw|n/.test(i) ? "Top" :
6389						/se|sw|s/.test(i) ? "Bottom" :
6390						/^e$/.test(i) ? "Right" : "Left" ].join("");
6391
6392					target.css(padPos, padWrapper);
6393
6394					this._proportionallyResize();
6395
6396				}
6397
6398				//TODO: What's that good for? There's not anything to be executed left
6399				if(!$(this.handles[i]).length) {
6400					continue;
6401				}
6402			}
6403		};
6404
6405		//TODO: make renderAxis a prototype function
6406		this._renderAxis(this.element);
6407
6408		this._handles = $(".ui-resizable-handle", this.element)
6409			.disableSelection();
6410
6411		//Matching axis name
6412		this._handles.mouseover(function() {
6413			if (!that.resizing) {
6414				if (this.className) {
6415					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
6416				}
6417				//Axis, default = se
6418				that.axis = axis && axis[1] ? axis[1] : "se";
6419			}
6420		});
6421
6422		//If we want to auto hide the elements
6423		if (o.autoHide) {
6424			this._handles.hide();
6425			$(this.element)
6426				.addClass("ui-resizable-autohide")
6427				.mouseenter(function() {
6428					if (o.disabled) {
6429						return;
6430					}
6431					$(this).removeClass("ui-resizable-autohide");
6432					that._handles.show();
6433				})
6434				.mouseleave(function(){
6435					if (o.disabled) {
6436						return;
6437					}
6438					if (!that.resizing) {
6439						$(this).addClass("ui-resizable-autohide");
6440						that._handles.hide();
6441					}
6442				});
6443		}
6444
6445		//Initialize the mouse interaction
6446		this._mouseInit();
6447
6448	},
6449
6450	_destroy: function() {
6451
6452		this._mouseDestroy();
6453
6454		var wrapper,
6455			_destroy = function(exp) {
6456				$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
6457					.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
6458			};
6459
6460		//TODO: Unwrap at same DOM position
6461		if (this.elementIsWrapper) {
6462			_destroy(this.element);
6463			wrapper = this.element;
6464			this.originalElement.css({
6465				position: wrapper.css("position"),
6466				width: wrapper.outerWidth(),
6467				height: wrapper.outerHeight(),
6468				top: wrapper.css("top"),
6469				left: wrapper.css("left")
6470			}).insertAfter( wrapper );
6471			wrapper.remove();
6472		}
6473
6474		this.originalElement.css("resize", this.originalResizeStyle);
6475		_destroy(this.originalElement);
6476
6477		return this;
6478	},
6479
6480	_mouseCapture: function(event) {
6481		var i, handle,
6482			capture = false;
6483
6484		for (i in this.handles) {
6485			handle = $(this.handles[i])[0];
6486			if (handle === event.target || $.contains(handle, event.target)) {
6487				capture = true;
6488			}
6489		}
6490
6491		return !this.options.disabled && capture;
6492	},
6493
6494	_mouseStart: function(event) {
6495
6496		var curleft, curtop, cursor,
6497			o = this.options,
6498			iniPos = this.element.position(),
6499			el = this.element;
6500
6501		this.resizing = true;
6502
6503		// bugfix for http://dev.jquery.com/ticket/1749
6504		if ( (/absolute/).test( el.css("position") ) ) {
6505			el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
6506		} else if (el.is(".ui-draggable")) {
6507			el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
6508		}
6509
6510		this._renderProxy();
6511
6512		curleft = num(this.helper.css("left"));
6513		curtop = num(this.helper.css("top"));
6514
6515		if (o.containment) {
6516			curleft += $(o.containment).scrollLeft() || 0;
6517			curtop += $(o.containment).scrollTop() || 0;
6518		}
6519
6520		//Store needed variables
6521		this.offset = this.helper.offset();
6522		this.position = { left: curleft, top: curtop };
6523		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
6524		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
6525		this.originalPosition = { left: curleft, top: curtop };
6526		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
6527		this.originalMousePosition = { left: event.pageX, top: event.pageY };
6528
6529		//Aspect Ratio
6530		this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
6531
6532		cursor = $(".ui-resizable-" + this.axis).css("cursor");
6533		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
6534
6535		el.addClass("ui-resizable-resizing");
6536		this._propagate("start", event);
6537		return true;
6538	},
6539
6540	_mouseDrag: function(event) {
6541
6542		//Increase performance, avoid regex
6543		var data,
6544			el = this.helper, props = {},
6545			smp = this.originalMousePosition,
6546			a = this.axis,
6547			prevTop = this.position.top,
6548			prevLeft = this.position.left,
6549			prevWidth = this.size.width,
6550			prevHeight = this.size.height,
6551			dx = (event.pageX-smp.left)||0,
6552			dy = (event.pageY-smp.top)||0,
6553			trigger = this._change[a];
6554
6555		if (!trigger) {
6556			return false;
6557		}
6558
6559		// Calculate the attrs that will be change
6560		data = trigger.apply(this, [event, dx, dy]);
6561
6562		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
6563		this._updateVirtualBoundaries(event.shiftKey);
6564		if (this._aspectRatio || event.shiftKey) {
6565			data = this._updateRatio(data, event);
6566		}
6567
6568		data = this._respectSize(data, event);
6569
6570		this._updateCache(data);
6571
6572		// plugins callbacks need to be called first
6573		this._propagate("resize", event);
6574
6575		if (this.position.top !== prevTop) {
6576			props.top = this.position.top + "px";
6577		}
6578		if (this.position.left !== prevLeft) {
6579			props.left = this.position.left + "px";
6580		}
6581		if (this.size.width !== prevWidth) {
6582			props.width = this.size.width + "px";
6583		}
6584		if (this.size.height !== prevHeight) {
6585			props.height = this.size.height + "px";
6586		}
6587		el.css(props);
6588
6589		if (!this._helper && this._proportionallyResizeElements.length) {
6590			this._proportionallyResize();
6591		}
6592
6593		// Call the user callback if the element was resized
6594		if ( ! $.isEmptyObject(props) ) {
6595			this._trigger("resize", event, this.ui());
6596		}
6597
6598		return false;
6599	},
6600
6601	_mouseStop: function(event) {
6602
6603		this.resizing = false;
6604		var pr, ista, soffseth, soffsetw, s, left, top,
6605			o = this.options, that = this;
6606
6607		if(this._helper) {
6608
6609			pr = this._proportionallyResizeElements;
6610			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
6611			soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
6612			soffsetw = ista ? 0 : that.sizeDiff.width;
6613
6614			s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
6615			left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
6616			top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
6617
6618			if (!o.animate) {
6619				this.element.css($.extend(s, { top: top, left: left }));
6620			}
6621
6622			that.helper.height(that.size.height);
6623			that.helper.width(that.size.width);
6624
6625			if (this._helper && !o.animate) {
6626				this._proportionallyResize();
6627			}
6628		}
6629
6630		$("body").css("cursor", "auto");
6631
6632		this.element.removeClass("ui-resizable-resizing");
6633
6634		this._propagate("stop", event);
6635
6636		if (this._helper) {
6637			this.helper.remove();
6638		}
6639
6640		return false;
6641
6642	},
6643
6644	_updateVirtualBoundaries: function(forceAspectRatio) {
6645		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
6646			o = this.options;
6647
6648		b = {
6649			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
6650			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
6651			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
6652			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
6653		};
6654
6655		if(this._aspectRatio || forceAspectRatio) {
6656			// We want to create an enclosing box whose aspect ration is the requested one
6657			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
6658			pMinWidth = b.minHeight * this.aspectRatio;
6659			pMinHeight = b.minWidth / this.aspectRatio;
6660			pMaxWidth = b.maxHeight * this.aspectRatio;
6661			pMaxHeight = b.maxWidth / this.aspectRatio;
6662
6663			if(pMinWidth > b.minWidth) {
6664				b.minWidth = pMinWidth;
6665			}
6666			if(pMinHeight > b.minHeight) {
6667				b.minHeight = pMinHeight;
6668			}
6669			if(pMaxWidth < b.maxWidth) {
6670				b.maxWidth = pMaxWidth;
6671			}
6672			if(pMaxHeight < b.maxHeight) {
6673				b.maxHeight = pMaxHeight;
6674			}
6675		}
6676		this._vBoundaries = b;
6677	},
6678
6679	_updateCache: function(data) {
6680		this.offset = this.helper.offset();
6681		if (isNumber(data.left)) {
6682			this.position.left = data.left;
6683		}
6684		if (isNumber(data.top)) {
6685			this.position.top = data.top;
6686		}
6687		if (isNumber(data.height)) {
6688			this.size.height = data.height;
6689		}
6690		if (isNumber(data.width)) {
6691			this.size.width = data.width;
6692		}
6693	},
6694
6695	_updateRatio: function( data ) {
6696
6697		var cpos = this.position,
6698			csize = this.size,
6699			a = this.axis;
6700
6701		if (isNumber(data.height)) {
6702			data.width = (data.height * this.aspectRatio);
6703		} else if (isNumber(data.width)) {
6704			data.height = (data.width / this.aspectRatio);
6705		}
6706
6707		if (a === "sw") {
6708			data.left = cpos.left + (csize.width - data.width);
6709			data.top = null;
6710		}
6711		if (a === "nw") {
6712			data.top = cpos.top + (csize.height - data.height);
6713			data.left = cpos.left + (csize.width - data.width);
6714		}
6715
6716		return data;
6717	},
6718
6719	_respectSize: function( data ) {
6720
6721		var o = this._vBoundaries,
6722			a = this.axis,
6723			ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
6724			isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
6725			dw = this.originalPosition.left + this.originalSize.width,
6726			dh = this.position.top + this.size.height,
6727			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
6728		if (isminw) {
6729			data.width = o.minWidth;
6730		}
6731		if (isminh) {
6732			data.height = o.minHeight;
6733		}
6734		if (ismaxw) {
6735			data.width = o.maxWidth;
6736		}
6737		if (ismaxh) {
6738			data.height = o.maxHeight;
6739		}
6740
6741		if (isminw && cw) {
6742			data.left = dw - o.minWidth;
6743		}
6744		if (ismaxw && cw) {
6745			data.left = dw - o.maxWidth;
6746		}
6747		if (isminh && ch) {
6748			data.top = dh - o.minHeight;
6749		}
6750		if (ismaxh && ch) {
6751			data.top = dh - o.maxHeight;
6752		}
6753
6754		// fixing jump error on top/left - bug #2330
6755		if (!data.width && !data.height && !data.left && data.top) {
6756			data.top = null;
6757		} else if (!data.width && !data.height && !data.top && data.left) {
6758			data.left = null;
6759		}
6760
6761		return data;
6762	},
6763
6764	_proportionallyResize: function() {
6765
6766		if (!this._proportionallyResizeElements.length) {
6767			return;
6768		}
6769
6770		var i, j, borders, paddings, prel,
6771			element = this.helper || this.element;
6772
6773		for ( i=0; i < this._proportionallyResizeElements.length; i++) {
6774
6775			prel = this._proportionallyResizeElements[i];
6776
6777			if (!this.borderDif) {
6778				this.borderDif = [];
6779				borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
6780				paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
6781
6782				for ( j = 0; j < borders.length; j++ ) {
6783					this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
6784				}
6785			}
6786
6787			prel.css({
6788				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
6789				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
6790			});
6791
6792		}
6793
6794	},
6795
6796	_renderProxy: function() {
6797
6798		var el = this.element, o = this.options;
6799		this.elementOffset = el.offset();
6800
6801		if(this._helper) {
6802
6803			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
6804
6805			this.helper.addClass(this._helper).css({
6806				width: this.element.outerWidth() - 1,
6807				height: this.element.outerHeight() - 1,
6808				position: "absolute",
6809				left: this.elementOffset.left +"px",
6810				top: this.elementOffset.top +"px",
6811				zIndex: ++o.zIndex //TODO: Don't modify option
6812			});
6813
6814			this.helper
6815				.appendTo("body")
6816				.disableSelection();
6817
6818		} else {
6819			this.helper = this.element;
6820		}
6821
6822	},
6823
6824	_change: {
6825		e: function(event, dx) {
6826			return { width: this.originalSize.width + dx };
6827		},
6828		w: function(event, dx) {
6829			var cs = this.originalSize, sp = this.originalPosition;
6830			return { left: sp.left + dx, width: cs.width - dx };
6831		},
6832		n: function(event, dx, dy) {
6833			var cs = this.originalSize, sp = this.originalPosition;
6834			return { top: sp.top + dy, height: cs.height - dy };
6835		},
6836		s: function(event, dx, dy) {
6837			return { height: this.originalSize.height + dy };
6838		},
6839		se: function(event, dx, dy) {
6840			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
6841		},
6842		sw: function(event, dx, dy) {
6843			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
6844		},
6845		ne: function(event, dx, dy) {
6846			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
6847		},
6848		nw: function(event, dx, dy) {
6849			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
6850		}
6851	},
6852
6853	_propagate: function(n, event) {
6854		$.ui.plugin.call(this, n, [event, this.ui()]);
6855		(n !== "resize" && this._trigger(n, event, this.ui()));
6856	},
6857
6858	plugins: {},
6859
6860	ui: function() {
6861		return {
6862			originalElement: this.originalElement,
6863			element: this.element,
6864			helper: this.helper,
6865			position: this.position,
6866			size: this.size,
6867			originalSize: this.originalSize,
6868			originalPosition: this.originalPosition
6869		};
6870	}
6871
6872});
6873
6874/*
6875 * Resizable Extensions
6876 */
6877
6878$.ui.plugin.add("resizable", "animate", {
6879
6880	stop: function( event ) {
6881		var that = $(this).data("ui-resizable"),
6882			o = that.options,
6883			pr = that._proportionallyResizeElements,
6884			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
6885			soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
6886			soffsetw = ista ? 0 : that.sizeDiff.width,
6887			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
6888			left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
6889			top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
6890
6891		that.element.animate(
6892			$.extend(style, top && left ? { top: top, left: left } : {}), {
6893				duration: o.animateDuration,
6894				easing: o.animateEasing,
6895				step: function() {
6896
6897					var data = {
6898						width: parseInt(that.element.css("width"), 10),
6899						height: parseInt(that.element.css("height"), 10),
6900						top: parseInt(that.element.css("top"), 10),
6901						left: parseInt(that.element.css("left"), 10)
6902					};
6903
6904					if (pr && pr.length) {
6905						$(pr[0]).css({ width: data.width, height: data.height });
6906					}
6907
6908					// propagating resize, and updating values for each animation step
6909					that._updateCache(data);
6910					that._propagate("resize", event);
6911
6912				}
6913			}
6914		);
6915	}
6916
6917});
6918
6919$.ui.plugin.add("resizable", "containment", {
6920
6921	start: function() {
6922		var element, p, co, ch, cw, width, height,
6923			that = $(this).data("ui-resizable"),
6924			o = that.options,
6925			el = that.element,
6926			oc = o.containment,
6927			ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
6928
6929		if (!ce) {
6930			return;
6931		}
6932
6933		that.containerElement = $(ce);
6934
6935		if (/document/.test(oc) || oc === document) {
6936			that.containerOffset = { left: 0, top: 0 };
6937			that.containerPosition = { left: 0, top: 0 };
6938
6939			that.parentData = {
6940				element: $(document), left: 0, top: 0,
6941				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
6942			};
6943		}
6944
6945		// i'm a node, so compute top, left, right, bottom
6946		else {
6947			element = $(ce);
6948			p = [];
6949			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
6950
6951			that.containerOffset = element.offset();
6952			that.containerPosition = element.position();
6953			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
6954
6955			co = that.containerOffset;
6956			ch = that.containerSize.height;
6957			cw = that.containerSize.width;
6958			width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
6959			height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
6960
6961			that.parentData = {
6962				element: ce, left: co.left, top: co.top, width: width, height: height
6963			};
6964		}
6965	},
6966
6967	resize: function( event ) {
6968		var woset, hoset, isParent, isOffsetRelative,
6969			that = $(this).data("ui-resizable"),
6970			o = that.options,
6971			co = that.containerOffset, cp = that.position,
6972			pRatio = that._aspectRatio || event.shiftKey,
6973			cop = { top:0, left:0 }, ce = that.containerElement;
6974
6975		if (ce[0] !== document && (/static/).test(ce.css("position"))) {
6976			cop = co;
6977		}
6978
6979		if (cp.left < (that._helper ? co.left : 0)) {
6980			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
6981			if (pRatio) {
6982				that.size.height = that.size.width / that.aspectRatio;
6983			}
6984			that.position.left = o.helper ? co.left : 0;
6985		}
6986
6987		if (cp.top < (that._helper ? co.top : 0)) {
6988			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
6989			if (pRatio) {
6990				that.size.width = that.size.height * that.aspectRatio;
6991			}
6992			that.position.top = that._helper ? co.top : 0;
6993		}
6994
6995		that.offset.left = that.parentData.left+that.position.left;
6996		that.offset.top = that.parentData.top+that.position.top;
6997
6998		woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
6999		hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
7000
7001		isParent = that.containerElement.get(0) === that.element.parent().get(0);
7002		isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
7003
7004		if(isParent && isOffsetRelative) {
7005			woset -= that.parentData.left;
7006		}
7007
7008		if (woset + that.size.width >= that.parentData.width) {
7009			that.size.width = that.parentData.width - woset;
7010			if (pRatio) {
7011				that.size.height = that.size.width / that.aspectRatio;
7012			}
7013		}
7014
7015		if (hoset + that.size.height >= that.parentData.height) {
7016			that.size.height = that.parentData.height - hoset;
7017			if (pRatio) {
7018				that.size.width = that.size.height * that.aspectRatio;
7019			}
7020		}
7021	},
7022
7023	stop: function(){
7024		var that = $(this).data("ui-resizable"),
7025			o = that.options,
7026			co = that.containerOffset,
7027			cop = that.containerPosition,
7028			ce = that.containerElement,
7029			helper = $(that.helper),
7030			ho = helper.offset(),
7031			w = helper.outerWidth() - that.sizeDiff.width,
7032			h = helper.outerHeight() - that.sizeDiff.height;
7033
7034		if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
7035			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
7036		}
7037
7038		if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
7039			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
7040		}
7041
7042	}
7043});
7044
7045$.ui.plugin.add("resizable", "alsoResize", {
7046
7047	start: function () {
7048		var that = $(this).data("ui-resizable"),
7049			o = that.options,
7050			_store = function (exp) {
7051				$(exp).each(function() {
7052					var el = $(this);
7053					el.data("ui-resizable-alsoresize", {
7054						width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
7055						left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
7056					});
7057				});
7058			};
7059
7060		if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
7061			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
7062			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
7063		}else{
7064			_store(o.alsoResize);
7065		}
7066	},
7067
7068	resize: function (event, ui) {
7069		var that = $(this).data("ui-resizable"),
7070			o = that.options,
7071			os = that.originalSize,
7072			op = that.originalPosition,
7073			delta = {
7074				height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
7075				top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
7076			},
7077
7078			_alsoResize = function (exp, c) {
7079				$(exp).each(function() {
7080					var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
7081						css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
7082
vendor: 32,676 bytes, lines 7083-8236
7083					$.each(css, function (i, prop) {
7084						var sum = (start[prop]||0) + (delta[prop]||0);
7085						if (sum && sum >= 0) {
7086							style[prop] = sum || null;
7087						}
7088					});
7089
7090					el.css(style);
7091				});
7092			};
7093
7094		if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
7095			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
7096		}else{
7097			_alsoResize(o.alsoResize);
7098		}
7099	},
7100
7101	stop: function () {
7102		$(this).removeData("resizable-alsoresize");
7103	}
7104});
7105
7106$.ui.plugin.add("resizable", "ghost", {
7107
7108	start: function() {
7109
7110		var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
7111
7112		that.ghost = that.originalElement.clone();
7113		that.ghost
7114			.css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
7115			.addClass("ui-resizable-ghost")
7116			.addClass(typeof o.ghost === "string" ? o.ghost : "");
7117
7118		that.ghost.appendTo(that.helper);
7119
7120	},
7121
7122	resize: function(){
7123		var that = $(this).data("ui-resizable");
7124		if (that.ghost) {
7125			that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
7126		}
7127	},
7128
7129	stop: function() {
7130		var that = $(this).data("ui-resizable");
7131		if (that.ghost && that.helper) {
7132			that.helper.get(0).removeChild(that.ghost.get(0));
7133		}
7134	}
7135
7136});
7137
7138$.ui.plugin.add("resizable", "grid", {
7139
7140	resize: function() {
7141		var that = $(this).data("ui-resizable"),
7142			o = that.options,
7143			cs = that.size,
7144			os = that.originalSize,
7145			op = that.originalPosition,
7146			a = that.axis,
7147			grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
7148			gridX = (grid[0]||1),
7149			gridY = (grid[1]||1),
7150			ox = Math.round((cs.width - os.width) / gridX) * gridX,
7151			oy = Math.round((cs.height - os.height) / gridY) * gridY,
7152			newWidth = os.width + ox,
7153			newHeight = os.height + oy,
7154			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
7155			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
7156			isMinWidth = o.minWidth && (o.minWidth > newWidth),
7157			isMinHeight = o.minHeight && (o.minHeight > newHeight);
7158
7159		o.grid = grid;
7160
7161		if (isMinWidth) {
7162			newWidth = newWidth + gridX;
7163		}
7164		if (isMinHeight) {
7165			newHeight = newHeight + gridY;
7166		}
7167		if (isMaxWidth) {
7168			newWidth = newWidth - gridX;
7169		}
7170		if (isMaxHeight) {
7171			newHeight = newHeight - gridY;
7172		}
7173
7174		if (/^(se|s|e)$/.test(a)) {
7175			that.size.width = newWidth;
7176			that.size.height = newHeight;
7177		} else if (/^(ne)$/.test(a)) {
7178			that.size.width = newWidth;
7179			that.size.height = newHeight;
7180			that.position.top = op.top - oy;
7181		} else if (/^(sw)$/.test(a)) {
7182			that.size.width = newWidth;
7183			that.size.height = newHeight;
7184			that.position.left = op.left - ox;
7185		} else {
7186			that.size.width = newWidth;
7187			that.size.height = newHeight;
7188			that.position.top = op.top - oy;
7189			that.position.left = op.left - ox;
7190		}
7191	}
7192
7193});
7194
7195})(jQuery);
7196(function( $, undefined ) {
7197
7198$.widget("ui.selectable", $.ui.mouse, {
7199	version: "1.10.3",
7200	options: {
7201		appendTo: "body",
7202		autoRefresh: true,
7203		distance: 0,
7204		filter: "*",
7205		tolerance: "touch",
7206
7207		// callbacks
7208		selected: null,
7209		selecting: null,
7210		start: null,
7211		stop: null,
7212		unselected: null,
7213		unselecting: null
7214	},
7215	_create: function() {
7216		var selectees,
7217			that = this;
7218
7219		this.element.addClass("ui-selectable");
7220
7221		this.dragged = false;
7222
7223		// cache selectee children based on filter
7224		this.refresh = function() {
7225			selectees = $(that.options.filter, that.element[0]);
7226			selectees.addClass("ui-selectee");
7227			selectees.each(function() {
7228				var $this = $(this),
7229					pos = $this.offset();
7230				$.data(this, "selectable-item", {
7231					element: this,
7232					$element: $this,
7233					left: pos.left,
7234					top: pos.top,
7235					right: pos.left + $this.outerWidth(),
7236					bottom: pos.top + $this.outerHeight(),
7237					startselected: false,
7238					selected: $this.hasClass("ui-selected"),
7239					selecting: $this.hasClass("ui-selecting"),
7240					unselecting: $this.hasClass("ui-unselecting")
7241				});
7242			});
7243		};
7244		this.refresh();
7245
7246		this.selectees = selectees.addClass("ui-selectee");
7247
7248		this._mouseInit();
7249
7250		this.helper = $("<div class='ui-selectable-helper'></div>");
7251	},
7252
7253	_destroy: function() {
7254		this.selectees
7255			.removeClass("ui-selectee")
7256			.removeData("selectable-item");
7257		this.element
7258			.removeClass("ui-selectable ui-selectable-disabled");
7259		this._mouseDestroy();
7260	},
7261
7262	_mouseStart: function(event) {
7263		var that = this,
7264			options = this.options;
7265
7266		this.opos = [event.pageX, event.pageY];
7267
7268		if (this.options.disabled) {
7269			return;
7270		}
7271
7272		this.selectees = $(options.filter, this.element[0]);
7273
7274		this._trigger("start", event);
7275
7276		$(options.appendTo).append(this.helper);
7277		// position helper (lasso)
7278		this.helper.css({
7279			"left": event.pageX,
7280			"top": event.pageY,
7281			"width": 0,
7282			"height": 0
7283		});
7284
7285		if (options.autoRefresh) {
7286			this.refresh();
7287		}
7288
7289		this.selectees.filter(".ui-selected").each(function() {
7290			var selectee = $.data(this, "selectable-item");
7291			selectee.startselected = true;
7292			if (!event.metaKey && !event.ctrlKey) {
7293				selectee.$element.removeClass("ui-selected");
7294				selectee.selected = false;
7295				selectee.$element.addClass("ui-unselecting");
7296				selectee.unselecting = true;
7297				// selectable UNSELECTING callback
7298				that._trigger("unselecting", event, {
7299					unselecting: selectee.element
7300				});
7301			}
7302		});
7303
7304		$(event.target).parents().addBack().each(function() {
7305			var doSelect,
7306				selectee = $.data(this, "selectable-item");
7307			if (selectee) {
7308				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
7309				selectee.$element
7310					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
7311					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
7312				selectee.unselecting = !doSelect;
7313				selectee.selecting = doSelect;
7314				selectee.selected = doSelect;
7315				// selectable (UN)SELECTING callback
7316				if (doSelect) {
7317					that._trigger("selecting", event, {
7318						selecting: selectee.element
7319					});
7320				} else {
7321					that._trigger("unselecting", event, {
7322						unselecting: selectee.element
7323					});
7324				}
7325				return false;
7326			}
7327		});
7328
7329	},
7330
7331	_mouseDrag: function(event) {
7332
7333		this.dragged = true;
7334
7335		if (this.options.disabled) {
7336			return;
7337		}
7338
7339		var tmp,
7340			that = this,
7341			options = this.options,
7342			x1 = this.opos[0],
7343			y1 = this.opos[1],
7344			x2 = event.pageX,
7345			y2 = event.pageY;
7346
7347		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
7348		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
7349		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
7350
7351		this.selectees.each(function() {
7352			var selectee = $.data(this, "selectable-item"),
7353				hit = false;
7354
7355			//prevent helper from being selected if appendTo: selectable
7356			if (!selectee || selectee.element === that.element[0]) {
7357				return;
7358			}
7359
7360			if (options.tolerance === "touch") {
7361				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
7362			} else if (options.tolerance === "fit") {
7363				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
7364			}
7365
7366			if (hit) {
7367				// SELECT
7368				if (selectee.selected) {
7369					selectee.$element.removeClass("ui-selected");
7370					selectee.selected = false;
7371				}
7372				if (selectee.unselecting) {
7373					selectee.$element.removeClass("ui-unselecting");
7374					selectee.unselecting = false;
7375				}
7376				if (!selectee.selecting) {
7377					selectee.$element.addClass("ui-selecting");
7378					selectee.selecting = true;
7379					// selectable SELECTING callback
7380					that._trigger("selecting", event, {
7381						selecting: selectee.element
7382					});
7383				}
7384			} else {
7385				// UNSELECT
7386				if (selectee.selecting) {
7387					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
7388						selectee.$element.removeClass("ui-selecting");
7389						selectee.selecting = false;
7390						selectee.$element.addClass("ui-selected");
7391						selectee.selected = true;
7392					} else {
7393						selectee.$element.removeClass("ui-selecting");
7394						selectee.selecting = false;
7395						if (selectee.startselected) {
7396							selectee.$element.addClass("ui-unselecting");
7397							selectee.unselecting = true;
7398						}
7399						// selectable UNSELECTING callback
7400						that._trigger("unselecting", event, {
7401							unselecting: selectee.element
7402						});
7403					}
7404				}
7405				if (selectee.selected) {
7406					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
7407						selectee.$element.removeClass("ui-selected");
7408						selectee.selected = false;
7409
7410						selectee.$element.addClass("ui-unselecting");
7411						selectee.unselecting = true;
7412						// selectable UNSELECTING callback
7413						that._trigger("unselecting", event, {
7414							unselecting: selectee.element
7415						});
7416					}
7417				}
7418			}
7419		});
7420
7421		return false;
7422	},
7423
7424	_mouseStop: function(event) {
7425		var that = this;
7426
7427		this.dragged = false;
7428
7429		$(".ui-unselecting", this.element[0]).each(function() {
7430			var selectee = $.data(this, "selectable-item");
7431			selectee.$element.removeClass("ui-unselecting");
7432			selectee.unselecting = false;
7433			selectee.startselected = false;
7434			that._trigger("unselected", event, {
7435				unselected: selectee.element
7436			});
7437		});
7438		$(".ui-selecting", this.element[0]).each(function() {
7439			var selectee = $.data(this, "selectable-item");
7440			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
7441			selectee.selecting = false;
7442			selectee.selected = true;
7443			selectee.startselected = true;
7444			that._trigger("selected", event, {
7445				selected: selectee.element
7446			});
7447		});
7448		this._trigger("stop", event);
7449
7450		this.helper.remove();
7451
7452		return false;
7453	}
7454
7455});
7456
7457})(jQuery);
7458(function( $, undefined ) {
7459
7460/*jshint loopfunc: true */
7461
7462function isOverAxis( x, reference, size ) {
7463	return ( x > reference ) && ( x < ( reference + size ) );
7464}
7465
7466function isFloating(item) {
7467	return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
7468}
7469
7470$.widget("ui.sortable", $.ui.mouse, {
7471	version: "1.10.3",
7472	widgetEventPrefix: "sort",
7473	ready: false,
7474	options: {
7475		appendTo: "parent",
7476		axis: false,
7477		connectWith: false,
7478		containment: false,
7479		cursor: "auto",
7480		cursorAt: false,
7481		dropOnEmpty: true,
7482		forcePlaceholderSize: false,
7483		forceHelperSize: false,
7484		grid: false,
7485		handle: false,
7486		helper: "original",
7487		items: "> *",
7488		opacity: false,
7489		placeholder: false,
7490		revert: false,
7491		scroll: true,
7492		scrollSensitivity: 20,
7493		scrollSpeed: 20,
7494		scope: "default",
7495		tolerance: "intersect",
7496		zIndex: 1000,
7497
7498		// callbacks
7499		activate: null,
7500		beforeStop: null,
7501		change: null,
7502		deactivate: null,
7503		out: null,
7504		over: null,
7505		receive: null,
7506		remove: null,
7507		sort: null,
7508		start: null,
7509		stop: null,
7510		update: null
7511	},
7512	_create: function() {
7513
7514		var o = this.options;
7515		this.containerCache = {};
7516		this.element.addClass("ui-sortable");
7517
7518		//Get the items
7519		this.refresh();
7520
7521		//Let's determine if the items are being displayed horizontally
7522		this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
7523
7524		//Let's determine the parent's offset
7525		this.offset = this.element.offset();
7526
7527		//Initialize mouse events for interaction
7528		this._mouseInit();
7529
7530		//We're ready to go
7531		this.ready = true;
7532
7533	},
7534
7535	_destroy: function() {
7536		this.element
7537			.removeClass("ui-sortable ui-sortable-disabled");
7538		this._mouseDestroy();
7539
7540		for ( var i = this.items.length - 1; i >= 0; i-- ) {
7541			this.items[i].item.removeData(this.widgetName + "-item");
7542		}
7543
7544		return this;
7545	},
7546
7547	_setOption: function(key, value){
7548		if ( key === "disabled" ) {
7549			this.options[ key ] = value;
7550
7551			this.widget().toggleClass( "ui-sortable-disabled", !!value );
7552		} else {
7553			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
7554			$.Widget.prototype._setOption.apply(this, arguments);
7555		}
7556	},
7557
7558	_mouseCapture: function(event, overrideHandle) {
7559		var currentItem = null,
7560			validHandle = false,
7561			that = this;
7562
7563		if (this.reverting) {
7564			return false;
7565		}
7566
7567		if(this.options.disabled || this.options.type === "static") {
7568			return false;
7569		}
7570
7571		//We have to refresh the items data once first
7572		this._refreshItems(event);
7573
7574		//Find out if the clicked node (or one of its parents) is a actual item in this.items
7575		$(event.target).parents().each(function() {
7576			if($.data(this, that.widgetName + "-item") === that) {
7577				currentItem = $(this);
7578				return false;
7579			}
7580		});
7581		if($.data(event.target, that.widgetName + "-item") === that) {
7582			currentItem = $(event.target);
7583		}
7584
7585		if(!currentItem) {
7586			return false;
7587		}
7588		if(this.options.handle && !overrideHandle) {
7589			$(this.options.handle, currentItem).find("*").addBack().each(function() {
7590				if(this === event.target) {
7591					validHandle = true;
7592				}
7593			});
7594			if(!validHandle) {
7595				return false;
7596			}
7597		}
7598
7599		this.currentItem = currentItem;
7600		this._removeCurrentsFromItems();
7601		return true;
7602
7603	},
7604
7605	_mouseStart: function(event, overrideHandle, noActivation) {
7606
7607		var i, body,
7608			o = this.options;
7609
7610		this.currentContainer = this;
7611
7612		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
7613		this.refreshPositions();
7614
7615		//Create and append the visible helper
7616		this.helper = this._createHelper(event);
7617
7618		//Cache the helper size
7619		this._cacheHelperProportions();
7620
7621		/*
7622		 * - Position generation -
7623		 * This block generates everything position related - it's the core of draggables.
7624		 */
7625
7626		//Cache the margins of the original element
7627		this._cacheMargins();
7628
7629		//Get the next scrolling parent
7630		this.scrollParent = this.helper.scrollParent();
7631
7632		//The element's absolute position on the page minus margins
7633		this.offset = this.currentItem.offset();
7634		this.offset = {
7635			top: this.offset.top - this.margins.top,
7636			left: this.offset.left - this.margins.left
7637		};
7638
7639		$.extend(this.offset, {
7640			click: { //Where the click happened, relative to the element
7641				left: event.pageX - this.offset.left,
7642				top: event.pageY - this.offset.top
7643			},
7644			parent: this._getParentOffset(),
7645			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
7646		});
7647
7648		// Only after we got the offset, we can change the helper's position to absolute
7649		// TODO: Still need to figure out a way to make relative sorting possible
7650		this.helper.css("position", "absolute");
7651		this.cssPosition = this.helper.css("position");
7652
7653		//Generate the original position
7654		this.originalPosition = this._generatePosition(event);
7655		this.originalPageX = event.pageX;
7656		this.originalPageY = event.pageY;
7657
7658		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
7659		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
7660
7661		//Cache the former DOM position
7662		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
7663
7664		//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
7665		if(this.helper[0] !== this.currentItem[0]) {
7666			this.currentItem.hide();
7667		}
7668
7669		//Create the placeholder
7670		this._createPlaceholder();
7671
7672		//Set a containment if given in the options
7673		if(o.containment) {
7674			this._setContainment();
7675		}
7676
7677		if( o.cursor && o.cursor !== "auto" ) { // cursor option
7678			body = this.document.find( "body" );
7679
7680			// support: IE
7681			this.storedCursor = body.css( "cursor" );
7682			body.css( "cursor", o.cursor );
7683
7684			this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
7685		}
7686
7687		if(o.opacity) { // opacity option
7688			if (this.helper.css("opacity")) {
7689				this._storedOpacity = this.helper.css("opacity");
7690			}
7691			this.helper.css("opacity", o.opacity);
7692		}
7693
7694		if(o.zIndex) { // zIndex option
7695			if (this.helper.css("zIndex")) {
7696				this._storedZIndex = this.helper.css("zIndex");
7697			}
7698			this.helper.css("zIndex", o.zIndex);
7699		}
7700
7701		//Prepare scrolling
7702		if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
7703			this.overflowOffset = this.scrollParent.offset();
7704		}
7705
7706		//Call callbacks
7707		this._trigger("start", event, this._uiHash());
7708
7709		//Recache the helper size
7710		if(!this._preserveHelperProportions) {
7711			this._cacheHelperProportions();
7712		}
7713
7714
7715		//Post "activate" events to possible containers
7716		if( !noActivation ) {
7717			for ( i = this.containers.length - 1; i >= 0; i-- ) {
7718				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
7719			}
7720		}
7721
7722		//Prepare possible droppables
7723		if($.ui.ddmanager) {
7724			$.ui.ddmanager.current = this;
7725		}
7726
7727		if ($.ui.ddmanager && !o.dropBehaviour) {
7728			$.ui.ddmanager.prepareOffsets(this, event);
7729		}
7730
7731		this.dragging = true;
7732
7733		this.helper.addClass("ui-sortable-helper");
7734		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
7735		return true;
7736
7737	},
7738
7739	_mouseDrag: function(event) {
7740		var i, item, itemElement, intersection,
7741			o = this.options,
7742			scrolled = false;
7743
7744		//Compute the helpers position
7745		this.position = this._generatePosition(event);
7746		this.positionAbs = this._convertPositionTo("absolute");
7747
7748		if (!this.lastPositionAbs) {
7749			this.lastPositionAbs = this.positionAbs;
7750		}
7751
7752		//Do scrolling
7753		if(this.options.scroll) {
7754			if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
7755
7756				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
7757					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
7758				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
7759					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
7760				}
7761
7762				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
7763					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
7764				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
7765					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
7766				}
7767
7768			} else {
7769
7770				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
7771					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
7772				} else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
7773					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
7774				}
7775
7776				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
7777					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
7778				} else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
7779					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
7780				}
7781
7782			}
7783
7784			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
7785				$.ui.ddmanager.prepareOffsets(this, event);
7786			}
7787		}
7788
7789		//Regenerate the absolute position used for position checks
7790		this.positionAbs = this._convertPositionTo("absolute");
7791
7792		//Set the helper position
7793		if(!this.options.axis || this.options.axis !== "y") {
7794			this.helper[0].style.left = this.position.left+"px";
7795		}
7796		if(!this.options.axis || this.options.axis !== "x") {
7797			this.helper[0].style.top = this.position.top+"px";
7798		}
7799
7800		//Rearrange
7801		for (i = this.items.length - 1; i >= 0; i--) {
7802
7803			//Cache variables and intersection, continue if no intersection
7804			item = this.items[i];
7805			itemElement = item.item[0];
7806			intersection = this._intersectsWithPointer(item);
7807			if (!intersection) {
7808				continue;
7809			}
7810
7811			// Only put the placeholder inside the current Container, skip all
7812			// items form other containers. This works because when moving
7813			// an item from one container to another the
7814			// currentContainer is switched before the placeholder is moved.
7815			//
7816			// Without this moving items in "sub-sortables" can cause the placeholder to jitter
7817			// beetween the outer and inner container.
7818			if (item.instance !== this.currentContainer) {
7819				continue;
7820			}
7821
7822			// cannot intersect with itself
7823			// no useless actions that have been done before
7824			// no action if the item moved is the parent of the item checked
7825			if (itemElement !== this.currentItem[0] &&
7826				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
7827				!$.contains(this.placeholder[0], itemElement) &&
7828				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
7829			) {
7830
7831				this.direction = intersection === 1 ? "down" : "up";
7832
7833				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
7834					this._rearrange(event, item);
7835				} else {
7836					break;
7837				}
7838
7839				this._trigger("change", event, this._uiHash());
7840				break;
7841			}
7842		}
7843
7844		//Post events to containers
7845		this._contactContainers(event);
7846
7847		//Interconnect with droppables
7848		if($.ui.ddmanager) {
7849			$.ui.ddmanager.drag(this, event);
7850		}
7851
7852		//Call callbacks
7853		this._trigger("sort", event, this._uiHash());
7854
7855		this.lastPositionAbs = this.positionAbs;
7856		return false;
7857
7858	},
7859
7860	_mouseStop: function(event, noPropagation) {
7861
7862		if(!event) {
7863			return;
7864		}
7865
7866		//If we are using droppables, inform the manager about the drop
7867		if ($.ui.ddmanager && !this.options.dropBehaviour) {
7868			$.ui.ddmanager.drop(this, event);
7869		}
7870
7871		if(this.options.revert) {
7872			var that = this,
7873				cur = this.placeholder.offset(),
7874				axis = this.options.axis,
7875				animation = {};
7876
7877			if ( !axis || axis === "x" ) {
7878				animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
7879			}
7880			if ( !axis || axis === "y" ) {
7881				animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
7882			}
7883			this.reverting = true;
7884			$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
7885				that._clear(event);
7886			});
7887		} else {
7888			this._clear(event, noPropagation);
7889		}
7890
7891		return false;
7892
7893	},
7894
7895	cancel: function() {
7896
7897		if(this.dragging) {
7898
7899			this._mouseUp({ target: null });
7900
7901			if(this.options.helper === "original") {
7902				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
7903			} else {
7904				this.currentItem.show();
7905			}
7906
7907			//Post deactivating events to containers
7908			for (var i = this.containers.length - 1; i >= 0; i--){
7909				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
7910				if(this.containers[i].containerCache.over) {
7911					this.containers[i]._trigger("out", null, this._uiHash(this));
7912					this.containers[i].containerCache.over = 0;
7913				}
7914			}
7915
7916		}
7917
7918		if (this.placeholder) {
7919			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
7920			if(this.placeholder[0].parentNode) {
7921				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
7922			}
7923			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
7924				this.helper.remove();
7925			}
7926
7927			$.extend(this, {
7928				helper: null,
7929				dragging: false,
7930				reverting: false,
7931				_noFinalSort: null
7932			});
7933
7934			if(this.domPosition.prev) {
7935				$(this.domPosition.prev).after(this.currentItem);
7936			} else {
7937				$(this.domPosition.parent).prepend(this.currentItem);
7938			}
7939		}
7940
7941		return this;
7942
7943	},
7944
7945	serialize: function(o) {
7946
7947		var items = this._getItemsAsjQuery(o && o.connected),
7948			str = [];
7949		o = o || {};
7950
7951		$(items).each(function() {
7952			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
7953			if (res) {
7954				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
7955			}
7956		});
7957
7958		if(!str.length && o.key) {
7959			str.push(o.key + "=");
7960		}
7961
7962		return str.join("&");
7963
7964	},
7965
7966	toArray: function(o) {
7967
7968		var items = this._getItemsAsjQuery(o && o.connected),
7969			ret = [];
7970
7971		o = o || {};
7972
7973		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
7974		return ret;
7975
7976	},
7977
7978	/* Be careful with the following core functions */
7979	_intersectsWith: function(item) {
7980
7981		var x1 = this.positionAbs.left,
7982			x2 = x1 + this.helperProportions.width,
7983			y1 = this.positionAbs.top,
7984			y2 = y1 + this.helperProportions.height,
7985			l = item.left,
7986			r = l + item.width,
7987			t = item.top,
7988			b = t + item.height,
7989			dyClick = this.offset.click.top,
7990			dxClick = this.offset.click.left,
7991			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
7992			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
7993			isOverElement = isOverElementHeight && isOverElementWidth;
7994
7995		if ( this.options.tolerance === "pointer" ||
7996			this.options.forcePointerForContainers ||
7997			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
7998		) {
7999			return isOverElement;
8000		} else {
8001
8002			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
8003				x2 - (this.helperProportions.width / 2) < r && // Left Half
8004				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
8005				y2 - (this.helperProportions.height / 2) < b ); // Top Half
8006
8007		}
8008	},
8009
8010	_intersectsWithPointer: function(item) {
8011
8012		var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
8013			isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
8014			isOverElement = isOverElementHeight && isOverElementWidth,
8015			verticalDirection = this._getDragVerticalDirection(),
8016			horizontalDirection = this._getDragHorizontalDirection();
8017
8018		if (!isOverElement) {
8019			return false;
8020		}
8021
8022		return this.floating ?
8023			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
8024			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
8025
8026	},
8027
8028	_intersectsWithSides: function(item) {
8029
8030		var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
8031			isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
8032			verticalDirection = this._getDragVerticalDirection(),
8033			horizontalDirection = this._getDragHorizontalDirection();
8034
8035		if (this.floating && horizontalDirection) {
8036			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
8037		} else {
8038			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
8039		}
8040
8041	},
8042
8043	_getDragVerticalDirection: function() {
8044		var delta = this.positionAbs.top - this.lastPositionAbs.top;
8045		return delta !== 0 && (delta > 0 ? "down" : "up");
8046	},
8047
8048	_getDragHorizontalDirection: function() {
8049		var delta = this.positionAbs.left - this.lastPositionAbs.left;
8050		return delta !== 0 && (delta > 0 ? "right" : "left");
8051	},
8052
8053	refresh: function(event) {
8054		this._refreshItems(event);
8055		this.refreshPositions();
8056		return this;
8057	},
8058
8059	_connectWith: function() {
8060		var options = this.options;
8061		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
8062	},
8063
8064	_getItemsAsjQuery: function(connected) {
8065
8066		var i, j, cur, inst,
8067			items = [],
8068			queries = [],
8069			connectWith = this._connectWith();
8070
8071		if(connectWith && connected) {
8072			for (i = connectWith.length - 1; i >= 0; i--){
8073				cur = $(connectWith[i]);
8074				for ( j = cur.length - 1; j >= 0; j--){
8075					inst = $.data(cur[j], this.widgetFullName);
8076					if(inst && inst !== this && !inst.options.disabled) {
8077						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
8078					}
8079				}
8080			}
8081		}
8082
8083		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").not(".ui-sortable-placeholder"), this]);
8084
8085		for (i = queries.length - 1; i >= 0; i--){
8086			queries[i][0].each(function() {
8087				items.push(this);
8088			});
8089		}
8090
8091		return $(items);
8092
8093	},
8094
8095	_removeCurrentsFromItems: function() {
8096
8097		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
8098
8099		this.items = $.grep(this.items, function (item) {
8100			for (var j=0; j < list.length; j++) {
8101				if(list[j] === item.item[0]) {
8102					return false;
8103				}
8104			}
8105			return true;
8106		});
8107
8108	},
8109
8110	_refreshItems: function(event) {
8111
8112		this.items = [];
8113		this.containers = [this];
8114
8115		var i, j, cur, inst, targetData, _queries, item, queriesLength,
8116			items = this.items,
8117			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
8118			connectWith = this._connectWith();
8119
8120		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
8121			for (i = connectWith.length - 1; i >= 0; i--){
8122				cur = $(connectWith[i]);
8123				for (j = cur.length - 1; j >= 0; j--){
8124					inst = $.data(cur[j], this.widgetFullName);
8125					if(inst && inst !== this && !inst.options.disabled) {
8126						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
8127						this.containers.push(inst);
8128					}
8129				}
8130			}
8131		}
8132
8133		for (i = queries.length - 1; i >= 0; i--) {
8134			targetData = queries[i][1];
8135			_queries = queries[i][0];
8136
8137			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
8138				item = $(_queries[j]);
8139
8140				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
8141
8142				items.push({
8143					item: item,
8144					instance: targetData,
8145					width: 0, height: 0,
8146					left: 0, top: 0
8147				});
8148			}
8149		}
8150
8151	},
8152
8153	refreshPositions: function(fast) {
8154
8155		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
8156		if(this.offsetParent && this.helper) {
8157			this.offset.parent = this._getParentOffset();
8158		}
8159
8160		var i, item, t, p;
8161
8162		for (i = this.items.length - 1; i >= 0; i--){
8163			item = this.items[i];
8164
8165			//We ignore calculating positions of all connected containers when we're not over them
8166			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
8167				continue;
8168			}
8169
8170			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
8171
8172			if (!fast) {
8173				item.width = t.outerWidth();
8174				item.height = t.outerHeight();
8175			}
8176
8177			p = t.offset();
8178			item.left = p.left;
8179			item.top = p.top;
8180		}
8181
8182		if(this.options.custom && this.options.custom.refreshContainers) {
8183			this.options.custom.refreshContainers.call(this);
8184		} else {
8185			for (i = this.containers.length - 1; i >= 0; i--){
8186				p = this.containers[i].element.offset();
8187				this.containers[i].containerCache.left = p.left;
8188				this.containers[i].containerCache.top = p.top;
8189				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
8190				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
8191			}
8192		}
8193
8194		return this;
8195	},
8196
8197	_createPlaceholder: function(that) {
8198		that = that || this;
8199		var className,
8200			o = that.options;
8201
8202		if(!o.placeholder || o.placeholder.constructor === String) {
8203			className = o.placeholder;
8204			o.placeholder = {
8205				element: function() {
8206
8207					var nodeName = that.currentItem[0].nodeName.toLowerCase(),
8208						element = $( "<" + nodeName + ">", that.document[0] )
8209							.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
8210							.removeClass("ui-sortable-helper");
8211
8212					if ( nodeName === "tr" ) {
8213						that.currentItem.children().each(function() {
8214							$( "<td>&#160;</td>", that.document[0] )
8215								.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
8216								.appendTo( element );
8217						});
8218					} else if ( nodeName === "img" ) {
8219						element.attr( "src", that.currentItem.attr( "src" ) );
8220					}
8221
8222					if ( !className ) {
8223						element.css( "visibility", "hidden" );
8224					}
8225
8226					return element;
8227				},
8228				update: function(container, p) {
8229
8230					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
8231					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
8232					if(className && !o.forcePlaceholderSize) {
8233						return;
8234					}
8235
8236					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
8237					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
8238					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
8239				}
8240			};
8241		}
8242
8243		//Create the placeholder
8244		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
8245
8246		//Append it after the actual current item
8247		that.currentItem.after(that.placeholder);
8248
8249		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
8250		o.placeholder.update(that, that.placeholder);
8251
8252	},
8253
8254	_contactContainers: function(event) {
8255		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
8256			innermostContainer = null,
8257			innermostIndex = null;
8258
8259		// get innermost container that intersects with item
8260		for (i = this.containers.length - 1; i >= 0; i--) {
8261
8262			// never consider a container that's located within the item itself
8263			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
8264				continue;
8265			}
8266
8267			if(this._intersectsWith(this.containers[i].containerCache)) {
8268
8269				// if we've already found a container and it's more "inner" than this, then continue
8270				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
8271					continue;
8272				}
8273
8274				innermostContainer = this.containers[i];
8275				innermostIndex = i;
8276
8277			} else {
8278				// container doesn't intersect. trigger "out" event if necessary
8279				if(this.containers[i].containerCache.over) {
8280					this.containers[i]._trigger("out", event, this._uiHash(this));
8281					this.containers[i].containerCache.over = 0;
8282				}
8283			}
8284
8285		}
8286
8287		// if no intersecting containers found, return
8288		if(!innermostContainer) {
8289			return;
8290		}
8291
8292		// move the item into the container if it's not there already
8293		if(this.containers.length === 1) {
8294			if (!this.containers[innermostIndex].containerCache.over) {
8295				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
8296				this.containers[innermostIndex].containerCache.over = 1;
8297			}
8298		} else {
8299
8300			//When entering a new container, we will find the item with the least distance and append our item near it
8301			dist = 10000;
8302			itemWithLeastDistance = null;
8303			floating = innermostContainer.floating || isFloating(this.currentItem);
8304			posProperty = floating ? "left" : "top";
8305			sizeProperty = floating ? "width" : "height";
8306			base = this.positionAbs[posProperty] + this.offset.click[posProperty];
8307			for (j = this.items.length - 1; j >= 0; j--) {
8308				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
8309					continue;
8310				}
8311				if(this.items[j].item[0] === this.currentItem[0]) {
8312					continue;
8313				}
8314				if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
8315					continue;
8316				}
8317				cur = this.items[j].item.offset()[posProperty];
8318				nearBottom = false;
8319				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
8320					nearBottom = true;
8321					cur += this.items[j][sizeProperty];
8322				}
8323
8324				if(Math.abs(cur - base) < dist) {
8325					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j
vendor: 13,544 bytes, lines 8325-8646
8325];
8326					this.direction = nearBottom ? "up": "down";
8327				}
8328			}
8329
8330			//Check if dropOnEmpty is enabled
8331			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
8332				return;
8333			}
8334
8335			if(this.currentContainer === this.containers[innermostIndex]) {
8336				return;
8337			}
8338
8339			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
8340			this._trigger("change", event, this._uiHash());
8341			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
8342			this.currentContainer = this.containers[innermostIndex];
8343
8344			//Update the placeholder
8345			this.options.placeholder.update(this.currentContainer, this.placeholder);
8346
8347			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
8348			this.containers[innermostIndex].containerCache.over = 1;
8349		}
8350
8351
8352	},
8353
8354	_createHelper: function(event) {
8355
8356		var o = this.options,
8357			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
8358
8359		//Add the helper to the DOM if that didn't happen already
8360		if(!helper.parents("body").length) {
8361			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
8362		}
8363
8364		if(helper[0] === this.currentItem[0]) {
8365			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") };
8366		}
8367
8368		if(!helper[0].style.width || o.forceHelperSize) {
8369			helper.width(this.currentItem.width());
8370		}
8371		if(!helper[0].style.height || o.forceHelperSize) {
8372			helper.height(this.currentItem.height());
8373		}
8374
8375		return helper;
8376
8377	},
8378
8379	_adjustOffsetFromHelper: function(obj) {
8380		if (typeof obj === "string") {
8381			obj = obj.split(" ");
8382		}
8383		if ($.isArray(obj)) {
8384			obj = {left: +obj[0], top: +obj[1] || 0};
8385		}
8386		if ("left" in obj) {
8387			this.offset.click.left = obj.left + this.margins.left;
8388		}
8389		if ("right" in obj) {
8390			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
8391		}
8392		if ("top" in obj) {
8393			this.offset.click.top = obj.top + this.margins.top;
8394		}
8395		if ("bottom" in obj) {
8396			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
8397		}
8398	},
8399
8400	_getParentOffset: function() {
8401
8402
8403		//Get the offsetParent and cache its position
8404		this.offsetParent = this.helper.offsetParent();
8405		var po = this.offsetParent.offset();
8406
8407		// This is a special case where we need to modify a offset calculated on start, since the following happened:
8408		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
8409		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
8410		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
8411		if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
8412			po.left += this.scrollParent.scrollLeft();
8413			po.top += this.scrollParent.scrollTop();
8414		}
8415
8416		// This needs to be actually done for all browsers, since pageX/pageY includes this information
8417		// with an ugly IE fix
8418		if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
8419			po = { top: 0, left: 0 };
8420		}
8421
8422		return {
8423			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
8424			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
8425		};
8426
8427	},
8428
8429	_getRelativeOffset: function() {
8430
8431		if(this.cssPosition === "relative") {
8432			var p = this.currentItem.position();
8433			return {
8434				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
8435				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
8436			};
8437		} else {
8438			return { top: 0, left: 0 };
8439		}
8440
8441	},
8442
8443	_cacheMargins: function() {
8444		this.margins = {
8445			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
8446			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
8447		};
8448	},
8449
8450	_cacheHelperProportions: function() {
8451		this.helperProportions = {
8452			width: this.helper.outerWidth(),
8453			height: this.helper.outerHeight()
8454		};
8455	},
8456
8457	_setContainment: function() {
8458
8459		var ce, co, over,
8460			o = this.options;
8461		if(o.containment === "parent") {
8462			o.containment = this.helper[0].parentNode;
8463		}
8464		if(o.containment === "document" || o.containment === "window") {
8465			this.containment = [
8466				0 - this.offset.relative.left - this.offset.parent.left,
8467				0 - this.offset.relative.top - this.offset.parent.top,
8468				$(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
8469				($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
8470			];
8471		}
8472
8473		if(!(/^(document|window|parent)$/).test(o.containment)) {
8474			ce = $(o.containment)[0];
8475			co = $(o.containment).offset();
8476			over = ($(ce).css("overflow") !== "hidden");
8477
8478			this.containment = [
8479				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
8480				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
8481				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
8482				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
8483			];
8484		}
8485
8486	},
8487
8488	_convertPositionTo: function(d, pos) {
8489
8490		if(!pos) {
8491			pos = this.position;
8492		}
8493		var mod = d === "absolute" ? 1 : -1,
8494			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
8495			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
8496
8497		return {
8498			top: (
8499				pos.top	+																// The absolute mouse position
8500				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
8501				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
8502				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
8503			),
8504			left: (
8505				pos.left +																// The absolute mouse position
8506				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
8507				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
8508				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
8509			)
8510		};
8511
8512	},
8513
8514	_generatePosition: function(event) {
8515
8516		var top, left,
8517			o = this.options,
8518			pageX = event.pageX,
8519			pageY = event.pageY,
8520			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
8521
8522		// This is another very weird special case that only happens for relative elements:
8523		// 1. If the css position is relative
8524		// 2. and the scroll parent is the document or similar to the offset parent
8525		// we have to refresh the relative offset during the scroll so there are no jumps
8526		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
8527			this.offset.relative = this._getRelativeOffset();
8528		}
8529
8530		/*
8531		 * - Position constraining -
8532		 * Constrain the position to a mix of grid, containment.
8533		 */
8534
8535		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
8536
8537			if(this.containment) {
8538				if(event.pageX - this.offset.click.left < this.containment[0]) {
8539					pageX = this.containment[0] + this.offset.click.left;
8540				}
8541				if(event.pageY - this.offset.click.top < this.containment[1]) {
8542					pageY = this.containment[1] + this.offset.click.top;
8543				}
8544				if(event.pageX - this.offset.click.left > this.containment[2]) {
8545					pageX = this.containment[2] + this.offset.click.left;
8546				}
8547				if(event.pageY - this.offset.click.top > this.containment[3]) {
8548					pageY = this.containment[3] + this.offset.click.top;
8549				}
8550			}
8551
8552			if(o.grid) {
8553				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
8554				pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
8555
8556				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
8557				pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
8558			}
8559
8560		}
8561
8562		return {
8563			top: (
8564				pageY -																// The absolute mouse position
8565				this.offset.click.top -													// Click offset (relative to the element)
8566				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
8567				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
8568				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
8569			),
8570			left: (
8571				pageX -																// The absolute mouse position
8572				this.offset.click.left -												// Click offset (relative to the element)
8573				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
8574				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
8575				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
8576			)
8577		};
8578
8579	},
8580
8581	_rearrange: function(event, i, a, hardRefresh) {
8582
8583		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));
8584
8585		//Various things done here to improve the performance:
8586		// 1. we create a setTimeout, that calls refreshPositions
8587		// 2. on the instance, we have a counter variable, that get's higher after every append
8588		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
8589		// 4. this lets only the last addition to the timeout stack through
8590		this.counter = this.counter ? ++this.counter : 1;
8591		var counter = this.counter;
8592
8593		this._delay(function() {
8594			if(counter === this.counter) {
8595				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
8596			}
8597		});
8598
8599	},
8600
8601	_clear: function(event, noPropagation) {
8602
8603		this.reverting = false;
8604		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
8605		// everything else normalized again
8606		var i,
8607			delayedTriggers = [];
8608
8609		// We first have to update the dom position of the actual currentItem
8610		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
8611		if(!this._noFinalSort && this.currentItem.parent().length) {
8612			this.placeholder.before(this.currentItem);
8613		}
8614		this._noFinalSort = null;
8615
8616		if(this.helper[0] === this.currentItem[0]) {
8617			for(i in this._storedCSS) {
8618				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
8619					this._storedCSS[i] = "";
8620				}
8621			}
8622			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
8623		} else {
8624			this.currentItem.show();
8625		}
8626
8627		if(this.fromOutside && !noPropagation) {
8628			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
8629		}
8630		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
8631			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
8632		}
8633
8634		// Check if the items Container has Changed and trigger appropriate
8635		// events.
8636		if (this !== this.currentContainer) {
8637			if(!noPropagation) {
8638				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
8639				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
8640				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
8641			}
8642		}
8643
8644
8645		//Post events to containers
8646		f
vendor: 40,230 bytes, lines 8646-10133
8646or (i = this.containers.length - 1; i >= 0; i--){
8647			if(!noPropagation) {
8648				delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
8649			}
8650			if(this.containers[i].containerCache.over) {
8651				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
8652				this.containers[i].containerCache.over = 0;
8653			}
8654		}
8655
8656		//Do what was originally in plugins
8657		if ( this.storedCursor ) {
8658			this.document.find( "body" ).css( "cursor", this.storedCursor );
8659			this.storedStylesheet.remove();
8660		}
8661		if(this._storedOpacity) {
8662			this.helper.css("opacity", this._storedOpacity);
8663		}
8664		if(this._storedZIndex) {
8665			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
8666		}
8667
8668		this.dragging = false;
8669		if(this.cancelHelperRemoval) {
8670			if(!noPropagation) {
8671				this._trigger("beforeStop", event, this._uiHash());
8672				for (i=0; i < delayedTriggers.length; i++) {
8673					delayedTriggers[i].call(this, event);
8674				} //Trigger all delayed events
8675				this._trigger("stop", event, this._uiHash());
8676			}
8677
8678			this.fromOutside = false;
8679			return false;
8680		}
8681
8682		if(!noPropagation) {
8683			this._trigger("beforeStop", event, this._uiHash());
8684		}
8685
8686		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
8687		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
8688
8689		if(this.helper[0] !== this.currentItem[0]) {
8690			this.helper.remove();
8691		}
8692		this.helper = null;
8693
8694		if(!noPropagation) {
8695			for (i=0; i < delayedTriggers.length; i++) {
8696				delayedTriggers[i].call(this, event);
8697			} //Trigger all delayed events
8698			this._trigger("stop", event, this._uiHash());
8699		}
8700
8701		this.fromOutside = false;
8702		return true;
8703
8704	},
8705
8706	_trigger: function() {
8707		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
8708			this.cancel();
8709		}
8710	},
8711
8712	_uiHash: function(_inst) {
8713		var inst = _inst || this;
8714		return {
8715			helper: inst.helper,
8716			placeholder: inst.placeholder || $([]),
8717			position: inst.position,
8718			originalPosition: inst.originalPosition,
8719			offset: inst.positionAbs,
8720			item: inst.currentItem,
8721			sender: _inst ? _inst.element : null
8722		};
8723	}
8724
8725});
8726
8727})(jQuery);
8728(function( $, undefined ) {
8729
8730var uid = 0,
8731	hideProps = {},
8732	showProps = {};
8733
8734hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
8735	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
8736showProps.height = showProps.paddingTop = showProps.paddingBottom =
8737	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
8738
8739$.widget( "ui.accordion", {
8740	version: "1.10.3",
8741	options: {
8742		active: 0,
8743		animate: {},
8744		collapsible: false,
8745		event: "click",
8746		header: "> li > :first-child,> :not(li):even",
8747		heightStyle: "auto",
8748		icons: {
8749			activeHeader: "ui-icon-triangle-1-s",
8750			header: "ui-icon-triangle-1-e"
8751		},
8752
8753		// callbacks
8754		activate: null,
8755		beforeActivate: null
8756	},
8757
8758	_create: function() {
8759		var options = this.options;
8760		this.prevShow = this.prevHide = $();
8761		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
8762			// ARIA
8763			.attr( "role", "tablist" );
8764
8765		// don't allow collapsible: false and active: false / null
8766		if ( !options.collapsible && (options.active === false || options.active == null) ) {
8767			options.active = 0;
8768		}
8769
8770		this._processPanels();
8771		// handle negative values
8772		if ( options.active < 0 ) {
8773			options.active += this.headers.length;
8774		}
8775		this._refresh();
8776	},
8777
8778	_getCreateEventData: function() {
8779		return {
8780			header: this.active,
8781			panel: !this.active.length ? $() : this.active.next(),
8782			content: !this.active.length ? $() : this.active.next()
8783		};
8784	},
8785
8786	_createIcons: function() {
8787		var icons = this.options.icons;
8788		if ( icons ) {
8789			$( "<span>" )
8790				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
8791				.prependTo( this.headers );
8792			this.active.children( ".ui-accordion-header-icon" )
8793				.removeClass( icons.header )
8794				.addClass( icons.activeHeader );
8795			this.headers.addClass( "ui-accordion-icons" );
8796		}
8797	},
8798
8799	_destroyIcons: function() {
8800		this.headers
8801			.removeClass( "ui-accordion-icons" )
8802			.children( ".ui-accordion-header-icon" )
8803				.remove();
8804	},
8805
8806	_destroy: function() {
8807		var contents;
8808
8809		// clean up main element
8810		this.element
8811			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
8812			.removeAttr( "role" );
8813
8814		// clean up headers
8815		this.headers
8816			.removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
8817			.removeAttr( "role" )
8818			.removeAttr( "aria-selected" )
8819			.removeAttr( "aria-controls" )
8820			.removeAttr( "tabIndex" )
8821			.each(function() {
8822				if ( /^ui-accordion/.test( this.id ) ) {
8823					this.removeAttribute( "id" );
8824				}
8825			});
8826		this._destroyIcons();
8827
8828		// clean up content panels
8829		contents = this.headers.next()
8830			.css( "display", "" )
8831			.removeAttr( "role" )
8832			.removeAttr( "aria-expanded" )
8833			.removeAttr( "aria-hidden" )
8834			.removeAttr( "aria-labelledby" )
8835			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
8836			.each(function() {
8837				if ( /^ui-accordion/.test( this.id ) ) {
8838					this.removeAttribute( "id" );
8839				}
8840			});
8841		if ( this.options.heightStyle !== "content" ) {
8842			contents.css( "height", "" );
8843		}
8844	},
8845
8846	_setOption: function( key, value ) {
8847		if ( key === "active" ) {
8848			// _activate() will handle invalid values and update this.options
8849			this._activate( value );
8850			return;
8851		}
8852
8853		if ( key === "event" ) {
8854			if ( this.options.event ) {
8855				this._off( this.headers, this.options.event );
8856			}
8857			this._setupEvents( value );
8858		}
8859
8860		this._super( key, value );
8861
8862		// setting collapsible: false while collapsed; open first panel
8863		if ( key === "collapsible" && !value && this.options.active === false ) {
8864			this._activate( 0 );
8865		}
8866
8867		if ( key === "icons" ) {
8868			this._destroyIcons();
8869			if ( value ) {
8870				this._createIcons();
8871			}
8872		}
8873
8874		// #5332 - opacity doesn't cascade to positioned elements in IE
8875		// so we need to add the disabled class to the headers and panels
8876		if ( key === "disabled" ) {
8877			this.headers.add( this.headers.next() )
8878				.toggleClass( "ui-state-disabled", !!value );
8879		}
8880	},
8881
8882	_keydown: function( event ) {
8883		/*jshint maxcomplexity:15*/
8884		if ( event.altKey || event.ctrlKey ) {
8885			return;
8886		}
8887
8888		var keyCode = $.ui.keyCode,
8889			length = this.headers.length,
8890			currentIndex = this.headers.index( event.target ),
8891			toFocus = false;
8892
8893		switch ( event.keyCode ) {
8894			case keyCode.RIGHT:
8895			case keyCode.DOWN:
8896				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
8897				break;
8898			case keyCode.LEFT:
8899			case keyCode.UP:
8900				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
8901				break;
8902			case keyCode.SPACE:
8903			case keyCode.ENTER:
8904				this._eventHandler( event );
8905				break;
8906			case keyCode.HOME:
8907				toFocus = this.headers[ 0 ];
8908				break;
8909			case keyCode.END:
8910				toFocus = this.headers[ length - 1 ];
8911				break;
8912		}
8913
8914		if ( toFocus ) {
8915			$( event.target ).attr( "tabIndex", -1 );
8916			$( toFocus ).attr( "tabIndex", 0 );
8917			toFocus.focus();
8918			event.preventDefault();
8919		}
8920	},
8921
8922	_panelKeyDown : function( event ) {
8923		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
8924			$( event.currentTarget ).prev().focus();
8925		}
8926	},
8927
8928	refresh: function() {
8929		var options = this.options;
8930		this._processPanels();
8931
8932		// was collapsed or no panel
8933		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
8934			options.active = false;
8935			this.active = $();
8936		// active false only when collapsible is true
8937		} else if ( options.active === false ) {
8938			this._activate( 0 );
8939		// was active, but active panel is gone
8940		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
8941			// all remaining panel are disabled
8942			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
8943				options.active = false;
8944				this.active = $();
8945			// activate previous panel
8946			} else {
8947				this._activate( Math.max( 0, options.active - 1 ) );
8948			}
8949		// was active, active panel still exists
8950		} else {
8951			// make sure active index is correct
8952			options.active = this.headers.index( this.active );
8953		}
8954
8955		this._destroyIcons();
8956
8957		this._refresh();
8958	},
8959
8960	_processPanels: function() {
8961		this.headers = this.element.find( this.options.header )
8962			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
8963
8964		this.headers.next()
8965			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
8966			.filter(":not(.ui-accordion-content-active)")
8967			.hide();
8968	},
8969
8970	_refresh: function() {
8971		var maxHeight,
8972			options = this.options,
8973			heightStyle = options.heightStyle,
8974			parent = this.element.parent(),
8975			accordionId = this.accordionId = "ui-accordion-" +
8976				(this.element.attr( "id" ) || ++uid);
8977
8978		this.active = this._findActive( options.active )
8979			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
8980			.removeClass( "ui-corner-all" );
8981		this.active.next()
8982			.addClass( "ui-accordion-content-active" )
8983			.show();
8984
8985		this.headers
8986			.attr( "role", "tab" )
8987			.each(function( i ) {
8988				var header = $( this ),
8989					headerId = header.attr( "id" ),
8990					panel = header.next(),
8991					panelId = panel.attr( "id" );
8992				if ( !headerId ) {
8993					headerId = accordionId + "-header-" + i;
8994					header.attr( "id", headerId );
8995				}
8996				if ( !panelId ) {
8997					panelId = accordionId + "-panel-" + i;
8998					panel.attr( "id", panelId );
8999				}
9000				header.attr( "aria-controls", panelId );
9001				panel.attr( "aria-labelledby", headerId );
9002			})
9003			.next()
9004				.attr( "role", "tabpanel" );
9005
9006		this.headers
9007			.not( this.active )
9008			.attr({
9009				"aria-selected": "false",
9010				tabIndex: -1
9011			})
9012			.next()
9013				.attr({
9014					"aria-expanded": "false",
9015					"aria-hidden": "true"
9016				})
9017				.hide();
9018
9019		// make sure at least one header is in the tab order
9020		if ( !this.active.length ) {
9021			this.headers.eq( 0 ).attr( "tabIndex", 0 );
9022		} else {
9023			this.active.attr({
9024				"aria-selected": "true",
9025				tabIndex: 0
9026			})
9027			.next()
9028				.attr({
9029					"aria-expanded": "true",
9030					"aria-hidden": "false"
9031				});
9032		}
9033
9034		this._createIcons();
9035
9036		this._setupEvents( options.event );
9037
9038		if ( heightStyle === "fill" ) {
9039			maxHeight = parent.height();
9040			this.element.siblings( ":visible" ).each(function() {
9041				var elem = $( this ),
9042					position = elem.css( "position" );
9043
9044				if ( position === "absolute" || position === "fixed" ) {
9045					return;
9046				}
9047				maxHeight -= elem.outerHeight( true );
9048			});
9049
9050			this.headers.each(function() {
9051				maxHeight -= $( this ).outerHeight( true );
9052			});
9053
9054			this.headers.next()
9055				.each(function() {
9056					$( this ).height( Math.max( 0, maxHeight -
9057						$( this ).innerHeight() + $( this ).height() ) );
9058				})
9059				.css( "overflow", "auto" );
9060		} else if ( heightStyle === "auto" ) {
9061			maxHeight = 0;
9062			this.headers.next()
9063				.each(function() {
9064					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
9065				})
9066				.height( maxHeight );
9067		}
9068	},
9069
9070	_activate: function( index ) {
9071		var active = this._findActive( index )[ 0 ];
9072
9073		// trying to activate the already active panel
9074		if ( active === this.active[ 0 ] ) {
9075			return;
9076		}
9077
9078		// trying to collapse, simulate a click on the currently active header
9079		active = active || this.active[ 0 ];
9080
9081		this._eventHandler({
9082			target: active,
9083			currentTarget: active,
9084			preventDefault: $.noop
9085		});
9086	},
9087
9088	_findActive: function( selector ) {
9089		return typeof selector === "number" ? this.headers.eq( selector ) : $();
9090	},
9091
9092	_setupEvents: function( event ) {
9093		var events = {
9094			keydown: "_keydown"
9095		};
9096		if ( event ) {
9097			$.each( event.split(" "), function( index, eventName ) {
9098				events[ eventName ] = "_eventHandler";
9099			});
9100		}
9101
9102		this._off( this.headers.add( this.headers.next() ) );
9103		this._on( this.headers, events );
9104		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
9105		this._hoverable( this.headers );
9106		this._focusable( this.headers );
9107	},
9108
9109	_eventHandler: function( event ) {
9110		var options = this.options,
9111			active = this.active,
9112			clicked = $( event.currentTarget ),
9113			clickedIsActive = clicked[ 0 ] === active[ 0 ],
9114			collapsing = clickedIsActive && options.collapsible,
9115			toShow = collapsing ? $() : clicked.next(),
9116			toHide = active.next(),
9117			eventData = {
9118				oldHeader: active,
9119				oldPanel: toHide,
9120				newHeader: collapsing ? $() : clicked,
9121				newPanel: toShow
9122			};
9123
9124		event.preventDefault();
9125
9126		if (
9127				// click on active header, but not collapsible
9128				( clickedIsActive && !options.collapsible ) ||
9129				// allow canceling activation
9130				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
9131			return;
9132		}
9133
9134		options.active = collapsing ? false : this.headers.index( clicked );
9135
9136		// when the call to ._toggle() comes after the class changes
9137		// it causes a very odd bug in IE 8 (see #6720)
9138		this.active = clickedIsActive ? $() : clicked;
9139		this._toggle( eventData );
9140
9141		// switch classes
9142		// corner classes on the previously active header stay after the animation
9143		active.removeClass( "ui-accordion-header-active ui-state-active" );
9144		if ( options.icons ) {
9145			active.children( ".ui-accordion-header-icon" )
9146				.removeClass( options.icons.activeHeader )
9147				.addClass( options.icons.header );
9148		}
9149
9150		if ( !clickedIsActive ) {
9151			clicked
9152				.removeClass( "ui-corner-all" )
9153				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
9154			if ( options.icons ) {
9155				clicked.children( ".ui-accordion-header-icon" )
9156					.removeClass( options.icons.header )
9157					.addClass( options.icons.activeHeader );
9158			}
9159
9160			clicked
9161				.next()
9162				.addClass( "ui-accordion-content-active" );
9163		}
9164	},
9165
9166	_toggle: function( data ) {
9167		var toShow = data.newPanel,
9168			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
9169
9170		// handle activating a panel during the animation for another activation
9171		this.prevShow.add( this.prevHide ).stop( true, true );
9172		this.prevShow = toShow;
9173		this.prevHide = toHide;
9174
9175		if ( this.options.animate ) {
9176			this._animate( toShow, toHide, data );
9177		} else {
9178			toHide.hide();
9179			toShow.show();
9180			this._toggleComplete( data );
9181		}
9182
9183		toHide.attr({
9184			"aria-expanded": "false",
9185			"aria-hidden": "true"
9186		});
9187		toHide.prev().attr( "aria-selected", "false" );
9188		// if we're switching panels, remove the old header from the tab order
9189		// if we're opening from collapsed state, remove the previous header from the tab order
9190		// if we're collapsing, then keep the collapsing header in the tab order
9191		if ( toShow.length && toHide.length ) {
9192			toHide.prev().attr( "tabIndex", -1 );
9193		} else if ( toShow.length ) {
9194			this.headers.filter(function() {
9195				return $( this ).attr( "tabIndex" ) === 0;
9196			})
9197			.attr( "tabIndex", -1 );
9198		}
9199
9200		toShow
9201			.attr({
9202				"aria-expanded": "true",
9203				"aria-hidden": "false"
9204			})
9205			.prev()
9206				.attr({
9207					"aria-selected": "true",
9208					tabIndex: 0
9209				});
9210	},
9211
9212	_animate: function( toShow, toHide, data ) {
9213		var total, easing, duration,
9214			that = this,
9215			adjust = 0,
9216			down = toShow.length &&
9217				( !toHide.length || ( toShow.index() < toHide.index() ) ),
9218			animate = this.options.animate || {},
9219			options = down && animate.down || animate,
9220			complete = function() {
9221				that._toggleComplete( data );
9222			};
9223
9224		if ( typeof options === "number" ) {
9225			duration = options;
9226		}
9227		if ( typeof options === "string" ) {
9228			easing = options;
9229		}
9230		// fall back from options to animation in case of partial down settings
9231		easing = easing || options.easing || animate.easing;
9232		duration = duration || options.duration || animate.duration;
9233
9234		if ( !toHide.length ) {
9235			return toShow.animate( showProps, duration, easing, complete );
9236		}
9237		if ( !toShow.length ) {
9238			return toHide.animate( hideProps, duration, easing, complete );
9239		}
9240
9241		total = toShow.show().outerHeight();
9242		toHide.animate( hideProps, {
9243			duration: duration,
9244			easing: easing,
9245			step: function( now, fx ) {
9246				fx.now = Math.round( now );
9247			}
9248		});
9249		toShow
9250			.hide()
9251			.animate( showProps, {
9252				duration: duration,
9253				easing: easing,
9254				complete: complete,
9255				step: function( now, fx ) {
9256					fx.now = Math.round( now );
9257					if ( fx.prop !== "height" ) {
9258						adjust += fx.now;
9259					} else if ( that.options.heightStyle !== "content" ) {
9260						fx.now = Math.round( total - toHide.outerHeight() - adjust );
9261						adjust = 0;
9262					}
9263				}
9264			});
9265	},
9266
9267	_toggleComplete: function( data ) {
9268		var toHide = data.oldPanel;
9269
9270		toHide
9271			.removeClass( "ui-accordion-content-active" )
9272			.prev()
9273				.removeClass( "ui-corner-top" )
9274				.addClass( "ui-corner-all" );
9275
9276		// Work around for rendering bug in IE (#5421)
9277		if ( toHide.length ) {
9278			toHide.parent()[0].className = toHide.parent()[0].className;
9279		}
9280
9281		this._trigger( "activate", null, data );
9282	}
9283});
9284
9285})( jQuery );
9286(function( $, undefined ) {
9287
9288// used to prevent race conditions with remote data sources
9289var requestIndex = 0;
9290
9291$.widget( "ui.autocomplete", {
9292	version: "1.10.3",
9293	defaultElement: "<input>",
9294	options: {
9295		appendTo: null,
9296		autoFocus: false,
9297		delay: 300,
9298		minLength: 1,
9299		position: {
9300			my: "left top",
9301			at: "left bottom",
9302			collision: "none"
9303		},
9304		source: null,
9305
9306		// callbacks
9307		change: null,
9308		close: null,
9309		focus: null,
9310		open: null,
9311		response: null,
9312		search: null,
9313		select: null
9314	},
9315
9316	pending: 0,
9317
9318	_create: function() {
9319		// Some browsers only repeat keydown events, not keypress events,
9320		// so we use the suppressKeyPress flag to determine if we've already
9321		// handled the keydown event. #7269
9322		// Unfortunately the code for & in keypress is the same as the up arrow,
9323		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
9324		// events when we know the keydown event was used to modify the
9325		// search term. #7799
9326		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
9327			nodeName = this.element[0].nodeName.toLowerCase(),
9328			isTextarea = nodeName === "textarea",
9329			isInput = nodeName === "input";
9330
9331		this.isMultiLine =
9332			// Textareas are always multi-line
9333			isTextarea ? true :
9334			// Inputs are always single-line, even if inside a contentEditable element
9335			// IE also treats inputs as contentEditable
9336			isInput ? false :
9337			// All other element types are determined by whether or not they're contentEditable
9338			this.element.prop( "isContentEditable" );
9339
9340		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
9341		this.isNewMenu = true;
9342
9343		this.element
9344			.addClass( "ui-autocomplete-input" )
9345			.attr( "autocomplete", "off" );
9346
9347		this._on( this.element, {
9348			keydown: function( event ) {
9349				/*jshint maxcomplexity:15*/
9350				if ( this.element.prop( "readOnly" ) ) {
9351					suppressKeyPress = true;
9352					suppressInput = true;
9353					suppressKeyPressRepeat = true;
9354					return;
9355				}
9356
9357				suppressKeyPress = false;
9358				suppressInput = false;
9359				suppressKeyPressRepeat = false;
9360				var keyCode = $.ui.keyCode;
9361				switch( event.keyCode ) {
9362				case keyCode.PAGE_UP:
9363					suppressKeyPress = true;
9364					this._move( "previousPage", event );
9365					break;
9366				case keyCode.PAGE_DOWN:
9367					suppressKeyPress = true;
9368					this._move( "nextPage", event );
9369					break;
9370				case keyCode.UP:
9371					suppressKeyPress = true;
9372					this._keyEvent( "previous", event );
9373					break;
9374				case keyCode.DOWN:
9375					suppressKeyPress = true;
9376					this._keyEvent( "next", event );
9377					break;
9378				case keyCode.ENTER:
9379				case keyCode.NUMPAD_ENTER:
9380					// when menu is open and has focus
9381					if ( this.menu.active ) {
9382						// #6055 - Opera still allows the keypress to occur
9383						// which causes forms to submit
9384						suppressKeyPress = true;
9385						event.preventDefault();
9386						this.menu.select( event );
9387					}
9388					break;
9389				case keyCode.TAB:
9390					if ( this.menu.active ) {
9391						this.menu.select( event );
9392					}
9393					break;
9394				case keyCode.ESCAPE:
9395					if ( this.menu.element.is( ":visible" ) ) {
9396						this._value( this.term );
9397						this.close( event );
9398						// Different browsers have different default behavior for escape
9399						// Single press can mean undo or clear
9400						// Double press in IE means clear the whole form
9401						event.preventDefault();
9402					}
9403					break;
9404				default:
9405					suppressKeyPressRepeat = true;
9406					// search timeout should be triggered before the input value is changed
9407					this._searchTimeout( event );
9408					break;
9409				}
9410			},
9411			keypress: function( event ) {
9412				if ( suppressKeyPress ) {
9413					suppressKeyPress = false;
9414					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
9415						event.preventDefault();
9416					}
9417					return;
9418				}
9419				if ( suppressKeyPressRepeat ) {
9420					return;
9421				}
9422
9423				// replicate some key handlers to allow them to repeat in Firefox and Opera
9424				var keyCode = $.ui.keyCode;
9425				switch( event.keyCode ) {
9426				case keyCode.PAGE_UP:
9427					this._move( "previousPage", event );
9428					break;
9429				case keyCode.PAGE_DOWN:
9430					this._move( "nextPage", event );
9431					break;
9432				case keyCode.UP:
9433					this._keyEvent( "previous", event );
9434					break;
9435				case keyCode.DOWN:
9436					this._keyEvent( "next", event );
9437					break;
9438				}
9439			},
9440			input: function( event ) {
9441				if ( suppressInput ) {
9442					suppressInput = false;
9443					event.preventDefault();
9444					return;
9445				}
9446				this._searchTimeout( event );
9447			},
9448			focus: function() {
9449				this.selectedItem = null;
9450				this.previous = this._value();
9451			},
9452			blur: function( event ) {
9453				if ( this.cancelBlur ) {
9454					delete this.cancelBlur;
9455					return;
9456				}
9457
9458				clearTimeout( this.searching );
9459				this.close( event );
9460				this._change( event );
9461			}
9462		});
9463
9464		this._initSource();
9465		this.menu = $( "<ul>" )
9466			.addClass( "ui-autocomplete ui-front" )
9467			.appendTo( this._appendTo() )
9468			.menu({
9469				// disable ARIA support, the live region takes care of that
9470				role: null
9471			})
9472			.hide()
9473			.data( "ui-menu" );
9474
9475		this._on( this.menu.element, {
9476			mousedown: function( event ) {
9477				// prevent moving focus out of the text field
9478				event.preventDefault();
9479
9480				// IE doesn't prevent moving focus even with event.preventDefault()
9481				// so we set a flag to know when we should ignore the blur event
9482				this.cancelBlur = true;
9483				this._delay(function() {
9484					delete this.cancelBlur;
9485				});
9486
9487				// clicking on the scrollbar causes focus to shift to the body
9488				// but we can't detect a mouseup or a click immediately afterward
9489				// so we have to track the next mousedown and close the menu if
9490				// the user clicks somewhere outside of the autocomplete
9491				var menuElement = this.menu.element[ 0 ];
9492				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
9493					this._delay(function() {
9494						var that = this;
9495						this.document.one( "mousedown", function( event ) {
9496							if ( event.target !== that.element[ 0 ] &&
9497									event.target !== menuElement &&
9498									!$.contains( menuElement, event.target ) ) {
9499								that.close();
9500							}
9501						});
9502					});
9503				}
9504			},
9505			menufocus: function( event, ui ) {
9506				// support: Firefox
9507				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
9508				if ( this.isNewMenu ) {
9509					this.isNewMenu = false;
9510					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
9511						this.menu.blur();
9512
9513						this.document.one( "mousemove", function() {
9514							$( event.target ).trigger( event.originalEvent );
9515						});
9516
9517						return;
9518					}
9519				}
9520
9521				var item = ui.item.data( "ui-autocomplete-item" );
9522				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
9523					// use value to match what will end up in the input, if it was a key event
9524					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
9525						this._value( item.value );
9526					}
9527				} else {
9528					// Normally the input is populated with the item's value as the
9529					// menu is navigated, causing screen readers to notice a change and
9530					// announce the item. Since the focus event was canceled, this doesn't
9531					// happen, so we update the live region so that screen readers can
9532					// still notice the change and announce it.
9533					this.liveRegion.text( item.value );
9534				}
9535			},
9536			menuselect: function( event, ui ) {
9537				var item = ui.item.data( "ui-autocomplete-item" ),
9538					previous = this.previous;
9539
9540				// only trigger when focus was lost (click on menu)
9541				if ( this.element[0] !== this.document[0].activeElement ) {
9542					this.element.focus();
9543					this.previous = previous;
9544					// #6109 - IE triggers two focus events and the second
9545					// is asynchronous, so we need to reset the previous
9546					// term synchronously and asynchronously :-(
9547					this._delay(function() {
9548						this.previous = previous;
9549						this.selectedItem = item;
9550					});
9551				}
9552
9553				if ( false !== this._trigger( "select", event, { item: item } ) ) {
9554					this._value( item.value );
9555				}
9556				// reset the term after the select event
9557				// this allows custom select handling to work properly
9558				this.term = this._value();
9559
9560				this.close( event );
9561				this.selectedItem = item;
9562			}
9563		});
9564
9565		this.liveRegion = $( "<span>", {
9566				role: "status",
9567				"aria-live": "polite"
9568			})
9569			.addClass( "ui-helper-hidden-accessible" )
9570			.insertBefore( this.element );
9571
9572		// turning off autocomplete prevents the browser from remembering the
9573		// value when navigating through history, so we re-enable autocomplete
9574		// if the page is unloaded before the widget is destroyed. #7790
9575		this._on( this.window, {
9576			beforeunload: function() {
9577				this.element.removeAttr( "autocomplete" );
9578			}
9579		});
9580	},
9581
9582	_destroy: function() {
9583		clearTimeout( this.searching );
9584		this.element
9585			.removeClass( "ui-autocomplete-input" )
9586			.removeAttr( "autocomplete" );
9587		this.menu.element.remove();
9588		this.liveRegion.remove();
9589	},
9590
9591	_setOption: function( key, value ) {
9592		this._super( key, value );
9593		if ( key === "source" ) {
9594			this._initSource();
9595		}
9596		if ( key === "appendTo" ) {
9597			this.menu.element.appendTo( this._appendTo() );
9598		}
9599		if ( key === "disabled" && value && this.xhr ) {
9600			this.xhr.abort();
9601		}
9602	},
9603
9604	_appendTo: function() {
9605		var element = this.options.appendTo;
9606
9607		if ( element ) {
9608			element = element.jquery || element.nodeType ?
9609				$( element ) :
9610				this.document.find( element ).eq( 0 );
9611		}
9612
9613		if ( !element ) {
9614			element = this.element.closest( ".ui-front" );
9615		}
9616
9617		if ( !element.length ) {
9618			element = this.document[0].body;
9619		}
9620
9621		return element;
9622	},
9623
9624	_initSource: function() {
9625		var array, url,
9626			that = this;
9627		if ( $.isArray(this.options.source) ) {
9628			array = this.options.source;
9629			this.source = function( request, response ) {
9630				response( $.ui.autocomplete.filter( array, request.term ) );
9631			};
9632		} else if ( typeof this.options.source === "string" ) {
9633			url = this.options.source;
9634			this.source = function( request, response ) {
9635				if ( that.xhr ) {
9636					that.xhr.abort();
9637				}
9638				that.xhr = $.ajax({
9639					url: url,
9640					data: request,
9641					dataType: "json",
9642					success: function( data ) {
9643						response( data );
9644					},
9645					error: function() {
9646						response( [] );
9647					}
9648				});
9649			};
9650		} else {
9651			this.source = this.options.source;
9652		}
9653	},
9654
9655	_searchTimeout: function( event ) {
9656		clearTimeout( this.searching );
9657		this.searching = this._delay(function() {
9658			// only search if the value has changed
9659			if ( this.term !== this._value() ) {
9660				this.selectedItem = null;
9661				this.search( null, event );
9662			}
9663		}, this.options.delay );
9664	},
9665
9666	search: function( value, event ) {
9667		value = value != null ? value : this._value();
9668
9669		// always save the actual value, not the one passed as an argument
9670		this.term = this._value();
9671
9672		if ( value.length < this.options.minLength ) {
9673			return this.close( event );
9674		}
9675
9676		if ( this._trigger( "search", event ) === false ) {
9677			return;
9678		}
9679
9680		return this._search( value );
9681	},
9682
9683	_search: function( value ) {
9684		this.pending++;
9685		this.element.addClass( "ui-autocomplete-loading" );
9686		this.cancelSearch = false;
9687
9688		this.source( { term: value }, this._response() );
9689	},
9690
9691	_response: function() {
9692		var that = this,
9693			index = ++requestIndex;
9694
9695		return function( content ) {
9696			if ( index === requestIndex ) {
9697				that.__response( content );
9698			}
9699
9700			that.pending--;
9701			if ( !that.pending ) {
9702				that.element.removeClass( "ui-autocomplete-loading" );
9703			}
9704		};
9705	},
9706
9707	__response: function( content ) {
9708		if ( content ) {
9709			content = this._normalize( content );
9710		}
9711		this._trigger( "response", null, { content: content } );
9712		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
9713			this._suggest( content );
9714			this._trigger( "open" );
9715		} else {
9716			// use ._close() instead of .close() so we don't cancel future searches
9717			this._close();
9718		}
9719	},
9720
9721	close: function( event ) {
9722		this.cancelSearch = true;
9723		this._close( event );
9724	},
9725
9726	_close: function( event ) {
9727		if ( this.menu.element.is( ":visible" ) ) {
9728			this.menu.element.hide();
9729			this.menu.blur();
9730			this.isNewMenu = true;
9731			this._trigger( "close", event );
9732		}
9733	},
9734
9735	_change: function( event ) {
9736		if ( this.previous !== this._value() ) {
9737			this._trigger( "change", event, { item: this.selectedItem } );
9738		}
9739	},
9740
9741	_normalize: function( items ) {
9742		// assume all items have the right format when the first item is complete
9743		if ( items.length && items[0].label && items[0].value ) {
9744			return items;
9745		}
9746		return $.map( items, function( item ) {
9747			if ( typeof item === "string" ) {
9748				return {
9749					label: item,
9750					value: item
9751				};
9752			}
9753			return $.extend({
9754				label: item.label || item.value,
9755				value: item.value || item.label
9756			}, item );
9757		});
9758	},
9759
9760	_suggest: function( items ) {
9761		var ul = this.menu.element.empty();
9762		this._renderMenu( ul, items );
9763		this.isNewMenu = true;
9764		this.menu.refresh();
9765
9766		// size and position menu
9767		ul.show();
9768		this._resizeMenu();
9769		ul.position( $.extend({
9770			of: this.element
9771		}, this.options.position ));
9772
9773		if ( this.options.autoFocus ) {
9774			this.menu.next();
9775		}
9776	},
9777
9778	_resizeMenu: function() {
9779		var ul = this.menu.element;
9780		ul.outerWidth( Math.max(
9781			// Firefox wraps long text (possibly a rounding bug)
9782			// so we add 1px to avoid the wrapping (#7513)
9783			ul.width( "" ).outerWidth() + 1,
9784			this.element.outerWidth()
9785		) );
9786	},
9787
9788	_renderMenu: function( ul, items ) {
9789		var that = this;
9790		$.each( items, function( index, item ) {
9791			that._renderItemData( ul, item );
9792		});
9793	},
9794
9795	_renderItemData: function( ul, item ) {
9796		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
9797	},
9798
9799	_renderItem: function( ul, item ) {
9800		return $( "<li>" )
9801			.append( $( "<a>" ).text( item.label ) )
9802			.appendTo( ul );
9803	},
9804
9805	_move: function( direction, event ) {
9806		if ( !this.menu.element.is( ":visible" ) ) {
9807			this.search( null, event );
9808			return;
9809		}
9810		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
9811				this.menu.isLastItem() && /^next/.test( direction ) ) {
9812			this._value( this.term );
9813			this.menu.blur();
9814			return;
9815		}
9816		this.menu[ direction ]( event );
9817	},
9818
9819	widget: function() {
9820		return this.menu.element;
9821	},
9822
9823	_value: function() {
9824		return this.valueMethod.apply( this.element, arguments );
9825	},
9826
9827	_keyEvent: function( keyEvent, event ) {
9828		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
9829			this._move( keyEvent, event );
9830
9831			// prevents moving cursor to beginning/end of the text field in some browsers
9832			event.preventDefault();
9833		}
9834	}
9835});
9836
9837$.extend( $.ui.autocomplete, {
9838	escapeRegex: function( value ) {
9839		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
9840	},
9841	filter: function(array, term) {
9842		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
9843		return $.grep( array, function(value) {
9844			return matcher.test( value.label || value.value || value );
9845		});
9846	}
9847});
9848
9849
9850// live region extension, adding a `messages` option
9851// NOTE: This is an experimental API. We are still investigating
9852// a full solution for string manipulation and internationalization.
9853$.widget( "ui.autocomplete", $.ui.autocomplete, {
9854	options: {
9855		messages: {
9856			noResults: "No search results.",
9857			results: function( amount ) {
9858				return amount + ( amount > 1 ? " results are" : " result is" ) +
9859					" available, use up and down arrow keys to navigate.";
9860			}
9861		}
9862	},
9863
9864	__response: function( content ) {
9865		var message;
9866		this._superApply( arguments );
9867		if ( this.options.disabled || this.cancelSearch ) {
9868			return;
9869		}
9870		if ( content && content.length ) {
9871			message = this.options.messages.results( content.length );
9872		} else {
9873			message = this.options.messages.noResults;
9874		}
9875		this.liveRegion.text( message );
9876	}
9877});
9878
9879}( jQuery ));
9880(function( $, undefined ) {
9881
9882var lastActive, startXPos, startYPos, clickDragged,
9883	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
9884	stateClasses = "ui-state-hover ui-state-active ",
9885	typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
9886	formResetHandler = function() {
9887		var form = $( this );
9888		setTimeout(function() {
9889			form.find( ":ui-button" ).button( "refresh" );
9890		}, 1 );
9891	},
9892	radioGroup = function( radio ) {
9893		var name = radio.name,
9894			form = radio.form,
9895			radios = $( [] );
9896		if ( name ) {
9897			name = name.replace( /'/g, "\\'" );
9898			if ( form ) {
9899				radios = $( form ).find( "[name='" + name + "']" );
9900			} else {
9901				radios = $( "[name='" + name + "']", radio.ownerDocument )
9902					.filter(function() {
9903						return !this.form;
9904					});
9905			}
9906		}
9907		return radios;
9908	};
9909
9910$.widget( "ui.button", {
9911	version: "1.10.3",
9912	defaultElement: "<button>",
9913	options: {
9914		disabled: null,
9915		text: true,
9916		label: null,
9917		icons: {
9918			primary: null,
9919			secondary: null
9920		}
9921	},
9922	_create: function() {
9923		this.element.closest( "form" )
9924			.unbind( "reset" + this.eventNamespace )
9925			.bind( "reset" + this.eventNamespace, formResetHandler );
9926
9927		if ( typeof this.options.disabled !== "boolean" ) {
9928			this.options.disabled = !!this.element.prop( "disabled" );
9929		} else {
9930			this.element.prop( "disabled", this.options.disabled );
9931		}
9932
9933		this._determineButtonType();
9934		this.hasTitle = !!this.buttonElement.attr( "title" );
9935
9936		var that = this,
9937			options = this.options,
9938			toggleButton = this.type === "checkbox" || this.type === "radio",
9939			activeClass = !toggleButton ? "ui-state-active" : "",
9940			focusClass = "ui-state-focus";
9941
9942		if ( options.label === null ) {
9943			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
9944		}
9945
9946		this._hoverable( this.buttonElement );
9947
9948		this.buttonElement
9949			.addClass( baseClasses )
9950			.attr( "role", "button" )
9951			.bind( "mouseenter" + this.eventNamespace, function() {
9952				if ( options.disabled ) {
9953					return;
9954				}
9955				if ( this === lastActive ) {
9956					$( this ).addClass( "ui-state-active" );
9957				}
9958			})
9959			.bind( "mouseleave" + this.eventNamespace, function() {
9960				if ( options.disabled ) {
9961					return;
9962				}
9963				$( this ).removeClass( activeClass );
9964			})
9965			.bind( "click" + this.eventNamespace, function( event ) {
9966				if ( options.disabled ) {
9967					event.preventDefault();
9968					event.stopImmediatePropagation();
9969				}
9970			});
9971
9972		this.element
9973			.bind( "focus" + this.eventNamespace, function() {
9974				// no need to check disabled, focus won't be triggered anyway
9975				that.buttonElement.addClass( focusClass );
9976			})
9977			.bind( "blur" + this.eventNamespace, function() {
9978				that.buttonElement.removeClass( focusClass );
9979			});
9980
9981		if ( toggleButton ) {
9982			this.element.bind( "change" + this.eventNamespace, function() {
9983				if ( clickDragged ) {
9984					return;
9985				}
9986				that.refresh();
9987			});
9988			// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
9989			// prevents issue where button state changes but checkbox/radio checked state
9990			// does not in Firefox (see ticket #6970)
9991			this.buttonElement
9992				.bind( "mousedown" + this.eventNamespace, function( event ) {
9993					if ( options.disabled ) {
9994						return;
9995					}
9996					clickDragged = false;
9997					startXPos = event.pageX;
9998					startYPos = event.pageY;
9999				})
10000				.bind( "mouseup" + this.eventNamespace, function( event ) {
10001					if ( options.disabled ) {
10002						return;
10003					}
10004					if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
10005						clickDragged = true;
10006					}
10007			});
10008		}
10009
10010		if ( this.type === "checkbox" ) {
10011			this.buttonElement.bind( "click" + this.eventNamespace, function() {
10012				if ( options.disabled || clickDragged ) {
10013					return false;
10014				}
10015			});
10016		} else if ( this.type === "radio" ) {
10017			this.buttonElement.bind( "click" + this.eventNamespace, function() {
10018				if ( options.disabled || clickDragged ) {
10019					return false;
10020				}
10021				$( this ).addClass( "ui-state-active" );
10022				that.buttonElement.attr( "aria-pressed", "true" );
10023
10024				var radio = that.element[ 0 ];
10025				radioGroup( radio )
10026					.not( radio )
10027					.map(function() {
10028						return $( this ).button( "widget" )[ 0 ];
10029					})
10030					.removeClass( "ui-state-active" )
10031					.attr( "aria-pressed", "false" );
10032			});
10033		} else {
10034			this.buttonElement
10035				.bind( "mousedown" + this.eventNamespace, function() {
10036					if ( options.disabled ) {
10037						return false;
10038					}
10039					$( this ).addClass( "ui-state-active" );
10040					lastActive = this;
10041					that.document.one( "mouseup", function() {
10042						lastActive = null;
10043					});
10044				})
10045				.bind( "mouseup" + this.eventNamespace, function() {
10046					if ( options.disabled ) {
10047						return false;
10048					}
10049					$( this ).removeClass( "ui-state-active" );
10050				})
10051				.bind( "keydown" + this.eventNamespace, function(event) {
10052					if ( options.disabled ) {
10053						return false;
10054					}
10055					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
10056						$( this ).addClass( "ui-state-active" );
10057					}
10058				})
10059				// see #8559, we bind to blur here in case the button element loses
10060				// focus between keydown and keyup, it would be left in an "active" state
10061				.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
10062					$( this ).removeClass( "ui-state-active" );
10063				});
10064
10065			if ( this.buttonElement.is("a") ) {
10066				this.buttonElement.keyup(function(event) {
10067					if ( event.keyCode === $.ui.keyCode.SPACE ) {
10068						// TODO pass through original event correctly (just as 2nd argument doesn't work)
10069						$( this ).click();
10070					}
10071				});
10072			}
10073		}
10074
10075		// TODO: pull out $.Widget's handling for the disabled option into
10076		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
10077		// be overridden by individual plugins
10078		this._setOption( "disabled", options.disabled );
10079		this._resetButton();
10080	},
10081
10082	_determineButtonType: function() {
10083		var ancestor, labelSelector, checked;
10084
10085		if ( this.element.is("[type=checkbox]") ) {
10086			this.type = "checkbox";
10087		} else if ( this.element.is("[type=radio]") ) {
10088			this.type = "radio";
10089		} else if ( this.element.is("input") ) {
10090			this.type = "input";
10091		} else {
10092			this.type = "button";
10093		}
10094
10095		if ( this.type === "checkbox" || this.type === "radio" ) {
10096			// we don't search against the document in case the element
10097			// is disconnected from the DOM
10098			ancestor = this.element.parents().last();
10099			labelSelector = "label[for='" + this.element.attr("id") + "']";
10100			this.buttonElement = ancestor.find( labelSelector );
10101			if ( !this.buttonElement.length ) {
10102				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
10103				this.buttonElement = ancestor.filter( labelSelector );
10104				if ( !this.buttonElement.length ) {
10105					this.buttonElement = ancestor.find( labelSelector );
10106				}
10107			}
10108			this.element.addClass( "ui-helper-hidden-accessible" );
10109
10110			checked = this.element.is( ":checked" );
10111			if ( checked ) {
10112				this.buttonElement.addClass( "ui-state-active" );
10113			}
10114			this.buttonElement.prop( "aria-pressed", checked );
10115		} else {
10116			this.buttonElement = this.element;
10117		}
10118	},
10119
10120	widget: function() {
10121		return this.buttonElement;
10122	},
10123
10124	_destroy: function() {
10125		this.element
10126			.removeClass( "ui-helper-hidden-accessible" );
10127		this.buttonElement
10128			.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
10129			.removeAttr( "role" )
10130			.removeAttr( "aria-pressed" )
10131			.html( this.buttonElement.find(".ui-button-text").html() );
10132
10133		if ( !this.hasTitle ) {
vendor: 3,948 bytes, lines 10134-10284
10134			this.buttonElement.removeAttr( "title" );
10135		}
10136	},
10137
10138	_setOption: function( key, value ) {
10139		this._super( key, value );
10140		if ( key === "disabled" ) {
10141			if ( value ) {
10142				this.element.prop( "disabled", true );
10143			} else {
10144				this.element.prop( "disabled", false );
10145			}
10146			return;
10147		}
10148		this._resetButton();
10149	},
10150
10151	refresh: function() {
10152		//See #8237 & #8828
10153		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
10154
10155		if ( isDisabled !== this.options.disabled ) {
10156			this._setOption( "disabled", isDisabled );
10157		}
10158		if ( this.type === "radio" ) {
10159			radioGroup( this.element[0] ).each(function() {
10160				if ( $( this ).is( ":checked" ) ) {
10161					$( this ).button( "widget" )
10162						.addClass( "ui-state-active" )
10163						.attr( "aria-pressed", "true" );
10164				} else {
10165					$( this ).button( "widget" )
10166						.removeClass( "ui-state-active" )
10167						.attr( "aria-pressed", "false" );
10168				}
10169			});
10170		} else if ( this.type === "checkbox" ) {
10171			if ( this.element.is( ":checked" ) ) {
10172				this.buttonElement
10173					.addClass( "ui-state-active" )
10174					.attr( "aria-pressed", "true" );
10175			} else {
10176				this.buttonElement
10177					.removeClass( "ui-state-active" )
10178					.attr( "aria-pressed", "false" );
10179			}
10180		}
10181	},
10182
10183	_resetButton: function() {
10184		if ( this.type === "input" ) {
10185			if ( this.options.label ) {
10186				this.element.val( this.options.label );
10187			}
10188			return;
10189		}
10190		var buttonElement = this.buttonElement.removeClass( typeClasses ),
10191			buttonText = $( "<span></span>", this.document[0] )
10192				.addClass( "ui-button-text" )
10193				.html( this.options.label )
10194				.appendTo( buttonElement.empty() )
10195				.text(),
10196			icons = this.options.icons,
10197			multipleIcons = icons.primary && icons.secondary,
10198			buttonClasses = [];
10199
10200		if ( icons.primary || icons.secondary ) {
10201			if ( this.options.text ) {
10202				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
10203			}
10204
10205			if ( icons.primary ) {
10206				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
10207			}
10208
10209			if ( icons.secondary ) {
10210				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
10211			}
10212
10213			if ( !this.options.text ) {
10214				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
10215
10216				if ( !this.hasTitle ) {
10217					buttonElement.attr( "title", $.trim( buttonText ) );
10218				}
10219			}
10220		} else {
10221			buttonClasses.push( "ui-button-text-only" );
10222		}
10223		buttonElement.addClass( buttonClasses.join( " " ) );
10224	}
10225});
10226
10227$.widget( "ui.buttonset", {
10228	version: "1.10.3",
10229	options: {
10230		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
10231	},
10232
10233	_create: function() {
10234		this.element.addClass( "ui-buttonset" );
10235	},
10236
10237	_init: function() {
10238		this.refresh();
10239	},
10240
10241	_setOption: function( key, value ) {
10242		if ( key === "disabled" ) {
10243			this.buttons.button( "option", key, value );
10244		}
10245
10246		this._super( key, value );
10247	},
10248
10249	refresh: function() {
10250		var rtl = this.element.css( "direction" ) === "rtl";
10251
10252		this.buttons = this.element.find( this.options.items )
10253			.filter( ":ui-button" )
10254				.button( "refresh" )
10255			.end()
10256			.not( ":ui-button" )
10257				.button()
10258			.end()
10259			.map(function() {
10260				return $( this ).button( "widget" )[ 0 ];
10261			})
10262				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
10263				.filter( ":first" )
10264					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
10265				.end()
10266				.filter( ":last" )
10267					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
10268				.end()
10269			.end();
10270	},
10271
10272	_destroy: function() {
10273		this.element.removeClass( "ui-buttonset" );
10274		this.buttons
10275			.map(function() {
10276				return $( this ).button( "widget" )[ 0 ];
10277			})
10278				.removeClass( "ui-corner-left ui-corner-right" )
10279			.end()
10280			.button( "destroy" );
10281	}
10282});
10283
10284}( jQuery )
vendor: 76,062 bytes, lines 10284-12309
10284 );
10285(function( $, undefined ) {
10286
10287$.extend($.ui, { datepicker: { version: "1.10.3" } });
10288
10289var PROP_NAME = "datepicker",
10290	instActive;
10291
10292/* Date picker manager.
10293   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
10294   Settings for (groups of) date pickers are maintained in an instance object,
10295   allowing multiple different settings on the same page. */
10296
10297function Datepicker() {
10298	this._curInst = null; // The current instance in use
10299	this._keyEvent = false; // If the last event was a key event
10300	this._disabledInputs = []; // List of date picker inputs that have been disabled
10301	this._datepickerShowing = false; // True if the popup picker is showing , false if not
10302	this._inDialog = false; // True if showing within a "dialog", false if not
10303	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
10304	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
10305	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
10306	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
10307	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
10308	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
10309	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
10310	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
10311	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
10312	this.regional = []; // Available regional settings, indexed by language code
10313	this.regional[""] = { // Default regional settings
10314		closeText: "Done", // Display text for close link
10315		prevText: "Prev", // Display text for previous month link
10316		nextText: "Next", // Display text for next month link
10317		currentText: "Today", // Display text for current month link
10318		monthNames: ["January","February","March","April","May","June",
10319			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
10320		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
10321		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
10322		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
10323		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
10324		weekHeader: "Wk", // Column header for week of the year
10325		dateFormat: "mm/dd/yy", // See format options on parseDate
10326		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
10327		isRTL: false, // True if right-to-left language, false if left-to-right
10328		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
10329		yearSuffix: "" // Additional text to append to the year in the month headers
10330	};
10331	this._defaults = { // Global defaults for all the date picker instances
10332		showOn: "focus", // "focus" for popup on focus,
10333			// "button" for trigger button, or "both" for either
10334		showAnim: "fadeIn", // Name of jQuery animation for popup
10335		showOptions: {}, // Options for enhanced animations
10336		defaultDate: null, // Used when field is blank: actual date,
10337			// +/-number for offset from today, null for today
10338		appendText: "", // Display text following the input box, e.g. showing the format
10339		buttonText: "...", // Text for trigger button
10340		buttonImage: "", // URL for trigger button image
10341		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
10342		hideIfNoPrevNext: false, // True to hide next/previous month links
10343			// if not applicable, false to just disable them
10344		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
10345		gotoCurrent: false, // True if today link goes back to current selection instead
10346		changeMonth: false, // True if month can be selected directly, false if only prev/next
10347		changeYear: false, // True if year can be selected directly, false if only prev/next
10348		yearRange: "c-10:c+10", // Range of years to display in drop-down,
10349			// either relative to today's year (-nn:+nn), relative to currently displayed year
10350			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
10351		showOtherMonths: false, // True to show dates in other months, false to leave blank
10352		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
10353		showWeek: false, // True to show week of the year, false to not show it
10354		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
10355			// takes a Date and returns the number of the week for it
10356		shortYearCutoff: "+10", // Short year values < this are in the current century,
10357			// > this are in the previous century,
10358			// string value starting with "+" for current year + value
10359		minDate: null, // The earliest selectable date, or null for no limit
10360		maxDate: null, // The latest selectable date, or null for no limit
10361		duration: "fast", // Duration of display/closure
10362		beforeShowDay: null, // Function that takes a date and returns an array with
10363			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
10364			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
10365		beforeShow: null, // Function that takes an input field and
10366			// returns a set of custom settings for the date picker
10367		onSelect: null, // Define a callback function when a date is selected
10368		onChangeMonthYear: null, // Define a callback function when the month or year is changed
10369		onClose: null, // Define a callback function when the datepicker is closed
10370		numberOfMonths: 1, // Number of months to show at a time
10371		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
10372		stepMonths: 1, // Number of months to step back/forward
10373		stepBigMonths: 12, // Number of months to step back/forward for the big links
10374		altField: "", // Selector for an alternate field to store selected dates into
10375		altFormat: "", // The date format to use for the alternate field
10376		constrainInput: true, // The input is constrained by the current date format
10377		showButtonPanel: false, // True to show button panel, false to not show it
10378		autoSize: false, // True to size the input for the date format, false to leave as is
10379		disabled: false // The initial disabled state
10380	};
10381	$.extend(this._defaults, this.regional[""]);
10382	this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
10383}
10384
10385$.extend(Datepicker.prototype, {
10386	/* Class name added to elements to indicate already configured with a date picker. */
10387	markerClassName: "hasDatepicker",
10388
10389	//Keep track of the maximum number of rows displayed (see #7043)
10390	maxRows: 4,
10391
10392	// TODO rename to "widget" when switching to widget factory
10393	_widgetDatepicker: function() {
10394		return this.dpDiv;
10395	},
10396
10397	/* Override the default settings for all instances of the date picker.
10398	 * @param  settings  object - the new settings to use as defaults (anonymous object)
10399	 * @return the manager object
10400	 */
10401	setDefaults: function(settings) {
10402		extendRemove(this._defaults, settings || {});
10403		return this;
10404	},
10405
10406	/* Attach the date picker to a jQuery selection.
10407	 * @param  target	element - the target input field or division or span
10408	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
10409	 */
10410	_attachDatepicker: function(target, settings) {
10411		var nodeName, inline, inst;
10412		nodeName = target.nodeName.toLowerCase();
10413		inline = (nodeName === "div" || nodeName === "span");
10414		if (!target.id) {
10415			this.uuid += 1;
10416			target.id = "dp" + this.uuid;
10417		}
10418		inst = this._newInst($(target), inline);
10419		inst.settings = $.extend({}, settings || {});
10420		if (nodeName === "input") {
10421			this._connectDatepicker(target, inst);
10422		} else if (inline) {
10423			this._inlineDatepicker(target, inst);
10424		}
10425	},
10426
10427	/* Create a new instance object. */
10428	_newInst: function(target, inline) {
10429		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
10430		return {id: id, input: target, // associated target
10431			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
10432			drawMonth: 0, drawYear: 0, // month being drawn
10433			inline: inline, // is datepicker inline or not
10434			dpDiv: (!inline ? this.dpDiv : // presentation div
10435			bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
10436	},
10437
10438	/* Attach the date picker to an input field. */
10439	_connectDatepicker: function(target, inst) {
10440		var input = $(target);
10441		inst.append = $([]);
10442		inst.trigger = $([]);
10443		if (input.hasClass(this.markerClassName)) {
10444			return;
10445		}
10446		this._attachments(input, inst);
10447		input.addClass(this.markerClassName).keydown(this._doKeyDown).
10448			keypress(this._doKeyPress).keyup(this._doKeyUp);
10449		this._autoSize(inst);
10450		$.data(target, PROP_NAME, inst);
10451		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
10452		if( inst.settings.disabled ) {
10453			this._disableDatepicker( target );
10454		}
10455	},
10456
10457	/* Make attachments based on settings. */
10458	_attachments: function(input, inst) {
10459		var showOn, buttonText, buttonImage,
10460			appendText = this._get(inst, "appendText"),
10461			isRTL = this._get(inst, "isRTL");
10462
10463		if (inst.append) {
10464			inst.append.remove();
10465		}
10466		if (appendText) {
10467			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
10468			input[isRTL ? "before" : "after"](inst.append);
10469		}
10470
10471		input.unbind("focus", this._showDatepicker);
10472
10473		if (inst.trigger) {
10474			inst.trigger.remove();
10475		}
10476
10477		showOn = this._get(inst, "showOn");
10478		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
10479			input.focus(this._showDatepicker);
10480		}
10481		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
10482			buttonText = this._get(inst, "buttonText");
10483			buttonImage = this._get(inst, "buttonImage");
10484			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
10485				$("<img/>").addClass(this._triggerClass).
10486					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
10487				$("<button type='button'></button>").addClass(this._triggerClass).
10488					html(!buttonImage ? buttonText : $("<img/>").attr(
10489					{ src:buttonImage, alt:buttonText, title:buttonText })));
10490			input[isRTL ? "before" : "after"](inst.trigger);
10491			inst.trigger.click(function() {
10492				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
10493					$.datepicker._hideDatepicker();
10494				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
10495					$.datepicker._hideDatepicker();
10496					$.datepicker._showDatepicker(input[0]);
10497				} else {
10498					$.datepicker._showDatepicker(input[0]);
10499				}
10500				return false;
10501			});
10502		}
10503	},
10504
10505	/* Apply the maximum length for the date format. */
10506	_autoSize: function(inst) {
10507		if (this._get(inst, "autoSize") && !inst.inline) {
10508			var findMax, max, maxI, i,
10509				date = new Date(2009, 12 - 1, 20), // Ensure double digits
10510				dateFormat = this._get(inst, "dateFormat");
10511
10512			if (dateFormat.match(/[DM]/)) {
10513				findMax = function(names) {
10514					max = 0;
10515					maxI = 0;
10516					for (i = 0; i < names.length; i++) {
10517						if (names[i].length > max) {
10518							max = names[i].length;
10519							maxI = i;
10520						}
10521					}
10522					return maxI;
10523				};
10524				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
10525					"monthNames" : "monthNamesShort"))));
10526				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
10527					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
10528			}
10529			inst.input.attr("size", this._formatDate(inst, date).length);
10530		}
10531	},
10532
10533	/* Attach an inline date picker to a div. */
10534	_inlineDatepicker: function(target, inst) {
10535		var divSpan = $(target);
10536		if (divSpan.hasClass(this.markerClassName)) {
10537			return;
10538		}
10539		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
10540		$.data(target, PROP_NAME, inst);
10541		this._setDate(inst, this._getDefaultDate(inst), true);
10542		this._updateDatepicker(inst);
10543		this._updateAlternate(inst);
10544		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
10545		if( inst.settings.disabled ) {
10546			this._disableDatepicker( target );
10547		}
10548		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
10549		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
10550		inst.dpDiv.css( "display", "block" );
10551	},
10552
10553	/* Pop-up the date picker in a "dialog" box.
10554	 * @param  input element - ignored
10555	 * @param  date	string or Date - the initial date to display
10556	 * @param  onSelect  function - the function to call when a date is selected
10557	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
10558	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
10559	 *					event - with x/y coordinates or
10560	 *					leave empty for default (screen centre)
10561	 * @return the manager object
10562	 */
10563	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
10564		var id, browserWidth, browserHeight, scrollX, scrollY,
10565			inst = this._dialogInst; // internal instance
10566
10567		if (!inst) {
10568			this.uuid += 1;
10569			id = "dp" + this.uuid;
10570			this._dialogInput = $("<input type='text' id='" + id +
10571				"' style='position: absolute; top: -100px; width: 0px;'/>");
10572			this._dialogInput.keydown(this._doKeyDown);
10573			$("body").append(this._dialogInput);
10574			inst = this._dialogInst = this._newInst(this._dialogInput, false);
10575			inst.settings = {};
10576			$.data(this._dialogInput[0], PROP_NAME, inst);
10577		}
10578		extendRemove(inst.settings, settings || {});
10579		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
10580		this._dialogInput.val(date);
10581
10582		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
10583		if (!this._pos) {
10584			browserWidth = document.documentElement.clientWidth;
10585			browserHeight = document.documentElement.clientHeight;
10586			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
10587			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
10588			this._pos = // should use actual width/height below
10589				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
10590		}
10591
10592		// move input on screen for focus, but hidden behind dialog
10593		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
10594		inst.settings.onSelect = onSelect;
10595		this._inDialog = true;
10596		this.dpDiv.addClass(this._dialogClass);
10597		this._showDatepicker(this._dialogInput[0]);
10598		if ($.blockUI) {
10599			$.blockUI(this.dpDiv);
10600		}
10601		$.data(this._dialogInput[0], PROP_NAME, inst);
10602		return this;
10603	},
10604
10605	/* Detach a datepicker from its control.
10606	 * @param  target	element - the target input field or division or span
10607	 */
10608	_destroyDatepicker: function(target) {
10609		var nodeName,
10610			$target = $(target),
10611			inst = $.data(target, PROP_NAME);
10612
10613		if (!$target.hasClass(this.markerClassName)) {
10614			return;
10615		}
10616
10617		nodeName = target.nodeName.toLowerCase();
10618		$.removeData(target, PROP_NAME);
10619		if (nodeName === "input") {
10620			inst.append.remove();
10621			inst.trigger.remove();
10622			$target.removeClass(this.markerClassName).
10623				unbind("focus", this._showDatepicker).
10624				unbind("keydown", this._doKeyDown).
10625				unbind("keypress", this._doKeyPress).
10626				unbind("keyup", this._doKeyUp);
10627		} else if (nodeName === "div" || nodeName === "span") {
10628			$target.removeClass(this.markerClassName).empty();
10629		}
10630	},
10631
10632	/* Enable the date picker to a jQuery selection.
10633	 * @param  target	element - the target input field or division or span
10634	 */
10635	_enableDatepicker: function(target) {
10636		var nodeName, inline,
10637			$target = $(target),
10638			inst = $.data(target, PROP_NAME);
10639
10640		if (!$target.hasClass(this.markerClassName)) {
10641			return;
10642		}
10643
10644		nodeName = target.nodeName.toLowerCase();
10645		if (nodeName === "input") {
10646			target.disabled = false;
10647			inst.trigger.filter("button").
10648				each(function() { this.disabled = false; }).end().
10649				filter("img").css({opacity: "1.0", cursor: ""});
10650		} else if (nodeName === "div" || nodeName === "span") {
10651			inline = $target.children("." + this._inlineClass);
10652			inline.children().removeClass("ui-state-disabled");
10653			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
10654				prop("disabled", false);
10655		}
10656		this._disabledInputs = $.map(this._disabledInputs,
10657			function(value) { return (value === target ? null : value); }); // delete entry
10658	},
10659
10660	/* Disable the date picker to a jQuery selection.
10661	 * @param  target	element - the target input field or division or span
10662	 */
10663	_disableDatepicker: function(target) {
10664		var nodeName, inline,
10665			$target = $(target),
10666			inst = $.data(target, PROP_NAME);
10667
10668		if (!$target.hasClass(this.markerClassName)) {
10669			return;
10670		}
10671
10672		nodeName = target.nodeName.toLowerCase();
10673		if (nodeName === "input") {
10674			target.disabled = true;
10675			inst.trigger.filter("button").
10676				each(function() { this.disabled = true; }).end().
10677				filter("img").css({opacity: "0.5", cursor: "default"});
10678		} else if (nodeName === "div" || nodeName === "span") {
10679			inline = $target.children("." + this._inlineClass);
10680			inline.children().addClass("ui-state-disabled");
10681			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
10682				prop("disabled", true);
10683		}
10684		this._disabledInputs = $.map(this._disabledInputs,
10685			function(value) { return (value === target ? null : value); }); // delete entry
10686		this._disabledInputs[this._disabledInputs.length] = target;
10687	},
10688
10689	/* Is the first field in a jQuery collection disabled as a datepicker?
10690	 * @param  target	element - the target input field or division or span
10691	 * @return boolean - true if disabled, false if enabled
10692	 */
10693	_isDisabledDatepicker: function(target) {
10694		if (!target) {
10695			return false;
10696		}
10697		for (var i = 0; i < this._disabledInputs.length; i++) {
10698			if (this._disabledInputs[i] === target) {
10699				return true;
10700			}
10701		}
10702		return false;
10703	},
10704
10705	/* Retrieve the instance data for the target control.
10706	 * @param  target  element - the target input field or division or span
10707	 * @return  object - the associated instance data
10708	 * @throws  error if a jQuery problem getting data
10709	 */
10710	_getInst: function(target) {
10711		try {
10712			return $.data(target, PROP_NAME);
10713		}
10714		catch (err) {
10715			throw "Missing instance data for this datepicker";
10716		}
10717	},
10718
10719	/* Update or retrieve the settings for a date picker attached to an input field or division.
10720	 * @param  target  element - the target input field or division or span
10721	 * @param  name	object - the new settings to update or
10722	 *				string - the name of the setting to change or retrieve,
10723	 *				when retrieving also "all" for all instance settings or
10724	 *				"defaults" for all global defaults
10725	 * @param  value   any - the new value for the setting
10726	 *				(omit if above is an object or to retrieve a value)
10727	 */
10728	_optionDatepicker: function(target, name, value) {
10729		var settings, date, minDate, maxDate,
10730			inst = this._getInst(target);
10731
10732		if (arguments.length === 2 && typeof name === "string") {
10733			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
10734				(inst ? (name === "all" ? $.extend({}, inst.settings) :
10735				this._get(inst, name)) : null));
10736		}
10737
10738		settings = name || {};
10739		if (typeof name === "string") {
10740			settings = {};
10741			settings[name] = value;
10742		}
10743
10744		if (inst) {
10745			if (this._curInst === inst) {
10746				this._hideDatepicker();
10747			}
10748
10749			date = this._getDateDatepicker(target, true);
10750			minDate = this._getMinMaxDate(inst, "min");
10751			maxDate = this._getMinMaxDate(inst, "max");
10752			extendRemove(inst.settings, settings);
10753			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
10754			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
10755				inst.settings.minDate = this._formatDate(inst, minDate);
10756			}
10757			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
10758				inst.settings.maxDate = this._formatDate(inst, maxDate);
10759			}
10760			if ( "disabled" in settings ) {
10761				if ( settings.disabled ) {
10762					this._disableDatepicker(target);
10763				} else {
10764					this._enableDatepicker(target);
10765				}
10766			}
10767			this._attachments($(target), inst);
10768			this._autoSize(inst);
10769			this._setDate(inst, date);
10770			this._updateAlternate(inst);
10771			this._updateDatepicker(inst);
10772		}
10773	},
10774
10775	// change method deprecated
10776	_changeDatepicker: function(target, name, value) {
10777		this._optionDatepicker(target, name, value);
10778	},
10779
10780	/* Redraw the date picker attached to an input field or division.
10781	 * @param  target  element - the target input field or division or span
10782	 */
10783	_refreshDatepicker: function(target) {
10784		var inst = this._getInst(target);
10785		if (inst) {
10786			this._updateDatepicker(inst);
10787		}
10788	},
10789
10790	/* Set the dates for a jQuery selection.
10791	 * @param  target element - the target input field or division or span
10792	 * @param  date	Date - the new date
10793	 */
10794	_setDateDatepicker: function(target, date) {
10795		var inst = this._getInst(target);
10796		if (inst) {
10797			this._setDate(inst, date);
10798			this._updateDatepicker(inst);
10799			this._updateAlternate(inst);
10800		}
10801	},
10802
10803	/* Get the date(s) for the first entry in a jQuery selection.
10804	 * @param  target element - the target input field or division or span
10805	 * @param  noDefault boolean - true if no default date is to be used
10806	 * @return Date - the current date
10807	 */
10808	_getDateDatepicker: function(target, noDefault) {
10809		var inst = this._getInst(target);
10810		if (inst && !inst.inline) {
10811			this._setDateFromField(inst, noDefault);
10812		}
10813		return (inst ? this._getDate(inst) : null);
10814	},
10815
10816	/* Handle keystrokes. */
10817	_doKeyDown: function(event) {
10818		var onSelect, dateStr, sel,
10819			inst = $.datepicker._getInst(event.target),
10820			handled = true,
10821			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
10822
10823		inst._keyEvent = true;
10824		if ($.datepicker._datepickerShowing) {
10825			switch (event.keyCode) {
10826				case 9: $.datepicker._hideDatepicker();
10827						handled = false;
10828						break; // hide on tab out
10829				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
10830									$.datepicker._currentClass + ")", inst.dpDiv);
10831						if (sel[0]) {
10832							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
10833						}
10834
10835						onSelect = $.datepicker._get(inst, "onSelect");
10836						if (onSelect) {
10837							dateStr = $.datepicker._formatDate(inst);
10838
10839							// trigger custom callback
10840							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
10841						} else {
10842							$.datepicker._hideDatepicker();
10843						}
10844
10845						return false; // don't submit the form
10846				case 27: $.datepicker._hideDatepicker();
10847						break; // hide on escape
10848				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
10849							-$.datepicker._get(inst, "stepBigMonths") :
10850							-$.datepicker._get(inst, "stepMonths")), "M");
10851						break; // previous month/year on page up/+ ctrl
10852				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
10853							+$.datepicker._get(inst, "stepBigMonths") :
10854							+$.datepicker._get(inst, "stepMonths")), "M");
10855						break; // next month/year on page down/+ ctrl
10856				case 35: if (event.ctrlKey || event.metaKey) {
10857							$.datepicker._clearDate(event.target);
10858						}
10859						handled = event.ctrlKey || event.metaKey;
10860						break; // clear on ctrl or command +end
10861				case 36: if (event.ctrlKey || event.metaKey) {
10862							$.datepicker._gotoToday(event.target);
10863						}
10864						handled = event.ctrlKey || event.metaKey;
10865						break; // current on ctrl or command +home
10866				case 37: if (event.ctrlKey || event.metaKey) {
10867							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
10868						}
10869						handled = event.ctrlKey || event.metaKey;
10870						// -1 day on ctrl or command +left
10871						if (event.originalEvent.altKey) {
10872							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
10873								-$.datepicker._get(inst, "stepBigMonths") :
10874								-$.datepicker._get(inst, "stepMonths")), "M");
10875						}
10876						// next month/year on alt +left on Mac
10877						break;
10878				case 38: if (event.ctrlKey || event.metaKey) {
10879							$.datepicker._adjustDate(event.target, -7, "D");
10880						}
10881						handled = event.ctrlKey || event.metaKey;
10882						break; // -1 week on ctrl or command +up
10883				case 39: if (event.ctrlKey || event.metaKey) {
10884							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
10885						}
10886						handled = event.ctrlKey || event.metaKey;
10887						// +1 day on ctrl or command +right
10888						if (event.originalEvent.altKey) {
10889							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
10890								+$.datepicker._get(inst, "stepBigMonths") :
10891								+$.datepicker._get(inst, "stepMonths")), "M");
10892						}
10893						// next month/year on alt +right
10894						break;
10895				case 40: if (event.ctrlKey || event.metaKey) {
10896							$.datepicker._adjustDate(event.target, +7, "D");
10897						}
10898						handled = event.ctrlKey || event.metaKey;
10899						break; // +1 week on ctrl or command +down
10900				default: handled = false;
10901			}
10902		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
10903			$.datepicker._showDatepicker(this);
10904		} else {
10905			handled = false;
10906		}
10907
10908		if (handled) {
10909			event.preventDefault();
10910			event.stopPropagation();
10911		}
10912	},
10913
10914	/* Filter entered characters - based on date format. */
10915	_doKeyPress: function(event) {
10916		var chars, chr,
10917			inst = $.datepicker._getInst(event.target);
10918
10919		if ($.datepicker._get(inst, "constrainInput")) {
10920			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
10921			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
10922			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
10923		}
10924	},
10925
10926	/* Synchronise manual entry and field/alternate field. */
10927	_doKeyUp: function(event) {
10928		var date,
10929			inst = $.datepicker._getInst(event.target);
10930
10931		if (inst.input.val() !== inst.lastVal) {
10932			try {
10933				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
10934					(inst.input ? inst.input.val() : null),
10935					$.datepicker._getFormatConfig(inst));
10936
10937				if (date) { // only if valid
10938					$.datepicker._setDateFromField(inst);
10939					$.datepicker._updateAlternate(inst);
10940					$.datepicker._updateDatepicker(inst);
10941				}
10942			}
10943			catch (err) {
10944			}
10945		}
10946		return true;
10947	},
10948
10949	/* Pop-up the date picker for a given input field.
10950	 * If false returned from beforeShow event handler do not show.
10951	 * @param  input  element - the input field attached to the date picker or
10952	 *					event - if triggered by focus
10953	 */
10954	_showDatepicker: function(input) {
10955		input = input.target || input;
10956		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
10957			input = $("input", input.parentNode)[0];
10958		}
10959
10960		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
10961			return;
10962		}
10963
10964		var inst, beforeShow, beforeShowSettings, isFixed,
10965			offset, showAnim, duration;
10966
10967		inst = $.datepicker._getInst(input);
10968		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
10969			$.datepicker._curInst.dpDiv.stop(true, true);
10970			if ( inst && $.datepicker._datepickerShowing ) {
10971				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
10972			}
10973		}
10974
10975		beforeShow = $.datepicker._get(inst, "beforeShow");
10976		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
10977		if(beforeShowSettings === false){
10978			return;
10979		}
10980		extendRemove(inst.settings, beforeShowSettings);
10981
10982		inst.lastVal = null;
10983		$.datepicker._lastInput = input;
10984		$.datepicker._setDateFromField(inst);
10985
10986		if ($.datepicker._inDialog) { // hide cursor
10987			input.value = "";
10988		}
10989		if (!$.datepicker._pos) { // position below input
10990			$.datepicker._pos = $.datepicker._findPos(input);
10991			$.datepicker._pos[1] += input.offsetHeight; // add the height
10992		}
10993
10994		isFixed = false;
10995		$(input).parents().each(function() {
10996			isFixed |= $(this).css("position") === "fixed";
10997			return !isFixed;
10998		});
10999
11000		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
11001		$.datepicker._pos = null;
11002		//to avoid flashes on Firefox
11003		inst.dpDiv.empty();
11004		// determine sizing offscreen
11005		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
11006		$.datepicker._updateDatepicker(inst);
11007		// fix width for dynamic number of date pickers
11008		// and adjust position before showing
11009		offset = $.datepicker._checkOffset(inst, offset, isFixed);
11010		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
11011			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
11012			left: offset.left + "px", top: offset.top + "px"});
11013
11014		if (!inst.inline) {
11015			showAnim = $.datepicker._get(inst, "showAnim");
11016			duration = $.datepicker._get(inst, "duration");
11017			inst.dpDiv.zIndex($(input).zIndex()+1);
11018			$.datepicker._datepickerShowing = true;
11019
11020			if ( $.effects && $.effects.effect[ showAnim ] ) {
11021				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
11022			} else {
11023				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
11024			}
11025
11026			if ( $.datepicker._shouldFocusInput( inst ) ) {
11027				inst.input.focus();
11028			}
11029
11030			$.datepicker._curInst = inst;
11031		}
11032	},
11033
11034	/* Generate the date picker content. */
11035	_updateDatepicker: function(inst) {
11036		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
11037		instActive = inst; // for delegate hover events
11038		inst.dpDiv.empty().append(this._generateHTML(inst));
11039		this._attachHandlers(inst);
11040		inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
11041
11042		var origyearshtml,
11043			numMonths = this._getNumberOfMonths(inst),
11044			cols = numMonths[1],
11045			width = 17;
11046
11047		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
11048		if (cols > 1) {
11049			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
11050		}
11051		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
11052			"Class"]("ui-datepicker-multi");
11053		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
11054			"Class"]("ui-datepicker-rtl");
11055
11056		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
11057			inst.input.focus();
11058		}
11059
11060		// deffered render of the years select (to avoid flashes on Firefox)
11061		if( inst.yearshtml ){
11062			origyearshtml = inst.yearshtml;
11063			setTimeout(function(){
11064				//assure that inst.yearshtml didn't change.
11065				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
11066					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
11067				}
11068				origyearshtml = inst.yearshtml = null;
11069			}, 0);
11070		}
11071	},
11072
11073	// #6694 - don't focus the input if it's already focused
11074	// this breaks the change event in IE
11075	// Support: IE and jQuery <1.9
11076	_shouldFocusInput: function( inst ) {
11077		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
11078	},
11079
11080	/* Check positioning to remain on screen. */
11081	_checkOffset: function(inst, offset, isFixed) {
11082		var dpWidth = inst.dpDiv.outerWidth(),
11083			dpHeight = inst.dpDiv.outerHeight(),
11084			inputWidth = inst.input ? inst.input.outerWidth() : 0,
11085			inputHeight = inst.input ? inst.input.outerHeight() : 0,
11086			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
11087			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
11088
11089		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
11090		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
11091		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
11092
11093		// now check if datepicker is showing outside window viewport - move to a better place if so.
11094		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
11095			Math.abs(offset.left + dpWidth - viewWidth) : 0);
11096		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
11097			Math.abs(dpHeight + inputHeight) : 0);
11098
11099		return offset;
11100	},
11101
11102	/* Find an object's position on the screen. */
11103	_findPos: function(obj) {
11104		var position,
11105			inst = this._getInst(obj),
11106			isRTL = this._get(inst, "isRTL");
11107
11108		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
11109			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
11110		}
11111
11112		position = $(obj).offset();
11113		return [position.left, position.top];
11114	},
11115
11116	/* Hide the date picker from view.
11117	 * @param  input  element - the input field attached to the date picker
11118	 */
11119	_hideDatepicker: function(input) {
11120		var showAnim, duration, postProcess, onClose,
11121			inst = this._curInst;
11122
11123		if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
11124			return;
11125		}
11126
11127		if (this._datepickerShowing) {
11128			showAnim = this._get(inst, "showAnim");
11129			duration = this._get(inst, "duration");
11130			postProcess = function() {
11131				$.datepicker._tidyDialog(inst);
11132			};
11133
11134			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
11135			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
11136				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
11137			} else {
11138				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
11139					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
11140			}
11141
11142			if (!showAnim) {
11143				postProcess();
11144			}
11145			this._datepickerShowing = false;
11146
11147			onClose = this._get(inst, "onClose");
11148			if (onClose) {
11149				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
11150			}
11151
11152			this._lastInput = null;
11153			if (this._inDialog) {
11154				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
11155				if ($.blockUI) {
11156					$.unblockUI();
11157					$("body").append(this.dpDiv);
11158				}
11159			}
11160			this._inDialog = false;
11161		}
11162	},
11163
11164	/* Tidy up after a dialog display. */
11165	_tidyDialog: function(inst) {
11166		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
11167	},
11168
11169	/* Close date picker if clicked elsewhere. */
11170	_checkExternalClick: function(event) {
11171		if (!$.datepicker._curInst) {
11172			return;
11173		}
11174
11175		var $target = $(event.target),
11176			inst = $.datepicker._getInst($target[0]);
11177
11178		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
11179				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
11180				!$target.hasClass($.datepicker.markerClassName) &&
11181				!$target.closest("." + $.datepicker._triggerClass).length &&
11182				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
11183			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
11184				$.datepicker._hideDatepicker();
11185		}
11186	},
11187
11188	/* Adjust one of the date sub-fields. */
11189	_adjustDate: function(id, offset, period) {
11190		var target = $(id),
11191			inst = this._getInst(target[0]);
11192
11193		if (this._isDisabledDatepicker(target[0])) {
11194			return;
11195		}
11196		this._adjustInstDate(inst, offset +
11197			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
11198			period);
11199		this._updateDatepicker(inst);
11200	},
11201
11202	/* Action for current link. */
11203	_gotoToday: function(id) {
11204		var date,
11205			target = $(id),
11206			inst = this._getInst(target[0]);
11207
11208		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
11209			inst.selectedDay = inst.currentDay;
11210			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
11211			inst.drawYear = inst.selectedYear = inst.currentYear;
11212		} else {
11213			date = new Date();
11214			inst.selectedDay = date.getDate();
11215			inst.drawMonth = inst.selectedMonth = date.getMonth();
11216			inst.drawYear = inst.selectedYear = date.getFullYear();
11217		}
11218		this._notifyChange(inst);
11219		this._adjustDate(target);
11220	},
11221
11222	/* Action for selecting a new month/year. */
11223	_selectMonthYear: function(id, select, period) {
11224		var target = $(id),
11225			inst = this._getInst(target[0]);
11226
11227		inst["selected" + (period === "M" ? "Month" : "Year")] =
11228		inst["draw" + (period === "M" ? "Month" : "Year")] =
11229			parseInt(select.options[select.selectedIndex].value,10);
11230
11231		this._notifyChange(inst);
11232		this._adjustDate(target);
11233	},
11234
11235	/* Action for selecting a day. */
11236	_selectDay: function(id, month, year, td) {
11237		var inst,
11238			target = $(id);
11239
11240		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
11241			return;
11242		}
11243
11244		inst = this._getInst(target[0]);
11245		inst.selectedDay = inst.currentDay = $("a", td).html();
11246		inst.selectedMonth = inst.currentMonth = month;
11247		inst.selectedYear = inst.currentYear = year;
11248		this._selectDate(id, this._formatDate(inst,
11249			inst.currentDay, inst.currentMonth, inst.currentYear));
11250	},
11251
11252	/* Erase the input field and hide the date picker. */
11253	_clearDate: function(id) {
11254		var target = $(id);
11255		this._selectDate(target, "");
11256	},
11257
11258	/* Update the input field with the selected date. */
11259	_selectDate: function(id, dateStr) {
11260		var onSelect,
11261			target = $(id),
11262			inst = this._getInst(target[0]);
11263
11264		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
11265		if (inst.input) {
11266			inst.input.val(dateStr);
11267		}
11268		this._updateAlternate(inst);
11269
11270		onSelect = this._get(inst, "onSelect");
11271		if (onSelect) {
11272			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
11273		} else if (inst.input) {
11274			inst.input.trigger("change"); // fire the change event
11275		}
11276
11277		if (inst.inline){
11278			this._updateDatepicker(inst);
11279		} else {
11280			this._hideDatepicker();
11281			this._lastInput = inst.input[0];
11282			if (typeof(inst.input[0]) !== "object") {
11283				inst.input.focus(); // restore focus
11284			}
11285			this._lastInput = null;
11286		}
11287	},
11288
11289	/* Update any alternate field to synchronise with the main field. */
11290	_updateAlternate: function(inst) {
11291		var altFormat, date, dateStr,
11292			altField = this._get(inst, "altField");
11293
11294		if (altField) { // update alternate field too
11295			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
11296			date = this._getDate(inst);
11297			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
11298			$(altField).each(function() { $(this).val(dateStr); });
11299		}
11300	},
11301
11302	/* Set as beforeShowDay function to prevent selection of weekends.
11303	 * @param  date  Date - the date to customise
11304	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
11305	 */
11306	noWeekends: function(date) {
11307		var day = date.getDay();
11308		return [(day > 0 && day < 6), ""];
11309	},
11310
11311	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
11312	 * @param  date  Date - the date to get the week for
11313	 * @return  number - the number of the week within the year that contains this date
11314	 */
11315	iso8601Week: function(date) {
11316		var time,
11317			checkDate = new Date(date.getTime());
11318
11319		// Find Thursday of this week starting on Monday
11320		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
11321
11322		time = checkDate.getTime();
11323		checkDate.setMonth(0); // Compare with Jan 1
11324		checkDate.setDate(1);
11325		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
11326	},
11327
11328	/* Parse a string value into a date object.
11329	 * See formatDate below for the possible formats.
11330	 *
11331	 * @param  format string - the expected format of the date
11332	 * @param  value string - the date in the above format
11333	 * @param  settings Object - attributes include:
11334	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
11335	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
11336	 *					dayNames		string[7] - names of the days from Sunday (optional)
11337	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
11338	 *					monthNames		string[12] - names of the months (optional)
11339	 * @return  Date - the extracted date value or null if value is blank
11340	 */
11341	parseDate: function (format, value, settings) {
11342		if (format == null || value == null) {
11343			throw "Invalid arguments";
11344		}
11345
11346		value = (typeof value === "object" ? value.toString() : value + "");
11347		if (value === "") {
11348			return null;
11349		}
11350
11351		var iFormat, dim, extra,
11352			iValue = 0,
11353			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
11354			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
11355				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
11356			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
11357			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
11358			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
11359			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
11360			year = -1,
11361			month = -1,
11362			day = -1,
11363			doy = -1,
11364			literal = false,
11365			date,
11366			// Check whether a format character is doubled
11367			lookAhead = function(match) {
11368				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
11369				if (matches) {
11370					iFormat++;
11371				}
11372				return matches;
11373			},
11374			// Extract a number from the string value
11375			getNumber = function(match) {
11376				var isDoubled = lookAhead(match),
11377					size = (match === "@" ? 14 : (match === "!" ? 20 :
11378					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
11379					digits = new RegExp("^\\d{1," + size + "}"),
11380					num = value.substring(iValue).match(digits);
11381				if (!num) {
11382					throw "Missing number at position " + iValue;
11383				}
11384				iValue += num[0].length;
11385				return parseInt(num[0], 10);
11386			},
11387			// Extract a name from the string value and convert to an index
11388			getName = function(match, shortNames, longNames) {
11389				var index = -1,
11390					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
11391						return [ [k, v] ];
11392					}).sort(function (a, b) {
11393						return -(a[1].length - b[1].length);
11394					});
11395
11396				$.each(names, function (i, pair) {
11397					var name = pair[1];
11398					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
11399						index = pair[0];
11400						iValue += name.length;
11401						return false;
11402					}
11403				});
11404				if (index !== -1) {
11405					return index + 1;
11406				} else {
11407					throw "Unknown name at position " + iValue;
11408				}
11409			},
11410			// Confirm that a literal character matches the string value
11411			checkLiteral = function() {
11412				if (value.charAt(iValue) !== format.charAt(iFormat)) {
11413					throw "Unexpected literal at position " + iValue;
11414				}
11415				iValue++;
11416			};
11417
11418		for (iFormat = 0; iFormat < format.length; iFormat++) {
11419			if (literal) {
11420				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
11421					literal = false;
11422				} else {
11423					checkLiteral();
11424				}
11425			} else {
11426				switch (format.charAt(iFormat)) {
11427					case "d":
11428						day = getNumber("d");
11429						break;
11430					case "D":
11431						getName("D", dayNamesShort, dayNames);
11432						break;
11433					case "o":
11434						doy = getNumber("o");
11435						break;
11436					case "m":
11437						month = getNumber("m");
11438						break;
11439					case "M":
11440						month = getName("M", monthNamesShort, monthNames);
11441						break;
11442					case "y":
11443						year = getNumber("y");
11444						break;
11445					case "@":
11446						date = new Date(getNumber("@"));
11447						year = date.getFullYear();
11448						month = date.getMonth() + 1;
11449						day = date.getDate();
11450						break;
11451					case "!":
11452						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
11453						year = date.getFullYear();
11454						month = date.getMonth() + 1;
11455						day = date.getDate();
11456						break;
11457					case "'":
11458						if (lookAhead("'")){
11459							checkLiteral();
11460						} else {
11461							literal = true;
11462						}
11463						break;
11464					default:
11465						checkLiteral();
11466				}
11467			}
11468		}
11469
11470		if (iValue < value.length){
11471			extra = value.substr(iValue);
11472			if (!/^\s+/.test(extra)) {
11473				throw "Extra/unparsed characters found in date: " + extra;
11474			}
11475		}
11476
11477		if (year === -1) {
11478			year = new Date().getFullYear();
11479		} else if (year < 100) {
11480			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
11481				(year <= shortYearCutoff ? 0 : -100);
11482		}
11483
11484		if (doy > -1) {
11485			month = 1;
11486			day = doy;
11487			do {
11488				dim = this._getDaysInMonth(year, month - 1);
11489				if (day <= dim) {
11490					break;
11491				}
11492				month++;
11493				day -= dim;
11494			} while (true);
11495		}
11496
11497		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
11498		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
11499			throw "Invalid date"; // E.g. 31/02/00
11500		}
11501		return date;
11502	},
11503
11504	/* Standard date formats. */
11505	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
11506	COOKIE: "D, dd M yy",
11507	ISO_8601: "yy-mm-dd",
11508	RFC_822: "D, d M y",
11509	RFC_850: "DD, dd-M-y",
11510	RFC_1036: "D, d M y",
11511	RFC_1123: "D, d M yy",
11512	RFC_2822: "D, d M yy",
11513	RSS: "D, d M y", // RFC 822
11514	TICKS: "!",
11515	TIMESTAMP: "@",
11516	W3C: "yy-mm-dd", // ISO 8601
11517
11518	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
11519		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
11520
11521	/* Format a date object into a string value.
11522	 * The format can be combinations of the following:
11523	 * d  - day of month (no leading zero)
11524	 * dd - day of month (two digit)
11525	 * o  - day of year (no leading zeros)
11526	 * oo - day of year (three digit)
11527	 * D  - day name short
11528	 * DD - day name long
11529	 * m  - month of year (no leading zero)
11530	 * mm - month of year (two digit)
11531	 * M  - month name short
11532	 * MM - month name long
11533	 * y  - year (two digit)
11534	 * yy - year (four digit)
11535	 * @ - Unix timestamp (ms since 01/01/1970)
11536	 * ! - Windows ticks (100ns since 01/01/0001)
11537	 * "..." - literal text
11538	 * '' - single quote
11539	 *
11540	 * @param  format string - the desired format of the date
11541	 * @param  date Date - the date value to format
11542	 * @param  settings Object - attributes include:
11543	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
11544	 *					dayNames		string[7] - names of the days from Sunday (optional)
11545	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
11546	 *					monthNames		string[12] - names of the months (optional)
11547	 * @return  string - the date in the above format
11548	 */
11549	formatDate: function (format, date, settings) {
11550		if (!date) {
11551			return "";
11552		}
11553
11554		var iFormat,
11555			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
11556			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
11557			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
11558			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
11559			// Check whether a format character is doubled
11560			lookAhead = function(match) {
11561				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
11562				if (matches) {
11563					iFormat++;
11564				}
11565				return matches;
11566			},
11567			// Format a number, with leading zero if necessary
11568			formatNumber = function(match, value, len) {
11569				var num = "" + value;
11570				if (lookAhead(match)) {
11571					while (num.length < len) {
11572						num = "0" + num;
11573					}
11574				}
11575				return num;
11576			},
11577			// Format a name, short or long as requested
11578			formatName = function(match, value, shortNames, longNames) {
11579				return (lookAhead(match) ? longNames[value] : shortNames[value]);
11580			},
11581			output = "",
11582			literal = false;
11583
11584		if (date) {
11585			for (iFormat = 0; iFormat < format.length; iFormat++) {
11586				if (literal) {
11587					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
11588						literal = false;
11589					} else {
11590						output += format.charAt(iFormat);
11591					}
11592				} else {
11593					switch (format.charAt(iFormat)) {
11594						case "d":
11595							output += formatNumber("d", date.getDate(), 2);
11596							break;
11597						case "D":
11598							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
11599							break;
11600						case "o":
11601							output += formatNumber("o",
11602								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
11603							break;
11604						case "m":
11605							output += formatNumber("m", date.getMonth() + 1, 2);
11606							break;
11607						case "M":
11608							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
11609							break;
11610						case "y":
11611							output += (lookAhead("y") ? date.getFullYear() :
11612								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
11613							break;
11614						case "@":
11615							output += date.getTime();
11616							break;
11617						case "!":
11618							output += date.getTime() * 10000 + this._ticksTo1970;
11619							break;
11620						case "'":
11621							if (lookAhead("'")) {
11622								output += "'";
11623							} else {
11624								literal = true;
11625							}
11626							break;
11627						default:
11628							output += format.charAt(iFormat);
11629					}
11630				}
11631			}
11632		}
11633		return output;
11634	},
11635
11636	/* Extract all possible characters from the date format. */
11637	_possibleChars: function (format) {
11638		var iFormat,
11639			chars = "",
11640			literal = false,
11641			// Check whether a format character is doubled
11642			lookAhead = function(match) {
11643				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
11644				if (matches) {
11645					iFormat++;
11646				}
11647				return matches;
11648			};
11649
11650		for (iFormat = 0; iFormat < format.length; iFormat++) {
11651			if (literal) {
11652				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
11653					literal = false;
11654				} else {
11655					chars += format.charAt(iFormat);
11656				}
11657			} else {
11658				switch (format.charAt(iFormat)) {
11659					case "d": case "m": case "y": case "@":
11660						chars += "0123456789";
11661						break;
11662					case "D": case "M":
11663						return null; // Accept anything
11664					case "'":
11665						if (lookAhead("'")) {
11666							chars += "'";
11667						} else {
11668							literal = true;
11669						}
11670						break;
11671					default:
11672						chars += format.charAt(iFormat);
11673				}
11674			}
11675		}
11676		return chars;
11677	},
11678
11679	/* Get a setting value, defaulting if necessary. */
11680	_get: function(inst, name) {
11681		return inst.settings[name] !== undefined ?
11682			inst.settings[name] : this._defaults[name];
11683	},
11684
11685	/* Parse existing date and initialise date picker. */
11686	_setDateFromField: function(inst, noDefault) {
11687		if (inst.input.val() === inst.lastVal) {
11688			return;
11689		}
11690
11691		var dateFormat = this._get(inst, "dateFormat"),
11692			dates = inst.lastVal = inst.input ? inst.input.val() : null,
11693			defaultDate = this._getDefaultDate(inst),
11694			date = defaultDate,
11695			settings = this._getFormatConfig(inst);
11696
11697		try {
11698			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
11699		} catch (event) {
11700			dates = (noDefault ? "" : dates);
11701		}
11702		inst.selectedDay = date.getDate();
11703		inst.drawMonth = inst.selectedMonth = date.getMonth();
11704		inst.drawYear = inst.selectedYear = date.getFullYear();
11705		inst.currentDay = (dates ? date.getDate() : 0);
11706		inst.currentMonth = (dates ? date.getMonth() : 0);
11707		inst.currentYear = (dates ? date.getFullYear() : 0);
11708		this._adjustInstDate(inst);
11709	},
11710
11711	/* Retrieve the default date shown on opening. */
11712	_getDefaultDate: function(inst) {
11713		return this._restrictMinMax(inst,
11714			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
11715	},
11716
11717	/* A date may be specified as an exact value or a relative one. */
11718	_determineDate: function(inst, date, defaultDate) {
11719		var offsetNumeric = function(offset) {
11720				var date = new Date();
11721				date.setDate(date.getDate() + offset);
11722				return date;
11723			},
11724			offsetString = function(offset) {
11725				try {
11726					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
11727						offset, $.datepicker._getFormatConfig(inst));
11728				}
11729				catch (e) {
11730					// Ignore
11731				}
11732
11733				var date = (offset.toLowerCase().match(/^c/) ?
11734					$.datepicker._getDate(inst) : null) || new Date(),
11735					year = date.getFullYear(),
11736					month = date.getMonth(),
11737					day = date.getDate(),
11738					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
11739					matches = pattern.exec(offset);
11740
11741				while (matches) {
11742					switch (matches[2] || "d") {
11743						case "d" : case "D" :
11744							day += parseInt(matches[1],10); break;
11745						case "w" : case "W" :
11746							day += parseInt(matches[1],10) * 7; break;
11747						case "m" : case "M" :
11748							month += parseInt(matches[1],10);
11749							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
11750							break;
11751						case "y": case "Y" :
11752							year += parseInt(matches[1],10);
11753							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
11754							break;
11755					}
11756					matches = pattern.exec(offset);
11757				}
11758				return new Date(year, month, day);
11759			},
11760			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
11761				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
11762
11763		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
11764		if (newDate) {
11765			newDate.setHours(0);
11766			newDate.setMinutes(0);
11767			newDate.setSeconds(0);
11768			newDate.setMilliseconds(0);
11769		}
11770		return this._daylightSavingAdjust(newDate);
11771	},
11772
11773	/* Handle switch to/from daylight saving.
11774	 * Hours may be non-zero on daylight saving cut-over:
11775	 * > 12 when midnight changeover, but then cannot generate
11776	 * midnight datetime, so jump to 1AM, otherwise reset.
11777	 * @param  date  (Date) the date to check
11778	 * @return  (Date) the corrected date
11779	 */
11780	_daylightSavingAdjust: function(date) {
11781		if (!date) {
11782			return null;
11783		}
11784		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
11785		return date;
11786	},
11787
11788	/* Set the date(s) directly. */
11789	_setDate: function(inst, date, noChange) {
11790		var clear = !date,
11791			origMonth = inst.selectedMonth,
11792			origYear = inst.selectedYear,
11793			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
11794
11795		inst.selectedDay = inst.currentDay = newDate.getDate();
11796		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
11797		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
11798		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
11799			this._notifyChange(inst);
11800		}
11801		this._adjustInstDate(inst);
11802		if (inst.input) {
11803			inst.input.val(clear ? "" : this._formatDate(inst));
11804		}
11805	},
11806
11807	/* Retrieve the date(s) directly. */
11808	_getDate: function(inst) {
11809		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
11810			this._daylightSavingAdjust(new Date(
11811			inst.currentYear, inst.currentMonth, inst.currentDay)));
11812			return startDate;
11813	},
11814
11815	/* Attach the onxxx handlers.  These are declared statically so
11816	 * they work with static code transformers like Caja.
11817	 */
11818	_attachHandlers: function(inst) {
11819		var stepMonths = this._get(inst, "stepMonths"),
11820			id = "#" + inst.id.replace( /\\\\/g, "\\" );
11821		inst.dpDiv.find("[data-handler]").map(function () {
11822			var handler = {
11823				prev: function () {
11824					$.datepicker._adjustDate(id, -stepMonths, "M");
11825				},
11826				next: function () {
11827					$.datepicker._adjustDate(id, +stepMonths, "M");
11828				},
11829				hide: function () {
11830					$.datepicker._hideDatepicker();
11831				},
11832				today: function () {
11833					$.datepicker._gotoToday(id);
11834				},
11835				selectDay: function () {
11836					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
11837					return false;
11838				},
11839				selectMonth: function () {
11840					$.datepicker._selectMonthYear(id, this, "M");
11841					return false;
11842				},
11843				selectYear: function () {
11844					$.datepicker._selectMonthYear(id, this, "Y");
11845					return false;
11846				}
11847			};
11848			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
11849		});
11850	},
11851
11852	/* Generate the HTML for the current state of the date picker. */
11853	_generateHTML: function(inst) {
11854		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
11855			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
11856			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
11857			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
11858			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
11859			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
11860			tempDate = new Date(),
11861			today = this._daylightSavingAdjust(
11862				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
11863			isRTL = this._get(inst, "isRTL"),
11864			showButtonPanel = this._get(inst, "showButtonPanel"),
11865			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
11866			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
11867			numMonths = this._getNumberOfMonths(inst),
11868			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
11869			stepMonths = this._get(inst, "stepMonths"),
11870			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
11871			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
11872				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
11873			minDate = this._getMinMaxDate(inst, "min"),
11874			maxDate = this._getMinMaxDate(inst, "max"),
11875			drawMonth = inst.drawMonth - showCurrentAtPos,
11876			drawYear = inst.drawYear;
11877
11878		if (drawMonth < 0) {
11879			drawMonth += 12;
11880			drawYear--;
11881		}
11882		if (maxDate) {
11883			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
11884				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
11885			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
11886			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
11887				drawMonth--;
11888				if (drawMonth < 0) {
11889					drawMonth = 11;
11890					drawYear--;
11891				}
11892			}
11893		}
11894		inst.drawMonth = drawMonth;
11895		inst.drawYear = drawYear;
11896
11897		prevText = this._get(inst, "prevText");
11898		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
11899			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
11900			this._getFormatConfig(inst)));
11901
11902		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
11903			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
11904			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
11905			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
11906
11907		nextText = this._get(inst, "nextText");
11908		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
11909			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
11910			this._getFormatConfig(inst)));
11911
11912		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
11913			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
11914			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
11915			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
11916
11917		currentText = this._get(inst, "currentText");
11918		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
11919		currentText = (!navigationAsDateFormat ? currentText :
11920			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
11921
11922		controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
11923			this._get(inst, "closeText") + "</button>" : "");
11924
11925		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
11926			(this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
11927			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
11928
11929		firstDay = parseInt(this._get(inst, "firstDay"),10);
11930		firstDay = (isNaN(firstDay) ? 0 : firstDay);
11931
11932		showWeek = this._get(inst, "showWeek");
11933		dayNames = this._get(inst, "dayNames");
11934		dayNamesMin = this._get(inst, "dayNamesMin");
11935		monthNames = this._get(inst, "monthNames");
11936		monthNamesShort = this._get(inst, "monthNamesShort");
11937		beforeShowDay = this._get(inst, "beforeShowDay");
11938		showOtherMonths = this._get(inst, "showOtherMonths");
11939		selectOtherMonths = this._get(inst, "selectOtherMonths");
11940		defaultDate = this._getDefaultDate(inst);
11941		html = "";
11942		dow;
11943		for (row = 0; row < numMonths[0]; row++) {
11944			group = "";
11945			this.maxRows = 4;
11946			for (col = 0; col < numMonths[1]; col++) {
11947				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
11948				cornerClass = " ui-corner-all";
11949				calender = "";
11950				if (isMultiMonth) {
11951					calender += "<div class='ui-datepicker-group";
11952					if (numMonths[1] > 1) {
11953						switch (col) {
11954							case 0: calender += " ui-datepicker-group-first";
11955								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
11956							case numMonths[1]-1: calender += " ui-datepicker-group-last";
11957								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
11958							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
11959						}
11960					}
11961					calender += "'>";
11962				}
11963				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
11964					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
11965					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
11966					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
11967					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
11968					"</div><table class='ui-datepicker-calendar'><thead>" +
11969					"<tr>";
11970				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
11971				for (dow = 0; dow < 7; dow++) { // days of the week
11972					day = (dow + firstDay) % 7;
11973					thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
11974						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
11975				}
11976				calender += thead + "</tr></thead><tbody>";
11977				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
11978				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
11979					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
11980				}
11981				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
11982				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
11983				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
11984				this.maxRows = numRows;
11985				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
11986				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
11987					calender += "<tr>";
11988					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
11989						this._get(inst, "calculateWeek")(printDate) + "</td>");
11990					for (dow = 0; dow < 7; dow++) { // create date picker days
11991						daySettings = (beforeShowDay ?
11992							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
11993						otherMonth = (printDate.getMonth() !== drawMonth);
11994						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
11995							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
11996						tbody += "<td class='" +
11997							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
11998							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
11999							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
12000							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
12001							// or defaultDate is current printedDate and defaultDate is selectedDate
12002							" " + this._dayOverClass : "") + // highlight selected day
12003							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
12004							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
12005							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
12006							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
12007							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
12008							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
12009							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
12010							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
12011							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
12012							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
12013							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
12014							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
12015						printDate.setDate(printDate.getDate() + 1);
12016						printDate = this._daylightSavingAdjust(printDate);
12017					}
12018					calender += tbody + "</tr>";
12019				}
12020				drawMonth++;
12021				if (drawMonth > 11) {
12022					drawMonth = 0;
12023					drawYear++;
12024				}
12025				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
12026							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
12027				group += calender;
12028			}
12029			html += group;
12030		}
12031		html += buttonPanel;
12032		inst._keyEvent = false;
12033		return html;
12034	},
12035
12036	/* Generate the month and year header. */
12037	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
12038			secondary, monthNames, monthNamesShort) {
12039
12040		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
12041			changeMonth = this._get(inst, "changeMonth"),
12042			changeYear = this._get(inst, "changeYear"),
12043			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
12044			html = "<div class='ui-datepicker-title'>",
12045			monthHtml = "";
12046
12047		// month selection
12048		if (secondary || !changeMonth) {
12049			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
12050		} else {
12051			inMinYear = (minDate && minDate.getFullYear() === drawYear);
12052			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
12053			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
12054			for ( month = 0; month < 12; month++) {
12055				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
12056					monthHtml += "<option value='" + month + "'" +
12057						(month === drawMonth ? " selected='selected'" : "") +
12058						">" + monthNamesShort[month] + "</option>";
12059				}
12060			}
12061			monthHtml += "</select>";
12062		}
12063
12064		if (!showMonthAfterYear) {
12065			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
12066		}
12067
12068		// year selection
12069		if ( !inst.yearshtml ) {
12070			inst.yearshtml = "";
12071			if (secondary || !changeYear) {
12072				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
12073			} else {
12074				// determine range of years to display
12075				years = this._get(inst, "yearRange").split(":");
12076				thisYear = new Date().getFullYear();
12077				determineYear = function(value) {
12078					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
12079						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
12080						parseInt(value, 10)));
12081					return (isNaN(year) ? thisYear : year);
12082				};
12083				year = determineYear(years[0]);
12084				endYear = Math.max(year, determineYear(years[1] || ""));
12085				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
12086				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
12087				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
12088				for (; year <= endYear; year++) {
12089					inst.yearshtml += "<option value='" + year + "'" +
12090						(year === drawYear ? " selected='selected'" : "") +
12091						">" + year + "</option>";
12092				}
12093				inst.yearshtml += "</select>";
12094
12095				html += inst.yearshtml;
12096				inst.yearshtml = null;
12097			}
12098		}
12099
12100		html += this._get(inst, "yearSuffix");
12101		if (showMonthAfterYear) {
12102			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
12103		}
12104		html += "</div>"; // Close datepicker_header
12105		return html;
12106	},
12107
12108	/* Adjust one of the date sub-fields. */
12109	_adjustInstDate: function(inst, offset, period) {
12110		var year = inst.drawYear + (period === "Y" ? offset : 0),
12111			month = inst.drawMonth + (period === "M" ? offset : 0),
12112			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
12113			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
12114
12115		inst.selectedDay = date.getDate();
12116		inst.drawMonth = inst.selectedMonth = date.getMonth();
12117		inst.drawYear = inst.selectedYear = date.getFullYear();
12118		if (period === "M" || period === "Y") {
12119			this._notifyChange(inst);
12120		}
12121	},
12122
12123	/* Ensure a date is within any min/max bounds. */
12124	_restrictMinMax: function(inst, date) {
12125		var minDate = this._getMinMaxDate(inst, "min"),
12126			maxDate = this._getMinMaxDate(inst, "max"),
12127			newDate = (minDate && date < minDate ? minDate : date);
12128		return (maxDate && newDate > maxDate ? maxDate : newDate);
12129	},
12130
12131	/* Notify change of month/year. */
12132	_notifyChange: function(inst) {
12133		var onChange = this._get(inst, "onChangeMonthYear");
12134		if (onChange) {
12135			onChange.apply((inst.input ? inst.input[0] : null),
12136				[inst.selectedYear, inst.selectedMonth + 1, inst]);
12137		}
12138	},
12139
12140	/* Determine the number of months to show. */
12141	_getNumberOfMonths: function(inst) {
12142		var numMonths = this._get(inst, "numberOfMonths");
12143		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
12144	},
12145
12146	/* Determine the current maximum date - ensure no time components are set. */
12147	_getMinMaxDate: function(inst, minMax) {
12148		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
12149	},
12150
12151	/* Find the number of days in a given month. */
12152	_getDaysInMonth: function(year, month) {
12153		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
12154	},
12155
12156	/* Find the day of the week of the first of a month. */
12157	_getFirstDayOfMonth: function(year, month) {
12158		return new Date(year, month, 1).getDay();
12159	},
12160
12161	/* Determines if we should allow a "next/prev" month display change. */
12162	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
12163		var numMonths = this._getNumberOfMonths(inst),
12164			date = this._daylightSavingAdjust(new Date(curYear,
12165			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
12166
12167		if (offset < 0) {
12168			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
12169		}
12170		return this._isInRange(inst, date);
12171	},
12172
12173	/* Is the given date in the accepted range? */
12174	_isInRange: function(inst, date) {
12175		var yearSplit, currentYear,
12176			minDate = this._getMinMaxDate(inst, "min"),
12177			maxDate = this._getMinMaxDate(inst, "max"),
12178			minYear = null,
12179			maxYear = null,
12180			years = this._get(inst, "yearRange");
12181			if (years){
12182				yearSplit = years.split(":");
12183				currentYear = new Date().getFullYear();
12184				minYear = parseInt(yearSplit[0], 10);
12185				maxYear = parseInt(yearSplit[1], 10);
12186				if ( yearSplit[0].match(/[+\-].*/) ) {
12187					minYear += currentYear;
12188				}
12189				if ( yearSplit[1].match(/[+\-].*/) ) {
12190					maxYear += currentYear;
12191				}
12192			}
12193
12194		return ((!minDate || date.getTime() >= minDate.getTime()) &&
12195			(!maxDate || date.getTime() <= maxDate.getTime()) &&
12196			(!minYear || date.getFullYear() >= minYear) &&
12197			(!maxYear || date.getFullYear() <= maxYear));
12198	},
12199
12200	/* Provide the configuration settings for formatting/parsing. */
12201	_getFormatConfig: function(inst) {
12202		var shortYearCutoff = this._get(inst, "shortYearCutoff");
12203		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
12204			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
12205		return {shortYearCutoff: shortYearCutoff,
12206			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
12207			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
12208	},
12209
12210	/* Format the given date for display. */
12211	_formatDate: function(inst, day, month, year) {
12212		if (!day) {
12213			inst.currentDay = inst.selectedDay;
12214			inst.currentMonth = inst.selectedMonth;
12215			inst.currentYear = inst.selectedYear;
12216		}
12217		var date = (day ? (typeof day === "object" ? day :
12218			this._daylightSavingAdjust(new Date(year, month, day))) :
12219			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
12220		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
12221	}
12222});
12223
12224/*
12225 * Bind hover events for datepicker elements.
12226 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
12227 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
12228 */
12229function bindHover(dpDiv) {
12230	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
12231	return dpDiv.delegate(selector, "mouseout", function() {
12232			$(this).removeClass("ui-state-hover");
12233			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
12234				$(this).removeClass("ui-datepicker-prev-hover");
12235			}
12236			if (this.className.indexOf("ui-datepicker-next") !== -1) {
12237				$(this).removeClass("ui-datepicker-next-hover");
12238			}
12239		})
12240		.delegate(selector, "mouseover", function(){
12241			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
12242				$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
12243				$(this).addClass("ui-state-hover");
12244				if (this.className.indexOf("ui-datepicker-prev") !== -1) {
12245					$(this).addClass("ui-datepicker-prev-hover");
12246				}
12247				if (this.className.indexOf("ui-datepicker-next") !== -1) {
12248					$(this).addClass("ui-datepicker-next-hover");
12249				}
12250			}
12251		});
12252}
12253
12254/* jQuery extend now ignores nulls! */
12255function extendRemove(target, props) {
12256	$.extend(target, props);
12257	for (var name in props) {
12258		if (props[name] == null) {
12259			target[name] = props[name];
12260		}
12261	}
12262	return target;
12263}
12264
12265/* Invoke the datepicker functionality.
12266   @param  options  string - a command, optionally followed by additional parameters or
12267					Object - settings for attaching new datepicker functionality
12268   @return  jQuery object */
12269$.fn.datepicker = function(options){
12270
12271	/* Verify an empty collection wasn't passed - Fixes #6976 */
12272	if ( !this.length ) {
12273		return this;
12274	}
12275
12276	/* Initialise the date picker. */
12277	if (!$.datepicker.initialized) {
12278		$(document).mousedown($.datepicker._checkExternalClick);
12279		$.datepicker.initialized = true;
12280	}
12281
12282	/* Append datepicker main container to body if not exist. */
12283	if ($("#"+$.datepicker._mainDivId).length === 0) {
12284		$("body").append($.datepicker.dpDiv);
12285	}
12286
12287	var otherArgs = Array.prototype.slice.call(arguments, 1);
12288	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
12289		return $.datepicker["_" + options + "Datepicker"].
12290			apply($.datepicker, [this[0]].concat(otherArgs));
12291	}
12292	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
12293		return $.datepicker["_" + options + "Datepicker"].
12294			apply($.datepicker, [this[0]].concat(otherArgs));
12295	}
12296	return this.each(function() {
12297		typeof options === "string" ?
12298			$.datepicker["_" + options + "Datepicker"].
12299				apply($.datepicker, [this].concat(otherArgs)) :
12300			$.datepicker._attachDatepicker(this, options);
12301	});
12302};
12303
12304$.datepicker = new Datepicker(); // singleton instance
12305$.datepicker.initialized = false;
12306$.datepicker.uuid = new Date().getTime();
12307$.datepicker.version = "1.10.3";
12308
12309})(jQuery);
12310(function( $, undefined ) {
12311
12312$.widget( "ui.menu", {
12313	version: "1.10.3",
12314	defaultElement: "<ul>",
12315	delay: 300,
12316	options: {
12317		icons: {
12318			submenu: "ui-icon-carat-1-e"
12319		},
12320		menus: "ul",
12321		position: {
12322			my: "left top",
12323			at: "right top"
12324		},
12325		role: "menu",
12326
12327		// callbacks
12328		blur: null,
12329		focus: null,
12330		select: null
12331	},
12332
12333	_create: function() {
12334		this.activeMenu = this.element;
12335		// flag used to prevent firing of the click handler
12336		// as the event bubbles up through nested menus
12337		this.mouseHandled = false;
12338		this.element
12339			.uniqueId()
12340			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
12341			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
12342			.attr({
12343				role: this.options.role,
12344				tabIndex: 0
12345			})
12346			// need to catch all clicks on disabled menu
12347			// not possible through _on
12348			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
12349				if ( this.options.disabled ) {
12350					event.preventDefault();
12351				}
12352			}, this ));
12353
12354		if ( this.options.disabled ) {
12355			this.element
12356				.addClass( "ui-state-disabled" )
12357				.attr( "aria-disabled", "true" );
12358		}
12359
12360		this._on({
12361			// Prevent focus from sticking to links inside menu after clicking
12362			// them (focus should always stay on UL during navigation).
12363			"mousedown .ui-menu-item > a": function( event ) {
12364				event.preventDefault();
12365			},
12366			"click .ui-state-disabled > a": function( event ) {
12367				event.preventDefault();
12368			},
12369			"click .ui-menu-item:has(a)": function( event ) {
12370				var target = $( event.target ).closest( ".ui-menu-item" );
12371				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
12372					this.mouseHandled = true;
12373
12374					this.select( event );
12375					// Open submenu on click
12376					if ( target.has( ".ui-menu" ).length ) {
12377						this.expand( event );
12378					} else if ( !this.element.is( ":focus" ) ) {
12379						// Redirect focus to the menu
12380						this.element.trigger( "focus", [ true ] );
12381
12382						// If the active item is on the top level, let it stay active.
12383						// Otherwise, blur the active item since it is no longer visible.
12384						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
12385							clearTimeout( this.timer );
12386						}
12387					}
12388				}
12389			},
12390			"mouseenter .ui-menu-item": function( event ) {
12391				var target = $( event.currentTarget );
12392				// Remove ui-state-active class from siblings of the newly focused menu item
12393				// to avoid a jump caused by adjacent elements both having a class with a border
12394				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
12395				this.focus( event, target );
12396			},
12397			mouseleave: "collapseAll",
12398			"mouseleave .ui-menu": "collapseAll",
12399			focus: function( event, keepActiveItem ) {
12400				// If there's already an active item, keep it active
12401				// If not, activate the first item
12402				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
12403
12404				if ( !keepActiveItem ) {
12405					this.focus( event, item );
12406				}
12407			},
12408			blur: function( event ) {
12409				this._delay(function() {
12410					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
12411						this.collapseAll( event );
12412					}
12413				});
12414			},
12415			keydown: "_keydown"
12416		});
12417
12418		this.refresh();
12419
vendor: 133,438 bytes, lines 12420-17635
12420		// Clicks outside of a menu collapse any open menus
12421		this._on( this.document, {
12422			click: function( event ) {
12423				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
12424					this.collapseAll( event );
12425				}
12426
12427				// Reset the mouseHandled flag
12428				this.mouseHandled = false;
12429			}
12430		});
12431	},
12432
12433	_destroy: function() {
12434		// Destroy (sub)menus
12435		this.element
12436			.removeAttr( "aria-activedescendant" )
12437			.find( ".ui-menu" ).addBack()
12438				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
12439				.removeAttr( "role" )
12440				.removeAttr( "tabIndex" )
12441				.removeAttr( "aria-labelledby" )
12442				.removeAttr( "aria-expanded" )
12443				.removeAttr( "aria-hidden" )
12444				.removeAttr( "aria-disabled" )
12445				.removeUniqueId()
12446				.show();
12447
12448		// Destroy menu items
12449		this.element.find( ".ui-menu-item" )
12450			.removeClass( "ui-menu-item" )
12451			.removeAttr( "role" )
12452			.removeAttr( "aria-disabled" )
12453			.children( "a" )
12454				.removeUniqueId()
12455				.removeClass( "ui-corner-all ui-state-hover" )
12456				.removeAttr( "tabIndex" )
12457				.removeAttr( "role" )
12458				.removeAttr( "aria-haspopup" )
12459				.children().each( function() {
12460					var elem = $( this );
12461					if ( elem.data( "ui-menu-submenu-carat" ) ) {
12462						elem.remove();
12463					}
12464				});
12465
12466		// Destroy menu dividers
12467		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
12468	},
12469
12470	_keydown: function( event ) {
12471		/*jshint maxcomplexity:20*/
12472		var match, prev, character, skip, regex,
12473			preventDefault = true;
12474
12475		function escape( value ) {
12476			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
12477		}
12478
12479		switch ( event.keyCode ) {
12480		case $.ui.keyCode.PAGE_UP:
12481			this.previousPage( event );
12482			break;
12483		case $.ui.keyCode.PAGE_DOWN:
12484			this.nextPage( event );
12485			break;
12486		case $.ui.keyCode.HOME:
12487			this._move( "first", "first", event );
12488			break;
12489		case $.ui.keyCode.END:
12490			this._move( "last", "last", event );
12491			break;
12492		case $.ui.keyCode.UP:
12493			this.previous( event );
12494			break;
12495		case $.ui.keyCode.DOWN:
12496			this.next( event );
12497			break;
12498		case $.ui.keyCode.LEFT:
12499			this.collapse( event );
12500			break;
12501		case $.ui.keyCode.RIGHT:
12502			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
12503				this.expand( event );
12504			}
12505			break;
12506		case $.ui.keyCode.ENTER:
12507		case $.ui.keyCode.SPACE:
12508			this._activate( event );
12509			break;
12510		case $.ui.keyCode.ESCAPE:
12511			this.collapse( event );
12512			break;
12513		default:
12514			preventDefault = false;
12515			prev = this.previousFilter || "";
12516			character = String.fromCharCode( event.keyCode );
12517			skip = false;
12518
12519			clearTimeout( this.filterTimer );
12520
12521			if ( character === prev ) {
12522				skip = true;
12523			} else {
12524				character = prev + character;
12525			}
12526
12527			regex = new RegExp( "^" + escape( character ), "i" );
12528			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
12529				return regex.test( $( this ).children( "a" ).text() );
12530			});
12531			match = skip && match.index( this.active.next() ) !== -1 ?
12532				this.active.nextAll( ".ui-menu-item" ) :
12533				match;
12534
12535			// If no matches on the current filter, reset to the last character pressed
12536			// to move down the menu to the first item that starts with that character
12537			if ( !match.length ) {
12538				character = String.fromCharCode( event.keyCode );
12539				regex = new RegExp( "^" + escape( character ), "i" );
12540				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
12541					return regex.test( $( this ).children( "a" ).text() );
12542				});
12543			}
12544
12545			if ( match.length ) {
12546				this.focus( event, match );
12547				if ( match.length > 1 ) {
12548					this.previousFilter = character;
12549					this.filterTimer = this._delay(function() {
12550						delete this.previousFilter;
12551					}, 1000 );
12552				} else {
12553					delete this.previousFilter;
12554				}
12555			} else {
12556				delete this.previousFilter;
12557			}
12558		}
12559
12560		if ( preventDefault ) {
12561			event.preventDefault();
12562		}
12563	},
12564
12565	_activate: function( event ) {
12566		if ( !this.active.is( ".ui-state-disabled" ) ) {
12567			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
12568				this.expand( event );
12569			} else {
12570				this.select( event );
12571			}
12572		}
12573	},
12574
12575	refresh: function() {
12576		var menus,
12577			icon = this.options.icons.submenu,
12578			submenus = this.element.find( this.options.menus );
12579
12580		// Initialize nested menus
12581		submenus.filter( ":not(.ui-menu)" )
12582			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
12583			.hide()
12584			.attr({
12585				role: this.options.role,
12586				"aria-hidden": "true",
12587				"aria-expanded": "false"
12588			})
12589			.each(function() {
12590				var menu = $( this ),
12591					item = menu.prev( "a" ),
12592					submenuCarat = $( "<span>" )
12593						.addClass( "ui-menu-icon ui-icon " + icon )
12594						.data( "ui-menu-submenu-carat", true );
12595
12596				item
12597					.attr( "aria-haspopup", "true" )
12598					.prepend( submenuCarat );
12599				menu.attr( "aria-labelledby", item.attr( "id" ) );
12600			});
12601
12602		menus = submenus.add( this.element );
12603
12604		// Don't refresh list items that are already adapted
12605		menus.children( ":not(.ui-menu-item):has(a)" )
12606			.addClass( "ui-menu-item" )
12607			.attr( "role", "presentation" )
12608			.children( "a" )
12609				.uniqueId()
12610				.addClass( "ui-corner-all" )
12611				.attr({
12612					tabIndex: -1,
12613					role: this._itemRole()
12614				});
12615
12616		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
12617		menus.children( ":not(.ui-menu-item)" ).each(function() {
12618			var item = $( this );
12619			// hyphen, em dash, en dash
12620			if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
12621				item.addClass( "ui-widget-content ui-menu-divider" );
12622			}
12623		});
12624
12625		// Add aria-disabled attribute to any disabled menu item
12626		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
12627
12628		// If the active item has been removed, blur the menu
12629		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
12630			this.blur();
12631		}
12632	},
12633
12634	_itemRole: function() {
12635		return {
12636			menu: "menuitem",
12637			listbox: "option"
12638		}[ this.options.role ];
12639	},
12640
12641	_setOption: function( key, value ) {
12642		if ( key === "icons" ) {
12643			this.element.find( ".ui-menu-icon" )
12644				.removeClass( this.options.icons.submenu )
12645				.addClass( value.submenu );
12646		}
12647		this._super( key, value );
12648	},
12649
12650	focus: function( event, item ) {
12651		var nested, focused;
12652		this.blur( event, event && event.type === "focus" );
12653
12654		this._scrollIntoView( item );
12655
12656		this.active = item.first();
12657		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
12658		// Only update aria-activedescendant if there's a role
12659		// otherwise we assume focus is managed elsewhere
12660		if ( this.options.role ) {
12661			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
12662		}
12663
12664		// Highlight active parent menu item, if any
12665		this.active
12666			.parent()
12667			.closest( ".ui-menu-item" )
12668			.children( "a:first" )
12669			.addClass( "ui-state-active" );
12670
12671		if ( event && event.type === "keydown" ) {
12672			this._close();
12673		} else {
12674			this.timer = this._delay(function() {
12675				this._close();
12676			}, this.delay );
12677		}
12678
12679		nested = item.children( ".ui-menu" );
12680		if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
12681			this._startOpening(nested);
12682		}
12683		this.activeMenu = item.parent();
12684
12685		this._trigger( "focus", event, { item: item } );
12686	},
12687
12688	_scrollIntoView: function( item ) {
12689		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
12690		if ( this._hasScroll() ) {
12691			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
12692			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
12693			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
12694			scroll = this.activeMenu.scrollTop();
12695			elementHeight = this.activeMenu.height();
12696			itemHeight = item.height();
12697
12698			if ( offset < 0 ) {
12699				this.activeMenu.scrollTop( scroll + offset );
12700			} else if ( offset + itemHeight > elementHeight ) {
12701				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
12702			}
12703		}
12704	},
12705
12706	blur: function( event, fromFocus ) {
12707		if ( !fromFocus ) {
12708			clearTimeout( this.timer );
12709		}
12710
12711		if ( !this.active ) {
12712			return;
12713		}
12714
12715		this.active.children( "a" ).removeClass( "ui-state-focus" );
12716		this.active = null;
12717
12718		this._trigger( "blur", event, { item: this.active } );
12719	},
12720
12721	_startOpening: function( submenu ) {
12722		clearTimeout( this.timer );
12723
12724		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
12725		// shift in the submenu position when mousing over the carat icon
12726		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
12727			return;
12728		}
12729
12730		this.timer = this._delay(function() {
12731			this._close();
12732			this._open( submenu );
12733		}, this.delay );
12734	},
12735
12736	_open: function( submenu ) {
12737		var position = $.extend({
12738			of: this.active
12739		}, this.options.position );
12740
12741		clearTimeout( this.timer );
12742		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
12743			.hide()
12744			.attr( "aria-hidden", "true" );
12745
12746		submenu
12747			.show()
12748			.removeAttr( "aria-hidden" )
12749			.attr( "aria-expanded", "true" )
12750			.position( position );
12751	},
12752
12753	collapseAll: function( event, all ) {
12754		clearTimeout( this.timer );
12755		this.timer = this._delay(function() {
12756			// If we were passed an event, look for the submenu that contains the event
12757			var currentMenu = all ? this.element :
12758				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
12759
12760			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
12761			if ( !currentMenu.length ) {
12762				currentMenu = this.element;
12763			}
12764
12765			this._close( currentMenu );
12766
12767			this.blur( event );
12768			this.activeMenu = currentMenu;
12769		}, this.delay );
12770	},
12771
12772	// With no arguments, closes the currently active menu - if nothing is active
12773	// it closes all menus.  If passed an argument, it will search for menus BELOW
12774	_close: function( startMenu ) {
12775		if ( !startMenu ) {
12776			startMenu = this.active ? this.active.parent() : this.element;
12777		}
12778
12779		startMenu
12780			.find( ".ui-menu" )
12781				.hide()
12782				.attr( "aria-hidden", "true" )
12783				.attr( "aria-expanded", "false" )
12784			.end()
12785			.find( "a.ui-state-active" )
12786				.removeClass( "ui-state-active" );
12787	},
12788
12789	collapse: function( event ) {
12790		var newItem = this.active &&
12791			this.active.parent().closest( ".ui-menu-item", this.element );
12792		if ( newItem && newItem.length ) {
12793			this._close();
12794			this.focus( event, newItem );
12795		}
12796	},
12797
12798	expand: function( event ) {
12799		var newItem = this.active &&
12800			this.active
12801				.children( ".ui-menu " )
12802				.children( ".ui-menu-item" )
12803				.first();
12804
12805		if ( newItem && newItem.length ) {
12806			this._open( newItem.parent() );
12807
12808			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
12809			this._delay(function() {
12810				this.focus( event, newItem );
12811			});
12812		}
12813	},
12814
12815	next: function( event ) {
12816		this._move( "next", "first", event );
12817	},
12818
12819	previous: function( event ) {
12820		this._move( "prev", "last", event );
12821	},
12822
12823	isFirstItem: function() {
12824		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
12825	},
12826
12827	isLastItem: function() {
12828		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
12829	},
12830
12831	_move: function( direction, filter, event ) {
12832		var next;
12833		if ( this.active ) {
12834			if ( direction === "first" || direction === "last" ) {
12835				next = this.active
12836					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
12837					.eq( -1 );
12838			} else {
12839				next = this.active
12840					[ direction + "All" ]( ".ui-menu-item" )
12841					.eq( 0 );
12842			}
12843		}
12844		if ( !next || !next.length || !this.active ) {
12845			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
12846		}
12847
12848		this.focus( event, next );
12849	},
12850
12851	nextPage: function( event ) {
12852		var item, base, height;
12853
12854		if ( !this.active ) {
12855			this.next( event );
12856			return;
12857		}
12858		if ( this.isLastItem() ) {
12859			return;
12860		}
12861		if ( this._hasScroll() ) {
12862			base = this.active.offset().top;
12863			height = this.element.height();
12864			this.active.nextAll( ".ui-menu-item" ).each(function() {
12865				item = $( this );
12866				return item.offset().top - base - height < 0;
12867			});
12868
12869			this.focus( event, item );
12870		} else {
12871			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
12872				[ !this.active ? "first" : "last" ]() );
12873		}
12874	},
12875
12876	previousPage: function( event ) {
12877		var item, base, height;
12878		if ( !this.active ) {
12879			this.next( event );
12880			return;
12881		}
12882		if ( this.isFirstItem() ) {
12883			return;
12884		}
12885		if ( this._hasScroll() ) {
12886			base = this.active.offset().top;
12887			height = this.element.height();
12888			this.active.prevAll( ".ui-menu-item" ).each(function() {
12889				item = $( this );
12890				return item.offset().top - base + height > 0;
12891			});
12892
12893			this.focus( event, item );
12894		} else {
12895			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
12896		}
12897	},
12898
12899	_hasScroll: function() {
12900		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
12901	},
12902
12903	select: function( event ) {
12904		// TODO: It should never be possible to not have an active item at this
12905		// point, but the tests don't trigger mouseenter before click.
12906		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
12907		var ui = { item: this.active };
12908		if ( !this.active.has( ".ui-menu" ).length ) {
12909			this.collapseAll( event, true );
12910		}
12911		this._trigger( "select", event, ui );
12912	}
12913});
12914
12915}( jQuery ));
12916(function( $, undefined ) {
12917
12918$.widget( "ui.progressbar", {
12919	version: "1.10.3",
12920	options: {
12921		max: 100,
12922		value: 0,
12923
12924		change: null,
12925		complete: null
12926	},
12927
12928	min: 0,
12929
12930	_create: function() {
12931		// Constrain initial value
12932		this.oldValue = this.options.value = this._constrainedValue();
12933
12934		this.element
12935			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12936			.attr({
12937				// Only set static values, aria-valuenow and aria-valuemax are
12938				// set inside _refreshValue()
12939				role: "progressbar",
12940				"aria-valuemin": this.min
12941			});
12942
12943		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12944			.appendTo( this.element );
12945
12946		this._refreshValue();
12947	},
12948
12949	_destroy: function() {
12950		this.element
12951			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12952			.removeAttr( "role" )
12953			.removeAttr( "aria-valuemin" )
12954			.removeAttr( "aria-valuemax" )
12955			.removeAttr( "aria-valuenow" );
12956
12957		this.valueDiv.remove();
12958	},
12959
12960	value: function( newValue ) {
12961		if ( newValue === undefined ) {
12962			return this.options.value;
12963		}
12964
12965		this.options.value = this._constrainedValue( newValue );
12966		this._refreshValue();
12967	},
12968
12969	_constrainedValue: function( newValue ) {
12970		if ( newValue === undefined ) {
12971			newValue = this.options.value;
12972		}
12973
12974		this.indeterminate = newValue === false;
12975
12976		// sanitize value
12977		if ( typeof newValue !== "number" ) {
12978			newValue = 0;
12979		}
12980
12981		return this.indeterminate ? false :
12982			Math.min( this.options.max, Math.max( this.min, newValue ) );
12983	},
12984
12985	_setOptions: function( options ) {
12986		// Ensure "value" option is set after other values (like max)
12987		var value = options.value;
12988		delete options.value;
12989
12990		this._super( options );
12991
12992		this.options.value = this._constrainedValue( value );
12993		this._refreshValue();
12994	},
12995
12996	_setOption: function( key, value ) {
12997		if ( key === "max" ) {
12998			// Don't allow a max less than min
12999			value = Math.max( this.min, value );
13000		}
13001
13002		this._super( key, value );
13003	},
13004
13005	_percentage: function() {
13006		return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13007	},
13008
13009	_refreshValue: function() {
13010		var value = this.options.value,
13011			percentage = this._percentage();
13012
13013		this.valueDiv
13014			.toggle( this.indeterminate || value > this.min )
13015			.toggleClass( "ui-corner-right", value === this.options.max )
13016			.width( percentage.toFixed(0) + "%" );
13017
13018		this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
13019
13020		if ( this.indeterminate ) {
13021			this.element.removeAttr( "aria-valuenow" );
13022			if ( !this.overlayDiv ) {
13023				this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
13024			}
13025		} else {
13026			this.element.attr({
13027				"aria-valuemax": this.options.max,
13028				"aria-valuenow": value
13029			});
13030			if ( this.overlayDiv ) {
13031				this.overlayDiv.remove();
13032				this.overlayDiv = null;
13033			}
13034		}
13035
13036		if ( this.oldValue !== value ) {
13037			this.oldValue = value;
13038			this._trigger( "change" );
13039		}
13040		if ( value === this.options.max ) {
13041			this._trigger( "complete" );
13042		}
13043	}
13044});
13045
13046})( jQuery );
13047(function( $, undefined ) {
13048
13049// number of pages in a slider
13050// (how many times can you page up/down to go through the whole range)
13051var numPages = 5;
13052
13053$.widget( "ui.slider", $.ui.mouse, {
13054	version: "1.10.3",
13055	widgetEventPrefix: "slide",
13056
13057	options: {
13058		animate: false,
13059		distance: 0,
13060		max: 100,
13061		min: 0,
13062		orientation: "horizontal",
13063		range: false,
13064		step: 1,
13065		value: 0,
13066		values: null,
13067
13068		// callbacks
13069		change: null,
13070		slide: null,
13071		start: null,
13072		stop: null
13073	},
13074
13075	_create: function() {
13076		this._keySliding = false;
13077		this._mouseSliding = false;
13078		this._animateOff = true;
13079		this._handleIndex = null;
13080		this._detectOrientation();
13081		this._mouseInit();
13082
13083		this.element
13084			.addClass( "ui-slider" +
13085				" ui-slider-" + this.orientation +
13086				" ui-widget" +
13087				" ui-widget-content" +
13088				" ui-corner-all");
13089
13090		this._refresh();
13091		this._setOption( "disabled", this.options.disabled );
13092
13093		this._animateOff = false;
13094	},
13095
13096	_refresh: function() {
13097		this._createRange();
13098		this._createHandles();
13099		this._setupEvents();
13100		this._refreshValue();
13101	},
13102
13103	_createHandles: function() {
13104		var i, handleCount,
13105			options = this.options,
13106			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
13107			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
13108			handles = [];
13109
13110		handleCount = ( options.values && options.values.length ) || 1;
13111
13112		if ( existingHandles.length > handleCount ) {
13113			existingHandles.slice( handleCount ).remove();
13114			existingHandles = existingHandles.slice( 0, handleCount );
13115		}
13116
13117		for ( i = existingHandles.length; i < handleCount; i++ ) {
13118			handles.push( handle );
13119		}
13120
13121		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
13122
13123		this.handle = this.handles.eq( 0 );
13124
13125		this.handles.each(function( i ) {
13126			$( this ).data( "ui-slider-handle-index", i );
13127		});
13128	},
13129
13130	_createRange: function() {
13131		var options = this.options,
13132			classes = "";
13133
13134		if ( options.range ) {
13135			if ( options.range === true ) {
13136				if ( !options.values ) {
13137					options.values = [ this._valueMin(), this._valueMin() ];
13138				} else if ( options.values.length && options.values.length !== 2 ) {
13139					options.values = [ options.values[0], options.values[0] ];
13140				} else if ( $.isArray( options.values ) ) {
13141					options.values = options.values.slice(0);
13142				}
13143			}
13144
13145			if ( !this.range || !this.range.length ) {
13146				this.range = $( "<div></div>" )
13147					.appendTo( this.element );
13148
13149				classes = "ui-slider-range" +
13150				// note: this isn't the most fittingly semantic framework class for this element,
13151				// but worked best visually with a variety of themes
13152				" ui-widget-header ui-corner-all";
13153			} else {
13154				this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
13155					// Handle range switching from true to min/max
13156					.css({
13157						"left": "",
13158						"bottom": ""
13159					});
13160			}
13161
13162			this.range.addClass( classes +
13163				( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
13164		} else {
13165			this.range = $([]);
13166		}
13167	},
13168
13169	_setupEvents: function() {
13170		var elements = this.handles.add( this.range ).filter( "a" );
13171		this._off( elements );
13172		this._on( elements, this._handleEvents );
13173		this._hoverable( elements );
13174		this._focusable( elements );
13175	},
13176
13177	_destroy: function() {
13178		this.handles.remove();
13179		this.range.remove();
13180
13181		this.element
13182			.removeClass( "ui-slider" +
13183				" ui-slider-horizontal" +
13184				" ui-slider-vertical" +
13185				" ui-widget" +
13186				" ui-widget-content" +
13187				" ui-corner-all" );
13188
13189		this._mouseDestroy();
13190	},
13191
13192	_mouseCapture: function( event ) {
13193		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
13194			that = this,
13195			o = this.options;
13196
13197		if ( o.disabled ) {
13198			return false;
13199		}
13200
13201		this.elementSize = {
13202			width: this.element.outerWidth(),
13203			height: this.element.outerHeight()
13204		};
13205		this.elementOffset = this.element.offset();
13206
13207		position = { x: event.pageX, y: event.pageY };
13208		normValue = this._normValueFromMouse( position );
13209		distance = this._valueMax() - this._valueMin() + 1;
13210		this.handles.each(function( i ) {
13211			var thisDistance = Math.abs( normValue - that.values(i) );
13212			if (( distance > thisDistance ) ||
13213				( distance === thisDistance &&
13214					(i === that._lastChangedValue || that.values(i) === o.min ))) {
13215				distance = thisDistance;
13216				closestHandle = $( this );
13217				index = i;
13218			}
13219		});
13220
13221		allowed = this._start( event, index );
13222		if ( allowed === false ) {
13223			return false;
13224		}
13225		this._mouseSliding = true;
13226
13227		this._handleIndex = index;
13228
13229		closestHandle
13230			.addClass( "ui-state-active" )
13231			.focus();
13232
13233		offset = closestHandle.offset();
13234		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
13235		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
13236			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
13237			top: event.pageY - offset.top -
13238				( closestHandle.height() / 2 ) -
13239				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
13240				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
13241				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
13242		};
13243
13244		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
13245			this._slide( event, index, normValue );
13246		}
13247		this._animateOff = true;
13248		return true;
13249	},
13250
13251	_mouseStart: function() {
13252		return true;
13253	},
13254
13255	_mouseDrag: function( event ) {
13256		var position = { x: event.pageX, y: event.pageY },
13257			normValue = this._normValueFromMouse( position );
13258
13259		this._slide( event, this._handleIndex, normValue );
13260
13261		return false;
13262	},
13263
13264	_mouseStop: function( event ) {
13265		this.handles.removeClass( "ui-state-active" );
13266		this._mouseSliding = false;
13267
13268		this._stop( event, this._handleIndex );
13269		this._change( event, this._handleIndex );
13270
13271		this._handleIndex = null;
13272		this._clickOffset = null;
13273		this._animateOff = false;
13274
13275		return false;
13276	},
13277
13278	_detectOrientation: function() {
13279		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13280	},
13281
13282	_normValueFromMouse: function( position ) {
13283		var pixelTotal,
13284			pixelMouse,
13285			percentMouse,
13286			valueTotal,
13287			valueMouse;
13288
13289		if ( this.orientation === "horizontal" ) {
13290			pixelTotal = this.elementSize.width;
13291			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
13292		} else {
13293			pixelTotal = this.elementSize.height;
13294			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
13295		}
13296
13297		percentMouse = ( pixelMouse / pixelTotal );
13298		if ( percentMouse > 1 ) {
13299			percentMouse = 1;
13300		}
13301		if ( percentMouse < 0 ) {
13302			percentMouse = 0;
13303		}
13304		if ( this.orientation === "vertical" ) {
13305			percentMouse = 1 - percentMouse;
13306		}
13307
13308		valueTotal = this._valueMax() - this._valueMin();
13309		valueMouse = this._valueMin() + percentMouse * valueTotal;
13310
13311		return this._trimAlignValue( valueMouse );
13312	},
13313
13314	_start: function( event, index ) {
13315		var uiHash = {
13316			handle: this.handles[ index ],
13317			value: this.value()
13318		};
13319		if ( this.options.values && this.options.values.length ) {
13320			uiHash.value = this.values( index );
13321			uiHash.values = this.values();
13322		}
13323		return this._trigger( "start", event, uiHash );
13324	},
13325
13326	_slide: function( event, index, newVal ) {
13327		var otherVal,
13328			newValues,
13329			allowed;
13330
13331		if ( this.options.values && this.options.values.length ) {
13332			otherVal = this.values( index ? 0 : 1 );
13333
13334			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
13335					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
13336				) {
13337				newVal = otherVal;
13338			}
13339
13340			if ( newVal !== this.values( index ) ) {
13341				newValues = this.values();
13342				newValues[ index ] = newVal;
13343				// A slide can be canceled by returning false from the slide callback
13344				allowed = this._trigger( "slide", event, {
13345					handle: this.handles[ index ],
13346					value: newVal,
13347					values: newValues
13348				} );
13349				otherVal = this.values( index ? 0 : 1 );
13350				if ( allowed !== false ) {
13351					this.values( index, newVal, true );
13352				}
13353			}
13354		} else {
13355			if ( newVal !== this.value() ) {
13356				// A slide can be canceled by returning false from the slide callback
13357				allowed = this._trigger( "slide", event, {
13358					handle: this.handles[ index ],
13359					value: newVal
13360				} );
13361				if ( allowed !== false ) {
13362					this.value( newVal );
13363				}
13364			}
13365		}
13366	},
13367
13368	_stop: function( event, index ) {
13369		var uiHash = {
13370			handle: this.handles[ index ],
13371			value: this.value()
13372		};
13373		if ( this.options.values && this.options.values.length ) {
13374			uiHash.value = this.values( index );
13375			uiHash.values = this.values();
13376		}
13377
13378		this._trigger( "stop", event, uiHash );
13379	},
13380
13381	_change: function( event, index ) {
13382		if ( !this._keySliding && !this._mouseSliding ) {
13383			var uiHash = {
13384				handle: this.handles[ index ],
13385				value: this.value()
13386			};
13387			if ( this.options.values && this.options.values.length ) {
13388				uiHash.value = this.values( index );
13389				uiHash.values = this.values();
13390			}
13391
13392			//store the last changed value index for reference when handles overlap
13393			this._lastChangedValue = index;
13394
13395			this._trigger( "change", event, uiHash );
13396		}
13397	},
13398
13399	value: function( newValue ) {
13400		if ( arguments.length ) {
13401			this.options.value = this._trimAlignValue( newValue );
13402			this._refreshValue();
13403			this._change( null, 0 );
13404			return;
13405		}
13406
13407		return this._value();
13408	},
13409
13410	values: function( index, newValue ) {
13411		var vals,
13412			newValues,
13413			i;
13414
13415		if ( arguments.length > 1 ) {
13416			this.options.values[ index ] = this._trimAlignValue( newValue );
13417			this._refreshValue();
13418			this._change( null, index );
13419			return;
13420		}
13421
13422		if ( arguments.length ) {
13423			if ( $.isArray( arguments[ 0 ] ) ) {
13424				vals = this.options.values;
13425				newValues = arguments[ 0 ];
13426				for ( i = 0; i < vals.length; i += 1 ) {
13427					vals[ i ] = this._trimAlignValue( newValues[ i ] );
13428					this._change( null, i );
13429				}
13430				this._refreshValue();
13431			} else {
13432				if ( this.options.values && this.options.values.length ) {
13433					return this._values( index );
13434				} else {
13435					return this.value();
13436				}
13437			}
13438		} else {
13439			return this._values();
13440		}
13441	},
13442
13443	_setOption: function( key, value ) {
13444		var i,
13445			valsLength = 0;
13446
13447		if ( key === "range" && this.options.range === true ) {
13448			if ( value === "min" ) {
13449				this.options.value = this._values( 0 );
13450				this.options.values = null;
13451			} else if ( value === "max" ) {
13452				this.options.value = this._values( this.options.values.length-1 );
13453				this.options.values = null;
13454			}
13455		}
13456
13457		if ( $.isArray( this.options.values ) ) {
13458			valsLength = this.options.values.length;
13459		}
13460
13461		$.Widget.prototype._setOption.apply( this, arguments );
13462
13463		switch ( key ) {
13464			case "orientation":
13465				this._detectOrientation();
13466				this.element
13467					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
13468					.addClass( "ui-slider-" + this.orientation );
13469				this._refreshValue();
13470				break;
13471			case "value":
13472				this._animateOff = true;
13473				this._refreshValue();
13474				this._change( null, 0 );
13475				this._animateOff = false;
13476				break;
13477			case "values":
13478				this._animateOff = true;
13479				this._refreshValue();
13480				for ( i = 0; i < valsLength; i += 1 ) {
13481					this._change( null, i );
13482				}
13483				this._animateOff = false;
13484				break;
13485			case "min":
13486			case "max":
13487				this._animateOff = true;
13488				this._refreshValue();
13489				this._animateOff = false;
13490				break;
13491			case "range":
13492				this._animateOff = true;
13493				this._refresh();
13494				this._animateOff = false;
13495				break;
13496		}
13497	},
13498
13499	//internal value getter
13500	// _value() returns value trimmed by min and max, aligned by step
13501	_value: function() {
13502		var val = this.options.value;
13503		val = this._trimAlignValue( val );
13504
13505		return val;
13506	},
13507
13508	//internal values getter
13509	// _values() returns array of values trimmed by min and max, aligned by step
13510	// _values( index ) returns single value trimmed by min and max, aligned by step
13511	_values: function( index ) {
13512		var val,
13513			vals,
13514			i;
13515
13516		if ( arguments.length ) {
13517			val = this.options.values[ index ];
13518			val = this._trimAlignValue( val );
13519
13520			return val;
13521		} else if ( this.options.values && this.options.values.length ) {
13522			// .slice() creates a copy of the array
13523			// this copy gets trimmed by min and max and then returned
13524			vals = this.options.values.slice();
13525			for ( i = 0; i < vals.length; i+= 1) {
13526				vals[ i ] = this._trimAlignValue( vals[ i ] );
13527			}
13528
13529			return vals;
13530		} else {
13531			return [];
13532		}
13533	},
13534
13535	// returns the step-aligned value that val is closest to, between (inclusive) min and max
13536	_trimAlignValue: function( val ) {
13537		if ( val <= this._valueMin() ) {
13538			return this._valueMin();
13539		}
13540		if ( val >= this._valueMax() ) {
13541			return this._valueMax();
13542		}
13543		var step = ( this.options.step > 0 ) ? this.options.step : 1,
13544			valModStep = (val - this._valueMin()) % step,
13545			alignValue = val - valModStep;
13546
13547		if ( Math.abs(valModStep) * 2 >= step ) {
13548			alignValue += ( valModStep > 0 ) ? step : ( -step );
13549		}
13550
13551		// Since JavaScript has problems with large floats, round
13552		// the final value to 5 digits after the decimal point (see #4124)
13553		return parseFloat( alignValue.toFixed(5) );
13554	},
13555
13556	_valueMin: function() {
13557		return this.options.min;
13558	},
13559
13560	_valueMax: function() {
13561		return this.options.max;
13562	},
13563
13564	_refreshValue: function() {
13565		var lastValPercent, valPercent, value, valueMin, valueMax,
13566			oRange = this.options.range,
13567			o = this.options,
13568			that = this,
13569			animate = ( !this._animateOff ) ? o.animate : false,
13570			_set = {};
13571
13572		if ( this.options.values && this.options.values.length ) {
13573			this.handles.each(function( i ) {
13574				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13575				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13576				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13577				if ( that.options.range === true ) {
13578					if ( that.orientation === "horizontal" ) {
13579						if ( i === 0 ) {
13580							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13581						}
13582						if ( i === 1 ) {
13583							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13584						}
13585					} else {
13586						if ( i === 0 ) {
13587							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13588						}
13589						if ( i === 1 ) {
13590							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13591						}
13592					}
13593				}
13594				lastValPercent = valPercent;
13595			});
13596		} else {
13597			value = this.value();
13598			valueMin = this._valueMin();
13599			valueMax = this._valueMax();
13600			valPercent = ( valueMax !== valueMin ) ?
13601					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13602					0;
13603			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13604			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13605
13606			if ( oRange === "min" && this.orientation === "horizontal" ) {
13607				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13608			}
13609			if ( oRange === "max" && this.orientation === "horizontal" ) {
13610				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13611			}
13612			if ( oRange === "min" && this.orientation === "vertical" ) {
13613				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13614			}
13615			if ( oRange === "max" && this.orientation === "vertical" ) {
13616				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13617			}
13618		}
13619	},
13620
13621	_handleEvents: {
13622		keydown: function( event ) {
13623			/*jshint maxcomplexity:25*/
13624			var allowed, curVal, newVal, step,
13625				index = $( event.target ).data( "ui-slider-handle-index" );
13626
13627			switch ( event.keyCode ) {
13628				case $.ui.keyCode.HOME:
13629				case $.ui.keyCode.END:
13630				case $.ui.keyCode.PAGE_UP:
13631				case $.ui.keyCode.PAGE_DOWN:
13632				case $.ui.keyCode.UP:
13633				case $.ui.keyCode.RIGHT:
13634				case $.ui.keyCode.DOWN:
13635				case $.ui.keyCode.LEFT:
13636					event.preventDefault();
13637					if ( !this._keySliding ) {
13638						this._keySliding = true;
13639						$( event.target ).addClass( "ui-state-active" );
13640						allowed = this._start( event, index );
13641						if ( allowed === false ) {
13642							return;
13643						}
13644					}
13645					break;
13646			}
13647
13648			step = this.options.step;
13649			if ( this.options.values && this.options.values.length ) {
13650				curVal = newVal = this.values( index );
13651			} else {
13652				curVal = newVal = this.value();
13653			}
13654
13655			switch ( event.keyCode ) {
13656				case $.ui.keyCode.HOME:
13657					newVal = this._valueMin();
13658					break;
13659				case $.ui.keyCode.END:
13660					newVal = this._valueMax();
13661					break;
13662				case $.ui.keyCode.PAGE_UP:
13663					newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
13664					break;
13665				case $.ui.keyCode.PAGE_DOWN:
13666					newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
13667					break;
13668				case $.ui.keyCode.UP:
13669				case $.ui.keyCode.RIGHT:
13670					if ( curVal === this._valueMax() ) {
13671						return;
13672					}
13673					newVal = this._trimAlignValue( curVal + step );
13674					break;
13675				case $.ui.keyCode.DOWN:
13676				case $.ui.keyCode.LEFT:
13677					if ( curVal === this._valueMin() ) {
13678						return;
13679					}
13680					newVal = this._trimAlignValue( curVal - step );
13681					break;
13682			}
13683
13684			this._slide( event, index, newVal );
13685		},
13686		click: function( event ) {
13687			event.preventDefault();
13688		},
13689		keyup: function( event ) {
13690			var index = $( event.target ).data( "ui-slider-handle-index" );
13691
13692			if ( this._keySliding ) {
13693				this._keySliding = false;
13694				this._stop( event, index );
13695				this._change( event, index );
13696				$( event.target ).removeClass( "ui-state-active" );
13697			}
13698		}
13699	}
13700
13701});
13702
13703}(jQuery));
13704(function( $ ) {
13705
13706function modifier( fn ) {
13707	return function() {
13708		var previous = this.element.val();
13709		fn.apply( this, arguments );
13710		this._refresh();
13711		if ( previous !== this.element.val() ) {
13712			this._trigger( "change" );
13713		}
13714	};
13715}
13716
13717$.widget( "ui.spinner", {
13718	version: "1.10.3",
13719	defaultElement: "<input>",
13720	widgetEventPrefix: "spin",
13721	options: {
13722		culture: null,
13723		icons: {
13724			down: "ui-icon-triangle-1-s",
13725			up: "ui-icon-triangle-1-n"
13726		},
13727		incremental: true,
13728		max: null,
13729		min: null,
13730		numberFormat: null,
13731		page: 10,
13732		step: 1,
13733
13734		change: null,
13735		spin: null,
13736		start: null,
13737		stop: null
13738	},
13739
13740	_create: function() {
13741		// handle string values that need to be parsed
13742		this._setOption( "max", this.options.max );
13743		this._setOption( "min", this.options.min );
13744		this._setOption( "step", this.options.step );
13745
13746		// format the value, but don't constrain
13747		this._value( this.element.val(), true );
13748
13749		this._draw();
13750		this._on( this._events );
13751		this._refresh();
13752
13753		// turning off autocomplete prevents the browser from remembering the
13754		// value when navigating through history, so we re-enable autocomplete
13755		// if the page is unloaded before the widget is destroyed. #7790
13756		this._on( this.window, {
13757			beforeunload: function() {
13758				this.element.removeAttr( "autocomplete" );
13759			}
13760		});
13761	},
13762
13763	_getCreateOptions: function() {
13764		var options = {},
13765			element = this.element;
13766
13767		$.each( [ "min", "max", "step" ], function( i, option ) {
13768			var value = element.attr( option );
13769			if ( value !== undefined && value.length ) {
13770				options[ option ] = value;
13771			}
13772		});
13773
13774		return options;
13775	},
13776
13777	_events: {
13778		keydown: function( event ) {
13779			if ( this._start( event ) && this._keydown( event ) ) {
13780				event.preventDefault();
13781			}
13782		},
13783		keyup: "_stop",
13784		focus: function() {
13785			this.previous = this.element.val();
13786		},
13787		blur: function( event ) {
13788			if ( this.cancelBlur ) {
13789				delete this.cancelBlur;
13790				return;
13791			}
13792
13793			this._stop();
13794			this._refresh();
13795			if ( this.previous !== this.element.val() ) {
13796				this._trigger( "change", event );
13797			}
13798		},
13799		mousewheel: function( event, delta ) {
13800			if ( !delta ) {
13801				return;
13802			}
13803			if ( !this.spinning && !this._start( event ) ) {
13804				return false;
13805			}
13806
13807			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
13808			clearTimeout( this.mousewheelTimer );
13809			this.mousewheelTimer = this._delay(function() {
13810				if ( this.spinning ) {
13811					this._stop( event );
13812				}
13813			}, 100 );
13814			event.preventDefault();
13815		},
13816		"mousedown .ui-spinner-button": function( event ) {
13817			var previous;
13818
13819			// We never want the buttons to have focus; whenever the user is
13820			// interacting with the spinner, the focus should be on the input.
13821			// If the input is focused then this.previous is properly set from
13822			// when the input first received focus. If the input is not focused
13823			// then we need to set this.previous based on the value before spinning.
13824			previous = this.element[0] === this.document[0].activeElement ?
13825				this.previous : this.element.val();
13826			function checkFocus() {
13827				var isActive = this.element[0] === this.document[0].activeElement;
13828				if ( !isActive ) {
13829					this.element.focus();
13830					this.previous = previous;
13831					// support: IE
13832					// IE sets focus asynchronously, so we need to check if focus
13833					// moved off of the input because the user clicked on the button.
13834					this._delay(function() {
13835						this.previous = previous;
13836					});
13837				}
13838			}
13839
13840			// ensure focus is on (or stays on) the text field
13841			event.preventDefault();
13842			checkFocus.call( this );
13843
13844			// support: IE
13845			// IE doesn't prevent moving focus even with event.preventDefault()
13846			// so we set a flag to know when we should ignore the blur event
13847			// and check (again) if focus moved off of the input.
13848			this.cancelBlur = true;
13849			this._delay(function() {
13850				delete this.cancelBlur;
13851				checkFocus.call( this );
13852			});
13853
13854			if ( this._start( event ) === false ) {
13855				return;
13856			}
13857
13858			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13859		},
13860		"mouseup .ui-spinner-button": "_stop",
13861		"mouseenter .ui-spinner-button": function( event ) {
13862			// button will add ui-state-active if mouse was down while mouseleave and kept down
13863			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
13864				return;
13865			}
13866
13867			if ( this._start( event ) === false ) {
13868				return false;
13869			}
13870			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13871		},
13872		// TODO: do we really want to consider this a stop?
13873		// shouldn't we just stop the repeater and wait until mouseup before
13874		// we trigger the stop event?
13875		"mouseleave .ui-spinner-button": "_stop"
13876	},
13877
13878	_draw: function() {
13879		var uiSpinner = this.uiSpinner = this.element
13880			.addClass( "ui-spinner-input" )
13881			.attr( "autocomplete", "off" )
13882			.wrap( this._uiSpinnerHtml() )
13883			.parent()
13884				// add buttons
13885				.append( this._buttonHtml() );
13886
13887		this.element.attr( "role", "spinbutton" );
13888
13889		// button bindings
13890		this.buttons = uiSpinner.find( ".ui-spinner-button" )
13891			.attr( "tabIndex", -1 )
13892			.button()
13893			.removeClass( "ui-corner-all" );
13894
13895		// IE 6 doesn't understand height: 50% for the buttons
13896		// unless the wrapper has an explicit height
13897		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
13898				uiSpinner.height() > 0 ) {
13899			uiSpinner.height( uiSpinner.height() );
13900		}
13901
13902		// disable spinner if element was already disabled
13903		if ( this.options.disabled ) {
13904			this.disable();
13905		}
13906	},
13907
13908	_keydown: function( event ) {
13909		var options = this.options,
13910			keyCode = $.ui.keyCode;
13911
13912		switch ( event.keyCode ) {
13913		case keyCode.UP:
13914			this._repeat( null, 1, event );
13915			return true;
13916		case keyCode.DOWN:
13917			this._repeat( null, -1, event );
13918			return true;
13919		case keyCode.PAGE_UP:
13920			this._repeat( null, options.page, event );
13921			return true;
13922		case keyCode.PAGE_DOWN:
13923			this._repeat( null, -options.page, event );
13924			return true;
13925		}
13926
13927		return false;
13928	},
13929
13930	_uiSpinnerHtml: function() {
13931		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
13932	},
13933
13934	_buttonHtml: function() {
13935		return "" +
13936			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
13937				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
13938			"</a>" +
13939			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
13940				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
13941			"</a>";
13942	},
13943
13944	_start: function( event ) {
13945		if ( !this.spinning && this._trigger( "start", event ) === false ) {
13946			return false;
13947		}
13948
13949		if ( !this.counter ) {
13950			this.counter = 1;
13951		}
13952		this.spinning = true;
13953		return true;
13954	},
13955
13956	_repeat: function( i, steps, event ) {
13957		i = i || 500;
13958
13959		clearTimeout( this.timer );
13960		this.timer = this._delay(function() {
13961			this._repeat( 40, steps, event );
13962		}, i );
13963
13964		this._spin( steps * this.options.step, event );
13965	},
13966
13967	_spin: function( step, event ) {
13968		var value = this.value() || 0;
13969
13970		if ( !this.counter ) {
13971			this.counter = 1;
13972		}
13973
13974		value = this._adjustValue( value + step * this._increment( this.counter ) );
13975
13976		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
13977			this._value( value );
13978			this.counter++;
13979		}
13980	},
13981
13982	_increment: function( i ) {
13983		var incremental = this.options.incremental;
13984
13985		if ( incremental ) {
13986			return $.isFunction( incremental ) ?
13987				incremental( i ) :
13988				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
13989		}
13990
13991		return 1;
13992	},
13993
13994	_precision: function() {
13995		var precision = this._precisionOf( this.options.step );
13996		if ( this.options.min !== null ) {
13997			precision = Math.max( precision, this._precisionOf( this.options.min ) );
13998		}
13999		return precision;
14000	},
14001
14002	_precisionOf: function( num ) {
14003		var str = num.toString(),
14004			decimal = str.indexOf( "." );
14005		return decimal === -1 ? 0 : str.length - decimal - 1;
14006	},
14007
14008	_adjustValue: function( value ) {
14009		var base, aboveMin,
14010			options = this.options;
14011
14012		// make sure we're at a valid step
14013		// - find out where we are relative to the base (min or 0)
14014		base = options.min !== null ? options.min : 0;
14015		aboveMin = value - base;
14016		// - round to the nearest step
14017		aboveMin = Math.round(aboveMin / options.step) * options.step;
14018		// - rounding is based on 0, so adjust back to our base
14019		value = base + aboveMin;
14020
14021		// fix precision from bad JS floating point math
14022		value = parseFloat( value.toFixed( this._precision() ) );
14023
14024		// clamp the value
14025		if ( options.max !== null && value > options.max) {
14026			return options.max;
14027		}
14028		if ( options.min !== null && value < options.min ) {
14029			return options.min;
14030		}
14031
14032		return value;
14033	},
14034
14035	_stop: function( event ) {
14036		if ( !this.spinning ) {
14037			return;
14038		}
14039
14040		clearTimeout( this.timer );
14041		clearTimeout( this.mousewheelTimer );
14042		this.counter = 0;
14043		this.spinning = false;
14044		this._trigger( "stop", event );
14045	},
14046
14047	_setOption: function( key, value ) {
14048		if ( key === "culture" || key === "numberFormat" ) {
14049			var prevValue = this._parse( this.element.val() );
14050			this.options[ key ] = value;
14051			this.element.val( this._format( prevValue ) );
14052			return;
14053		}
14054
14055		if ( key === "max" || key === "min" || key === "step" ) {
14056			if ( typeof value === "string" ) {
14057				value = this._parse( value );
14058			}
14059		}
14060		if ( key === "icons" ) {
14061			this.buttons.first().find( ".ui-icon" )
14062				.removeClass( this.options.icons.up )
14063				.addClass( value.up );
14064			this.buttons.last().find( ".ui-icon" )
14065				.removeClass( this.options.icons.down )
14066				.addClass( value.down );
14067		}
14068
14069		this._super( key, value );
14070
14071		if ( key === "disabled" ) {
14072			if ( value ) {
14073				this.element.prop( "disabled", true );
14074				this.buttons.button( "disable" );
14075			} else {
14076				this.element.prop( "disabled", false );
14077				this.buttons.button( "enable" );
14078			}
14079		}
14080	},
14081
14082	_setOptions: modifier(function( options ) {
14083		this._super( options );
14084		this._value( this.element.val() );
14085	}),
14086
14087	_parse: function( val ) {
14088		if ( typeof val === "string" && val !== "" ) {
14089			val = window.Globalize && this.options.numberFormat ?
14090				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
14091		}
14092		return val === "" || isNaN( val ) ? null : val;
14093	},
14094
14095	_format: function( value ) {
14096		if ( value === "" ) {
14097			return "";
14098		}
14099		return window.Globalize && this.options.numberFormat ?
14100			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
14101			value;
14102	},
14103
14104	_refresh: function() {
14105		this.element.attr({
14106			"aria-valuemin": this.options.min,
14107			"aria-valuemax": this.options.max,
14108			// TODO: what should we do with values that can't be parsed?
14109			"aria-valuenow": this._parse( this.element.val() )
14110		});
14111	},
14112
14113	// update the value without triggering change
14114	_value: function( value, allowAny ) {
14115		var parsed;
14116		if ( value !== "" ) {
14117			parsed = this._parse( value );
14118			if ( parsed !== null ) {
14119				if ( !allowAny ) {
14120					parsed = this._adjustValue( parsed );
14121				}
14122				value = this._format( parsed );
14123			}
14124		}
14125		this.element.val( value );
14126		this._refresh();
14127	},
14128
14129	_destroy: function() {
14130		this.element
14131			.removeClass( "ui-spinner-input" )
14132			.prop( "disabled", false )
14133			.removeAttr( "autocomplete" )
14134			.removeAttr( "role" )
14135			.removeAttr( "aria-valuemin" )
14136			.removeAttr( "aria-valuemax" )
14137			.removeAttr( "aria-valuenow" );
14138		this.uiSpinner.replaceWith( this.element );
14139	},
14140
14141	stepUp: modifier(function( steps ) {
14142		this._stepUp( steps );
14143	}),
14144	_stepUp: function( steps ) {
14145		if ( this._start() ) {
14146			this._spin( (steps || 1) * this.options.step );
14147			this._stop();
14148		}
14149	},
14150
14151	stepDown: modifier(function( steps ) {
14152		this._stepDown( steps );
14153	}),
14154	_stepDown: function( steps ) {
14155		if ( this._start() ) {
14156			this._spin( (steps || 1) * -this.options.step );
14157			this._stop();
14158		}
14159	},
14160
14161	pageUp: modifier(function( pages ) {
14162		this._stepUp( (pages || 1) * this.options.page );
14163	}),
14164
14165	pageDown: modifier(function( pages ) {
14166		this._stepDown( (pages || 1) * this.options.page );
14167	}),
14168
14169	value: function( newVal ) {
14170		if ( !arguments.length ) {
14171			return this._parse( this.element.val() );
14172		}
14173		modifier( this._value ).call( this, newVal );
14174	},
14175
14176	widget: function() {
14177		return this.uiSpinner;
14178	}
14179});
14180
14181}( jQuery ) );
14182(function( $, undefined ) {
14183
14184var tabId = 0,
14185	rhash = /#.*$/;
14186
14187function getNextTabId() {
14188	return ++tabId;
14189}
14190
14191function isLocal( anchor ) {
14192	return anchor.hash.length > 1 &&
14193		decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
14194			decodeURIComponent( location.href.replace( rhash, "" ) );
14195}
14196
14197$.widget( "ui.tabs", {
14198	version: "1.10.3",
14199	delay: 300,
14200	options: {
14201		active: null,
14202		collapsible: false,
14203		event: "click",
14204		heightStyle: "content",
14205		hide: null,
14206		show: null,
14207
14208		// callbacks
14209		activate: null,
14210		beforeActivate: null,
14211		beforeLoad: null,
14212		load: null
14213	},
14214
14215	_create: function() {
14216		var that = this,
14217			options = this.options;
14218
14219		this.running = false;
14220
14221		this.element
14222			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
14223			.toggleClass( "ui-tabs-collapsible", options.collapsible )
14224			// Prevent users from focusing disabled tabs via click
14225			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
14226				if ( $( this ).is( ".ui-state-disabled" ) ) {
14227					event.preventDefault();
14228				}
14229			})
14230			// support: IE <9
14231			// Preventing the default action in mousedown doesn't prevent IE
14232			// from focusing the element, so if the anchor gets focused, blur.
14233			// We don't have to worry about focusing the previously focused
14234			// element since clicking on a non-focusable element should focus
14235			// the body anyway.
14236			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
14237				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
14238					this.blur();
14239				}
14240			});
14241
14242		this._processTabs();
14243		options.active = this._initialActive();
14244
14245		// Take disabling tabs via class attribute from HTML
14246		// into account and update option properly.
14247		if ( $.isArray( options.disabled ) ) {
14248			options.disabled = $.unique( options.disabled.concat(
14249				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
14250					return that.tabs.index( li );
14251				})
14252			) ).sort();
14253		}
14254
14255		// check for length avoids error when initializing empty list
14256		if ( this.options.active !== false && this.anchors.length ) {
14257			this.active = this._findActive( options.active );
14258		} else {
14259			this.active = $();
14260		}
14261
14262		this._refresh();
14263
14264		if ( this.active.length ) {
14265			this.load( options.active );
14266		}
14267	},
14268
14269	_initialActive: function() {
14270		var active = this.options.active,
14271			collapsible = this.options.collapsible,
14272			locationHash = location.hash.substring( 1 );
14273
14274		if ( active === null ) {
14275			// check the fragment identifier in the URL
14276			if ( locationHash ) {
14277				this.tabs.each(function( i, tab ) {
14278					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
14279						active = i;
14280						return false;
14281					}
14282				});
14283			}
14284
14285			// check for a tab marked active via a class
14286			if ( active === null ) {
14287				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
14288			}
14289
14290			// no active tab, set to false
14291			if ( active === null || active === -1 ) {
14292				active = this.tabs.length ? 0 : false;
14293			}
14294		}
14295
14296		// handle numbers: negative, out of range
14297		if ( active !== false ) {
14298			active = this.tabs.index( this.tabs.eq( active ) );
14299			if ( active === -1 ) {
14300				active = collapsible ? false : 0;
14301			}
14302		}
14303
14304		// don't allow collapsible: false and active: false
14305		if ( !collapsible && active === false && this.anchors.length ) {
14306			active = 0;
14307		}
14308
14309		return active;
14310	},
14311
14312	_getCreateEventData: function() {
14313		return {
14314			tab: this.active,
14315			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
14316		};
14317	},
14318
14319	_tabKeydown: function( event ) {
14320		/*jshint maxcomplexity:15*/
14321		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
14322			selectedIndex = this.tabs.index( focusedTab ),
14323			goingForward = true;
14324
14325		if ( this._handlePageNav( event ) ) {
14326			return;
14327		}
14328
14329		switch ( event.keyCode ) {
14330			case $.ui.keyCode.RIGHT:
14331			case $.ui.keyCode.DOWN:
14332				selectedIndex++;
14333				break;
14334			case $.ui.keyCode.UP:
14335			case $.ui.keyCode.LEFT:
14336				goingForward = false;
14337				selectedIndex--;
14338				break;
14339			case $.ui.keyCode.END:
14340				selectedIndex = this.anchors.length - 1;
14341				break;
14342			case $.ui.keyCode.HOME:
14343				selectedIndex = 0;
14344				break;
14345			case $.ui.keyCode.SPACE:
14346				// Activate only, no collapsing
14347				event.preventDefault();
14348				clearTimeout( this.activating );
14349				this._activate( selectedIndex );
14350				return;
14351			case $.ui.keyCode.ENTER:
14352				// Toggle (cancel delayed activation, allow collapsing)
14353				event.preventDefault();
14354				clearTimeout( this.activating );
14355				// Determine if we should collapse or activate
14356				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
14357				return;
14358			default:
14359				return;
14360		}
14361
14362		// Focus the appropriate tab, based on which key was pressed
14363		event.preventDefault();
14364		clearTimeout( this.activating );
14365		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
14366
14367		// Navigating with control key will prevent automatic activation
14368		if ( !event.ctrlKey ) {
14369			// Update aria-selected immediately so that AT think the tab is already selected.
14370			// Otherwise AT may confuse the user by stating that they need to activate the tab,
14371			// but the tab will already be activated by the time the announcement finishes.
14372			focusedTab.attr( "aria-selected", "false" );
14373			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
14374
14375			this.activating = this._delay(function() {
14376				this.option( "active", selectedIndex );
14377			}, this.delay );
14378		}
14379	},
14380
14381	_panelKeydown: function( event ) {
14382		if ( this._handlePageNav( event ) ) {
14383			return;
14384		}
14385
14386		// Ctrl+up moves focus to the current tab
14387		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
14388			event.preventDefault();
14389			this.active.focus();
14390		}
14391	},
14392
14393	// Alt+page up/down moves focus to the previous/next tab (and activates)
14394	_handlePageNav: function( event ) {
14395		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
14396			this._activate( this._focusNextTab( this.options.active - 1, false ) );
14397			return true;
14398		}
14399		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
14400			this._activate( this._focusNextTab( this.options.active + 1, true ) );
14401			return true;
14402		}
14403	},
14404
14405	_findNextTab: function( index, goingForward ) {
14406		var lastTabIndex = this.tabs.length - 1;
14407
14408		function constrain() {
14409			if ( index > lastTabIndex ) {
14410				index = 0;
14411			}
14412			if ( index < 0 ) {
14413				index = lastTabIndex;
14414			}
14415			return index;
14416		}
14417
14418		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14419			index = goingForward ? index + 1 : index - 1;
14420		}
14421
14422		return index;
14423	},
14424
14425	_focusNextTab: function( index, goingForward ) {
14426		index = this._findNextTab( index, goingForward );
14427		this.tabs.eq( index ).focus();
14428		return index;
14429	},
14430
14431	_setOption: function( key, value ) {
14432		if ( key === "active" ) {
14433			// _activate() will handle invalid values and update this.options
14434			this._activate( value );
14435			return;
14436		}
14437
14438		if ( key === "disabled" ) {
14439			// don't use the widget factory's disabled handling
14440			this._setupDisabled( value );
14441			return;
14442		}
14443
14444		this._super( key, value);
14445
14446		if ( key === "collapsible" ) {
14447			this.element.toggleClass( "ui-tabs-collapsible", value );
14448			// Setting collapsible: false while collapsed; open first panel
14449			if ( !value && this.options.active === false ) {
14450				this._activate( 0 );
14451			}
14452		}
14453
14454		if ( key === "event" ) {
14455			this._setupEvents( value );
14456		}
14457
14458		if ( key === "heightStyle" ) {
14459			this._setupHeightStyle( value );
14460		}
14461	},
14462
14463	_tabId: function( tab ) {
14464		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
14465	},
14466
14467	_sanitizeSelector: function( hash ) {
14468		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
14469	},
14470
14471	refresh: function() {
14472		var options = this.options,
14473			lis = this.tablist.children( ":has(a[href])" );
14474
14475		// get disabled tabs from class attribute from HTML
14476		// this will get converted to a boolean if needed in _refresh()
14477		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
14478			return lis.index( tab );
14479		});
14480
14481		this._processTabs();
14482
14483		// was collapsed or no tabs
14484		if ( options.active === false || !this.anchors.length ) {
14485			options.active = false;
14486			this.active = $();
14487		// was active, but active tab is gone
14488		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
14489			// all remaining tabs are disabled
14490			if ( this.tabs.length === options.disabled.length ) {
14491				options.active = false;
14492				this.active = $();
14493			// activate previous tab
14494			} else {
14495				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
14496			}
14497		// was active, active tab still exists
14498		} else {
14499			// make sure active index is correct
14500			options.active = this.tabs.index( this.active );
14501		}
14502
14503		this._refresh();
14504	},
14505
14506	_refresh: function() {
14507		this._setupDisabled( this.options.disabled );
14508		this._setupEvents( this.options.event );
14509		this._setupHeightStyle( this.options.heightStyle );
14510
14511		this.tabs.not( this.active ).attr({
14512			"aria-selected": "false",
14513			tabIndex: -1
14514		});
14515		this.panels.not( this._getPanelForTab( this.active ) )
14516			.hide()
14517			.attr({
14518				"aria-expanded": "false",
14519				"aria-hidden": "true"
14520			});
14521
14522		// Make sure one tab is in the tab order
14523		if ( !this.active.length ) {
14524			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
14525		} else {
14526			this.active
14527				.addClass( "ui-tabs-active ui-state-active" )
14528				.attr({
14529					"aria-selected": "true",
14530					tabIndex: 0
14531				});
14532			this._getPanelForTab( this.active )
14533				.show()
14534				.attr({
14535					"aria-expanded": "true",
14536					"aria-hidden": "false"
14537				});
14538		}
14539	},
14540
14541	_processTabs: function() {
14542		var that = this;
14543
14544		this.tablist = this._getList()
14545			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14546			.attr( "role", "tablist" );
14547
14548		this.tabs = this.tablist.find( "> li:has(a[href])" )
14549			.addClass( "ui-state-default ui-corner-top" )
14550			.attr({
14551				role: "tab",
14552				tabIndex: -1
14553			});
14554
14555		this.anchors = this.tabs.map(function() {
14556				return $( "a", this )[ 0 ];
14557			})
14558			.addClass( "ui-tabs-anchor" )
14559			.attr({
14560				role: "presentation",
14561				tabIndex: -1
14562			});
14563
14564		this.panels = $();
14565
14566		this.anchors.each(function( i, anchor ) {
14567			var selector, panel, panelId,
14568				anchorId = $( anchor ).uniqueId().attr( "id" ),
14569				tab = $( anchor ).closest( "li" ),
14570				originalAriaControls = tab.attr( "aria-controls" );
14571
14572			// inline tab
14573			if ( isLocal( anchor ) ) {
14574				selector = anchor.hash;
14575				panel = that.element.find( that._sanitizeSelector( selector ) );
14576			// remote tab
14577			} else {
14578				panelId = that._tabId( tab );
14579				selector = "#" + panelId;
14580				panel = that.element.find( selector );
14581				if ( !panel.length ) {
14582					panel = that._createPanel( panelId );
14583					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
14584				}
14585				panel.attr( "aria-live", "polite" );
14586			}
14587
14588			if ( panel.length) {
14589				that.panels = that.panels.add( panel );
14590			}
14591			if ( originalAriaControls ) {
14592				tab.data( "ui-tabs-aria-controls", originalAriaControls );
14593			}
14594			tab.attr({
14595				"aria-controls": selector.substring( 1 ),
14596				"aria-labelledby": anchorId
14597			});
14598			panel.attr( "aria-labelledby", anchorId );
14599		});
14600
14601		this.panels
14602			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14603			.attr( "role", "tabpanel" );
14604	},
14605
14606	// allow overriding how to find the list for rare usage scenarios (#7715)
14607	_getList: function() {
14608		return this.element.find( "ol,ul" ).eq( 0 );
14609	},
14610
14611	_createPanel: function( id ) {
14612		return $( "<div>" )
14613			.attr( "id", id )
14614			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14615			.data( "ui-tabs-destroy", true );
14616	},
14617
14618	_setupDisabled: function( disabled ) {
14619		if ( $.isArray( disabled ) ) {
14620			if ( !disabled.length ) {
14621				disabled = false;
14622			} else if ( disabled.length === this.anchors.length ) {
14623				disabled = true;
14624			}
14625		}
14626
14627		// disable tabs
14628		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
14629			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
14630				$( li )
14631					.addClass( "ui-state-disabled" )
14632					.attr( "aria-disabled", "true" );
14633			} else {
14634				$( li )
14635					.removeClass( "ui-state-disabled" )
14636					.removeAttr( "aria-disabled" );
14637			}
14638		}
14639
14640		this.options.disabled = disabled;
14641	},
14642
14643	_setupEvents: function( event ) {
14644		var events = {
14645			click: function( event ) {
14646				event.preventDefault();
14647			}
14648		};
14649		if ( event ) {
14650			$.each( event.split(" "), function( index, eventName ) {
14651				events[ eventName ] = "_eventHandler";
14652			});
14653		}
14654
14655		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
14656		this._on( this.anchors, events );
14657		this._on( this.tabs, { keydown: "_tabKeydown" } );
14658		this._on( this.panels, { keydown: "_panelKeydown" } );
14659
14660		this._focusable( this.tabs );
14661		this._hoverable( this.tabs );
14662	},
14663
14664	_setupHeightStyle: function( heightStyle ) {
14665		var maxHeight,
14666			parent = this.element.parent();
14667
14668		if ( heightStyle === "fill" ) {
14669			maxHeight = parent.height();
14670			maxHeight -= this.element.outerHeight() - this.element.height();
14671
14672			this.element.siblings( ":visible" ).each(function() {
14673				var elem = $( this ),
14674					position = elem.css( "position" );
14675
14676				if ( position === "absolute" || position === "fixed" ) {
14677					return;
14678				}
14679				maxHeight -= elem.outerHeight( true );
14680			});
14681
14682			this.element.children().not( this.panels ).each(function() {
14683				maxHeight -= $( this ).outerHeight( true );
14684			});
14685
14686			this.panels.each(function() {
14687				$( this ).height( Math.max( 0, maxHeight -
14688					$( this ).innerHeight() + $( this ).height() ) );
14689			})
14690			.css( "overflow", "auto" );
14691		} else if ( heightStyle === "auto" ) {
14692			maxHeight = 0;
14693			this.panels.each(function() {
14694				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
14695			}).height( maxHeight );
14696		}
14697	},
14698
14699	_eventHandler: function( event ) {
14700		var options = this.options,
14701			active = this.active,
14702			anchor = $( event.currentTarget ),
14703			tab = anchor.closest( "li" ),
14704			clickedIsActive = tab[ 0 ] === active[ 0 ],
14705			collapsing = clickedIsActive && options.collapsible,
14706			toShow = collapsing ? $() : this._getPanelForTab( tab ),
14707			toHide = !active.length ? $() : this._getPanelForTab( active ),
14708			eventData = {
14709				oldTab: active,
14710				oldPanel: toHide,
14711				newTab: collapsing ? $() : tab,
14712				newPanel: toShow
14713			};
14714
14715		event.preventDefault();
14716
14717		if ( tab.hasClass( "ui-state-disabled" ) ||
14718				// tab is already loading
14719				tab.hasClass( "ui-tabs-loading" ) ||
14720				// can't switch durning an animation
14721				this.running ||
14722				// click on active header, but not collapsible
14723				( clickedIsActive && !options.collapsible ) ||
14724				// allow canceling activation
14725				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
14726			return;
14727		}
14728
14729		options.active = collapsing ? false : this.tabs.index( tab );
14730
14731		this.active = clickedIsActive ? $() : tab;
14732		if ( this.xhr ) {
14733			this.xhr.abort();
14734		}
14735
14736		if ( !toHide.length && !toShow.length ) {
14737			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
14738		}
14739
14740		if ( toShow.length ) {
14741			this.load( this.tabs.index( tab ), event );
14742		}
14743		this._toggle( event, eventData );
14744	},
14745
14746	// handles show/hide for selecting tabs
14747	_toggle: function( event, eventData ) {
14748		var that = this,
14749			toShow = eventData.newPanel,
14750			toHide = eventData.oldPanel;
14751
14752		this.running = true;
14753
14754		function complete() {
14755			that.running = false;
14756			that._trigger( "activate", event, eventData );
14757		}
14758
14759		function show() {
14760			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14761
14762			if ( toShow.length && that.options.show ) {
14763				that._show( toShow, that.options.show, complete );
14764			} else {
14765				toShow.show();
14766				complete();
14767			}
14768		}
14769
14770		// start out by hiding, then showing, then completing
14771		if ( toHide.length && this.options.hide ) {
14772			this._hide( toHide, this.options.hide, function() {
14773				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14774				show();
14775			});
14776		} else {
14777			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14778			toHide.hide();
14779			show();
14780		}
14781
14782		toHide.attr({
14783			"aria-expanded": "false",
14784			"aria-hidden": "true"
14785		});
14786		eventData.oldTab.attr( "aria-selected", "false" );
14787		// If we're switching tabs, remove the old tab from the tab order.
14788		// If we're opening from collapsed state, remove the previous tab from the tab order.
14789		// If we're collapsing, then keep the collapsing tab in the tab order.
14790		if ( toShow.length && toHide.length ) {
14791			eventData.oldTab.attr( "tabIndex", -1 );
14792		} else if ( toShow.length ) {
14793			this.tabs.filter(function() {
14794				return $( this ).attr( "tabIndex" ) === 0;
14795			})
14796			.attr( "tabIndex", -1 );
14797		}
14798
14799		toShow.attr({
14800			"aria-expanded": "true",
14801			"aria-hidden": "false"
14802		});
14803		eventData.newTab.attr({
14804			"aria-selected": "true",
14805			tabIndex: 0
14806		});
14807	},
14808
14809	_activate: function( index ) {
14810		var anchor,
14811			active = this._findActive( index );
14812
14813		// trying to activate the already active panel
14814		if ( active[ 0 ] === this.active[ 0 ] ) {
14815			return;
14816		}
14817
14818		// trying to collapse, simulate a click on the current active header
14819		if ( !active.length ) {
14820			active = this.active;
14821		}
14822
14823		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
14824		this._eventHandler({
14825			target: anchor,
14826			currentTarget: anchor,
14827			preventDefault: $.noop
14828		});
14829	},
14830
14831	_findActive: function( index ) {
14832		return index === false ? $() : this.tabs.eq( index );
14833	},
14834
14835	_getIndex: function( index ) {
14836		// meta-function to give users option to provide a href string instead of a numerical index.
14837		if ( typeof index === "string" ) {
14838			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
14839		}
14840
14841		return index;
14842	},
14843
14844	_destroy: function() {
14845		if ( this.xhr ) {
14846			this.xhr.abort();
14847		}
14848
14849		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
14850
14851		this.tablist
14852			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14853			.removeAttr( "role" );
14854
14855		this.anchors
14856			.removeClass( "ui-tabs-anchor" )
14857			.removeAttr( "role" )
14858			.removeAttr( "tabIndex" )
14859			.removeUniqueId();
14860
14861		this.tabs.add( this.panels ).each(function() {
14862			if ( $.data( this, "ui-tabs-destroy" ) ) {
14863				$( this ).remove();
14864			} else {
14865				$( this )
14866					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
14867						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
14868					.removeAttr( "tabIndex" )
14869					.removeAttr( "aria-live" )
14870					.removeAttr( "aria-busy" )
14871					.removeAttr( "aria-selected" )
14872					.removeAttr( "aria-labelledby" )
14873					.removeAttr( "aria-hidden" )
14874					.removeAttr( "aria-expanded" )
14875					.removeAttr( "role" );
14876			}
14877		});
14878
14879		this.tabs.each(function() {
14880			var li = $( this ),
14881				prev = li.data( "ui-tabs-aria-controls" );
14882			if ( prev ) {
14883				li
14884					.attr( "aria-controls", prev )
14885					.removeData( "ui-tabs-aria-controls" );
14886			} else {
14887				li.removeAttr( "aria-controls" );
14888			}
14889		});
14890
14891		this.panels.show();
14892
14893		if ( this.options.heightStyle !== "content" ) {
14894			this.panels.css( "height", "" );
14895		}
14896	},
14897
14898	enable: function( index ) {
14899		var disabled = this.options.disabled;
14900		if ( disabled === false ) {
14901			return;
14902		}
14903
14904		if ( index === undefined ) {
14905			disabled = false;
14906		} else {
14907			index = this._getIndex( index );
14908			if ( $.isArray( disabled ) ) {
14909				disabled = $.map( disabled, function( num ) {
14910					return num !== index ? num : null;
14911				});
14912			} else {
14913				disabled = $.map( this.tabs, function( li, num ) {
14914					return num !== index ? num : null;
14915				});
14916			}
14917		}
14918		this._setupDisabled( disabled );
14919	},
14920
14921	disable: function( index ) {
14922		var disabled = this.options.disabled;
14923		if ( disabled === true ) {
14924			return;
14925		}
14926
14927		if ( index === undefined ) {
14928			disabled = true;
14929		} else {
14930			index = this._getIndex( index );
14931			if ( $.inArray( index, disabled ) !== -1 ) {
14932				return;
14933			}
14934			if ( $.isArray( disabled ) ) {
14935				disabled = $.merge( [ index ], disabled ).sort();
14936			} else {
14937				disabled = [ index ];
14938			}
14939		}
14940		this._setupDisabled( disabled );
14941	},
14942
14943	load: function( index, event ) {
14944		index = this._getIndex( index );
14945		var that = this,
14946			tab = this.tabs.eq( index ),
14947			anchor = tab.find( ".ui-tabs-anchor" ),
14948			panel = this._getPanelForTab( tab ),
14949			eventData = {
14950				tab: tab,
14951				panel: panel
14952			};
14953
14954		// not remote
14955		if ( isLocal( anchor[ 0 ] ) ) {
14956			return;
14957		}
14958
14959		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
14960
14961		// support: jQuery <1.8
14962		// jQuery <1.8 returns false if the request is canceled in beforeSend,
14963		// but as of 1.8, $.ajax() always returns a jqXHR object.
14964		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
14965			tab.addClass( "ui-tabs-loading" );
14966			panel.attr( "aria-busy", "true" );
14967
14968			this.xhr
14969				.success(function( response ) {
14970					// support: jQuery <1.8
14971					// http://bugs.jquery.com/ticket/11778
14972					setTimeout(function() {
14973						panel.html( response );
14974						that._trigger( "load", event, eventData );
14975					}, 1 );
14976				})
14977				.complete(function( jqXHR, status ) {
14978					// support: jQuery <1.8
14979					// http://bugs.jquery.com/ticket/11778
14980					setTimeout(function() {
14981						if ( status === "abort" ) {
14982							that.panels.stop( false, true );
14983						}
14984
14985						tab.removeClass( "ui-tabs-loading" );
14986						panel.removeAttr( "aria-busy" );
14987
14988						if ( jqXHR === that.xhr ) {
14989							delete that.xhr;
14990						}
14991					}, 1 );
14992				});
14993		}
14994	},
14995
14996	_ajaxSettings: function( anchor, event, eventData ) {
14997		var that = this;
14998		return {
14999			url: anchor.attr( "href" ),
15000			beforeSend: function( jqXHR, settings ) {
15001				return that._trigger( "beforeLoad", event,
15002					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
15003			}
15004		};
15005	},
15006
15007	_getPanelForTab: function( tab ) {
15008		var id = $( tab ).attr( "aria-controls" );
15009		return this.element.find( this._sanitizeSelector( "#" + id ) );
15010	}
15011});
15012
15013})( jQuery );
15014(function( $ ) {
15015
15016var increments = 0;
15017
15018function addDescribedBy( elem, id ) {
15019	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
15020	describedby.push( id );
15021	elem
15022		.data( "ui-tooltip-id", id )
15023		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
15024}
15025
15026function removeDescribedBy( elem ) {
15027	var id = elem.data( "ui-tooltip-id" ),
15028		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
15029		index = $.inArray( id, describedby );
15030	if ( index !== -1 ) {
15031		describedby.splice( index, 1 );
15032	}
15033
15034	elem.removeData( "ui-tooltip-id" );
15035	describedby = $.trim( describedby.join( " " ) );
15036	if ( describedby ) {
15037		elem.attr( "aria-describedby", describedby );
15038	} else {
15039		elem.removeAttr( "aria-describedby" );
15040	}
15041}
15042
15043$.widget( "ui.tooltip", {
15044	version: "1.10.3",
15045	options: {
15046		content: function() {
15047			// support: IE<9, Opera in jQuery <1.7
15048			// .text() can't accept undefined, so coerce to a string
15049			var title = $( this ).attr( "title" ) || "";
15050			// Escape title, since we're going from an attribute to raw HTML
15051			return $( "<a>" ).text( title ).html();
15052		},
15053		hide: true,
15054		// Disabled elements have inconsistent behavior across browsers (#8661)
15055		items: "[title]:not([disabled])",
15056		position: {
15057			my: "left top+15",
15058			at: "left bottom",
15059			collision: "flipfit flip"
15060		},
15061		show: true,
15062		tooltipClass: null,
15063		track: false,
15064
15065		// callbacks
15066		close: null,
15067		open: null
15068	},
15069
15070	_create: function() {
15071		this._on({
15072			mouseover: "open",
15073			focusin: "open"
15074		});
15075
15076		// IDs of generated tooltips, needed for destroy
15077		this.tooltips = {};
15078		// IDs of parent tooltips where we removed the title attribute
15079		this.parents = {};
15080
15081		if ( this.options.disabled ) {
15082			this._disable();
15083		}
15084	},
15085
15086	_setOption: function( key, value ) {
15087		var that = this;
15088
15089		if ( key === "disabled" ) {
15090			this[ value ? "_disable" : "_enable" ]();
15091			this.options[ key ] = value;
15092			// disable element style changes
15093			return;
15094		}
15095
15096		this._super( key, value );
15097
15098		if ( key === "content" ) {
15099			$.each( this.tooltips, function( id, element ) {
15100				that._updateContent( element );
15101			});
15102		}
15103	},
15104
15105	_disable: function() {
15106		var that = this;
15107
15108		// close open tooltips
15109		$.each( this.tooltips, function( id, element ) {
15110			var event = $.Event( "blur" );
15111			event.target = event.currentTarget = element[0];
15112			that.close( event, true );
15113		});
15114
15115		// remove title attributes to prevent native tooltips
15116		this.element.find( this.options.items ).addBack().each(function() {
15117			var element = $( this );
15118			if ( element.is( "[title]" ) ) {
15119				element
15120					.data( "ui-tooltip-title", element.attr( "title" ) )
15121					.attr( "title", "" );
15122			}
15123		});
15124	},
15125
15126	_enable: function() {
15127		// restore title attributes
15128		this.element.find( this.options.items ).addBack().each(function() {
15129			var element = $( this );
15130			if ( element.data( "ui-tooltip-title" ) ) {
15131				element.attr( "title", element.data( "ui-tooltip-title" ) );
15132			}
15133		});
15134	},
15135
15136	open: function( event ) {
15137		var that = this,
15138			target = $( event ? event.target : this.element )
15139				// we need closest here due to mouseover bubbling,
15140				// but always pointing at the same event target
15141				.closest( this.options.items );
15142
15143		// No element to show a tooltip for or the tooltip is already open
15144		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
15145			return;
15146		}
15147
15148		if ( target.attr( "title" ) ) {
15149			target.data( "ui-tooltip-title", target.attr( "title" ) );
15150		}
15151
15152		target.data( "ui-tooltip-open", true );
15153
15154		// kill parent tooltips, custom or native, for hover
15155		if ( event && event.type === "mouseover" ) {
15156			target.parents().each(function() {
15157				var parent = $( this ),
15158					blurEvent;
15159				if ( parent.data( "ui-tooltip-open" ) ) {
15160					blurEvent = $.Event( "blur" );
15161					blurEvent.target = blurEvent.currentTarget = this;
15162					that.close( blurEvent, true );
15163				}
15164				if ( parent.attr( "title" ) ) {
15165					parent.uniqueId();
15166					that.parents[ this.id ] = {
15167						element: this,
15168						title: parent.attr( "title" )
15169					};
15170					parent.attr( "title", "" );
15171				}
15172			});
15173		}
15174
15175		this._updateContent( target, event );
15176	},
15177
15178	_updateContent: function( target, event ) {
15179		var content,
15180			contentOption = this.options.content,
15181			that = this,
15182			eventType = event ? event.type : null;
15183
15184		if ( typeof contentOption === "string" ) {
15185			return this._open( event, target, contentOption );
15186		}
15187
15188		content = contentOption.call( target[0], function( response ) {
15189			// ignore async response if tooltip was closed already
15190			if ( !target.data( "ui-tooltip-open" ) ) {
15191				return;
15192			}
15193			// IE may instantly serve a cached response for ajax requests
15194			// delay this call to _open so the other call to _open runs first
15195			that._delay(function() {
15196				// jQuery creates a special event for focusin when it doesn't
15197				// exist natively. To improve performance, the native event
15198				// object is reused and the type is changed. Therefore, we can't
15199				// rely on the type being correct after the event finished
15200				// bubbling, so we set it back to the previous value. (#8740)
15201				if ( event ) {
15202					event.type = eventType;
15203				}
15204				this._open( event, target, response );
15205			});
15206		});
15207		if ( content ) {
15208			this._open( event, target, content );
15209		}
15210	},
15211
15212	_open: function( event, target, content ) {
15213		var tooltip, events, delayedShow,
15214			positionOption = $.extend( {}, this.options.position );
15215
15216		if ( !content ) {
15217			return;
15218		}
15219
15220		// Content can be updated multiple times. If the tooltip already
15221		// exists, then just update the content and bail.
15222		tooltip = this._find( target );
15223		if ( tooltip.length ) {
15224			tooltip.find( ".ui-tooltip-content" ).html( content );
15225			return;
15226		}
15227
15228		// if we have a title, clear it to prevent the native tooltip
15229		// we have to check first to avoid defining a title if none exists
15230		// (we don't want to cause an element to start matching [title])
15231		//
15232		// We use removeAttr only for key events, to allow IE to export the correct
15233		// accessible attributes. For mouse events, set to empty string to avoid
15234		// native tooltip showing up (happens only when removing inside mouseover).
15235		if ( target.is( "[title]" ) ) {
15236			if ( event && event.type === "mouseover" ) {
15237				target.attr( "title", "" );
15238			} else {
15239				target.removeAttr( "title" );
15240			}
15241		}
15242
15243		tooltip = this._tooltip( target );
15244		addDescribedBy( target, tooltip.attr( "id" ) );
15245		tooltip.find( ".ui-tooltip-content" ).html( content );
15246
15247		function position( event ) {
15248			positionOption.of = event;
15249			if ( tooltip.is( ":hidden" ) ) {
15250				return;
15251			}
15252			tooltip.position( positionOption );
15253		}
15254		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
15255			this._on( this.document, {
15256				mousemove: position
15257			});
15258			// trigger once to override element-relative positioning
15259			position( event );
15260		} else {
15261			tooltip.position( $.extend({
15262				of: target
15263			}, this.options.position ) );
15264		}
15265
15266		tooltip.hide();
15267
15268		this._show( tooltip, this.options.show );
15269		// Handle tracking tooltips that are shown with a delay (#8644). As soon
15270		// as the tooltip is visible, position the tooltip using the most recent
15271		// event.
15272		if ( this.options.show && this.options.show.delay ) {
15273			delayedShow = this.delayedShow = setInterval(function() {
15274				if ( tooltip.is( ":visible" ) ) {
15275					position( positionOption.of );
15276					clearInterval( delayedShow );
15277				}
15278			}, $.fx.interval );
15279		}
15280
15281		this._trigger( "open", event, { tooltip: tooltip } );
15282
15283		events = {
15284			keyup: function( event ) {
15285				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
15286					var fakeEvent = $.Event(event);
15287					fakeEvent.currentTarget = target[0];
15288					this.close( fakeEvent, true );
15289				}
15290			},
15291			remove: function() {
15292				this._removeTooltip( tooltip );
15293			}
15294		};
15295		if ( !event || event.type === "mouseover" ) {
15296			events.mouseleave = "close";
15297		}
15298		if ( !event || event.type === "focusin" ) {
15299			events.focusout = "close";
15300		}
15301		this._on( true, target, events );
15302	},
15303
15304	close: function( event ) {
15305		var that = this,
15306			target = $( event ? event.currentTarget : this.element ),
15307			tooltip = this._find( target );
15308
15309		// disabling closes the tooltip, so we need to track when we're closing
15310		// to avoid an infinite loop in case the tooltip becomes disabled on close
15311		if ( this.closing ) {
15312			return;
15313		}
15314
15315		// Clear the interval for delayed tracking tooltips
15316		clearInterval( this.delayedShow );
15317
15318		// only set title if we had one before (see comment in _open())
15319		if ( target.data( "ui-tooltip-title" ) ) {
15320			target.attr( "title", target.data( "ui-tooltip-title" ) );
15321		}
15322
15323		removeDescribedBy( target );
15324
15325		tooltip.stop( true );
15326		this._hide( tooltip, this.options.hide, function() {
15327			that._removeTooltip( $( this ) );
15328		});
15329
15330		target.removeData( "ui-tooltip-open" );
15331		this._off( target, "mouseleave focusout keyup" );
15332		// Remove 'remove' binding only on delegated targets
15333		if ( target[0] !== this.element[0] ) {
15334			this._off( target, "remove" );
15335		}
15336		this._off( this.document, "mousemove" );
15337
15338		if ( event && event.type === "mouseleave" ) {
15339			$.each( this.parents, function( id, parent ) {
15340				$( parent.element ).attr( "title", parent.title );
15341				delete that.parents[ id ];
15342			});
15343		}
15344
15345		this.closing = true;
15346		this._trigger( "close", event, { tooltip: tooltip } );
15347		this.closing = false;
15348	},
15349
15350	_tooltip: function( element ) {
15351		var id = "ui-tooltip-" + increments++,
15352			tooltip = $( "<div>" )
15353				.attr({
15354					id: id,
15355					role: "tooltip"
15356				})
15357				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
15358					( this.options.tooltipClass || "" ) );
15359		$( "<div>" )
15360			.addClass( "ui-tooltip-content" )
15361			.appendTo( tooltip );
15362		tooltip.appendTo( this.document[0].body );
15363		this.tooltips[ id ] = element;
15364		return tooltip;
15365	},
15366
15367	_find: function( target ) {
15368		var id = target.data( "ui-tooltip-id" );
15369		return id ? $( "#" + id ) : $();
15370	},
15371
15372	_removeTooltip: function( tooltip ) {
15373		tooltip.remove();
15374		delete this.tooltips[ tooltip.attr( "id" ) ];
15375	},
15376
15377	_destroy: function() {
15378		var that = this;
15379
15380		// close open tooltips
15381		$.each( this.tooltips, function( id, element ) {
15382			// Delegate to close method to handle common cleanup
15383			var event = $.Event( "blur" );
15384			event.target = event.currentTarget = element[0];
15385			that.close( event, true );
15386
15387			// Remove immediately; destroying an open tooltip doesn't use the
15388			// hide animation
15389			$( "#" + id ).remove();
15390
15391			// Restore the title
15392			if ( element.data( "ui-tooltip-title" ) ) {
15393				element.attr( "title", element.data( "ui-tooltip-title" ) );
15394				element.removeData( "ui-tooltip-title" );
15395			}
15396		});
15397	}
15398});
15399
15400}( jQuery ) );
15401(function($, undefined) {
15402
15403var dataSpace = "ui-effects-";
15404
15405$.effects = {
15406	effect: {}
15407};
15408
15409/*!
15410 * jQuery Color Animations v2.1.2
15411 * https://github.com/jquery/jquery-color
15412 *
15413 * Copyright 2013 jQuery Foundation and other contributors
15414 * Released under the MIT license.
15415 * http://jquery.org/license
15416 *
15417 * Date: Wed Jan 16 08:47:09 2013 -0600
15418 */
15419(function( jQuery, undefined ) {
15420
15421	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
15422
15423	// plusequals test for += 100 -= 100
15424	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
15425	// a set of RE's that can match strings and generate color tuples.
15426	stringParsers = [{
15427			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
15428			parse: function( execResult ) {
15429				return [
15430					execResult[ 1 ],
15431					execResult[ 2 ],
15432					execResult[ 3 ],
15433					execResult[ 4 ]
15434				];
15435			}
15436		}, {
15437			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
15438			parse: function( execResult ) {
15439				return [
15440					execResult[ 1 ] * 2.55,
15441					execResult[ 2 ] * 2.55,
15442					execResult[ 3 ] * 2.55,
15443					execResult[ 4 ]
15444				];
15445			}
15446		}, {
15447			// this regex ignores A-F because it's compared against an already lowercased string
15448			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
15449			parse: function( execResult ) {
15450				return [
15451					parseInt( execResult[ 1 ], 16 ),
15452					parseInt( execResult[ 2 ], 16 ),
15453					parseInt( execResult[ 3 ], 16 )
15454				];
15455			}
15456		}, {
15457			// this regex ignores A-F because it's compared against an already lowercased string
15458			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
15459			parse: function( execResult ) {
15460				return [
15461					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
15462					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
15463					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
15464				];
15465			}
15466		}, {
15467			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
15468			space: "hsla",
15469			parse: function( execResult ) {
15470				return [
15471					execResult[ 1 ],
15472					execResult[ 2 ] / 100,
15473					execResult[ 3 ] / 100,
15474					execResult[ 4 ]
15475				];
15476			}
15477		}],
15478
15479	// jQuery.Color( )
15480	color = jQuery.Color = function( color, green, blue, alpha ) {
15481		return new jQuery.Color.fn.parse( color, green, blue, alpha );
15482	},
15483	spaces = {
15484		rgba: {
15485			props: {
15486				red: {
15487					idx: 0,
15488					type: "byte"
15489				},
15490				green: {
15491					idx: 1,
15492					type: "byte"
15493				},
15494				blue: {
15495					idx: 2,
15496					type: "byte"
15497				}
15498			}
15499		},
15500
15501		hsla: {
15502			props: {
15503				hue: {
15504					idx: 0,
15505					type: "degrees"
15506				},
15507				saturation: {
15508					idx: 1,
15509					type: "percent"
15510				},
15511				lightness: {
15512					idx: 2,
15513					type: "percent"
15514				}
15515			}
15516		}
15517	},
15518	propTypes = {
15519		"byte": {
15520			floor: true,
15521			max: 255
15522		},
15523		"percent": {
15524			max: 1
15525		},
15526		"degrees": {
15527			mod: 360,
15528			floor: true
15529		}
15530	},
15531	support = color.support = {},
15532
15533	// element for support tests
15534	supportElem = jQuery( "<p>" )[ 0 ],
15535
15536	// colors = jQuery.Color.names
15537	colors,
15538
15539	// local aliases of functions called often
15540	each = jQuery.each;
15541
15542// determine rgba support immediately
15543supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
15544support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
15545
15546// define cache name and alpha properties
15547// for rgba and hsla spaces
15548each( spaces, function( spaceName, space ) {
15549	space.cache = "_" + spaceName;
15550	space.props.alpha = {
15551		idx: 3,
15552		type: "percent",
15553		def: 1
15554	};
15555});
15556
15557function clamp( value, prop, allowEmpty ) {
15558	var type = propTypes[ prop.type ] || {};
15559
15560	if ( value == null ) {
15561		return (allowEmpty || !prop.def) ? null : prop.def;
15562	}
15563
15564	// ~~ is an short way of doing floor for positive numbers
15565	value = type.floor ? ~~value : parseFloat( value );
15566
15567	// IE will pass in empty strings as value for alpha,
15568	// which will hit this case
15569	if ( isNaN( value ) ) {
15570		return prop.def;
15571	}
15572
15573	if ( type.mod ) {
15574		// we add mod before modding to make sure that negatives values
15575		// get converted properly: -10 -> 350
15576		return (value + type.mod) % type.mod;
15577	}
15578
15579	// for now all property types without mod have min and max
15580	return 0 > value ? 0 : type.max < value ? type.max : value;
15581}
15582
15583function stringParse( string ) {
15584	var inst = color(),
15585		rgba = inst._rgba = [];
15586
15587	string = string.toLowerCase();
15588
15589	each( stringParsers, function( i, parser ) {
15590		var parsed,
15591			match = parser.re.exec( string ),
15592			values = match && parser.parse( match ),
15593			spaceName = parser.space || "rgba";
15594
15595		if ( values ) {
15596			parsed = inst[ spaceName ]( values );
15597
15598			// if this was an rgba parse the assignment might happen twice
15599			// oh well....
15600			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
15601			rgba = inst._rgba = parsed._rgba;
15602
15603			// exit each( stringParsers ) here because we matched
15604			return false;
15605		}
15606	});
15607
15608	// Found a stringParser that handled it
15609	if ( rgba.length ) {
15610
15611		// if this came from a parsed string, force "transparent" when alpha is 0
15612		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
15613		if ( rgba.join() === "0,0,0,0" ) {
15614			jQuery.extend( rgba, colors.transparent );
15615		}
15616		return inst;
15617	}
15618
15619	// named colors
15620	return colors[ string ];
15621}
15622
15623color.fn = jQuery.extend( color.prototype, {
15624	parse: function( red, green, blue, alpha ) {
15625		if ( red === undefined ) {
15626			this._rgba = [ null, null, null, null ];
15627			return this;
15628		}
15629		if ( red.jquery || red.nodeType ) {
15630			red = jQuery( red ).css( green );
15631			green = undefined;
15632		}
15633
15634		var inst = this,
15635			type = jQuery.type( red ),
15636			rgba = this._rgba = [];
15637
15638		// more than 1 argument specified - assume ( red, green, blue, alpha )
15639		if ( green !== undefined ) {
15640			red = [ red, green, blue, alpha ];
15641			type = "array";
15642		}
15643
15644		if ( type === "string" ) {
15645			return this.parse( stringParse( red ) || colors._default );
15646		}
15647
15648		if ( type === "array" ) {
15649			each( spaces.rgba.props, function( key, prop ) {
15650				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
15651			});
15652			return this;
15653		}
15654
15655		if ( type === "object" ) {
15656			if ( red instanceof color ) {
15657				each( spaces, function( spaceName, space ) {
15658					if ( red[ space.cache ] ) {
15659						inst[ space.cache ] = red[ space.cache ].slice();
15660					}
15661				});
15662			} else {
15663				each( spaces, function( spaceName, space ) {
15664					var cache = space.cache;
15665					each( space.props, function( key, prop ) {
15666
15667						// if the cache doesn't exist, and we know how to convert
15668						if ( !inst[ cache ] && space.to ) {
15669
15670							// if the value was null, we don't need to copy it
15671							// if the key was alpha, we don't need to copy it either
15672							if ( key === "alpha" || red[ key ] == null ) {
15673								return;
15674							}
15675							inst[ cache ] = space.to( inst._rgba );
15676						}
15677
15678						// this is the only case where we allow nulls for ALL properties.
15679						// call clamp with alwaysAllowEmpty
15680						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
15681					});
15682
15683					// everything defined but alpha?
15684					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
15685						// use the default of 1
15686						inst[ cache ][ 3 ] = 1;
15687						if ( space.from ) {
15688							inst._rgba = space.from( inst[ cache ] );
15689						}
15690					}
15691				});
15692			}
15693			return this;
15694		}
15695	},
15696	is: function( compare ) {
15697		var is = color( compare ),
15698			same = true,
15699			inst = this;
15700
15701		each( spaces, function( _, space ) {
15702			var localCache,
15703				isCache = is[ space.cache ];
15704			if (isCache) {
15705				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
15706				each( space.props, function( _, prop ) {
15707					if ( isCache[ prop.idx ] != null ) {
15708						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
15709						return same;
15710					}
15711				});
15712			}
15713			return same;
15714		});
15715		return same;
15716	},
15717	_space: function() {
15718		var used = [],
15719			inst = this;
15720		each( spaces, function( spaceName, space ) {
15721			if ( inst[ space.cache ] ) {
15722				used.push( spaceName );
15723			}
15724		});
15725		return used.pop();
15726	},
15727	transition: function( other, distance ) {
15728		var end = color( other ),
15729			spaceName = end._space(),
15730			space = spaces[ spaceName ],
15731			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
15732			start = startColor[ space.cache ] || space.to( startColor._rgba ),
15733			result = start.slice();
15734
15735		end = end[ space.cache ];
15736		each( space.props, function( key, prop ) {
15737			var index = prop.idx,
15738				startValue = start[ index ],
15739				endValue = end[ index ],
15740				type = propTypes[ prop.type ] || {};
15741
15742			// if null, don't override start value
15743			if ( endValue === null ) {
15744				return;
15745			}
15746			// if null - use end
15747			if ( startValue === null ) {
15748				result[ index ] = endValue;
15749			} else {
15750				if ( type.mod ) {
15751					if ( endValue - startValue > type.mod / 2 ) {
15752						startValue += type.mod;
15753					} else if ( startValue - endValue > type.mod / 2 ) {
15754						startValue -= type.mod;
15755					}
15756				}
15757				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
15758			}
15759		});
15760		return this[ spaceName ]( result );
15761	},
15762	blend: function( opaque ) {
15763		// if we are already opaque - return ourself
15764		if ( this._rgba[ 3 ] === 1 ) {
15765			return this;
15766		}
15767
15768		var rgb = this._rgba.slice(),
15769			a = rgb.pop(),
15770			blend = color( opaque )._rgba;
15771
15772		return color( jQuery.map( rgb, function( v, i ) {
15773			return ( 1 - a ) * blend[ i ] + a * v;
15774		}));
15775	},
15776	toRgbaString: function() {
15777		var prefix = "rgba(",
15778			rgba = jQuery.map( this._rgba, function( v, i ) {
15779				return v == null ? ( i > 2 ? 1 : 0 ) : v;
15780			});
15781
15782		if ( rgba[ 3 ] === 1 ) {
15783			rgba.pop();
15784			prefix = "rgb(";
15785		}
15786
15787		return prefix + rgba.join() + ")";
15788	},
15789	toHslaString: function() {
15790		var prefix = "hsla(",
15791			hsla = jQuery.map( this.hsla(), function( v, i ) {
15792				if ( v == null ) {
15793					v = i > 2 ? 1 : 0;
15794				}
15795
15796				// catch 1 and 2
15797				if ( i && i < 3 ) {
15798					v = Math.round( v * 100 ) + "%";
15799				}
15800				return v;
15801			});
15802
15803		if ( hsla[ 3 ] === 1 ) {
15804			hsla.pop();
15805			prefix = "hsl(";
15806		}
15807		return prefix + hsla.join() + ")";
15808	},
15809	toHexString: function( includeAlpha ) {
15810		var rgba = this._rgba.slice(),
15811			alpha = rgba.pop();
15812
15813		if ( includeAlpha ) {
15814			rgba.push( ~~( alpha * 255 ) );
15815		}
15816
15817		return "#" + jQuery.map( rgba, function( v ) {
15818
15819			// default to 0 when nulls exist
15820			v = ( v || 0 ).toString( 16 );
15821			return v.length === 1 ? "0" + v : v;
15822		}).join("");
15823	},
15824	toString: function() {
15825		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
15826	}
15827});
15828color.fn.parse.prototype = color.fn;
15829
15830// hsla conversions adapted from:
15831// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
15832
15833function hue2rgb( p, q, h ) {
15834	h = ( h + 1 ) % 1;
15835	if ( h * 6 < 1 ) {
15836		return p + (q - p) * h * 6;
15837	}
15838	if ( h * 2 < 1) {
15839		return q;
15840	}
15841	if ( h * 3 < 2 ) {
15842		return p + (q - p) * ((2/3) - h) * 6;
15843	}
15844	return p;
15845}
15846
15847spaces.hsla.to = function ( rgba ) {
15848	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
15849		return [ null, null, null, rgba[ 3 ] ];
15850	}
15851	var r = rgba[ 0 ] / 255,
15852		g = rgba[ 1 ] / 255,
15853		b = rgba[ 2 ] / 255,
15854		a = rgba[ 3 ],
15855		max = Math.max( r, g, b ),
15856		min = Math.min( r, g, b ),
15857		diff = max - min,
15858		add = max + min,
15859		l = add * 0.5,
15860		h, s;
15861
15862	if ( min === max ) {
15863		h = 0;
15864	} else if ( r === max ) {
15865		h = ( 60 * ( g - b ) / diff ) + 360;
15866	} else if ( g === max ) {
15867		h = ( 60 * ( b - r ) / diff ) + 120;
15868	} else {
15869		h = ( 60 * ( r - g ) / diff ) + 240;
15870	}
15871
15872	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
15873	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
15874	if ( diff === 0 ) {
15875		s = 0;
15876	} else if ( l <= 0.5 ) {
15877		s = diff / add;
15878	} else {
15879		s = diff / ( 2 - add );
15880	}
15881	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
15882};
15883
15884spaces.hsla.from = function ( hsla ) {
15885	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
15886		return [ null, null, null, hsla[ 3 ] ];
15887	}
15888	var h = hsla[ 0 ] / 360,
15889		s = hsla[ 1 ],
15890		l = hsla[ 2 ],
15891		a = hsla[ 3 ],
15892		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
15893		p = 2 * l - q;
15894
15895	return [
15896		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
15897		Math.round( hue2rgb( p, q, h ) * 255 ),
15898		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
15899		a
15900	];
15901};
15902
15903
15904each( spaces, function( spaceName, space ) {
15905	var props = space.props,
15906		cache = space.cache,
15907		to = space.to,
15908		from = space.from;
15909
15910	// makes rgba() and hsla()
15911	color.fn[ spaceName ] = function( value ) {
15912
15913		// generate a cache for this space if it doesn't exist
15914		if ( to && !this[ cache ] ) {
15915			this[ cache ] = to( this._rgba );
15916		}
15917		if ( value === undefined ) {
15918			return this[ cache ].slice();
15919		}
15920
15921		var ret,
15922			type = jQuery.type( value ),
15923			arr = ( type === "array" || type === "object" ) ? value : arguments,
15924			local = this[ cache ].slice();
15925
15926		each( props, function( key, prop ) {
15927			var val = arr[ type === "object" ? key : prop.idx ];
15928			if ( val == null ) {
15929				val = local[ prop.idx ];
15930			}
15931			local[ prop.idx ] = clamp( val, prop );
15932		});
15933
15934		if ( from ) {
15935			ret = color( from( local ) );
15936			ret[ cache ] = local;
15937			return ret;
15938		} else {
15939			return color( local );
15940		}
15941	};
15942
15943	// makes red() green() blue() alpha() hue() saturation() lightness()
15944	each( props, function( key, prop ) {
15945		// alpha is included in more than one space
15946		if ( color.fn[ key ] ) {
15947			return;
15948		}
15949		color.fn[ key ] = function( value ) {
15950			var vtype = jQuery.type( value ),
15951				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
15952				local = this[ fn ](),
15953				cur = local[ prop.idx ],
15954				match;
15955
15956			if ( vtype === "undefined" ) {
15957				return cur;
15958			}
15959
15960			if ( vtype === "function" ) {
15961				value = value.call( this, cur );
15962				vtype = jQuery.type( value );
15963			}
15964			if ( value == null && prop.empty ) {
15965				return this;
15966			}
15967			if ( vtype === "string" ) {
15968				match = rplusequals.exec( value );
15969				if ( match ) {
15970					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
15971				}
15972			}
15973			local[ prop.idx ] = value;
15974			return this[ fn ]( local );
15975		};
15976	});
15977});
15978
15979// add cssHook and .fx.step function for each named hook.
15980// accept a space separated string of properties
15981color.hook = function( hook ) {
15982	var hooks = hook.split( " " );
15983	each( hooks, function( i, hook ) {
15984		jQuery.cssHooks[ hook ] = {
15985			set: function( elem, value ) {
15986				var parsed, curElem,
15987					backgroundColor = "";
15988
15989				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
15990					value = color( parsed || value );
15991					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
15992						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
15993						while (
15994							(backgroundColor === "" || backgroundColor === "transparent") &&
15995							curElem && curElem.style
15996						) {
15997							try {
15998								backgroundColor = jQuery.css( curElem, "backgroundColor" );
15999								curElem = curElem.parentNode;
16000							} catch ( e ) {
16001							}
16002						}
16003
16004						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
16005							backgroundColor :
16006							"_default" );
16007					}
16008
16009					value = value.toRgbaString();
16010				}
16011				try {
16012					elem.style[ hook ] = value;
16013				} catch( e ) {
16014					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
16015				}
16016			}
16017		};
16018		jQuery.fx.step[ hook ] = function( fx ) {
16019			if ( !fx.colorInit ) {
16020				fx.start = color( fx.elem, hook );
16021				fx.end = color( fx.end );
16022				fx.colorInit = true;
16023			}
16024			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
16025		};
16026	});
16027
16028};
16029
16030color.hook( stepHooks );
16031
16032jQuery.cssHooks.borderColor = {
16033	expand: function( value ) {
16034		var expanded = {};
16035
16036		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
16037			expanded[ "border" + part + "Color" ] = value;
16038		});
16039		return expanded;
16040	}
16041};
16042
16043// Basic color names only.
16044// Usage of any of the other color names requires adding yourself or including
16045// jquery.color.svg-names.js.
16046colors = jQuery.Color.names = {
16047	// 4.1. Basic color keywords
16048	aqua: "#00ffff",
16049	black: "#000000",
16050	blue: "#0000ff",
16051	fuchsia: "#ff00ff",
16052	gray: "#808080",
16053	green: "#008000",
16054	lime: "#00ff00",
16055	maroon: "#800000",
16056	navy: "#000080",
16057	olive: "#808000",
16058	purple: "#800080",
16059	red: "#ff0000",
16060	silver: "#c0c0c0",
16061	teal: "#008080",
16062	white: "#ffffff",
16063	yellow: "#ffff00",
16064
16065	// 4.2.3. "transparent" color keyword
16066	transparent: [ null, null, null, 0 ],
16067
16068	_default: "#ffffff"
16069};
16070
16071})( jQuery );
16072
16073
16074/******************************************************************************/
16075/****************************** CLASS ANIMATIONS ******************************/
16076/******************************************************************************/
16077(function() {
16078
16079var classAnimationActions = [ "add", "remove", "toggle" ],
16080	shorthandStyles = {
16081		border: 1,
16082		borderBottom: 1,
16083		borderColor: 1,
16084		borderLeft: 1,
16085		borderRight: 1,
16086		borderTop: 1,
16087		borderWidth: 1,
16088		margin: 1,
16089		padding: 1
16090	};
16091
16092$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
16093	$.fx.step[ prop ] = function( fx ) {
16094		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
16095			jQuery.style( fx.elem, prop, fx.end );
16096			fx.setAttr = true;
16097		}
16098	};
16099});
16100
16101function getElementStyles( elem ) {
16102	var key, len,
16103		style = elem.ownerDocument.defaultView ?
16104			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
16105			elem.currentStyle,
16106		styles = {};
16107
16108	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
16109		len = style.length;
16110		while ( len-- ) {
16111			key = style[ len ];
16112			if ( typeof style[ key ] === "string" ) {
16113				styles[ $.camelCase( key ) ] = style[ key ];
16114			}
16115		}
16116	// support: Opera, IE <9
16117	} else {
16118		for ( key in style ) {
16119			if ( typeof style[ key ] === "string" ) {
16120				styles[ key ] = style[ key ];
16121			}
16122		}
16123	}
16124
16125	return styles;
16126}
16127
16128
16129function styleDifference( oldStyle, newStyle ) {
16130	var diff = {},
16131		name, value;
16132
16133	for ( name in newStyle ) {
16134		value = newStyle[ name ];
16135		if ( oldStyle[ name ] !== value ) {
16136			if ( !shorthandStyles[ name ] ) {
16137				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
16138					diff[ name ] = value;
16139				}
16140			}
16141		}
16142	}
16143
16144	return diff;
16145}
16146
16147// support: jQuery <1.8
16148if ( !$.fn.addBack ) {
16149	$.fn.addBack = function( selector ) {
16150		return this.add( selector == null ?
16151			this.prevObject : this.prevObject.filter( selector )
16152		);
16153	};
16154}
16155
16156$.effects.animateClass = function( value, duration, easing, callback ) {
16157	var o = $.speed( duration, easing, callback );
16158
16159	return this.queue( function() {
16160		var animated = $( this ),
16161			baseClass = animated.attr( "class" ) || "",
16162			applyClassChange,
16163			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
16164
16165		// map the animated objects to store the original styles.
16166		allAnimations = allAnimations.map(function() {
16167			var el = $( this );
16168			return {
16169				el: el,
16170				start: getElementStyles( this )
16171			};
16172		});
16173
16174		// apply class change
16175		applyClassChange = function() {
16176			$.each( classAnimationActions, function(i, action) {
16177				if ( value[ action ] ) {
16178					animated[ action + "Class" ]( value[ action ] );
16179				}
16180			});
16181		};
16182		applyClassChange();
16183
16184		// map all animated objects again - calculate new styles and diff
16185		allAnimations = allAnimations.map(function() {
16186			this.end = getElementStyles( this.el[ 0 ] );
16187			this.diff = styleDifference( this.start, this.end );
16188			return this;
16189		});
16190
16191		// apply original class
16192		animated.attr( "class", baseClass );
16193
16194		// map all animated objects again - this time collecting a promise
16195		allAnimations = allAnimations.map(function() {
16196			var styleInfo = this,
16197				dfd = $.Deferred(),
16198				opts = $.extend({}, o, {
16199					queue: false,
16200					complete: function() {
16201						dfd.resolve( styleInfo );
16202					}
16203				});
16204
16205			this.el.animate( this.diff, opts );
16206			return dfd.promise();
16207		});
16208
16209		// once all animations have completed:
16210		$.when.apply( $, allAnimations.get() ).done(function() {
16211
16212			// set the final class
16213			applyClassChange();
16214
16215			// for each animated element,
16216			// clear all css properties that were animated
16217			$.each( arguments, function() {
16218				var el = this.el;
16219				$.each( this.diff, function(key) {
16220					el.css( key, "" );
16221				});
16222			});
16223
16224			// this is guarnteed to be there if you use jQuery.speed()
16225			// it also handles dequeuing the next anim...
16226			o.complete.call( animated[ 0 ] );
16227		});
16228	});
16229};
16230
16231$.fn.extend({
16232	addClass: (function( orig ) {
16233		return function( classNames, speed, easing, callback ) {
16234			return speed ?
16235				$.effects.animateClass.call( this,
16236					{ add: classNames }, speed, easing, callback ) :
16237				orig.apply( this, arguments );
16238		};
16239	})( $.fn.addClass ),
16240
16241	removeClass: (function( orig ) {
16242		return function( classNames, speed, easing, callback ) {
16243			return arguments.length > 1 ?
16244				$.effects.animateClass.call( this,
16245					{ remove: classNames }, speed, easing, callback ) :
16246				orig.apply( this, arguments );
16247		};
16248	})( $.fn.removeClass ),
16249
16250	toggleClass: (function( orig ) {
16251		return function( classNames, force, speed, easing, callback ) {
16252			if ( typeof force === "boolean" || force === undefined ) {
16253				if ( !speed ) {
16254					// without speed parameter
16255					return orig.apply( this, arguments );
16256				} else {
16257					return $.effects.animateClass.call( this,
16258						(force ? { add: classNames } : { remove: classNames }),
16259						speed, easing, callback );
16260				}
16261			} else {
16262				// without force parameter
16263				return $.effects.animateClass.call( this,
16264					{ toggle: classNames }, force, speed, easing );
16265			}
16266		};
16267	})( $.fn.toggleClass ),
16268
16269	switchClass: function( remove, add, speed, easing, callback) {
16270		return $.effects.animateClass.call( this, {
16271			add: add,
16272			remove: remove
16273		}, speed, easing, callback );
16274	}
16275});
16276
16277})();
16278
16279/******************************************************************************/
16280/*********************************** EFFECTS **********************************/
16281/******************************************************************************/
16282
16283(function() {
16284
16285$.extend( $.effects, {
16286	version: "1.10.3",
16287
16288	// Saves a set of properties in a data storage
16289	save: function( element, set ) {
16290		for( var i=0; i < set.length; i++ ) {
16291			if ( set[ i ] !== null ) {
16292				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
16293			}
16294		}
16295	},
16296
16297	// Restores a set of previously saved properties from a data storage
16298	restore: function( element, set ) {
16299		var val, i;
16300		for( i=0; i < set.length; i++ ) {
16301			if ( set[ i ] !== null ) {
16302				val = element.data( dataSpace + set[ i ] );
16303				// support: jQuery 1.6.2
16304				// http://bugs.jquery.com/ticket/9917
16305				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
16306				// We can't differentiate between "" and 0 here, so we just assume
16307				// empty string since it's likely to be a more common value...
16308				if ( val === undefined ) {
16309					val = "";
16310				}
16311				element.css( set[ i ], val );
16312			}
16313		}
16314	},
16315
16316	setMode: function( el, mode ) {
16317		if (mode === "toggle") {
16318			mode = el.is( ":hidden" ) ? "show" : "hide";
16319		}
16320		return mode;
16321	},
16322
16323	// Translates a [top,left] array into a baseline value
16324	// this should be a little more flexible in the future to handle a string & hash
16325	getBaseline: function( origin, original ) {
16326		var y, x;
16327		switch ( origin[ 0 ] ) {
16328			case "top": y = 0; break;
16329			case "middle": y = 0.5; break;
16330			case "bottom": y = 1; break;
16331			default: y = origin[ 0 ] / original.height;
16332		}
16333		switch ( origin[ 1 ] ) {
16334			case "left": x = 0; break;
16335			case "center": x = 0.5; break;
16336			case "right": x = 1; break;
16337			default: x = origin[ 1 ] / original.width;
16338		}
16339		return {
16340			x: x,
16341			y: y
16342		};
16343	},
16344
16345	// Wraps the element around a wrapper that copies position properties
16346	createWrapper: function( element ) {
16347
16348		// if the element is already wrapped, return it
16349		if ( element.parent().is( ".ui-effects-wrapper" )) {
16350			return element.parent();
16351		}
16352
16353		// wrap the element
16354		var props = {
16355				width: element.outerWidth(true),
16356				height: element.outerHeight(true),
16357				"float": element.css( "float" )
16358			},
16359			wrapper = $( "<div></div>" )
16360				.addClass( "ui-effects-wrapper" )
16361				.css({
16362					fontSize: "100%",
16363					background: "transparent",
16364					border: "none",
16365					margin: 0,
16366					padding: 0
16367				}),
16368			// Store the size in case width/height are defined in % - Fixes #5245
16369			size = {
16370				width: element.width(),
16371				height: element.height()
16372			},
16373			active = document.activeElement;
16374
16375		// support: Firefox
16376		// Firefox incorrectly exposes anonymous content
16377		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
16378		try {
16379			active.id;
16380		} catch( e ) {
16381			active = document.body;
16382		}
16383
16384		element.wrap( wrapper );
16385
16386		// Fixes #7595 - Elements lose focus when wrapped.
16387		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
16388			$( active ).focus();
16389		}
16390
16391		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
16392
16393		// transfer positioning properties to the wrapper
16394		if ( element.css( "position" ) === "static" ) {
16395			wrapper.css({ position: "relative" });
16396			element.css({ position: "relative" });
16397		} else {
16398			$.extend( props, {
16399				position: element.css( "position" ),
16400				zIndex: element.css( "z-index" )
16401			});
16402			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
16403				props[ pos ] = element.css( pos );
16404				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
16405					props[ pos ] = "auto";
16406				}
16407			});
16408			element.css({
16409				position: "relative",
16410				top: 0,
16411				left: 0,
16412				right: "auto",
16413				bottom: "auto"
16414			});
16415		}
16416		element.css(size);
16417
16418		return wrapper.css( props ).show();
16419	},
16420
16421	removeWrapper: function( element ) {
16422		var active = document.activeElement;
16423
16424		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
16425			element.parent().replaceWith( element );
16426
16427			// Fixes #7595 - Elements lose focus when wrapped.
16428			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
16429				$( active ).focus();
16430			}
16431		}
16432
16433
16434		return element;
16435	},
16436
16437	setTransition: function( element, list, factor, value ) {
16438		value = value || {};
16439		$.each( list, function( i, x ) {
16440			var unit = element.cssUnit( x );
16441			if ( unit[ 0 ] > 0 ) {
16442				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
16443			}
16444		});
16445		return value;
16446	}
16447});
16448
16449// return an effect options object for the given parameters:
16450function _normalizeArguments( effect, options, speed, callback ) {
16451
16452	// allow passing all options as the first parameter
16453	if ( $.isPlainObject( effect ) ) {
16454		options = effect;
16455		effect = effect.effect;
16456	}
16457
16458	// convert to an object
16459	effect = { effect: effect };
16460
16461	// catch (effect, null, ...)
16462	if ( options == null ) {
16463		options = {};
16464	}
16465
16466	// catch (effect, callback)
16467	if ( $.isFunction( options ) ) {
16468		callback = options;
16469		speed = null;
16470		options = {};
16471	}
16472
16473	// catch (effect, speed, ?)
16474	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
16475		callback = speed;
16476		speed = options;
16477		options = {};
16478	}
16479
16480	// catch (effect, options, callback)
16481	if ( $.isFunction( speed ) ) {
16482		callback = speed;
16483		speed = null;
16484	}
16485
16486	// add options to effect
16487	if ( options ) {
16488		$.extend( effect, options );
16489	}
16490
16491	speed = speed || options.duration;
16492	effect.duration = $.fx.off ? 0 :
16493		typeof speed === "number" ? speed :
16494		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
16495		$.fx.speeds._default;
16496
16497	effect.complete = callback || options.complete;
16498
16499	return effect;
16500}
16501
16502function standardAnimationOption( option ) {
16503	// Valid standard speeds (nothing, number, named speed)
16504	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
16505		return true;
16506	}
16507
16508	// Invalid strings - treat as "normal" speed
16509	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
16510		return true;
16511	}
16512
16513	// Complete callback
16514	if ( $.isFunction( option ) ) {
16515		return true;
16516	}
16517
16518	// Options hash (but not naming an effect)
16519	if ( typeof option === "object" && !option.effect ) {
16520		return true;
16521	}
16522
16523	// Didn't match any standard API
16524	return false;
16525}
16526
16527$.fn.extend({
16528	effect: function( /* effect, options, speed, callback */ ) {
16529		var args = _normalizeArguments.apply( this, arguments ),
16530			mode = args.mode,
16531			queue = args.queue,
16532			effectMethod = $.effects.effect[ args.effect ];
16533
16534		if ( $.fx.off || !effectMethod ) {
16535			// delegate to the original method (e.g., .show()) if possible
16536			if ( mode ) {
16537				return this[ mode ]( args.duration, args.complete );
16538			} else {
16539				return this.each( function() {
16540					if ( args.complete ) {
16541						args.complete.call( this );
16542					}
16543				});
16544			}
16545		}
16546
16547		function run( next ) {
16548			var elem = $( this ),
16549				complete = args.complete,
16550				mode = args.mode;
16551
16552			function done() {
16553				if ( $.isFunction( complete ) ) {
16554					complete.call( elem[0] );
16555				}
16556				if ( $.isFunction( next ) ) {
16557					next();
16558				}
16559			}
16560
16561			// If the element already has the correct final state, delegate to
16562			// the core methods so the internal tracking of "olddisplay" works.
16563			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
16564				elem[ mode ]();
16565				done();
16566			} else {
16567				effectMethod.call( elem[0], args, done );
16568			}
16569		}
16570
16571		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
16572	},
16573
16574	show: (function( orig ) {
16575		return function( option ) {
16576			if ( standardAnimationOption( option ) ) {
16577				return orig.apply( this, arguments );
16578			} else {
16579				var args = _normalizeArguments.apply( this, arguments );
16580				args.mode = "show";
16581				return this.effect.call( this, args );
16582			}
16583		};
16584	})( $.fn.show ),
16585
16586	hide: (function( orig ) {
16587		return function( option ) {
16588			if ( standardAnimationOption( option ) ) {
16589				return orig.apply( this, arguments );
16590			} else {
16591				var args = _normalizeArguments.apply( this, arguments );
16592				args.mode = "hide";
16593				return this.effect.call( this, args );
16594			}
16595		};
16596	})( $.fn.hide ),
16597
16598	toggle: (function( orig ) {
16599		return function( option ) {
16600			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
16601				return orig.apply( this, arguments );
16602			} else {
16603				var args = _normalizeArguments.apply( this, arguments );
16604				args.mode = "toggle";
16605				return this.effect.call( this, args );
16606			}
16607		};
16608	})( $.fn.toggle ),
16609
16610	// helper functions
16611	cssUnit: function(key) {
16612		var style = this.css( key ),
16613			val = [];
16614
16615		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
16616			if ( style.indexOf( unit ) > 0 ) {
16617				val = [ parseFloat( style ), unit ];
16618			}
16619		});
16620		return val;
16621	}
16622});
16623
16624})();
16625
16626/******************************************************************************/
16627/*********************************** EASING ***********************************/
16628/******************************************************************************/
16629
16630(function() {
16631
16632// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
16633
16634var baseEasings = {};
16635
16636$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
16637	baseEasings[ name ] = function( p ) {
16638		return Math.pow( p, i + 2 );
16639	};
16640});
16641
16642$.extend( baseEasings, {
16643	Sine: function ( p ) {
16644		return 1 - Math.cos( p * Math.PI / 2 );
16645	},
16646	Circ: function ( p ) {
16647		return 1 - Math.sqrt( 1 - p * p );
16648	},
16649	Elastic: function( p ) {
16650		return p === 0 || p === 1 ? p :
16651			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
16652	},
16653	Back: function( p ) {
16654		return p * p * ( 3 * p - 2 );
16655	},
16656	Bounce: function ( p ) {
16657		var pow2,
16658			bounce = 4;
16659
16660		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
16661		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
16662	}
16663});
16664
16665$.each( baseEasings, function( name, easeIn ) {
16666	$.easing[ "easeIn" + name ] = easeIn;
16667	$.easing[ "easeOut" + name ] = function( p ) {
16668		return 1 - easeIn( 1 - p );
16669	};
16670	$.easing[ "easeInOut" + name ] = function( p ) {
16671		return p < 0.5 ?
16672			easeIn( p * 2 ) / 2 :
16673			1 - easeIn( p * -2 + 2 ) / 2;
16674	};
16675});
16676
16677})();
16678
16679})(jQuery);
16680(function( $, undefined ) {
16681
16682var rvertical = /up|down|vertical/,
16683	rpositivemotion = /up|left|vertical|horizontal/;
16684
16685$.effects.effect.blind = function( o, done ) {
16686	// Create element
16687	var el = $( this ),
16688		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
16689		mode = $.effects.setMode( el, o.mode || "hide" ),
16690		direction = o.direction || "up",
16691		vertical = rvertical.test( direction ),
16692		ref = vertical ? "height" : "width",
16693		ref2 = vertical ? "top" : "left",
16694		motion = rpositivemotion.test( direction ),
16695		animation = {},
16696		show = mode === "show",
16697		wrapper, distance, margin;
16698
16699	// if already wrapped, the wrapper's properties are my property. #6245
16700	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
16701		$.effects.save( el.parent(), props );
16702	} else {
16703		$.effects.save( el, props );
16704	}
16705	el.show();
16706	wrapper = $.effects.createWrapper( el ).css({
16707		overflow: "hidden"
16708	});
16709
16710	distance = wrapper[ ref ]();
16711	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
16712
16713	animation[ ref ] = show ? distance : 0;
16714	if ( !motion ) {
16715		el
16716			.css( vertical ? "bottom" : "right", 0 )
16717			.css( vertical ? "top" : "left", "auto" )
16718			.css({ position: "absolute" });
16719
16720		animation[ ref2 ] = show ? margin : distance + margin;
16721	}
16722
16723	// start at 0 if we are showing
16724	if ( show ) {
16725		wrapper.css( ref, 0 );
16726		if ( ! motion ) {
16727			wrapper.css( ref2, margin + distance );
16728		}
16729	}
16730
16731	// Animate
16732	wrapper.animate( animation, {
16733		duration: o.duration,
16734		easing: o.easing,
16735		queue: false,
16736		complete: function() {
16737			if ( mode === "hide" ) {
16738				el.hide();
16739			}
16740			$.effects.restore( el, props );
16741			$.effects.removeWrapper( el );
16742			done();
16743		}
16744	});
16745
16746};
16747
16748})(jQuery);
16749(function( $, undefined ) {
16750
16751$.effects.effect.bounce = function( o, done ) {
16752	var el = $( this ),
16753		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
16754
16755		// defaults:
16756		mode = $.effects.setMode( el, o.mode || "effect" ),
16757		hide = mode === "hide",
16758		show = mode === "show",
16759		direction = o.direction || "up",
16760		distance = o.distance,
16761		times = o.times || 5,
16762
16763		// number of internal animations
16764		anims = times * 2 + ( show || hide ? 1 : 0 ),
16765		speed = o.duration / anims,
16766		easing = o.easing,
16767
16768		// utility:
16769		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
16770		motion = ( direction === "up" || direction === "left" ),
16771		i,
16772		upAnim,
16773		downAnim,
16774
16775		// we will need to re-assemble the queue to stack our animations in place
16776		queue = el.queue(),
16777		queuelen = queue.length;
16778
16779	// Avoid touching opacity to prevent clearType and PNG issues in IE
16780	if ( show || hide ) {
16781		props.push( "opacity" );
16782	}
16783
16784	$.effects.save( el, props );
16785	el.show();
16786	$.effects.createWrapper( el ); // Create Wrapper
16787
16788	// default distance for the BIGGEST bounce is the outer Distance / 3
16789	if ( !distance ) {
16790		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
16791	}
16792
16793	if ( show ) {
16794		downAnim = { opacity: 1 };
16795		downAnim[ ref ] = 0;
16796
16797		// if we are showing, force opacity 0 and set the initial position
16798		// then do the "first" animation
16799		el.css( "opacity", 0 )
16800			.css( ref, motion ? -distance * 2 : distance * 2 )
16801			.animate( downAnim, speed, easing );
16802	}
16803
16804	// start at the smallest distance if we are hiding
16805	if ( hide ) {
16806		distance = distance / Math.pow( 2, times - 1 );
16807	}
16808
16809	downAnim = {};
16810	downAnim[ ref ] = 0;
16811	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
16812	for ( i = 0; i < times; i++ ) {
16813		upAnim = {};
16814		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
16815
16816		el.animate( upAnim, speed, easing )
16817			.animate( downAnim, speed, easing );
16818
16819		distance = hide ? distance * 2 : distance / 2;
16820	}
16821
16822	// Last Bounce when Hiding
16823	if ( hide ) {
16824		upAnim = { opacity: 0 };
16825		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
16826
16827		el.animate( upAnim, speed, easing );
16828	}
16829
16830	el.queue(function() {
16831		if ( hide ) {
16832			el.hide();
16833		}
16834		$.effects.restore( el, props );
16835		$.effects.removeWrapper( el );
16836		done();
16837	});
16838
16839	// inject all the animations we just queued to be first in line (after "inprogress")
16840	if ( queuelen > 1) {
16841		queue.splice.apply( queue,
16842			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16843	}
16844	el.dequeue();
16845
16846};
16847
16848})(jQuery);
16849(function( $, undefined ) {
16850
16851$.effects.effect.clip = function( o, done ) {
16852	// Create element
16853	var el = $( this ),
16854		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
16855		mode = $.effects.setMode( el, o.mode || "hide" ),
16856		show = mode === "show",
16857		direction = o.direction || "vertical",
16858		vert = direction === "vertical",
16859		size = vert ? "height" : "width",
16860		position = vert ? "top" : "left",
16861		animation = {},
16862		wrapper, animate, distance;
16863
16864	// Save & Show
16865	$.effects.save( el, props );
16866	el.show();
16867
16868	// Create Wrapper
16869	wrapper = $.effects.createWrapper( el ).css({
16870		overflow: "hidden"
16871	});
16872	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
16873	distance = animate[ size ]();
16874
16875	// Shift
16876	if ( show ) {
16877		animate.css( size, 0 );
16878		animate.css( position, distance / 2 );
16879	}
16880
16881	// Create Animation Object:
16882	animation[ size ] = show ? distance : 0;
16883	animation[ position ] = show ? 0 : distance / 2;
16884
16885	// Animate
16886	animate.animate( animation, {
16887		queue: false,
16888		duration: o.duration,
16889		easing: o.easing,
16890		complete: function() {
16891			if ( !show ) {
16892				el.hide();
16893			}
16894			$.effects.restore( el, props );
16895			$.effects.removeWrapper( el );
16896			done();
16897		}
16898	});
16899
16900};
16901
16902})(jQuery);
16903(function( $, undefined ) {
16904
16905$.effects.effect.drop = function( o, done ) {
16906
16907	var el = $( this ),
16908		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
16909		mode = $.effects.setMode( el, o.mode || "hide" ),
16910		show = mode === "show",
16911		direction = o.direction || "left",
16912		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
16913		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
16914		animation = {
16915			opacity: show ? 1 : 0
16916		},
16917		distance;
16918
16919	// Adjust
16920	$.effects.save( el, props );
16921	el.show();
16922	$.effects.createWrapper( el );
16923
16924	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
16925
16926	if ( show ) {
16927		el
16928			.css( "opacity", 0 )
16929			.css( ref, motion === "pos" ? -distance : distance );
16930	}
16931
16932	// Animation
16933	animation[ ref ] = ( show ?
16934		( motion === "pos" ? "+=" : "-=" ) :
16935		( motion === "pos" ? "-=" : "+=" ) ) +
16936		distance;
16937
16938	// Animate
16939	el.animate( animation, {
16940		queue: false,
16941		duration: o.duration,
16942		easing: o.easing,
16943		complete: function() {
16944			if ( mode === "hide" ) {
16945				el.hide();
16946			}
16947			$.effects.restore( el, props );
16948			$.effects.removeWrapper( el );
16949			done();
16950		}
16951	});
16952};
16953
16954})(jQuery);
16955(function( $, undefined ) {
16956
16957$.effects.effect.explode = function( o, done ) {
16958
16959	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
16960		cells = rows,
16961		el = $( this ),
16962		mode = $.effects.setMode( el, o.mode || "hide" ),
16963		show = mode === "show",
16964
16965		// show and then visibility:hidden the element before calculating offset
16966		offset = el.show().css( "visibility", "hidden" ).offset(),
16967
16968		// width and height of a piece
16969		width = Math.ceil( el.outerWidth() / cells ),
16970		height = Math.ceil( el.outerHeight() / rows ),
16971		pieces = [],
16972
16973		// loop
16974		i, j, left, top, mx, my;
16975
16976	// children animate complete:
16977	function childComplete() {
16978		pieces.push( this );
16979		if ( pieces.length === rows * cells ) {
16980			animComplete();
16981		}
16982	}
16983
16984	// clone the element for each row and cell.
16985	for( i = 0; i < rows ; i++ ) { // ===>
16986		top = offset.top + i * height;
16987		my = i - ( rows - 1 ) / 2 ;
16988
16989		for( j = 0; j < cells ; j++ ) { // |||
16990			left = offset.left + j * width;
16991			mx = j - ( cells - 1 ) / 2 ;
16992
16993			// Create a clone of the now hidden main element that will be absolute positioned
16994			// within a wrapper div off the -left and -top equal to size of our pieces
16995			el
16996				.clone()
16997				.appendTo( "body" )
16998				.wrap( "<div></div>" )
16999				.css({
17000					position: "absolute",
17001					visibility: "visible",
17002					left: -j * width,
17003					top: -i * height
17004				})
17005
17006			// select the wrapper - make it overflow: hidden and absolute positioned based on
17007			// where the original was located +left and +top equal to the size of pieces
17008				.parent()
17009				.addClass( "ui-effects-explode" )
17010				.css({
17011					position: "absolute",
17012					overflow: "hidden",
17013					width: width,
17014					height: height,
17015					left: left + ( show ? mx * width : 0 ),
17016					top: top + ( show ? my * height : 0 ),
17017					opacity: show ? 0 : 1
17018				}).animate({
17019					left: left + ( show ? 0 : mx * width ),
17020					top: top + ( show ? 0 : my * height ),
17021					opacity: show ? 1 : 0
17022				}, o.duration || 500, o.easing, childComplete );
17023		}
17024	}
17025
17026	function animComplete() {
17027		el.css({
17028			visibility: "visible"
17029		});
17030		$( pieces ).remove();
17031		if ( !show ) {
17032			el.hide();
17033		}
17034		done();
17035	}
17036};
17037
17038})(jQuery);
17039(function( $, undefined ) {
17040
17041$.effects.effect.fade = function( o, done ) {
17042	var el = $( this ),
17043		mode = $.effects.setMode( el, o.mode || "toggle" );
17044
17045	el.animate({
17046		opacity: mode
17047	}, {
17048		queue: false,
17049		duration: o.duration,
17050		easing: o.easing,
17051		complete: done
17052	});
17053};
17054
17055})( jQuery );
17056(function( $, undefined ) {
17057
17058$.effects.effect.fold = function( o, done ) {
17059
17060	// Create element
17061	var el = $( this ),
17062		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
17063		mode = $.effects.setMode( el, o.mode || "hide" ),
17064		show = mode === "show",
17065		hide = mode === "hide",
17066		size = o.size || 15,
17067		percent = /([0-9]+)%/.exec( size ),
17068		horizFirst = !!o.horizFirst,
17069		widthFirst = show !== horizFirst,
17070		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
17071		duration = o.duration / 2,
17072		wrapper, distance,
17073		animation1 = {},
17074		animation2 = {};
17075
17076	$.effects.save( el, props );
17077	el.show();
17078
17079	// Create Wrapper
17080	wrapper = $.effects.createWrapper( el ).css({
17081		overflow: "hidden"
17082	});
17083	distance = widthFirst ?
17084		[ wrapper.width(), wrapper.height() ] :
17085		[ wrapper.height(), wrapper.width() ];
17086
17087	if ( percent ) {
17088		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
17089	}
17090	if ( show ) {
17091		wrapper.css( horizFirst ? {
17092			height: 0,
17093			width: size
17094		} : {
17095			height: size,
17096			width: 0
17097		});
17098	}
17099
17100	// Animation
17101	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
17102	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
17103
17104	// Animate
17105	wrapper
17106		.animate( animation1, duration, o.easing )
17107		.animate( animation2, duration, o.easing, function() {
17108			if ( hide ) {
17109				el.hide();
17110			}
17111			$.effects.restore( el, props );
17112			$.effects.removeWrapper( el );
17113			done();
17114		});
17115
17116};
17117
17118})(jQuery);
17119(function( $, undefined ) {
17120
17121$.effects.effect.highlight = function( o, done ) {
17122	var elem = $( this ),
17123		props = [ "backgroundImage", "backgroundColor", "opacity" ],
17124		mode = $.effects.setMode( elem, o.mode || "show" ),
17125		animation = {
17126			backgroundColor: elem.css( "backgroundColor" )
17127		};
17128
17129	if (mode === "hide") {
17130		animation.opacity = 0;
17131	}
17132
17133	$.effects.save( elem, props );
17134
17135	elem
17136		.show()
17137		.css({
17138			backgroundImage: "none",
17139			backgroundColor: o.color || "#ffff99"
17140		})
17141		.animate( animation, {
17142			queue: false,
17143			duration: o.duration,
17144			easing: o.easing,
17145			complete: function() {
17146				if ( mode === "hide" ) {
17147					elem.hide();
17148				}
17149				$.effects.restore( elem, props );
17150				done();
17151			}
17152		});
17153};
17154
17155})(jQuery);
17156(function( $, undefined ) {
17157
17158$.effects.effect.pulsate = function( o, done ) {
17159	var elem = $( this ),
17160		mode = $.effects.setMode( elem, o.mode || "show" ),
17161		show = mode === "show",
17162		hide = mode === "hide",
17163		showhide = ( show || mode === "hide" ),
17164
17165		// showing or hiding leaves of the "last" animation
17166		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
17167		duration = o.duration / anims,
17168		animateTo = 0,
17169		queue = elem.queue(),
17170		queuelen = queue.length,
17171		i;
17172
17173	if ( show || !elem.is(":visible")) {
17174		elem.css( "opacity", 0 ).show();
17175		animateTo = 1;
17176	}
17177
17178	// anims - 1 opacity "toggles"
17179	for ( i = 1; i < anims; i++ ) {
17180		elem.animate({
17181			opacity: animateTo
17182		}, duration, o.easing );
17183		animateTo = 1 - animateTo;
17184	}
17185
17186	elem.animate({
17187		opacity: animateTo
17188	}, duration, o.easing);
17189
17190	elem.queue(function() {
17191		if ( hide ) {
17192			elem.hide();
17193		}
17194		done();
17195	});
17196
17197	// We just queued up "anims" animations, we need to put them next in the queue
17198	if ( queuelen > 1 ) {
17199		queue.splice.apply( queue,
17200			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
17201	}
17202	elem.dequeue();
17203};
17204
17205})(jQuery);
17206(function( $, undefined ) {
17207
17208$.effects.effect.puff = function( o, done ) {
17209	var elem = $( this ),
17210		mode = $.effects.setMode( elem, o.mode || "hide" ),
17211		hide = mode === "hide",
17212		percent = parseInt( o.percent, 10 ) || 150,
17213		factor = percent / 100,
17214		original = {
17215			height: elem.height(),
17216			width: elem.width(),
17217			outerHeight: elem.outerHeight(),
17218			outerWidth: elem.outerWidth()
17219		};
17220
17221	$.extend( o, {
17222		effect: "scale",
17223		queue: false,
17224		fade: true,
17225		mode: mode,
17226		complete: done,
17227		percent: hide ? percent : 100,
17228		from: hide ?
17229			original :
17230			{
17231				height: original.height * factor,
17232				width: original.width * factor,
17233				outerHeight: original.outerHeight * factor,
17234				outerWidth: original.outerWidth * factor
17235			}
17236	});
17237
17238	elem.effect( o );
17239};
17240
17241$.effects.effect.scale = function( o, done ) {
17242
17243	// Create element
17244	var el = $( this ),
17245		options = $.extend( true, {}, o ),
17246		mode = $.effects.setMode( el, o.mode || "effect" ),
17247		percent = parseInt( o.percent, 10 ) ||
17248			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
17249		direction = o.direction || "both",
17250		origin = o.origin,
17251		original = {
17252			height: el.height(),
17253			width: el.width(),
17254			outerHeight: el.outerHeight(),
17255			outerWidth: el.outerWidth()
17256		},
17257		factor = {
17258			y: direction !== "horizontal" ? (percent / 100) : 1,
17259			x: direction !== "vertical" ? (percent / 100) : 1
17260		};
17261
17262	// We are going to pass this effect to the size effect:
17263	options.effect = "size";
17264	options.queue = false;
17265	options.complete = done;
17266
17267	// Set default origin and restore for show/hide
17268	if ( mode !== "effect" ) {
17269		options.origin = origin || ["middle","center"];
17270		options.restore = true;
17271	}
17272
17273	options.from = o.from || ( mode === "show" ? {
17274		height: 0,
17275		width: 0,
17276		outerHeight: 0,
17277		outerWidth: 0
17278	} : original );
17279	options.to = {
17280		height: original.height * factor.y,
17281		width: original.width * factor.x,
17282		outerHeight: original.outerHeight * factor.y,
17283		outerWidth: original.outerWidth * factor.x
17284	};
17285
17286	// Fade option to support puff
17287	if ( options.fade ) {
17288		if ( mode === "show" ) {
17289			options.from.opacity = 0;
17290			options.to.opacity = 1;
17291		}
17292		if ( mode === "hide" ) {
17293			options.from.opacity = 1;
17294			options.to.opacity = 0;
17295		}
17296	}
17297
17298	// Animate
17299	el.effect( options );
17300
17301};
17302
17303$.effects.effect.size = function( o, done ) {
17304
17305	// Create element
17306	var original, baseline, factor,
17307		el = $( this ),
17308		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
17309
17310		// Always restore
17311		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
17312
17313		// Copy for children
17314		props2 = [ "width", "height", "overflow" ],
17315		cProps = [ "fontSize" ],
17316		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
17317		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
17318
17319		// Set options
17320		mode = $.effects.setMode( el, o.mode || "effect" ),
17321		restore = o.restore || mode !== "effect",
17322		scale = o.scale || "both",
17323		origin = o.origin || [ "middle", "center" ],
17324		position = el.css( "position" ),
17325		props = restore ? props0 : props1,
17326		zero = {
17327			height: 0,
17328			width: 0,
17329			outerHeight: 0,
17330			outerWidth: 0
17331		};
17332
17333	if ( mode === "show" ) {
17334		el.show();
17335	}
17336	original = {
17337		height: el.height(),
17338		width: el.width(),
17339		outerHeight: el.outerHeight(),
17340		outerWidth: el.outerWidth()
17341	};
17342
17343	if ( o.mode === "toggle" && mode === "show" ) {
17344		el.from = o.to || zero;
17345		el.to = o.from || original;
17346	} else {
17347		el.from = o.from || ( mode === "show" ? zero : original );
17348		el.to = o.to || ( mode === "hide" ? zero : original );
17349	}
17350
17351	// Set scaling factor
17352	factor = {
17353		from: {
17354			y: el.from.height / original.height,
17355			x: el.from.width / original.width
17356		},
17357		to: {
17358			y: el.to.height / original.height,
17359			x: el.to.width / original.width
17360		}
17361	};
17362
17363	// Scale the css box
17364	if ( scale === "box" || scale === "both" ) {
17365
17366		// Vertical props scaling
17367		if ( factor.from.y !== factor.to.y ) {
17368			props = props.concat( vProps );
17369			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
17370			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
17371		}
17372
17373		// Horizontal props scaling
17374		if ( factor.from.x !== factor.to.x ) {
17375			props = props.concat( hProps );
17376			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
17377			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
17378		}
17379	}
17380
17381	// Scale the content
17382	if ( scale === "content" || scale === "both" ) {
17383
17384		// Vertical props scaling
17385		if ( factor.from.y !== factor.to.y ) {
17386			props = props.concat( cProps ).concat( props2 );
17387			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
17388			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
17389		}
17390	}
17391
17392	$.effects.save( el, props );
17393	el.show();
17394	$.effects.createWrapper( el );
17395	el.css( "overflow", "hidden" ).css( el.from );
17396
17397	// Adjust
17398	if (origin) { // Calculate baseline shifts
17399		baseline = $.effects.getBaseline( origin, original );
17400		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
17401		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
17402		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
17403		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
17404	}
17405	el.css( el.from ); // set top & left
17406
17407	// Animate
17408	if ( scale === "content" || scale === "both" ) { // Scale the children
17409
17410		// Add margins/font-size
17411		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
17412		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
17413		props2 = props0.concat(vProps).concat(hProps);
17414
17415		el.find( "*[width]" ).each( function(){
17416			var child = $( this ),
17417				c_original = {
17418					height: child.height(),
17419					width: child.width(),
17420					outerHeight: child.outerHeight(),
17421					outerWidth: child.outerWidth()
17422				};
17423			if (restore) {
17424				$.effects.save(child, props2);
17425			}
17426
17427			child.from = {
17428				height: c_original.height * factor.from.y,
17429				width: c_original.width * factor.from.x,
17430				outerHeight: c_original.outerHeight * factor.from.y,
17431				outerWidth: c_original.outerWidth * factor.from.x
17432			};
17433			child.to = {
17434				height: c_original.height * factor.to.y,
17435				width: c_original.width * factor.to.x,
17436				outerHeight: c_original.height * factor.to.y,
17437				outerWidth: c_original.width * factor.to.x
17438			};
17439
17440			// Vertical props scaling
17441			if ( factor.from.y !== factor.to.y ) {
17442				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
17443				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
17444			}
17445
17446			// Horizontal props scaling
17447			if ( factor.from.x !== factor.to.x ) {
17448				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
17449				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
17450			}
17451
17452			// Animate children
17453			child.css( child.from );
17454			child.animate( child.to, o.duration, o.easing, function() {
17455
17456				// Restore children
17457				if ( restore ) {
17458					$.effects.restore( child, props2 );
17459				}
17460			});
17461		});
17462	}
17463
17464	// Animate
17465	el.animate( el.to, {
17466		queue: false,
17467		duration: o.duration,
17468		easing: o.easing,
17469		complete: function() {
17470			if ( el.to.opacity === 0 ) {
17471				el.css( "opacity", el.from.opacity );
17472			}
17473			if( mode === "hide" ) {
17474				el.hide();
17475			}
17476			$.effects.restore( el, props );
17477			if ( !restore ) {
17478
17479				// we need to calculate our new positioning based on the scaling
17480				if ( position === "static" ) {
17481					el.css({
17482						position: "relative",
17483						top: el.to.top,
17484						left: el.to.left
17485					});
17486				} else {
17487					$.each([ "top", "left" ], function( idx, pos ) {
17488						el.css( pos, function( _, str ) {
17489							var val = parseInt( str, 10 ),
17490								toRef = idx ? el.to.left : el.to.top;
17491
17492							// if original was "auto", recalculate the new value from wrapper
17493							if ( str === "auto" ) {
17494								return toRef + "px";
17495							}
17496
17497							return val + toRef + "px";
17498						});
17499					});
17500				}
17501			}
17502
17503			$.effects.removeWrapper( el );
17504			done();
17505		}
17506	});
17507
17508};
17509
17510})(jQuery);
17511(function( $, undefined ) {
17512
17513$.effects.effect.shake = function( o, done ) {
17514
17515	var el = $( this ),
17516		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
17517		mode = $.effects.setMode( el, o.mode || "effect" ),
17518		direction = o.direction || "left",
17519		distance = o.distance || 20,
17520		times = o.times || 3,
17521		anims = times * 2 + 1,
17522		speed = Math.round(o.duration/anims),
17523		ref = (direction === "up" || direction === "down") ? "top" : "left",
17524		positiveMotion = (direction === "up" || direction === "left"),
17525		animation = {},
17526		animation1 = {},
17527		animation2 = {},
17528		i,
17529
17530		// we will need to re-assemble the queue to stack our animations in place
17531		queue = el.queue(),
17532		queuelen = queue.length;
17533
17534	$.effects.save( el, props );
17535	el.show();
17536	$.effects.createWrapper( el );
17537
17538	// Animation
17539	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
17540	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
17541	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
17542
17543	// Animate
17544	el.animate( animation, speed, o.easing );
17545
17546	// Shakes
17547	for ( i = 1; i < times; i++ ) {
17548		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
17549	}
17550	el
17551		.animate( animation1, speed, o.easing )
17552		.animate( animation, speed / 2, o.easing )
17553		.queue(function() {
17554			if ( mode === "hide" ) {
17555				el.hide();
17556			}
17557			$.effects.restore( el, props );
17558			$.effects.removeWrapper( el );
17559			done();
17560		});
17561
17562	// inject all the animations we just queued to be first in line (after "inprogress")
17563	if ( queuelen > 1) {
17564		queue.splice.apply( queue,
17565			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
17566	}
17567	el.dequeue();
17568
17569};
17570
17571})(jQuery);
17572(function( $, undefined ) {
17573
17574$.effects.effect.slide = function( o, done ) {
17575
17576	// Create element
17577	var el = $( this ),
17578		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
17579		mode = $.effects.setMode( el, o.mode || "show" ),
17580		show = mode === "show",
17581		direction = o.direction || "left",
17582		ref = (direction === "up" || direction === "down") ? "top" : "left",
17583		positiveMotion = (direction === "up" || direction === "left"),
17584		distance,
17585		animation = {};
17586
17587	// Adjust
17588	$.effects.save( el, props );
17589	el.show();
17590	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
17591
17592	$.effects.createWrapper( el ).css({
17593		overflow: "hidden"
17594	});
17595
17596	if ( show ) {
17597		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
17598	}
17599
17600	// Animation
17601	animation[ ref ] = ( show ?
17602		( positiveMotion ? "+=" : "-=") :
17603		( positiveMotion ? "-=" : "+=")) +
17604		distance;
17605
17606	// Animate
17607	el.animate( animation, {
17608		queue: false,
17609		duration: o.duration,
17610		easing: o.easing,
17611		complete: function() {
17612			if ( mode === "hide" ) {
17613				el.hide();
17614			}
17615			$.effects.restore( el, props );
17616			$.effects.removeWrapper( el );
17617			done();
17618		}
17619	});
17620};
17621
17622})(jQuery);
17623(function( $, undefined ) {
17624
17625$.effects.effect.transfer = function( o, done ) {
17626	var elem = $( this ),
17627		target = $( o.to ),
17628		targetFixed = target.css( "position" ) === "fixed",
17629		body = $("body"),
17630		fixTop = targetFixed ? body.scrollTop() : 0,
17631		fixLeft = targetFixed ? body.scrollLeft() : 0,
17632		endPosition = target.offset(),
17633		animation = {
17634			top: endPosition.top - fixTop ,
17635			left: endPosition.left - fixLeft ,
17636			height: target.innerHeight(),
17637			width: target.innerWidth()
17638		},
17639		startPosition = elem.offset(),
17640		transfer = $( "<div class='ui-effects-transfer'></div>" )
17641			.appendTo( document.body )
17642			.addClass( o.className )
17643			.css({
17644				top: startPosition.top - fixTop ,
17645				left: startPosition.left - fixLeft ,
17646				height: elem.innerHeight(),
17647				width: elem.innerWidth(),
17648				position: targetFixed ? "fixed" : "absolute"
17649			})
17650			.animate( animation, o.duration, o.easing, function() {
17651				transfer.remove();
17652				done();
17653			});
17654};
17655
17656})(jQuery);
17657
17658/* End */
17659;
17660; /* Start:"a:4:{s:4:"full";s:45:"/js/google_analitics_submit.js?17212255671066";s:6:"source";s:30:"/js/google_analitics_submit.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
17661	/******************************************************
17662	GA СОБЫТИЯ
17663	*********************************************************/
17664$(document).ready(function() {
17665	//bottom form
17666	$( "#bottomform	form" ).submit(function() {
17667	    ga('send', 'pageview', 'bottomformsubmit.html');
17668	});
17669	
17670	//header callback
17671	//link click 
17672	$( ".link .popup" ).click(function() {
17673	    ga('send', 'pageview', 'opencallback');
17674	});
17675	//submit form лежит в исходниках формы
17676
17677	//ostalis voprosy
17678	//link click 
17679	$( ".ask a" ).click(function() {
17680	  _gaq.push(['_trackPageview', '/contentformopen.html']);
17681	});
17682	//submit form лежит в исходниках формы
17683	
17684	//karlov form
17685	$( "#karlovform	form" ).submit(function() {
17686	  _gaq.push(['_trackPageview', '/Czechiasubmit.html']);
17687	});
17688	
17689	//European universities
17690	//link click 
17691	$( ".information_goal" ).submit(function() {
17692	  ga('send', 'event', 'submit', 'look_univer');
17693	  look_univer_submit.reachGoal(ym);
17694	});
17695	
17696	$(".popup.consult2").click(function() {
17697	    ga('send', 'pageview', 'openconsult');
17698	});
17699
17700});
17701/* End */
17702;
17703; /* Start:"a:4:{s:4:"full";s:84:"/bitrix/templates/main_new/components/bitrix/menu/top_header/script.js?1721225566682";s:6:"source";s:70:"/bitrix/templates/main_new/components/bitrix/menu/top_header/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
17704var jshover = function()
17705{
17706	var menuDiv = document.getElementById("horizontal-multilevel-menu")
17707	if (!menuDiv)
17708		return;
17709
17710	var sfEls = menuDiv.getElementsByTagName("li");
17711	for (var i=0; i<sfEls.length; i++) 
17712	{
17713		sfEls[i].onmouseover=function()
17714		{
17715			this.className+=" jshover";
17716		}
17717		sfEls[i].onmouseout=function() 
17718		{
17719			this.className=this.className.replace(new RegExp(" jshover\\b"), "");
17720		}
17721	}
17722}
17723
17724if (window.attachEvent) 
17725	window.attachEvent("onload", jshover);
17726
17727$(document).ready(function(){
17728	$('.block').hover(function() {
17729		 $(this).closest('li').find('.parent').addClass("hover");
17730	}, function(){
17731		$(this).closest('li').find('.parent').removeClass("hover");
17732    });
17733});
17734/* End */
17735;
17736; /* Start:"a:4:{s:4:"full";s:77:"/bitrix/templates/main_new/components/bitrix/menu/top/script.js?1721225566682";s:6:"source";s:63:"/bitrix/templates/main_new/components/bitrix/menu/top/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
17737var jshover = function()
17738{
17739	var menuDiv = document.getElementById("horizontal-multilevel-menu")
17740	if (!menuDiv)
17741		return;
17742
17743	var sfEls = menuDiv.getElementsByTagName("li");
17744	for (var i=0; i<sfEls.length; i++) 
17745	{
17746		sfEls[i].onmouseover=function()
17747		{
17748			this.className+=" jshover";
17749		}
17750		sfEls[i].onmouseout=function() 
17751		{
17752			this.className=this.className.replace(new RegExp(" jshover\\b"), "");
17753		}
17754	}
17755}
17756
17757if (window.attachEvent) 
17758	window.attachEvent("onload", jshover);
17759
17760$(document).ready(function(){
17761	$('.block').hover(function() {
17762		 $(this).closest('li').find('.parent').addClass("hover");
17763	}, function(){
17764		$(this).closest('li').find('.parent').removeClass("hover");
17765    });
17766});
17767/* End */
17768;
17769; /* Start:"a:4:{s:4:"full";s:82:"/bitrix/templates/main_new/components/bitrix/menu/programs/script.js?1721225566682";s:6:"source";s:68:"/bitrix/templates/main_new/components/bitrix/menu/programs/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
17770var jshover = function()
17771{
17772	var menuDiv = document.getElementById("horizontal-multilevel-menu")
17773	if (!menuDiv)
17774		return;
17775
17776	var sfEls = menuDiv.getElementsByTagName("li");
17777	for (var i=0; i<sfEls.length; i++) 
17778	{
17779		sfEls[i].onmouseover=function()
17780		{
17781			this.className+=" jshover";
17782		}
17783		sfEls[i].onmouseout=function() 
17784		{
17785			this.className=this.className.replace(new RegExp(" jshover\\b"), "");
17786		}
17787	}
17788}
17789
17790if (window.attachEvent) 
17791	window.attachEvent("onload", jshover);
17792
17793$(document).ready(function(){
17794	$('.block').hover(function() {
17795		 $(this).closest('li').find('.parent').addClass("hover");
17796	}, function(){
17797		$(this).closest('li').find('.parent').removeClass("hover");
17798    });
17799});
17800/* End */
17801;
17802; /* Start:"a:4:{s:4:"full";s:84:"/bitrix/templates/main_new/components/bitrix/menu/mobile-top/script.js?1721225566682";s:6:"source";s:70:"/bitrix/templates/main_new/components/bitrix/menu/mobile-top/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
17803var jshover = function()
17804{
17805	var menuDiv = document.getElementById("horizontal-multilevel-menu")
17806	if (!menuDiv)
17807		return;
17808
17809	var sfEls = menuDiv.getElementsByTagName("li");
17810	for (var i=0; i<sfEls.length; i++) 
17811	{
17812		sfEls[i].onmouseover=function()
17813		{
17814			this.className+=" jshover";
17815		}
17816		sfEls[i].onmouseout=function() 
17817		{
17818			this.className=this.className.replace(new RegExp(" jshover\\b"), "");
17819		}
17820	}
17821}
17822
17823if (window.attachEvent) 
17824	window.attachEvent("onload", jshover);
17825
17826$(document).ready(function(){
17827	$('.block').hover(function() {
17828		 $(this).closest('li').find('.parent').addClass("hover");
17829	}, function(){
17830		$(this).closest('li').find('.parent').removeClass("hover");
17831    });
17832});
17833/* End */
17834;
17835; /* Start:"a:4:{s:4:"full";s:88:"/bitrix/templates/main_new/components/bitrix/menu/social_network/script.js?1721225566682";s:6:"source";s:74:"/bitrix/templates/main_new/components/bitrix/menu/social_network/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
17836var jshover = function()
17837{
17838	var menuDiv = document.getElementById("horizontal-multilevel-menu")
17839	if (!menuDiv)
17840		return;
17841
17842	var sfEls = menuDiv.getElementsByTagName("li");
17843	for (var i=0; i<sfEls.length; i++) 
17844	{
17845		sfEls[i].onmouseover=function()
17846		{
17847			this.className+=" jshover";
17848		}
17849		sfEls[i].onmouseout=function() 
17850		{
17851			this.className=this.className.replace(new RegExp(" jshover\\b"), "");
17852		}
17853	}
17854}
17855
17856if (window.attachEvent) 
17857	window.attachEvent("onload", jshover);
17858
17859$(document).ready(function(){
17860	$('.block').hover(function() {
17861		 $(this).closest('li').find('.parent').addClass("hover");
17862	}, function(){
17863		$(this).closest('li').find('.parent').removeClass("hover");
17864    });
17865});
17866/* End */
17867;;
17867 /* /js/script.js?172122556711515*/
17868; /* /js/jquery.fancybox.js?172122556748706*/
17869; /* /js/jquery.jcarousel.js?172122556736009*/
17870; /* /js/jquery-ui-1.10.3.custom.js?1721225567416213*/
17871; /* /js/google_analitics_submit.js?17212255671066*/
17872; /* /bitrix/templates/main_new/components/bitrix/menu/top_header/script.js?1721225566682*/
17873; /* /bitrix/templates/main_new/components/bitrix/menu/top/script.js?1721225566682*/
17874; /* /bitrix/templates/main_new/components/bitrix/menu/programs/script.js?1721225566682*/
17875; /* /bitrix/templates/main_new/components/bitrix/menu/mobile-top/script.js?1721225566682*/
17876; /* /bitrix/templates/main_new/components/bitrix/menu/social_network/script.js?1721225566682*/

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.