diff options
author | Unrud <unrud@openaliasbox.org> | 2017-06-04 17:16:11 +0200 |
---|---|---|
committer | Unrud <unrud@openaliasbox.org> | 2017-06-04 17:16:36 +0200 |
commit | 10eef51a0f086ad148928ba965c330599b4765cb (patch) | |
tree | d0283e55f1b4e66c49bf17461b5fee211b78768a /radicale_web/web/infcloud/lib | |
parent | Update license (diff) | |
download | radicaleinfcloud-10eef51a0f086ad148928ba965c330599b4765cb.tar.gz radicaleinfcloud-10eef51a0f086ad148928ba965c330599b4765cb.tar.bz2 radicaleinfcloud-10eef51a0f086ad148928ba965c330599b4765cb.zip |
Update package for new web plugin interface
Diffstat (limited to 'radicale_web/web/infcloud/lib')
-rw-r--r-- | radicale_web/web/infcloud/lib/fullcalendar.js | 7196 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/ie_base64.js | 176 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/jquery-2.1.4.min.js | 4 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/jquery-ui-1.11.4.custom.js | 8226 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/jquery.autosize.js | 258 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/jquery.browser.js | 43 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/jquery.placeholder-1.1.9.js | 195 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/jquery.quicksearch.js | 205 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/jquery.tagsinput.js | 436 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/rrule.js | 1910 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/sha256.js | 16 | ||||
-rw-r--r-- | radicale_web/web/infcloud/lib/spectrum.js | 2027 |
12 files changed, 0 insertions, 20692 deletions
diff --git a/radicale_web/web/infcloud/lib/fullcalendar.js b/radicale_web/web/infcloud/lib/fullcalendar.js deleted file mode 100644 index 8effe83..0000000 --- a/radicale_web/web/infcloud/lib/fullcalendar.js +++ /dev/null @@ -1,7196 +0,0 @@ -/** - * @preserve - * FullCalendar v1.5.4 - * http://arshaw.com/fullcalendar/ - * - * Use fullcalendar.css for basic styling. - * For event drag & drop, requires jQuery UI draggable. - * For event resizing, requires jQuery UI resizable. - * - * Copyright (c) 2011 Adam Shaw - * Dual licensed under the MIT and GPL licenses, located in - * MIT-LICENSE.txt and GPL-LICENSE.txt respectively. - * - * Date: Tue Sep 4 23:38:33 2012 -0700 - * - */ - -(function($, undefined) { - -var defaults = { - - // display - defaultView: 'month', - aspectRatio: 1.35, - header: { - left: 'title', - center: '', - right: 'today prev,next' - }, - weekends: true, - currentTimeIndicator: false, - - // editing - //editable: false, - //disableDragging: false, - //disableResizing: false, - - allDayDefault: true, - ignoreTimezone: true, - - // event ajax - lazyFetching: true, - startParam: 'start', - endParam: 'end', - - // time formats - titleFormat: { - month: 'MMMM yyyy', - multiWeek: "MMM d[ yyyy]{ '–'[ MMM] d yyyy}", - week: "MMM d[ yyyy]{ '–'[ MMM] d yyyy}", - day: 'dddd, MMM d, yyyy', - list: 'MMM d, yyyy', - table: "MMM d[ yyyy]{ '–'[ MMM] d yyyy}", - todo: "MMM d[ yyyy]{ '–'[ MMM] d yyyy}", - }, - columnFormat: { - month: 'ddd', - multiWeek: 'ddd', - week: 'ddd M/d', - day: 'dddd M/d', - list: 'dddd, MMM d, yyyy', - table: 'MMM d, yyyy', - todo: 'MMM d, yyyy', - }, - timeFormat: { // for event elements - '': 'h(:mm)t', // default - agenda: 'h:mm{ – h:mm}', //agenda views - list: 'hh:mm{ – hh:mm}', //list and table views - listFull: 'hh:mm M d yyyy{ – hh:mm M d yyyy}', //list and table views for events that span multiple days - listFullAllDay: 'M d yyyy{ – M d yyyy}', //list and table views for allday events that span multiple days - }, - - // locale - isRTL: false, - firstDay: 0, - weekendDays: [0, 6], - monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'], - monthNamesShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'], - dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'], - dayNamesShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'], - buttonText: { - prev: ' ❮ ', - next: ' ❯ ', - prevYear: ' << ', - nextYear: ' >> ', - today: 'today', - month: 'month', - multiWeek: 'mweek', - week: 'week', - day: 'day', - list: 'list', - table: 'table', - todo: 'todo', - prevMonth: 'Load previous month', - nextMonth: 'Load next month', - filtersHeader: 'Filters', - filtersFooter: '* completed at or after %date%', - filterAction: 'Needs action', - filterProgress: 'In progress', - filterCompleted: 'Completed', - filterCanceled: 'Canceled' - }, - - listTexts: { - until: 'until', - past: 'Past events', - today: 'Today', - tomorrow: 'Tomorrow', - thisWeek: 'This week', - nextWeek: 'Next week', - thisMonth: 'This month', - nextMonth: 'Next month', - future: 'Future events', - week: 'W' - }, - - // list/table options - listSections: 'smart', // false|'day'|'week'|'month'|'smart' - listRange: 30, // number of days to be displayed - listPage: 7, // number of days to jump when paging - tableCols: ['handle', 'date', 'time', 'title'], - todoCols: ['handle', 'check', 'priority', 'time', 'title', 'location', 'status', 'percent'], - todoColThresholds: [], - todoOptionalCols: [], - //defaultFilters: ['filterAction', 'filterProgress', 'filterCompleted', 'filterCanceled'], - defaultFilters: [], - - // jquery-ui theming - theme: false, - buttonIcons: { - prev: 'circle-triangle-w', - next: 'circle-triangle-e' - }, - - //selectable: false, - unselectAuto: true, - - dropAccept: '*', - - headerContainer: false, - bindingMode: 'single', - dayEventSizeStrict: false, - startOfBusiness: 0, - endOfBusiness: 0, - showWeekNumbers: true, - multiWeekSize: 3, - showDatepicker: false, - eventMode: true, - showUnstartedEvents: false, - simpleFilters: false, -}; - -// right-to-left defaults -var rtlDefaults = { - header: { - left: 'next,prev today', - center: '', - right: 'title' - }, - headerContainer: '', - buttonText: { - prev: ' ► ', - next: ' ◄ ', - prevYear: ' >> ', - nextYear: ' << ' - }, - buttonIcons: { - prev: 'circle-triangle-e', - next: 'circle-triangle-w' - } -}; - -var fc = $.fullCalendar = { version: "1.5.4" }; -var fcViews = fc.views = {}; - -$.fn.fullCalendar = function(options) { - // method calling - if (typeof options == 'string') { - var args = Array.prototype.slice.call(arguments, 1); - var res; - this.each(function() { - var calendar = $.data(this, 'fullCalendar'); - if (calendar && $.isFunction(calendar[options])) { - var r = calendar[options].apply(calendar, args); - if (res === undefined) { - res = r; - } - if (options == 'destroy') { - $.removeData(this, 'fullCalendar'); - } - } - }); - if (res !== undefined) { - return res; - } - return this; - } - - // would like to have this logic in EventManager, but needs to happen before options are recursively extended - var eventSources = options.eventSources || []; - delete options.eventSources; - if (options.events) { - eventSources.push(options.events); - delete options.events; - } - - options = $.extend(true, {}, - defaults, - (options.isRTL || options.isRTL===undefined && defaults.isRTL) ? rtlDefaults : {}, - options - ); - - this.each(function(i, _element) { - var element = $(_element); - var calendar = new Calendar(element, options, eventSources); - element.data('fullCalendar', calendar); // TODO: look into memory leak implications - calendar.render(); - }); - - return this; -}; - -// function for adding/overriding defaults -function setDefaults(d) { - $.extend(true, defaults, d); -} - -function Calendar(element, options, eventSources) { - var t = this; - - // exports - t.options = options; - t.render = render; - t.destroy = destroy; - t.refetchEvents = refetchEvents; - t.reportEvents = reportEvents; - t.reportEventChange = reportEventChange; - t.rerenderEvents = rerenderEvents; - t.changeView = changeView; - t.select = select; - t.unselect = unselect; - t.prev = prev; - t.next = next; - t.prevYear = prevYear; - t.nextYear = nextYear; - t.today = today; - t.findToday = findToday; - t.gotoDate = gotoDate; - t.incrementDate = incrementDate; - t.formatDate = function(format, date) { return formatDate(format, date, options) }; - t.formatDates = function(format, date1, date2) { return formatDates(format, date1, date2, options) }; - t.getDate = getDate; - t.getView = getView; - t.option = option; - t.trigger = trigger; - t.selectEvent = selectEvent; - t.allowSelectEvent = allowSelectEvent; - t.updateToday = updateToday; - t.updateGrid = updateGrid; - t.renderViews = renderViews; - t.setOptions = setOptions; - t.getOption = getOption; - t.viewInstances = {}; - - // imports - EventManager.call(t, options, eventSources); - var isFetchNeeded = t.isFetchNeeded; - var fetchEvents = t.fetchEvents; - - // locals - var _element = element[0]; - var header; - var headerElement; - var content; - var tm; // for making theme classes - var currentView; - var elementOuterWidth; - var suggestedViewHeight; - var absoluteViewElement; - var resizeUID = 0; - var ignoreWindowResize = 0; - var date = new Date(); - var events = []; - var _dragElement; - - /* Main Rendering - -----------------------------------------------------------------------------*/ - - setYMD(date, options.year, options.month, options.date); - - function render(inc) { - if (!content) { - initialRender(); - }else{ - calcSize(); - markSizesDirty(); - markEventsDirty(); - renderView(inc); - } - } - - function initialRender() { - tm = options.theme ? 'ui' : 'fc'; - element.addClass('fc'); - if (options.isRTL) { - element.addClass('fc-rtl'); - } - if (options.theme) { - element.addClass('ui-widget'); - } - content = $("<div class='fc-content' style='position:relative'/>") - .prependTo(element); - header = new Header(t, options); - headerElement = header.render(); - if (headerElement) { - options.headerContainer ? options.headerContainer.prepend(headerElement) : element.prepend(headerElement); - } - changeView(options.defaultView); - $(window).resize(windowResize); - // needed for IE in a 0x0 iframe, b/c when it is resized, never triggers a windowResize - if (!bodyVisible()) { - lateRender(); - } - } - - // called when we know the calendar couldn't be rendered when it was initialized, - // but we think it's ready now - function lateRender() { - setTimeout(function() { // IE7 needs this so dimensions are calculated correctly - if (!currentView.start && bodyVisible()) { // !currentView.start makes sure this never happens more than once - renderView(); - } - },0); - } - - function updateToday() - { - for(var view in t.viewInstances) - t.viewInstances[view].updateToday(); - } - - function updateGrid() - { - for(var view in t.viewInstances) - t.viewInstances[view].updateGrid(); - } - - function renderViews() - { - //Force rerender of all views - for(var view in t.viewInstances) - t.viewInstances[view].start=null; - renderView(); - } - - function setOptions(newOptions) - { - var rerender=false; - - $.each(newOptions, function(key,value){ - if($.isPlainObject(value)) - $.extend(options[key],value); - else - options[key]=value; - - if(key=='firstDay' || key=='timeFormat') - rerender=true; - else - { - for(var view in t.viewInstances) - t.viewInstances[view]['set'+key.charAt(0).toUpperCase()+key.slice(1)](); - } - }); - - if(rerender) - renderViews(); - } - - function getOption(option) - { - return options[option]; - } - - function destroy() { - $(window).unbind('resize', windowResize); - header.destroy(); - content.remove(); - element.removeClass('fc fc-rtl ui-widget'); - } - - function elementVisible() { - return _element.offsetWidth !== 0; - } - - function bodyVisible() { - return $('body')[0].offsetWidth !== 0; - } - - /* View Rendering - -----------------------------------------------------------------------------*/ - - // TODO: improve view switching (still weird transition in IE, and FF has whiteout problem) - - function changeView(newViewName) { - if (!currentView || newViewName != currentView.name) { - ignoreWindowResize++; // because setMinHeight might change the height before render (and subsequently setSize) is reached - - unselect(); - - var oldView = currentView; - var newViewElement; - - if (oldView) { - (oldView.beforeHide || noop)(); // called before changing min-height. if called after, scroll state is reset (in Opera) - //setMinHeight(content, content.height()); why is this necessary? - oldView.element.hide(); - if(oldView.addedView) { - oldView.addedView.element.hide(); - } - }else{ - setMinHeight(content, 1); // needs to be 1 (not 0) for IE7, or else view dimensions miscalculated - } - content.css('overflow', 'hidden'); - - currentView = t.viewInstances[newViewName]; - if (currentView) { - currentView.element.show(); - }else{ - currentView = t.viewInstances[newViewName] = new fcViews[newViewName]( - newViewElement = absoluteViewElement = - $("<div class='fc-view fc-view-" + newViewName + "' style='position:absolute'/>") - .appendTo(content), - t // the calendar object - ); - } - - if(newViewName == 'agendaDay') { - addedView = t.viewInstances['table']; - if (addedView) { - addedView.element.show(); - }else{ - addedView = t.viewInstances['table'] = new fcViews['table']( - addedNewViewElement = addedAbsoluteViewElement = - $("<div class='fc-view fc-view-" + 'table' + "' style='position:absolute'/>") - .appendTo(content), - t // the calendar object - ); - currentView.addedView = addedView; - } - } - - if (oldView) { - header.deactivateButton(oldView.name); - } - header.activateButton(newViewName); - - renderView(); // after height has been set, will make absoluteViewElement's position=relative, then set to null - - content.css('overflow', ''); - if (oldView) { - setMinHeight(content, 1); - } - - if (!newViewElement) { - (currentView.afterShow || noop)(); // called after setting min-height/overflow, so in final scroll state (for Opera) - } - - ignoreWindowResize--; - currentView.trigger('viewChanged', _element); - } - } - - function renderView(inc) { - if (elementVisible()) { - currentView.trigger('beforeViewDisplay', _element); - ignoreWindowResize++; // because renderEvents might temporarily change the height before setSize is reached - - unselect(); - - if (suggestedViewHeight === undefined) { - calcSize(); - } - - if(currentView.addedView && currentView.start && cloneDate(date, true).getTime() == currentView.start.getTime()) { - currentView.addedView.scrollToDate(date); - } - - var forceEventRender = false; - if (!currentView.start || inc || date < currentView.start || date >= currentView.end) { - // view must render an entire new date range (and refetch/render events) - currentView.render(date, inc || 0); // responsible for clearing events - setSize(true); - forceEventRender = true; - } - else if (currentView.sizeDirty) { - // view must resize (and rerender events) - currentView.clearEvents(); - setSize(); - forceEventRender = true; - } - else if (currentView.eventsDirty) { - currentView.clearEvents(); - forceEventRender = true; - } - - currentView.sizeDirty = false; - currentView.eventsDirty = false; - updateEvents(forceEventRender); - - elementOuterWidth = element.outerWidth(); - - header.updateTitle(currentView.title); - var today = new Date(); - if (today >= currentView.start && today < currentView.end) { - //header.disableButton('today'); - header.setTodayScroll(element); - findToday(); - }else{ - //header.enableButton('today'); - header.setTodayDefault(); - } - - ignoreWindowResize--; - currentView.trigger('viewDisplay', _element); - } - } - - /* Resizing - -----------------------------------------------------------------------------*/ - - function updateSize() { - markSizesDirty(); - if (elementVisible()) { - calcSize(); - setSize(); - if(currentView.name!='todo') - { - unselect(); - currentView.clearEvents(); - currentView.renderEvents(events); - } - currentView.sizeDirty = false; - } - } - - function markSizesDirty() { - $.each(t.viewInstances, function(i, inst) { - inst.sizeDirty = true; - }); - } - - function calcSize() { - if (options.contentHeight) { - suggestedViewHeight = options.contentHeight; - } - else if (options.height) { - suggestedViewHeight = options.height - (headerElement ? headerElement.height() : 0) - vsides(content); - } - else { - suggestedViewHeight = Math.round(content.width() / Math.max(options.aspectRatio, .5)); - } - } - - function setSize(dateChanged) { // todo: dateChanged? - ignoreWindowResize++; - currentView.setWidth(content.width(), dateChanged); - currentView.setHeight(suggestedViewHeight, dateChanged); - if (absoluteViewElement) { - absoluteViewElement.css('position', 'relative'); - absoluteViewElement = null; - } - /*if(currentView.addedView) { - currentView.addedView.setWidth(content.width(), dateChanged); - var tmpContentWidth = Math.floor(content.width() / 2); - currentView.element.width(tmpContentWidth); - currentView.addedView.element.css({'left' : tmpContentWidth, - 'width' : tmpContentWidth - 2}); - }*/ - ignoreWindowResize--; - } - - function windowResize() { - if (!ignoreWindowResize) { - if (currentView.start) { // view has already been rendered - var uid = ++resizeUID; - //setTimeout(function() { // add a delay - if (uid == resizeUID && !ignoreWindowResize && elementVisible()) { - if (elementOuterWidth != (elementOuterWidth = element.outerWidth())) { - ignoreWindowResize++; // in case the windowResize callback changes the height - updateSize(); - currentView.trigger('windowResize', _element); - ignoreWindowResize--; - } - } - //}, 200); - }else{ - // calendar must have been initialized in a 0x0 iframe that has just been resized - lateRender(); - } - } - } - - /* Event Fetching/Rendering - -----------------------------------------------------------------------------*/ - - // fetches events if necessary, rerenders events if necessary (or if forced) - function updateEvents(forceRender) { - if (!options.lazyFetching || isFetchNeeded(currentView.visStart, currentView.visEnd)) { - refetchEvents(); - } - else if (forceRender) { - rerenderEvents(); - } - } - - function refetchEvents() { - fetchEvents(currentView.visStart, currentView.visEnd); // will call reportEvents - } - - // called when event data arrives - function reportEvents(_events) { - events = _events; - rerenderEvents(); - } - - // called when a single event's data has been changed - function reportEventChange(eventID) { - rerenderEvents(eventID); - } - - // attempts to rerenderEvents - function rerenderEvents(modifiedEventID) { - markEventsDirty(); - if (elementVisible()) { - currentView.clearEvents(); - currentView.renderEvents(events, modifiedEventID); - currentView.eventsDirty = false; - } - } - - function markEventsDirty() { - $.each(t.viewInstances, function(i, inst) { - inst.eventsDirty = true; - }); - } - - /* Selection - -----------------------------------------------------------------------------*/ - - function select(start, end, allDay) { - currentView.select(start, end, allDay===undefined ? true : allDay); - } - - function unselect() { // safe to be called before renderView - if(currentView) - currentView.unselect(); - } - - /* Date - -----------------------------------------------------------------------------*/ - - function prev() { - renderView(-1); - trigger('prevClick'); - } - - function next() { - renderView(1); - trigger('nextClick'); - } - - function prevYear() { - addYears(date, -1); - renderView(); - } - - function nextYear() { - addYears(date, 1); - renderView(); - } - - function today() { - date = new Date(); - renderView(); - findToday(); - trigger('todayClick'); - } - - function findToday() { - if(currentView.addedView) { - if(currentView.addedView.getDaySegmentContainer().find('.fc-today').length>0) { - if(new Date().getDate()==1) { - currentView.addedView.getDaySegmentContainer().parent().scrollTop(0); - } - else { - offset = currentView.addedView.getDaySegmentContainer().find('.fc-today').position().top; - var top = currentView.addedView.getDaySegmentContainer().parent().scrollTop(); - currentView.addedView.getDaySegmentContainer().parent().scrollTop(top + offset); - } - } - } - else if(currentView.name == 'todo') { - if(currentView.getDaySegmentContainer().find('.fc-today').length>0) { - offset = currentView.getDaySegmentContainer().find('.fc-today').position().top; - var top = currentView.getDaySegmentContainer().parent().scrollTop(); - currentView.getDaySegmentContainer().parent().scrollTop(top + offset); - } - } - else { - var todayElem = currentView.element.find('.fc-today'); - if(todayElem.length>0) { - var offset = 0; - if(!todayElem.parent().hasClass('fc-week0')) { - offset = todayElem.position().top; - } - element.parent().scrollTop(offset); - } - } - } - - function gotoDate(year, month, dateOfMonth) { - if (year instanceof Date) - date = cloneDate(year); // provided 1 argument, a Date - else - setYMD(date, year, month, dateOfMonth); - renderView(); - } - - function incrementDate(years, months, days) { - if(years !== undefined) - addYears(date, years); - if(months !== undefined) - addMonths(date, months); - if(days !== undefined) - addDays(date, days); - renderView(); - } - - function getDate() { - return cloneDate(date); - } - - /* Misc - -----------------------------------------------------------------------------*/ - - function getView() { - return currentView; - } - - function option(name, value) { - if (value === undefined) { - return options[name]; - } - if (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') { - options[name] = value; - updateSize(); - } else if (name.indexOf('list') == 0 || name == 'tableCols') { - options[name] = value; - currentView.start = null; // force re-render - } - } - - function trigger(name, thisObj) { - if (options[name]) { - return options[name].apply( - thisObj || _element, - Array.prototype.slice.call(arguments, 2) - ); - } - } - - function selectEvent(eventElement, noClick) { - currentView.selectEvent(eventElement, noClick); - } - - function allowSelectEvent(value) { - currentView.allowSelectEvent(value); - } - - /* External Dragging - ------------------------------------------------------------------------*/ - - if (options.droppable) { - $(document) - .bind('dragstart', function(ev, ui) { - var _e = ev.target; - var e = $(_e); - if (!e.parents('.fc').length) { // not already inside a calendar - var accept = options.dropAccept; - if ($.isFunction(accept) ? accept.call(_e, e) : e.is(accept)) { - _dragElement = _e; - currentView.dragStart(_dragElement, ev, ui); - } - } - }) - .bind('dragstop', function(ev, ui) { - if (_dragElement) { - currentView.dragStop(_dragElement, ev, ui); - _dragElement = null; - } - }); - } -} - -function Header(calendar, options) { - var t = this; - - // exports - t.render = render; - t.destroy = destroy; - t.updateTitle = updateTitle; - t.activateButton = activateButton; - t.deactivateButton = deactivateButton; - t.disableButton = disableButton; - t.enableButton = enableButton; - t.setTodayDefault = setTodayDefault; - t.setTodayScroll = setTodayScroll; - - // locals - var element = $([]); - var tm; - - function render() { - tm = options.theme ? 'ui' : 'fc'; - var sections = options.header; - if (sections) { - element = $("<table class='fc-header' style='width:100%'/>") - .append( - $("<tr/>") - .append(renderSection('left')) - .append(renderSection('center')) - .append(renderSection('right')) - ); - return element; - } - } - - function destroy() { - element.remove(); - } - - function renderSection(position) { - var e = $("<td class='fc-header-" + position + "'/>"); - var buttonStr = options.header[position]; - if (buttonStr) { - $.each(buttonStr.split(' '), function(i) { - if (i > 0) { - e.append("<span class='fc-header-space'/>"); - } - var prevButton; - $.each(this.split(','), function(j, buttonName) { - if (buttonName == 'title') { - e.append("<span class='fc-header-title'><h2> </h2></span>"); - if (prevButton) { - prevButton.addClass(tm + '-corner-right'); - } - prevButton = null; - }else{ - var buttonClick; - if (calendar[buttonName]) { - buttonClick = calendar[buttonName]; // calendar method - } - else if (fcViews[buttonName]) { - buttonClick = function() { - button.removeClass(tm + '-state-hover'); // forget why - calendar.changeView(buttonName); - }; - } - if (buttonClick) { -// var icon = options.theme ? smartProperty(options.buttonIcons, buttonName) : null; // why are we using smartProperty here? - var icon = (buttonName=='prev' || buttonName=='next') ? buttonName : null; - var text = smartProperty(options.buttonText, buttonName); // why are we using smartProperty here? - var button = $( - "<span class='fc-button fc-button-" + buttonName + " " + tm + "-state-default'>" + - "<span class='fc-button-inner'>" + - "<span class='fc-button-content'>" + - (icon ? - "<img src='images/arrow_" + icon + ".svg'/>" : - text - ) + - "</span>" + - "<span class='fc-button-effect'><span></span></span>" + - "</span>" + - "</span>" - ); - if (button) { - button - .click(function() { - if (!button.hasClass(tm + '-state-disabled')) { - buttonClick(); - } - }) - .mousedown(function() { - button - .not('.' + tm + '-state-active') - .not('.' + tm + '-state-disabled') - .addClass(tm + '-state-down'); - }) - .mouseup(function() { - button.removeClass(tm + '-state-down'); - }) - .hover( - function() { - button - .not('.' + tm + '-state-active') - .not('.' + tm + '-state-disabled') - .addClass(tm + '-state-hover'); - }, - function() { - button - .removeClass(tm + '-state-hover') - .removeClass(tm + '-state-down'); - } - ) - .appendTo(e); - if (!prevButton) { - button.addClass(tm + '-corner-left'); - } - prevButton = button; - } - } - } - }); - if (prevButton) { - prevButton.addClass(tm + '-corner-right'); - } - }); - } - return e; - } - - function updateTitle(html) { - element.find('h2') - .html(html) - .attr('title', $("<div/>").html(html).text()); - } - - function activateButton(buttonName) { - element.find('span.fc-button-' + buttonName) - .addClass(tm + '-state-active'); - } - - function deactivateButton(buttonName) { - element.find('span.fc-button-' + buttonName) - .removeClass(tm + '-state-active'); - } - - function disableButton(buttonName) { - element.find('span.fc-button-' + buttonName) - .addClass(tm + '-state-disabled'); - } - - function enableButton(buttonName) { - element.find('span.fc-button-' + buttonName) - .removeClass(tm + '-state-disabled'); - } - - function setTodayDefault() { - var todayBt = element.find('span.fc-button-' + 'today'); - var todayBtClc = calendar['today']; - - todayBt.unbind('click'); - todayBt.click(function(){ - if(!todayBt.hasClass(tm + '-state-disabled')) { - todayBtClc(); - } - }); - } - - function setTodayScroll(body) { - var todayBt = element.find('span.fc-button-' + 'today'); - var todayBtClc = calendar['findToday']; - - todayBt.unbind('click'); - todayBt.click(function(){ - if(!todayBt.hasClass(tm + '-state-disabled')) - todayBtClc(); - }); - } - -} - -fc.sourceNormalizers = []; -fc.sourceFetchers = []; - -var ajaxDefaults = { - dataType: 'json', - cache: false -}; - -var eventGUID = 1; - -function EventManager(options, _sources) { - var t = this; - - // exports - t.isFetchNeeded = isFetchNeeded; - t.fetchEvents = fetchEvents; - t.addEventSource = addEventSource; - t.removeEventSource = removeEventSource; - t.removeEventSources = removeEventSources; - t.updateEvent = updateEvent; - t.renderEvent = renderEvent; - t.removeEvents = removeEvents; - t.clientEvents = clientEvents; - t.normalizeEvent = normalizeEvent; - - // imports - var trigger = t.trigger; - var getView = t.getView; - var reportEvents = t.reportEvents; - - // locals - var stickySource = { events: [] }; - var sources = [ stickySource ]; - var rangeStart, rangeEnd; - var currentFetchID = 0; - var pendingSourceCnt = 0; - var loadingLevel = 0; - var cache = []; - - for (var i=0; i<_sources.length; i++) { - _addEventSource(_sources[i]); - } - - /* Fetching - -----------------------------------------------------------------------------*/ - - function isFetchNeeded(start, end) { - return !rangeStart || start < rangeStart || end > rangeEnd; - } - - function fetchEvents(start, end) { - rangeStart = start; - rangeEnd = end; - cache = []; - var fetchID = ++currentFetchID; - var len = sources.length; - pendingSourceCnt = len; - for (var i=0; i<len; i++) { - fetchEventSource(sources[i], fetchID); - } - } - - function fetchEventSource(source, fetchID) { - _fetchEventSource(source, function(events) { - if (fetchID == currentFetchID) { - if (events) { - for (var i=0; i<events.length; i++) { - events[i].source = source; - normalizeEvent(events[i]); - } - cache = cache.concat(events); - } - pendingSourceCnt--; - if (!pendingSourceCnt) { - reportEvents(cache); - } - } - }); - } - - function _fetchEventSource(source, callback) { - var i; - var fetchers = fc.sourceFetchers; - var res; - for (i=0; i<fetchers.length; i++) { - res = fetchers[i](source, rangeStart, rangeEnd, callback); - if (res === true) { - // the fetcher is in charge. made its own async request - return; - } - else if (typeof res == 'object') { - // the fetcher returned a new source. process it - _fetchEventSource(res, callback); - return; - } - } - var events = source.events; - if (events) { - if ($.isFunction(events)) { - pushLoading(); - events(cloneDate(rangeStart), cloneDate(rangeEnd), function(events) { - callback(events); - popLoading(); - }); - } - else if ($.isArray(events)) { - callback(events); - } - else { - callback(); - } - }else{ - var url = source.url; - if (url) { - var success = source.success; - var error = source.error; - var complete = source.complete; - var data = $.extend({}, source.data || {}); - var startParam = firstDefined(source.startParam, options.startParam); - var endParam = firstDefined(source.endParam, options.endParam); - if (startParam) { - data[startParam] = Math.round(+rangeStart / 1000); - } - if (endParam) { - data[endParam] = Math.round(+rangeEnd / 1000); - } - pushLoading(); - $.ajax($.extend({}, ajaxDefaults, source, { - data: data, - success: function(events) { - events = events || []; - var res = applyAll(success, this, arguments); - if ($.isArray(res)) { - events = res; - } - callback(events); - }, - error: function() { - applyAll(error, this, arguments); - callback(); - }, - complete: function() { - applyAll(complete, this, arguments); - popLoading(); - } - })); - }else{ - callback(); - } - } - } - - /* Sources - -----------------------------------------------------------------------------*/ - - function addEventSource(source) { - source = _addEventSource(source); - if (source) { - pendingSourceCnt++; - fetchEventSource(source, currentFetchID); // will eventually call reportEvents - } - return source; - } - - function _addEventSource(source) { - if ($.isFunction(source) || $.isArray(source)) { - source = { events: source }; - } - else if (typeof source == 'string') { - source = { url: source }; - } - if (typeof source == 'object') { - normalizeSource(source); - sources.push(source); - return source; - } - } - - function removeEventSource(source) { - sources = $.grep(sources, function(src) { - return !isSourcesEqual(src, source); - }); - // remove all client events from that source - cache = $.grep(cache, function(e) { - return !isSourcesEqual(e.source, source); - }); - reportEvents(cache); - } - - function removeEventSources() { - while(source = sources.shift()) { - // remove all client events from that source - cache = $.grep(cache, function(e) { - return !isSourcesEqual(e.source, source); - }); - reportEvents(cache); - } - } - - /* Manipulation - -----------------------------------------------------------------------------*/ - - function updateEvent(event) { // update an existing event - var i, len = cache.length, e, - defaultEventEnd = getView().defaultEventEnd, // getView??? - startDelta = event.start - event._start, - endDelta = event.end ? - (event.end - (event._end || defaultEventEnd(event))) // event._end would be null if event.end - : 0; // was null and event was just resized - for (i=0; i<len; i++) { - e = cache[i]; - if (e._id == event._id && e != event) { - e.start = new Date(+e.start + startDelta); - if (event.end) { - if (e.end) { - e.end = new Date(+e.end + endDelta); - }else{ - e.end = new Date(+defaultEventEnd(e) + endDelta); - } - }else{ - e.end = null; - } - e.title = event.title; - e.url = event.url; - e.allDay = event.allDay; - e.className = event.className; - e.editable = event.editable; - e.color = event.color; - e.backgroudColor = event.backgroudColor; - e.borderColor = event.borderColor; - e.textColor = event.textColor; - normalizeEvent(e); - } - } - normalizeEvent(event); - reportEvents(cache); - } - - function renderEvent(event, stick) { - normalizeEvent(event); - if (!event.source) { - if (stick) { - stickySource.events.push(event); - event.source = stickySource; - } - } - // always push event to cache (issue #1112:) - cache.push(event); - reportEvents(cache); - } - - function removeEvents(filter) { - var oldCache = cache; - if (!filter) { // remove all - cache = []; - // clear all array sources - /*for (var i=0; i<sources.length; i++) { - if ($.isArray(sources[i].events)) { - sources[i].events = []; - } - }*/ - }else{ - if (!$.isFunction(filter)) { // an event ID - var id = filter + ''; - filter = function(e) { - return e._id == id; - }; - } - cache = $.grep(cache, filter, true); - // remove events from array sources - /*for (var i=0; i<sources.length; i++) { - if ($.isArray(sources[i].events)) { - sources[i].events = $.grep(sources[i].events, filter, true); - } - }*/ - } - if(oldCache.length != cache.length) - reportEvents(cache); - } - - function clientEvents(filter) { - if ($.isFunction(filter)) { - return $.grep(cache, filter); - } - else if (filter) { // an event ID - filter += ''; - return $.grep(cache, function(e) { - return e._id == filter; - }); - } - return cache; // else, return all - } - - /* Loading State - -----------------------------------------------------------------------------*/ - - function pushLoading() { - if (!loadingLevel++) { - trigger('loading', null, true); - } - } - - function popLoading() { - if (!--loadingLevel) { - trigger('loading', null, false); - } - } - - /* Event Normalization - -----------------------------------------------------------------------------*/ - - function normalizeEvent(event) { - var source = event.source || {}; - var ignoreTimezone = firstDefined(source.ignoreTimezone, options.ignoreTimezone); - event._id = event._id || (event.id === undefined ? '_fc' + eventGUID++ : event.id + ''); - if (event.date) { - if (!event.start) { - event.start = event.date; - } - delete event.date; - } - event._start = cloneDate(event.start = parseDate(event.start, ignoreTimezone)); - event.end = parseDate(event.end, ignoreTimezone); - if (event.end && ((options.eventMode && event.end <= event.start) || (!options.eventMode && event.end < event.start))) { - event.end = null; - } - event._end = event.end ? cloneDate(event.end) : null; - if (event.allDay === undefined) { - event.allDay = firstDefined(source.allDayDefault, options.allDayDefault); - } - if (event.className) { - if (typeof event.className == 'string') { - event.className = event.className.split(/\s+/); - } - }else{ - event.className = []; - } - // TODO: if there is no start date, return false to indicate an invalid event - } - - /* Utils - ------------------------------------------------------------------------------*/ - - function normalizeSource(source) { - if (source.className) { - // TODO: repeat code, same code for event classNames - if (typeof source.className == 'string') { - source.className = source.className.split(/\s+/); - } - }else{ - source.className = []; - } - var normalizers = fc.sourceNormalizers; - for (var i=0; i<normalizers.length; i++) { - normalizers[i](source); - } - } - - function isSourcesEqual(source1, source2) { - return source1 && source2 && getSourcePrimitive(source1) == getSourcePrimitive(source2); - } - - function getSourcePrimitive(source) { - return ((typeof source == 'object') ? (source.events || source.url) : '') || source; - } -} - -fc.addDays = addDays; -fc.cloneDate = cloneDate; -fc.parseDate = parseDate; -fc.parseISO8601 = parseISO8601; -fc.parseTime = parseTime; -fc.formatDate = formatDate; -fc.formatDates = formatDates; - -/* Date Math ------------------------------------------------------------------------------*/ - -var dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], - DAY_MS = 86400000, - HOUR_MS = 3600000, - MINUTE_MS = 60000; - -function addYears(d, n, keepTime) { - d.setFullYear(d.getFullYear() + n); - if (!keepTime) { - clearTime(d); - } - return d; -} - -function addMonths(d, n, keepTime) { // prevents day overflow/underflow - if (+d) { // prevent infinite looping on invalid dates - var m = d.getMonth() + n, - check = cloneDate(d); - check.setDate(1); - check.setMonth(m); - d.setMonth(m); - if (!keepTime) { - clearTime(d); - } - while (d.getMonth() != check.getMonth()) { - d.setDate(d.getDate() + (d < check ? 1 : -1)); - } - } - return d; -} - -function addDays(d, n, keepTime) { // deals with daylight savings - if (+d) { - var dd = d.getDate() + n, - check = cloneDate(d); - check.setHours(9); // set to middle of day - check.setDate(dd); - d.setDate(dd); - if (!keepTime) { - clearTime(d); - } - fixDate(d, check); - } - return d; -} - -function fixDate(d, check) { // force d to be on check's YMD, for daylight savings purposes - if (+d) { // prevent infinite looping on invalid dates - while (d.getDate() != check.getDate()) { - d.setTime(+d + (d < check ? 1 : -1) * HOUR_MS); - } - } -} - -function addMinutes(d, n) { - d.setMinutes(d.getMinutes() + n); - return d; -} - -function clearTime(d) { - d.setHours(0); - d.setMinutes(0); - d.setSeconds(0); - d.setMilliseconds(0); - return d; -} - -function cloneDate(d, dontKeepTime) { - if(d==null) { - return null; - } - else if (dontKeepTime) { - return clearTime(new Date(+d)); - } - return new Date(+d); -} - -function zeroDate() { // returns a Date with time 00:00:00 and dateOfMonth=1 - var i=0, d; - do { - d = new Date(1970, i++, 1); - } while (d.getHours()); // != 0 - return d; -} - -function skipWeekend(date, inc, excl) { - inc = inc || 1; - while (!date.getDay() || (excl && date.getDay()==1 || !excl && date.getDay()==6)) { - addDays(date, inc); - } - return date; -} - -function dayDiff(d1, d2) { // d1 - d2 - return Math.round((cloneDate(d1, true) - cloneDate(d2, true)) / DAY_MS); -} - -function minDiff(d1, d2) { // d1 - d2 - return Math.round((cloneDate(d1, false) - cloneDate(d2, false)) / MINUTE_MS); -} - -function setYMD(date, y, m, d) { - if (y !== undefined && y != date.getFullYear()) { - date.setDate(1); - date.setMonth(0); - date.setFullYear(y); - } - if (m !== undefined && m != date.getMonth()) { - date.setDate(1); - date.setMonth(m); - } - if (d !== undefined) { - date.setDate(d); - } -} - -/* Date Parsing ------------------------------------------------------------------------------*/ - -function parseDate(s, ignoreTimezone) { // ignoreTimezone defaults to true - if (typeof s == 'object') { // already a Date object - return s; - } - if (typeof s == 'number') { // a UNIX timestamp - return new Date(s * 1000); - } - if (typeof s == 'string') { - if (s.match(/^\d+(\.\d+)?$/)) { // a UNIX timestamp - return new Date(parseFloat(s) * 1000); - } - if (ignoreTimezone === undefined) { - ignoreTimezone = true; - } - return parseISO8601(s, ignoreTimezone) || (s ? new Date(s) : null); - } - // TODO: never return invalid dates (like from new Date(<string>)), return null instead - return null; -} - -function parseISO8601(s, ignoreTimezone) { // ignoreTimezone defaults to false - // derived from http://delete.me.uk/2005/03/iso8601.html - // TODO: for a know glitch/feature, read tests/issue_206_parseDate_dst.html - var m = s.match(/^([0-9]{4})(-([0-9]{2})(-([0-9]{2})([T ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2})(:?([0-9]{2}))?))?)?)?)?$/); - if (!m) { - return null; - } - var date = new Date(m[1], 0, 1); - if (ignoreTimezone || !m[13]) { - var check = new Date(m[1], 0, 1, 12, 0); - fixDate(date, check); - if (m[3]) { - date.setMonth(m[3] - 1); - check.setMonth(m[3] - 1); - } - if (m[5]) { - date.setDate(m[5]); - check.setDate(m[5]); - } - fixDate(date, check); - if (m[7]) { - date.setHours(m[7]); - } - if (m[8]) { - date.setMinutes(m[8]); - } - if (m[10]) { - date.setSeconds(m[10]); - } - if (m[12]) { - date.setMilliseconds(Number("0." + m[12]) * 1000); - } - fixDate(date, check); - }else{ - date.setUTCFullYear( - m[1], - m[3] ? m[3] - 1 : 0, - m[5] || 1 - ); - date.setUTCHours( - m[7] || 0, - m[8] || 0, - m[10] || 0, - m[12] ? Number("0." + m[12]) * 1000 : 0 - ); - if (m[14]) { - var offset = Number(m[16]) * 60 + (m[18] ? Number(m[18]) : 0); - offset *= m[15] == '-' ? 1 : -1; - date = new Date(+date + (offset * 60 * 1000)); - } - } - return date; -} - -function parseTime(s) { // returns minutes since start of day - if (typeof s == 'number') { // an hour - return s * 60; - } - if (typeof s == 'object') { // a Date object - return s.getHours() * 60 + s.getMinutes(); - } - var m = s.match(/(\d+)(?::(\d+))?\s*(\w+)?/); - if (m) { - var h = parseInt(m[1], 10); - if (m[3]) { - h %= 12; - if (m[3].toLowerCase().charAt(0) == 'p') { - h += 12; - } - } - return h * 60 + (m[2] ? parseInt(m[2], 10) : 0); - } -} - -/* Date Formatting ------------------------------------------------------------------------------*/ -// TODO: use same function formatDate(date, [date2], format, [options]) - -function formatDate(date, format, options) { - return formatDates(date, null, format, options); -} - -function formatDates(date1, date2, format, options) { - options = options || defaults; - var date = date1, - otherDate = date2, - i, len = format.length, c, - i2, formatter, - res = ''; - for (i=0; i<len; i++) { - c = format.charAt(i); - if (c == "'") { - for (i2=i+1; i2<len; i2++) { - if (format.charAt(i2) == "'") { - if (date) { - if (i2 == i+1) { - res += "'"; - }else{ - res += format.substring(i+1, i2); - } - i = i2; - } - break; - } - } - } - else if (c == '(') { - for (i2=i+1; i2<len; i2++) { - if (format.charAt(i2) == ')') { - var subres = formatDate(date, format.substring(i+1, i2), options); - if (parseInt(subres.replace(/\D/, ''), 10)) { - res += subres; - } - i = i2; - break; - } - } - } - else if (c == '[') { - for (i2=i+1; i2<len; i2++) { - if (format.charAt(i2) == ']') { - var subformat = format.substring(i+1, i2); - var subres = formatDate(date, subformat, options); - if (subres != formatDate(otherDate, subformat, options)) { - res += subres; - } - i = i2; - break; - } - } - } - else if (c == '{') { - date = date2; - otherDate = date1; - } - else if (c == '}') { - date = date1; - otherDate = date2; - } - else { - for (i2=len; i2>i; i2--) { - if (formatter = dateFormatters[format.substring(i, i2)]) { - if (date) { - res += formatter(date, options); - } - i = i2 - 1; - break; - } - } - if (i2 == i) { - if (date) { - res += c; - } - } - } - } - return res; -}; - -var dateFormatters = { - s : function(d) {return d.getSeconds() }, - ss : function(d) {return zeroPad(d.getSeconds())}, - m : function(d) {return d.getMinutes()}, - mm : function(d) {return zeroPad(d.getMinutes())}, - h : function(d) {return d.getHours() % 12 || 12}, - hh : function(d) {return zeroPad(d.getHours() % 12 || 12)}, - H : function(d) {return d.getHours()}, - HH : function(d) {return zeroPad(d.getHours())}, - d : function(d) {return d.getDate()}, - dd : function(d) {return zeroPad(d.getDate())}, - ddd : function(d,o) {return o.dayNamesShort[d.getDay()]}, - dddd: function(d,o) {return o.dayNames[d.getDay()]}, - W : function(d) {return getWeekNumber(d)}, - M : function(d) {return d.getMonth() + 1}, - MM : function(d) {return zeroPad(d.getMonth() + 1)}, - MMM : function(d,o) {return o.monthNamesShort[d.getMonth()]}, - MMMM: function(d,o) {return o.monthNames[d.getMonth()]}, - yy : function(d) {return (d.getFullYear()+'').substring(2)}, - yyyy: function(d) {return d.getFullYear()}, - t : function(d) {return d.getHours() < 12 ? 'a' : 'p'}, - tt : function(d) {return d.getHours() < 12 ? 'am' : 'pm'}, - T : function(d) {return d.getHours() < 12 ? 'A' : 'P'}, - TT : function(d) {return d.getHours() < 12 ? 'AM' : 'PM'}, - u : function(d) {return formatDate(d, "yyyy-MM-dd'T'HH:mm:ss'Z'")}, - S : function(d) { - var date = d.getDate(); - if (date > 10 && date < 20) { - return 'th'; - } - return ['st', 'nd', 'rd'][date%10-1] || 'th'; - } -}; - -fc.applyAll = applyAll; - -/* Event Date Math ------------------------------------------------------------------------------*/ - -function exclEndDay(event) { - if (event.end) { - return _exclEndDay(event.end, event.allDay); - }else{ - return addDays(cloneDate(event.start), 1); - } -} - -function _exclEndDay(end, allDay) { - end = cloneDate(end); - return allDay || end.getHours() || end.getMinutes() ? addDays(end, 1) : clearTime(end); -} - -function segCmp(a, b) { - return (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start); -} - -function segsCollide(seg1, seg2) { - return seg1.end > seg2.start && seg1.start < seg2.end; -} - -/* Event Sorting ------------------------------------------------------------------------------*/ - -// event rendering utilities -function sliceSegs(events, visEventEnds, start, end) { - var segs = [], - i, len=events.length, event, - eventStart, eventEnd, - segStart, segEnd, - isStart, isEnd; - for (i=0; i<len; i++) { - event = events[i]; - eventStart = event.start; - eventEnd = visEventEnds[i]; - if (eventEnd > start && eventStart < end) { - if (eventStart < start) { - segStart = cloneDate(start); - isStart = false; - }else{ - segStart = eventStart; - isStart = true; - } - if (eventEnd > end) { - segEnd = cloneDate(end); - isEnd = false; - }else{ - segEnd = eventEnd; - isEnd = true; - } - segs.push({ - event: event, - start: segStart, - end: segEnd, - isStart: isStart, - isEnd: isEnd, - msLength: segEnd - segStart - }); - } - } - return segs.sort(segCmp); -} - -// event rendering calculation utilities -function stackSegs(segs) { - var levels = [], - i, len = segs.length, seg, - j, collide, k; - for (i=0; i<len; i++) { - seg = segs[i]; - j = 0; // the level index where seg should belong - while (true) { - collide = false; - if (levels[j]) { - for (k=0; k<levels[j].length; k++) { - if (segsCollide(levels[j][k], seg)) { - collide = true; - break; - } - } - } - if (collide) { - j++; - }else{ - break; - } - } - if (levels[j]) { - levels[j].push(seg); - }else{ - levels[j] = [seg]; - } - } - return levels; -} - -/* Event Element Binding ------------------------------------------------------------------------------*/ - -function lazySegBind(container, segs, bindHandlers) { - container.unbind('mouseover').mouseover(function(ev) { - var parent=ev.target, e, - i, seg; - while (parent != this) { - e = parent; - parent = parent.parentNode; - } - if ((i = e._fci) !== undefined) { - e._fci = undefined; - seg = segs[i]; - bindHandlers(seg.event, seg.element, seg); - $(ev.target).trigger(ev); - } - ev.stopPropagation(); - }); -} - -/* Element Dimensions ------------------------------------------------------------------------------*/ - -function setOuterWidth(element, width, includeMargins) { - for (var i=0, e; i<element.length; i++) { - e = $(element[i]); - e.width(Math.max(0, width - hsides(e, includeMargins))); - } -} - -function setOuterHeight(element, height, includeMargins) { - for (var i=0, e; i<element.length; i++) { - e = $(element[i]); - e.height(Math.max(0, height - vsides(e, includeMargins))); - } -} - -function hsides(element, includeMargins) { - return hpadding(element) + hborders(element) + (includeMargins ? hmargins(element) : 0); -} - -function hpadding(element) { - return (parseFloat($.css(element[0], 'paddingLeft', true)) || 0) + - (parseFloat($.css(element[0], 'paddingRight', true)) || 0); -} - -function hmargins(element) { - return (parseFloat($.css(element[0], 'marginLeft', true)) || 0) + - (parseFloat($.css(element[0], 'marginRight', true)) || 0); -} - -function hborders(element) { - return (parseFloat($.css(element[0], 'borderLeftWidth', true)) || 0) + - (parseFloat($.css(element[0], 'borderRightWidth', true)) || 0); -} - -function vsides(element, includeMargins) { - return vpadding(element) + vborders(element) + (includeMargins ? vmargins(element) : 0); -} - -function vpadding(element) { - return (parseFloat($.css(element[0], 'paddingTop', true)) || 0) + - (parseFloat($.css(element[0], 'paddingBottom', true)) || 0); -} - -function vmargins(element) { - return (parseFloat($.css(element[0], 'marginTop', true)) || 0) + - (parseFloat($.css(element[0], 'marginBottom', true)) || 0); -} - -function vborders(element) { - return (parseFloat($.css(element[0], 'borderTopWidth', true)) || 0) + - (parseFloat($.css(element[0], 'borderBottomWidth', true)) || 0); -} - -function setMinHeight(element, height) { - height = (typeof height == 'number' ? height + 'px' : height); - element.each(function(i, _element) { - _element.style.cssText += ';min-height:' + height + ';_height:' + height; - // why can't we just use .css() ? i forget - }); -} - -/* Misc Utils ------------------------------------------------------------------------------*/ - -//TODO: arraySlice -//TODO: isFunction, grep ? - -function noop() { } - -function cmp(a, b) { - return a - b; -} - -function arrayMax(a) { - return Math.max.apply(Math, a); -} - -function zeroPad(n) { - return (n < 10 ? '0' : '') + n; -} - -function smartProperty(obj, name) { // get a camel-cased/namespaced property of an object - if (obj[name] !== undefined) { - return obj[name]; - } - var parts = name.split(/(?=[A-Z])/), - i=parts.length-1, res; - for (; i>=0; i--) { - res = obj[parts[i].toLowerCase()]; - if (res !== undefined) { - return res; - } - } - return obj['']; -} - -function htmlEscape(s) { - return s.replace(/&/g, '&') - .replace(/</g, '<') - .replace(/>/g, '>') - .replace(/'/g, ''') - .replace(/"/g, '"') - .replace(/\n/g, '<br />'); -} - -function cssKey(_element) { - return _element.id + '/' + _element.className + '/' + _element.style.cssText.replace(/(^|;)\s*(top|left|width|height)\s*:[^;]*/ig, ''); -} - -function disableTextSelection(element) { - element - .attr('unselectable', 'on') - .css('MozUserSelect', 'none') - .bind('selectstart.ui', function() { return false; }); -} - -/* -function enableTextSelection(element) { - element - .attr('unselectable', 'off') - .css('MozUserSelect', '') - .unbind('selectstart.ui'); -} -*/ - -function markFirstLast(e) { - e.children() - .removeClass('fc-first fc-last') - .filter(':first-child') - .addClass('fc-first') - .end() - .filter(':last-child') - .addClass('fc-last'); -} - -function setDayID(cell, date, opt) { - cell.each(function(i, _cell) { - _cell.className = _cell.className.replace(/^fc-\w*( fc-weekend-day)?/, 'fc-' + dayIDs[date.getDay()] + (opt('weekendDays').length>0 && opt('weekendDays').indexOf(date.getDay())!=-1 ? ' fc-weekend-day' : '')); - // TODO: make a way that doesn't rely on order of classes - }); -} - -function getSkinCss(event, opt) { - var source = event.source || {}; - var eventColor = event.color; - var sourceColor = source.color; - var optionColor = opt('eventColor'); - var backgroundColor = - event.backgroundColor || - eventColor || - source.backgroundColor || - sourceColor || - opt('eventBackgroundColor') || - optionColor; - var borderColor = - event.borderColor || - eventColor || - source.borderColor || - sourceColor || - opt('eventBorderColor') || - optionColor; - var textColor = - event.textColor || - source.textColor || - opt('eventTextColor'); - var statements = []; - if (backgroundColor) { - statements.push('background-color:' + backgroundColor); - } - if (borderColor) { - statements.push('border-color:' + borderColor); - } - if (textColor) { - statements.push('color:' + textColor); - } - return statements.join(';'); -} - -function applyAll(functions, thisObj, args) { - if ($.isFunction(functions)) { - functions = [ functions ]; - } - if (functions) { - var i; - var ret; - for (i=0; i<functions.length; i++) { - ret = functions[i].apply(thisObj, args) || ret; - } - return ret; - } -} - -function firstDefined() { - for (var i=0; i<arguments.length; i++) { - if (arguments[i] !== undefined) { - return arguments[i]; - } - } -} - -fcViews.month = MonthView; - -function MonthView(element, calendar) { - var t = this; - - // exports - t.render = render; - - // imports - BasicView.call(t, element, calendar, 'month'); - var opt = t.opt; - var renderBasic = t.renderBasic; - var formatDate = calendar.formatDate; - - function render(date, delta) { - if (delta) { - addMonths(date, delta); - date.setDate(1); - } - var start = cloneDate(date, true); - start.setDate(1); - var end = addMonths(cloneDate(start), 1); - var visStart = cloneDate(start); - var visEnd = cloneDate(end); - var firstDay = opt('firstDay'); - var nwe = opt('weekends') ? 0 : 1; - if (nwe) { - skipWeekend(visStart); - skipWeekend(visEnd, -1, true); - } - addDays(visStart, -((visStart.getDay() - Math.max(firstDay, nwe) + 7) % 7)); - addDays(visEnd, (7 - visEnd.getDay() + Math.max(firstDay, nwe)) % 7); - var rowCnt = Math.round((visEnd - visStart) / (DAY_MS * 7)); - if (opt('weekMode') == 'fixed') { - addDays(visEnd, (6 - rowCnt) * 7); - rowCnt = 6; - } - t.title = formatDate(start, opt('titleFormat')); - t.start = start; - t.end = end; - t.visStart = visStart; - t.visEnd = visEnd; - renderBasic(6, rowCnt, nwe ? 5 : 7, true); - } -} - -fcViews.multiWeek = MultiWeekView; - -function MultiWeekView(element, calendar) { - var t = this; - - // exports - t.render = render; - - // imports - BasicView.call(t, element, calendar, 'multiWeek'); - var opt = t.opt; - var renderBasic = t.renderBasic; - var formatDates = calendar.formatDates; - - function render(date, delta) { - if (delta) { - addDays(date, delta * opt('multiWeekSize') * 7); - } - //Adjust displayed date-range, to make sure today will always stay in the top row - var currentDate = cloneDate(new Date(), true); - var dateWeekStart = addDays(cloneDate(date), -((date.getDay() - opt('firstDay') + 7) % 7)); - var currentWeekStart = addDays(cloneDate(currentDate), -((currentDate.getDay() - opt('firstDay') + 7) % 7)); - if(opt('multiWeekSize')>0) - addDays(date, -(( - (Math.abs(Math.ceil(dayDiff(dateWeekStart, currentWeekStart) / 7)) % opt('multiWeekSize'))) % opt('multiWeekSize')) * 7); - - //var start = addDays(cloneDate(date), -((date.getDay() - opt('firstDay') + 7) % 7)); - var start = cloneDate(date); - //var end = addDays(cloneDate(start), opt('multiWeekSize') * 7); - //var visStart = cloneDate(start); - var visStart = addDays(cloneDate(date), -((date.getDay() - opt('firstDay') + 7) % 7)); - var end = addDays(cloneDate(visStart), opt('multiWeekSize') * 7); - var visEnd = cloneDate(end); - - var firstDay = opt('firstDay'); - var nwe = opt('weekends') ? 0 : 1; - if (nwe) { - skipWeekend(visStart); - skipWeekend(visEnd, -1, true); - } - - addDays(visStart, -((visStart.getDay() - Math.max(firstDay, nwe) + 7) % 7)); - addDays(visEnd, (7 - visEnd.getDay() + Math.max(firstDay, nwe)) % 7); - - t.title = formatDates( - visStart, - addDays(cloneDate(visEnd), -1), - opt('titleFormat') - ); - t.start = start; - t.end = end; - t.visStart = visStart; - t.visEnd = visEnd; - renderBasic(opt('multiWeekSize'), opt('multiWeekSize'), nwe ? 5 : 7, true); - } -} - -fcViews.basicWeek = BasicWeekView; - -function BasicWeekView(element, calendar) { - var t = this; - - // exports - t.render = render; - - // imports - BasicView.call(t, element, calendar, 'basicWeek'); - var opt = t.opt; - var renderBasic = t.renderBasic; - var formatDates = calendar.formatDates; - - function render(date, delta) { - if (delta) { - addDays(date, delta * 7); - } - var start = addDays(cloneDate(date), -((date.getDay() - opt('firstDay') + 7) % 7)); - var end = addDays(cloneDate(start), 7); - var visStart = cloneDate(start); - var visEnd = cloneDate(end); - var weekends = opt('weekends'); - if (!weekends) { - skipWeekend(visStart); - skipWeekend(visEnd, -1, true); - } - t.title = formatDates( - visStart, - addDays(cloneDate(visEnd), -1), - opt('titleFormat') - ); - t.start = start; - t.end = end; - t.visStart = visStart; - t.visEnd = visEnd; - renderBasic(1, 1, weekends ? 7 : 5, false); - } -} - -fcViews.basicDay = BasicDayView; - -//TODO: when calendar's date starts out on a weekend, shouldn't happen - -function BasicDayView(element, calendar) { - var t = this; - - // exports - t.render = render; - - // imports - BasicView.call(t, element, calendar, 'basicDay'); - var opt = t.opt; - var renderBasic = t.renderBasic; - var formatDate = calendar.formatDate; - - function render(date, delta) { - if (delta) { - addDays(date, delta); - if (!opt('weekends')) { - skipWeekend(date, delta < 0 ? -1 : 1); - } - } - t.title = formatDate(date, opt('titleFormat')); - t.start = t.visStart = cloneDate(date, true); - t.end = t.visEnd = addDays(cloneDate(t.start), 1); - renderBasic(1, 1, 1, false); - } -} - -setDefaults({ - weekMode: 'fixed' -}); - -function BasicView(element, calendar, viewName) { - var t = this; - - // exports - t.renderBasic = renderBasic; - t.setHeight = setHeight; - t.setWidth = setWidth; - t.renderDayOverlay = renderDayOverlay; - t.defaultSelectionEnd = defaultSelectionEnd; - t.renderSelection = renderSelection; - t.clearSelection = clearSelection; - t.reportDayClick = reportDayClick; // for selection (kinda hacky) - t.dragStart = dragStart; - t.dragStop = dragStop; - t.defaultEventEnd = defaultEventEnd; - t.getHoverListener = function() { return hoverListener }; - t.colContentLeft = colContentLeft; - t.colContentRight = colContentRight; - t.dayOfWeekCol = dayOfWeekCol; - t.dateCell = dateCell; - t.cellDate = cellDate; - t.cellIsAllDay = function() { return true }; - t.allDayRow = allDayRow; - t.allDayBounds = allDayBounds; - t.getRowCnt = function() { return rowCnt }; - t.getColCnt = function() { return colCnt }; - t.getColWidth = function() { return colWidth }; - t.getDaySegmentContainer = function() { return daySegmentContainer }; - t.updateGrid = updateGrid; - t.updateToday = updateToday; - t.setAxisFormat = setAxisFormat; - t.setStartOfBusiness = setStartOfBusiness; - t.setEndOfBusiness = setEndOfBusiness; - t.setWeekendDays = setWeekendDays; - t.setBindingMode = setBindingMode; - t.setSelectable = setSelectable; - - // imports - View.call(t, element, calendar, viewName); - OverlayManager.call(t); - SelectionManager.call(t); - BasicEventRenderer.call(t); - var opt = t.opt; - var trigger = t.trigger; - var clearEvents = t.clearEvents; - var renderOverlay = t.renderOverlay; - var clearOverlays = t.clearOverlays; - var daySelectionMousedown = t.daySelectionMousedown; - var formatDate = calendar.formatDate; - - // locals - var head; - var headCells; - var body; - var bodyRows; - var bodyCells; - var bodyFirstCells; - var bodyCellTopInners; - var daySegmentContainer; - - var viewWidth; - var viewHeight; - var colWidth; - - var rowCnt, colCnt; - var coordinateGrid; - var hoverListener; - var colContentPositions; - - var rtl, dis, dit; - var firstDay; - var nwe; - var tm; - var colFormat; - - /* Rendering - ------------------------------------------------------------*/ - - disableTextSelection(element.addClass('fc-grid')); - - function renderBasic(maxr, r, c, showNumbers) { - rowCnt = r; - colCnt = c; - updateOptions(); - var firstTime = !body; - if (firstTime) { - buildSkeleton(maxr, showNumbers); - }else{ - clearEvents(); - } - updateCells(true); - } - - function updateOptions() { - rtl = opt('isRTL'); - if (rtl) { - dis = -1; - dit = colCnt - 1; - }else{ - dis = 1; - dit = 0; - } - firstDay = opt('firstDay'); - nwe = opt('weekends') ? 0 : 1; - tm = opt('theme') ? 'ui' : 'fc'; - colFormat = opt('columnFormat'); - } - - function buildSkeleton(maxRowCnt, showNumbers) { - var s; - var headerClass = tm + "-widget-header"; - var contentClass = tm + "-widget-content"; - var i, j; - var table; - - s = - "<table class='fc-border-separate' style='width:100%' cellspacing='0'>" + - "<thead>" + - "<tr>"; - for (i=0; i<colCnt; i++) { - s += - "<th class='fc- " + headerClass + "'/>"; // need fc- for setDayID - } - s += - "</tr>" + - "</thead>" + - "<tbody>"; - for (i=0; i<maxRowCnt; i++) { - s += - "<tr class='fc-week" + i + "'>"; - for (j=0; j<colCnt; j++) { - s += - "<td class='fc- " + contentClass + " fc-day" + (i*colCnt+j) + "'>" + // need fc- for setDayID - "<div>" + - (showNumbers ? - "<div class='fc-day-header'><div class='fc-week-number'/><div class='fc-day-text'/><div class='fc-day-number'/></div>" : - '' - ) + - "<div class='fc-day-content'>" + - "<div style='position:relative'> </div>" + - "</div>" + - "</div>" + - "</td>"; - } - s += - "</tr>"; - } - s += - "</tbody>" + - "</table>"; - table = $(s).appendTo(element); - - head = table.find('thead'); - headCells = head.find('th'); - body = table.find('tbody'); - bodyRows = body.find('tr'); - bodyCells = body.find('td'); - bodyFirstCells = bodyCells.filter(':first-child'); - bodyCellTopInners = bodyRows.eq(0).find('div.fc-day-content div'); - - markFirstLast(head.add(head.find('tr'))); // marks first+last tr/th's - markFirstLast(bodyRows); // marks first+last td's - bodyRows.eq(0).addClass('fc-first'); // fc-last is done in updateCells - - dayBind(bodyCells); - daySegmentContainer = - $("<div style='position:absolute;z-index:8;top:0;left:0'/>") - .appendTo(element); - } - - function updateCells(firstTime) { - var dowDirty = firstTime || rowCnt == 1; // could the cells' day-of-weeks need updating? - var month = t.start.getMonth(); - var today = clearTime(new Date()); - var cell; - var date; - var row; - - if (dowDirty) { - headCells.each(function(i, _cell) { - cell = $(_cell); - date = indexDate(i); - cell.html(formatDate(date, colFormat)); - setDayID(cell, date, opt); - }); - } - - bodyCells.each(function(i, _cell) { - cell = $(_cell); - date = indexDate(i); - if (date.getMonth() == month) { - cell.removeClass('fc-other-month'); - }else{ - cell.addClass('fc-other-month'); - } - if(opt('showWeekNumbers') && (i % 7 == 0)) { - removeWeekNumber(cell, date); - addWeekNumber(cell, date); - } - if (+date == +today) { - cell.addClass(tm + '-state-highlight fc-today'); - removeTodayText(cell, opt('buttonText', 'today')); - addTodayText(cell, opt('buttonText', 'today')); - }else{ - cell.removeClass(tm + '-state-highlight fc-today'); - removeTodayText(cell, opt('buttonText', 'today')); - } - cell.find('div.fc-day-number').text(date.getDate()); - if (dowDirty) { - setDayID(cell, date, opt); - } - }); - - bodyRows.each(function(i, _row) { - row = $(_row); - if (i < rowCnt) { - row.show(); - if (i == rowCnt-1) { - row.addClass('fc-last'); - }else{ - row.removeClass('fc-last'); - } - }else{ - row.hide(); - } - }); - } - - function updateGrid() - { - updateToday(); - setAxisFormat(); - setStartOfBusiness(); - setEndOfBusiness(); - setWeekendDays(); - setBindingMode(); - setSelectable(); - } - - function updateToday() - { - var today = clearTime(new Date()); - var cell; - var date; - - bodyCells.each(function(i, _cell) { - cell = $(_cell); - date = indexDate(i); - - if (+date == +today) { - cell.addClass(tm + '-state-highlight fc-today'); - removeTodayText(cell, opt('buttonText', 'today')); - addTodayText(cell, opt('buttonText', 'today')); - }else{ - cell.removeClass(tm + '-state-highlight fc-today'); - removeTodayText(cell, opt('buttonText', 'today')); - } - }); - } - - function setAxisFormat() - { - // dummy - } - - function setStartOfBusiness() - { - // dummy - } - - function setEndOfBusiness() - { - // dummy - } - - function setWeekendDays() - { - headCells.each(function(i, _cell) { - setDayID($(_cell), indexDate(i), opt); - }); - - bodyCells.each(function(i, _cell) { - setDayID($(_cell), indexDate(i), opt); - }); - } - - function setBindingMode() - { - dayBind(bodyCells); - } - - function setSelectable() - { - dayBind(bodyCells); - } - - function setHeight(height) { - viewHeight = height; - var bodyHeight = viewHeight - head.height(); - var rowHeight; - var rowHeightLast; - var cell; - - if (opt('weekMode') == 'variable') { - rowHeight = rowHeightLast = Math.floor(bodyHeight / (rowCnt==1 ? 2 : 6)); - }else{ - rowHeight = Math.floor(bodyHeight / rowCnt); - rowHeightLast = bodyHeight - rowHeight * (rowCnt-1); - } - - bodyFirstCells.each(function(i, _cell) { - if (i < rowCnt) { - cell = $(_cell); - setMinHeight( - cell.find('> div'), - (i==rowCnt-1 ? rowHeightLast : rowHeight) - vsides(cell) - ); - } - }); - } - - function setWidth(width) { - viewWidth = width; - colContentPositions.clear(); - colWidth = Math.floor(viewWidth / colCnt); - setOuterWidth(headCells.slice(0, -1), colWidth); - } - - /* Day clicking and binding - -----------------------------------------------------------*/ - - function dayBind(days) { - days.unbind('click dblclick'); - if(opt('bindingMode') == 'double') - days.dblclick(dayClick).mousedown(daySelectionMousedown); - else - days.click(dayClick).mousedown(daySelectionMousedown); - } - - function dayClick(ev) { - //if (!opt('selectable')) { // if selectable, SelectionManager will worry about dayClick - var index = parseInt(this.className.match(/fc\-day(\d+)/)[1]); // TODO: maybe use .data - var date = indexDate(index); - trigger('dayClick', this, date, true, ev); - //} - } - - /* Semi-transparent Overlay Helpers - ------------------------------------------------------*/ - - function renderDayOverlay(overlayStart, overlayEnd, refreshCoordinateGrid) { // overlayEnd is exclusive - if (refreshCoordinateGrid) { - coordinateGrid.build(); - } - var rowStart = cloneDate(t.visStart); - var rowEnd = addDays(cloneDate(rowStart), colCnt); - for (var i=0; i<rowCnt; i++) { - var stretchStart = new Date(Math.max(rowStart, overlayStart)); - var stretchEnd = new Date(Math.min(rowEnd, overlayEnd)); - if (stretchStart < stretchEnd) { - var colStart, colEnd; - if (rtl) { - colStart = dayDiff(stretchEnd, rowStart)*dis+dit+1; - colEnd = dayDiff(stretchStart, rowStart)*dis+dit+1; - }else{ - colStart = dayDiff(stretchStart, rowStart); - colEnd = dayDiff(stretchEnd, rowStart); - } - dayBind( - renderCellOverlay(i, colStart, i, colEnd-1) - ); - } - addDays(rowStart, 7); - addDays(rowEnd, 7); - } - } - - function renderCellOverlay(row0, col0, row1, col1) { // row1,col1 is inclusive - var rect = coordinateGrid.rect(row0, col0, row1, col1, element); - return renderOverlay(rect, element); - } - - /* Selection - -----------------------------------------------------------------------*/ - - function defaultSelectionEnd(startDate, allDay) { - return cloneDate(startDate); - } - - function renderSelection(startDate, endDate, allDay) { - renderDayOverlay(startDate, addDays(cloneDate(endDate), 1), true); // rebuild every time??? - } - - function clearSelection() { - clearOverlays(); - } - - function reportDayClick(date, allDay, ev) { - var cell = dateCell(date); - var _element = bodyCells[cell.row*colCnt + cell.col]; - trigger('dayClick', _element, date, allDay, ev); - } - - /* External Dragging - -----------------------------------------------------------------------*/ - - function dragStart(_dragElement, ev, ui) { - hoverListener.start(function(cell) { - clearOverlays(); - if (cell) { - renderCellOverlay(cell.row, cell.col, cell.row, cell.col); - } - }, ev); - } - - function dragStop(_dragElement, ev, ui) { - var cell = hoverListener.stop(); - clearOverlays(); - if (cell) { - var d = cellDate(cell); - trigger('drop', _dragElement, d, true, ev, ui); - } - } - - /* Utilities - --------------------------------------------------------*/ - - function defaultEventEnd(event) { - return cloneDate(event.start); - } - - coordinateGrid = new CoordinateGrid(function(rows, cols) { - var e, n, p; - headCells.each(function(i, _e) { - e = $(_e); - n = e.offset().left; - if (i) { - p[1] = n; - } - p = [n]; - cols[i] = p; - }); - p[1] = n + e.outerWidth(); - bodyRows.each(function(i, _e) { - if (i < rowCnt) { - e = $(_e); - n = e.offset().top; - if (i) { - p[1] = n; - } - p = [n]; - rows[i] = p; - } - }); - p[1] = n + e.outerHeight(); - }); - - hoverListener = new HoverListener(coordinateGrid); - - colContentPositions = new HorizontalPositionCache(function(col) { - return bodyCellTopInners.eq(col); - }); - - function colContentLeft(col) { - return colContentPositions.left(col); - } - - function colContentRight(col) { - return colContentPositions.right(col); - } - - function dateCell(date) { - return { - row: Math.floor(dayDiff(date, t.visStart) / 7), - col: dayOfWeekCol(date.getDay()) - }; - } - - function cellDate(cell) { - return _cellDate(cell.row, cell.col); - } - - function _cellDate(row, col) { - return addDays(cloneDate(t.visStart), row*7 + col*dis+dit); - // what about weekends in middle of week? - } - - function indexDate(index) { - return _cellDate(Math.floor(index/colCnt), index%colCnt); - } - - function dayOfWeekCol(dayOfWeek) { - return ((dayOfWeek - Math.max(firstDay, nwe) + colCnt) % colCnt) * dis + dit; - } - - function allDayRow(i) { - return bodyRows.eq(i); - } - - function allDayBounds(i) { - return { - left: 0, - right: viewWidth - }; - } - -} - -function BasicEventRenderer() { - var t = this; - - // exports - t.renderEvents = renderEvents; - t.compileDaySegs = compileSegs; // for DayEventRenderer - t.clearEvents = clearEvents; - t.bindDaySeg = bindDaySeg; - - // imports - DayEventRenderer.call(t); - var opt = t.opt; - var trigger = t.trigger; - //var setOverflowHidden = t.setOverflowHidden; - var isEventDraggable = t.isEventDraggable; - var isEventResizable = t.isEventResizable; - var reportEvents = t.reportEvents; - var reportEventClear = t.reportEventClear; - var eventElementHandlers = t.eventElementHandlers; - var showEvents = t.showEvents; - var hideEvents = t.hideEvents; - var eventDrop = t.eventDrop; - var getDaySegmentContainer = t.getDaySegmentContainer; - var getHoverListener = t.getHoverListener; - var renderDayOverlay = t.renderDayOverlay; - var clearOverlays = t.clearOverlays; - var getRowCnt = t.getRowCnt; - var getColCnt = t.getColCnt; - var renderDaySegs = t.renderDaySegs; - var resizableDayEvent = t.resizableDayEvent; - - /* Rendering - --------------------------------------------------------------------*/ - - function renderEvents(events, modifiedEventId) { - reportEvents(events); - renderDaySegs(compileSegs(events), modifiedEventId, false); - } - - function clearEvents() { - reportEventClear(); - getDaySegmentContainer().empty(); - } - - function compileSegs(events) { - var rowCnt = getRowCnt(), - colCnt = getColCnt(), - d1 = cloneDate(t.visStart), - d2 = addDays(cloneDate(d1), colCnt), - visEventsEnds = $.map(events, exclEndDay), - i, row, - j, level, - k, seg, - segs=[]; - for (i=0; i<rowCnt; i++) { - row = stackSegs(sliceSegs(events, visEventsEnds, d1, d2)); - for (j=0; j<row.length; j++) { - level = row[j]; - for (k=0; k<level.length; k++) { - seg = level[k]; - seg.row = i; - seg.level = j; // not needed anymore - segs.push(seg); - } - } - addDays(d1, 7); - addDays(d2, 7); - } - return segs; - } - - function bindDaySeg(event, eventElement, seg) { - if (isEventDraggable(event)) { - draggableDayEvent(event, eventElement); - } - if (seg.isEnd && isEventResizable(event)) { - resizableDayEvent(event, eventElement, seg); - } - eventElementHandlers(event, eventElement); - // needs to be after, because resizableDayEvent might stopImmediatePropagation on click - } - - /* Dragging - ----------------------------------------------------------------------------*/ - - function draggableDayEvent(event, eventElement) { - var hoverListener = getHoverListener(); - var dayDelta; - eventElement.draggable({ - zIndex: 9, - delay: 50, - scroll: false, - opacity: opt('dragOpacity'), - revertDuration: opt('dragRevertDuration'), - start: function(ev, ui) { - trigger('eventDragStart', eventElement, event, ev, ui); - //hideEvents(event, eventElement); - hoverListener.start(function(cell, origCell, rowDelta, colDelta) { - eventElement.draggable('option', 'revert', !cell || !rowDelta && !colDelta); - clearOverlays(); - if (cell) { - //setOverflowHidden(true); - dayDelta = rowDelta*7 + colDelta * (opt('isRTL') ? -1 : 1); - renderDayOverlay( - addDays(cloneDate(event.start), dayDelta), - addDays(exclEndDay(event), dayDelta) - ); - }else{ - //setOverflowHidden(false); - dayDelta = 0; - } - }, ev, 'drag'); - }, - stop: function(ev, ui) { - hoverListener.stop(); - clearOverlays(); - trigger('eventDragStop', eventElement, event, ev, ui); - if (dayDelta) { - eventDrop(this, event, dayDelta, 0, event.allDay, ev, ui); - }else{ - eventElement.css('filter', ''); // clear IE opacity side-effects - //showEvents(event, eventElement); - } - //setOverflowHidden(false); - } - }); - } -} - -fcViews.agendaWeek = AgendaWeekView; - -function AgendaWeekView(element, calendar) { - var t = this; - - // exports - t.render = render; - - // imports - AgendaView.call(t, element, calendar, 'agendaWeek'); - var opt = t.opt; - var renderAgenda = t.renderAgenda; - var formatDates = calendar.formatDates; - - function render(date, delta) { - if (delta) { - addDays(date, delta * 7); - } - var start = addDays(cloneDate(date), -((date.getDay() - opt('firstDay') + 7) % 7)); - var end = addDays(cloneDate(start), 7); - var visStart = cloneDate(start); - var visEnd = cloneDate(end); - var weekends = opt('weekends'); - if (!weekends) { - skipWeekend(visStart); - skipWeekend(visEnd, -1, true); - } - t.title = formatDates( - visStart, - addDays(cloneDate(visEnd), -1), - opt('titleFormat') - ); - t.start = start; - t.end = end; - t.visStart = visStart; - t.visEnd = visEnd; - renderAgenda(weekends ? 7 : 5); - } -} - -fcViews.agendaDay = AgendaDayView; - -function AgendaDayView(element, calendar) { - var t = this; - - // exports - t.render = render; - t.addedView = null; - - // imports - AgendaView.call(t, element, calendar, 'agendaDay'); - var opt = t.opt; - var renderAgenda = t.renderAgenda; - var formatDate = calendar.formatDate; - - function render(date, delta) { - if (delta) { - addDays(date, delta); - if (!opt('weekends')) { - skipWeekend(date, delta < 0 ? -1 : 1); - } - } - var start = cloneDate(date, true); - var end = addDays(cloneDate(start), 1); - t.title = formatDate(date, opt('titleFormat')); - t.start = t.visStart = start; - t.end = t.visEnd = end; - renderAgenda(1); - - if(t.addedView) { - t.addedView.render(date); - } - } -} - -setDefaults({ - allDaySlot: true, - allDayText: 'all-day', - firstHour: 6, - slotMinutes: 30, - defaultEventMinutes: 120, - axisFormat: 'h(:mm)tt', - timeFormat: { - agenda: 'h:mm{ – h:mm}' - }, - dragOpacity: { - agenda: .5 - }, - minTime: 0, - maxTime: 24 -}); - -// TODO: make it work in quirks mode (event corners, all-day height) -// TODO: test liquid width, especially in IE6 - -function AgendaView(element, calendar, viewName) { - var t = this; - - // exports - t.renderAgenda = renderAgenda; - t.setWidth = setWidth; - t.setHeight = setHeight; - t.beforeHide = beforeHide; - t.afterShow = afterShow; - t.defaultEventEnd = defaultEventEnd; - t.timePosition = timePosition; - t.dayOfWeekCol = dayOfWeekCol; - t.dateCell = dateCell; - t.cellDate = cellDate; - t.cellIsAllDay = cellIsAllDay; - t.allDayRow = getAllDayRow; - t.allDayBounds = allDayBounds; - t.getHoverListener = function() { return hoverListener }; - t.colContentLeft = colContentLeft; - t.colContentRight = colContentRight; - t.getDaySegmentContainer = function() { return daySegmentContainer }; - t.getSlotJumpersTop = function() { return slotJumpersTop }; - t.getSlotJumpersBottom = function() { return slotJumpersBottom }; - t.getslotScroller = function() { return slotScroller }; - t.getSlotContent = function() { return slotContent }; - t.getSlotSegmentContainer = function() { return slotSegmentContainer }; - t.getMinMinute = function() { return minMinute }; - t.getMaxMinute = function() { return maxMinute }; - t.getBodyContent = function() { return slotContent }; // !!?? - t.getRowCnt = function() { return 1 }; - t.getColCnt = function() { return colCnt }; - t.getColWidth = function() { return colWidth }; - t.getSlotHeight = function() { return slotHeight }; - t.defaultSelectionEnd = defaultSelectionEnd; - t.renderDayOverlay = renderDayOverlay; - t.renderSelection = renderSelection; - t.renderSlotSelection = renderSlotSelection; - t.clearSelection = clearSelection; - t.reportDayClick = reportDayClick; // selection mousedown hack - t.dragStart = dragStart; - t.dragStop = dragStop; - t.updateGrid = updateGrid; - t.updateToday = updateToday; - t.setAxisFormat = setAxisFormat; - t.setStartOfBusiness = setStartOfBusiness; - t.setEndOfBusiness = setEndOfBusiness; - t.setWeekendDays = setWeekendDays; - t.setBindingMode = setBindingMode; - t.setSelectable = setSelectable; - - // imports - View.call(t, element, calendar, viewName); - OverlayManager.call(t); - SelectionManager.call(t); - AgendaEventRenderer.call(t); - var opt = t.opt; - var trigger = t.trigger; - var clearEvents = t.clearEvents; - var renderOverlay = t.renderOverlay; - var clearOverlays = t.clearOverlays; - var reportSelection = t.reportSelection; - var unselect = t.unselect; - var daySelectionMousedown = t.daySelectionMousedown; - var slotSegHtml = t.slotSegHtml; - var formatDate = calendar.formatDate; - var setTimeIndicator = t.setTimeIndicator; - - // locals - var dayTable; - var dayHead; - var dayHeadCells; - var dayBody; - var dayBodyCells; - var dayBodyCellInners; - var dayBodyFirstCell; - var dayBodyFirstCellStretcher; - var slotLayer; - var daySegmentContainer; - var allDayTable; - var allDayRow; - var slotJumpersTopContainer; - var slotJumpersTop; - var slotJumpersBottomContainer; - var slotJumpersBottom; - var slotScroller; - var slotContent; - var slotSegmentContainer; - var dayScroller; - var dayContent; - var daySegmentContainer; - var slotTable; - var slotTableFirstInner; - var axisFirstCells; - var gutterCells; - var divider; - var selectionHelper; - var viewWidth; - var viewHeight; - var axisWidth; - var colWidth; - var gutterWidth; - //var gutterAck = false; - var slotHeight; // TODO: what if slotHeight changes? (see issue 650) - var savedScrollTop; - var colCnt; - var slotCnt; - var coordinateGrid; - var hoverListener; - var colContentPositions; - var slotTopCache = {}; - var tm; - var firstDay; - var nwe; // no weekends (int) - var rtl, dis, dit; // day index sign / translate - var minMinute, maxMinute; - var colFormat; - - /* Rendering - -----------------------------------------------------------------------------*/ - - disableTextSelection(element.addClass('fc-agenda')); - - function renderAgenda(c) { - colCnt = c; - updateOptions(); - if (!dayTable) { - buildSkeleton(); - }else{ - clearEvents(); - } - updateCells(); - } - - function updateOptions() { - tm = opt('theme') ? 'ui' : 'fc'; - nwe = opt('weekends') ? 0 : 1; - firstDay = opt('firstDay'); - if (rtl = opt('isRTL')) { - dis = -1; - dit = colCnt - 1; - }else{ - dis = 1; - dit = 0; - } - minMinute = parseTime(opt('minTime')); - maxMinute = parseTime(opt('maxTime')); - colFormat = opt('columnFormat'); - } - - function buildSkeleton() { - var headerClass = tm + "-widget-header"; - var contentClass = tm + "-widget-content"; - var s; - var i; - var d; - var maxd; - var minutes; - var slotNormal = opt('slotMinutes') % 15 == 0; - - s = - "<table style='width:100%' class='fc-agenda-days fc-border-separate' cellspacing='0'>" + - "<thead>" + - "<tr>" + - "<th class='fc-agenda-axis " + headerClass + "'><div class='fc-week-number'/></th>"; - for (i=0; i<colCnt; i++) { - s += - "<th class='fc- fc-col" + i + ' ' + headerClass + "'/>"; // fc- needed for setDayID - } - s += - "<th class='fc-agenda-gutter " + headerClass + "'> </th>" + - "</tr>" + - "</thead>" + - "<tbody>" + - "<tr>" + - "<th class='fc-agenda-axis " + headerClass + "'> </th>"; - for (i=0; i<colCnt; i++) { - s += - "<td class='fc- fc-col" + i + ' ' + contentClass + "'>" + // fc- needed for setDayID - "<div>" + - "<div class='fc-day-content'>" + - "<div style='position:relative'> </div>" + - "</div>" + - "</div>" + - "</td>"; - } - s += - "<td class='fc-agenda-gutter " + contentClass + "'> </td>" + - "</tr>" + - "</tbody>" + - "</table>"; - dayTable = $(s).appendTo(element); - dayHead = dayTable.find('thead'); - dayHeadCells = dayHead.find('th').slice(1, -1); - dayBody = dayTable.find('tbody'); - dayBodyCells = dayBody.find('td').slice(0, -1); - dayBodyCellInners = dayBodyCells.find('div.fc-day-content div'); - dayBodyFirstCell = dayBodyCells.eq(0); - dayBodyFirstCellStretcher = dayBodyFirstCell.find('> div'); - - markFirstLast(dayHead.add(dayHead.find('tr'))); - markFirstLast(dayBody.add(dayBody.find('tr'))); - - axisFirstCells = dayHead.find('th:first'); - gutterCells = dayTable.find('.fc-agenda-gutter'); - - slotLayer = - $("<div style='position:absolute;z-index:2;left:0;width:100%'/>") - .appendTo(element); - - if(opt('allDaySlot')) { - dayScroller = $("<div style='position:absolute;width:100%;overflow-x:hidden;overflow-y:auto;'/>").appendTo(slotLayer); - dayContent = $("<div style='position:relative;width:100%;overflow:hidden;min-height:37px'/>").appendTo(dayScroller); - daySegmentContainer = $("<div style='position:absolute;z-index:8;top:0;left:0'/>").appendTo(dayContent); - - s = - "<table style='width:100%;' class='fc-agenda-allday' cellspacing='0'>" + - "<tr>" + - "<th class='" + headerClass + " fc-agenda-axis'>" + opt('allDayText') + "</th>" + - "<td>" + - "<div class='fc-day-content'><div style='position:relative;min-height:34px'/></div>" + - "</td>" + - "</tr>" + - "</table>"; - - allDayTable = $(s).appendTo(dayScroller); - allDayRow = allDayTable.find('tr'); - dayBind(allDayRow.find('td')); - axisFirstCells = axisFirstCells.add(allDayTable.find('th:first')); - gutterCells = gutterCells.add(allDayTable.find('th.fc-agenda-gutter')); - - divider = $( - "<div class='fc-agenda-divider " + headerClass + "'>" + - "<div class='fc-agenda-divider-inner'/>" + - "</div>" - ).appendTo(slotLayer); - - }else{ - daySegmentContainer = $([]); // in jQuery 1.4, we can just do $() - } - - slotJumpersTopContainer = $("<div style='position:relative;width:100%;'/>").appendTo(slotLayer); - slotJumpersBottomContainer = $("<div style='position:relative;width:100%;'/>").appendTo(slotLayer); - slotScroller = $("<div style='position:absolute;width:100%;overflow-x:hidden;overflow-y:auto'/>").appendTo(slotLayer); - slotContent = $("<div style='position:relative;width:100%;overflow:hidden'/>").appendTo(slotScroller); - slotSegmentContainer = $("<div style='position:absolute;z-index:8;top:0;left:0'/>").appendTo(slotContent); - - for (i=0; i<colCnt; i++) { - slotJumpersTopContainer.append($('<div class="fc-slot-jumper-top"/>')); - slotJumpersBottomContainer.append($('<div class="fc-slot-jumper-bottom"/>')); - } - slotJumpersTop = slotJumpersTopContainer.children(); - slotJumpersBottom = slotJumpersBottomContainer.children(); - - s = - "<table class='fc-agenda-slots' style='width:100%' cellspacing='0'>" + - "<tbody>"; - d = zeroDate(); - maxd = addMinutes(cloneDate(d), maxMinute); - addMinutes(d, minMinute); - slotCnt = 0; - - var startOfBusiness = opt("startOfBusiness") * (60/opt("slotMinutes")); - var endOfBusiness = (opt("endOfBusiness") - (opt("slotMinutes")/60)) * (60/opt("slotMinutes")); - for (i=0; d < maxd; i++) { - minutes = d.getMinutes(); - var nonBusinessHours = (i < startOfBusiness || i > endOfBusiness) ? " fc-non-business-hours" : ""; - s += - "<tr class='fc-slot" + i + ' ' + (!minutes ? '' : 'fc-minor') + nonBusinessHours + "'>" + - "<th class='fc-agenda-axis " + headerClass + "'>" + - ((!slotNormal || !minutes) ? formatDate(d, opt('axisFormat')) : ' ') + - "</th>" + - "<td class='" + contentClass + "'>" + - "<div style='position:relative'> </div>" + - "</td>" + - "</tr>"; - addMinutes(d, opt('slotMinutes')); - slotCnt++; - } - s += - "</tbody>" + - "</table>"; - slotTable = $(s).appendTo(slotContent); - slotTableFirstInner = slotTable.find('div:first'); - slotBind(slotTable.find('td')); - axisFirstCells = axisFirstCells.add(slotTable.find('th:first')); - } - - function updateCells() { - var i; - var headCell; - var bodyCell; - var axisCell; - var date; - var today = clearTime(new Date()); - axisCell = axisFirstCells[0]; - - if(opt('showWeekNumbers')) { - removeWeekNumber($(axisCell), colDate(0)); - addWeekNumber($(axisCell), colDate(0)); - } - for (i=0; i<colCnt; i++) { - date = colDate(i); - headCell = dayHeadCells.eq(i); - headCell.html(formatDate(date, colFormat)); - bodyCell = dayBodyCells.eq(i); - setDayID(headCell.add(bodyCell), date, opt); - if (+date == +today) { - bodyCell.addClass(tm + '-state-highlight fc-today'); - addTodayClass(bodyCell); - }else{ - bodyCell.removeClass(tm + '-state-highlight fc-today'); - removeTodayClass(bodyCell); - } - } - } - - function updateGrid() - { - updateToday(); - setTimeIndicator(); - setAxisFormat(); - setStartOfBusiness(); - setEndOfBusiness(); - setWeekendDays(); - setBindingMode(); - setSelectable(); - } - - function updateToday() - { - var i; - var bodyCell; - var date; - var today = clearTime(new Date()); - for (i=0; i<colCnt; i++) { - date = colDate(i); - bodyCell = dayBodyCells.eq(i); - if (+date == +today) { - bodyCell.addClass(tm + '-state-highlight fc-today'); - addTodayClass(bodyCell); - }else{ - bodyCell.removeClass(tm + '-state-highlight fc-today'); - removeTodayClass(bodyCell); - } - } - } - - function setAxisFormat() - { - var slotNormal = opt('slotMinutes') % 15 == 0; - var d = zeroDate(); - addMinutes(d, minMinute); - - slotTable.find('th').each(function(index, element){ - var minutes = d.getMinutes(); - $(element).html((!slotNormal || !minutes) ? formatDate(d, opt('axisFormat')) : ' '); - addMinutes(d, opt('slotMinutes')); - }); - } - - function setStartOfBusiness() - { - updateBusinessHours(); - } - - function setEndOfBusiness() - { - updateBusinessHours(); - } - - function updateBusinessHours() - { - var startOfBusiness = opt("startOfBusiness") * (60/opt("slotMinutes")); - var endOfBusiness = (opt("endOfBusiness") - (opt("slotMinutes")/60)) * (60/opt("slotMinutes")); - slotTable.find('tr').each(function(index, element){ - if(index < startOfBusiness || index > endOfBusiness) - $(element).addClass('fc-non-business-hours'); - else - $(element).removeClass('fc-non-business-hours'); - }); - } - - function setWeekendDays() - { - dayHeadCells.each(function(i, _cell) { - setDayID($(_cell), colDate(i), opt); - }); - - dayBodyCells.each(function(i, _cell) { - setDayID($(_cell), colDate(i), opt); - }); - } - - function setBindingMode() - { - dayBind(allDayRow.find('td')); - slotBind(slotTable.find('td')); - } - - function setSelectable() - { - dayBind(allDayRow.find('td')); - slotBind(slotTable.find('td')); - } - - function setHeight(height, dateChanged) { - if (height === undefined) { - height = viewHeight; - } - viewHeight = height; - slotTopCache = {}; - - var headHeight = dayBody.position().top; - var allDayHeight = opt('allDaySlot') ? 4 : 0; //if divider is present - var bodyHeight = Math.min( // total body height, including borders - height - headHeight, // when scrollbars - slotTable.height() + allDayHeight + 1 // when no scrollbars. +1 for bottom border - ); - - var maxAllDayHeight = Math.floor((bodyHeight - allDayHeight - 1) / 3); - dayScroller.css('max-height', maxAllDayHeight + 3); - allDayRow.find('div:first').children().css('max-height', maxAllDayHeight); - - allDayHeight = allDayTable.height(); - if(opt('allDaySlot')) { - divider.css('position', 'relative'); - divider.css('top', allDayHeight); - slotScroller.css('top', allDayHeight + 4); - } - - //allDayHeight = slotScroller.position().top; // including divider - bodyHeight = Math.min( // total body height, including borders - height - headHeight, // when scrollbars - slotTable.height() + allDayHeight + 1 // when no scrollbars. +1 for bottom border - ); - - dayBodyFirstCellStretcher - .height(bodyHeight - vsides(dayBodyFirstCell)); - - var slotScrollerHeight = bodyHeight - allDayHeight - 1 - (opt('allDaySlot') ? 4 : 0); - slotLayer.css('top', headHeight); - slotScroller.height(slotScrollerHeight); - slotHeight = slotTableFirstInner.height() + 1; // +1 for border - - slotJumpersTopContainer.css('top', allDayHeight+1); - slotJumpersBottomContainer.css('top', slotScrollerHeight + allDayHeight + 1 - slotJumpersBottom.first().height()); - - if (dateChanged) { - resetScroll(); - } - - if(t.addedView) { - t.addedView.setHeight(height, dateChanged); - } - } - - function setWidth(width) { - if (width === undefined) { - width = viewWidth; - } - viewWidth = width; - if(t.addedView) { - var outerWidth = Math.floor(element.parent().width() / 2); - element.css({'width' : outerWidth}); - viewWidth = outerWidth; - } - colContentPositions.clear(); - - axisWidth = 0; - setOuterWidth( - axisFirstCells - .width('') - .each(function(i, _cell) { - axisWidth = Math.max(axisWidth, $(_cell).outerWidth()); - }), - axisWidth - ); - - var slotTableWidth = slotScroller[0].clientWidth; // needs to be done after axisWidth (for IE7) - //slotTable.width(slotTableWidth); - - //var oldGutterWidth = gutterWidth; - gutterWidth = slotScroller.width() - slotTableWidth || dayScroller.width() - dayContent.width(); - if (gutterWidth) { - /*if(!gutterAck) { - viewWidth -= gutterWidth; - gutterAck = true; - }*/ - setOuterWidth(gutterCells, gutterWidth); - gutterCells - .show() - .prev() - .removeClass('fc-last'); - }else{ - /*if(gutterAck) { - viewWidth += oldGutterWidth; - gutterAck = false; - }*/ - gutterCells - .hide() - .prev() - .addClass('fc-last'); - } - - colWidth = Math.floor((slotTableWidth - axisWidth) / colCnt); - setOuterWidth(dayHeadCells.slice(0, -1), colWidth); - - slotJumpersTop.each(function(i,e){ - var jumper=$(e); - jumper.css('left',axisWidth + (colWidth*(i+1)) - 1 - jumper.width()); - }); - slotJumpersBottom.each(function(i,e){ - var jumper=$(e); - jumper.css('left',axisWidth + (colWidth*(i+1)) - 1 - jumper.width()); - }); - - if(t.addedView) { - t.addedView.setWidth(outerWidth); - } - } - - function resetScroll() { - var d0 = zeroDate(); - var scrollDate = cloneDate(d0); - scrollDate.setHours(opt('firstHour')); - var top = timePosition(d0, scrollDate) + 1; // +1 for the border - function scroll() { - slotScroller.scrollTop(top); - } - scroll(); - setTimeout(scroll, 0); // overrides any previous scroll state made by the browser - } - - function beforeHide() { - savedScrollTop = slotScroller.scrollTop(); - } - - function afterShow() { - slotScroller.scrollTop(savedScrollTop); - } - - /* Slot/Day clicking and binding - -----------------------------------------------------------------------*/ - - function dayBind(cells) { - cells.unbind('click dblclick'); - if(opt('bindingMode') == 'double') - cells.dblclick(daySlotClick).mousedown(daySelectionMousedown); - else - cells.click(daySlotClick).mousedown(daySelectionMousedown); - } - - function slotBind(cells) { - cells.unbind('click dblclick'); - if(opt('bindingMode') == 'double') - cells.dblclick(slotClick).mousedown(slotSelectionMousedown); - else - cells.click(slotClick).mousedown(slotSelectionMousedown); - } - - function daySlotClick(ev) { - var col = Math.min(colCnt-1, Math.floor((ev.pageX - dayTable.offset().left - axisWidth) / colWidth)); - var date = colDate(col); - trigger('dayClick', dayBodyCells[col], date, true, ev); - } - - function slotClick(ev) { - //if (!opt('selectable')) { // if selectable, SelectionManager will worry about dayClick - var col = Math.min(colCnt-1, Math.floor((ev.pageX - dayTable.offset().left - axisWidth) / colWidth)); - var date = colDate(col); - var rowMatch = this.parentNode.className.match(/fc-slot(\d+)/); // TODO: maybe use data - if (rowMatch) { - var mins = parseInt(rowMatch[1]) * opt('slotMinutes'); - var hours = Math.floor(mins/60); - date.setHours(hours); - date.setMinutes(mins%60 + minMinute); - trigger('dayClick', dayBodyCells[col], date, false, ev); - }else{ - trigger('dayClick', dayBodyCells[col], date, true, ev); - } - //} - } - - /* Semi-transparent Overlay Helpers - -----------------------------------------------------*/ - - function renderDayOverlay(startDate, endDate, refreshCoordinateGrid) { // endDate is exclusive - if (refreshCoordinateGrid) { - coordinateGrid.build(); - } - var visStart = cloneDate(t.visStart); - var startCol, endCol; - if (rtl) { - startCol = dayDiff(endDate, visStart)*dis+dit+1; - endCol = dayDiff(startDate, visStart)*dis+dit+1; - }else{ - startCol = dayDiff(startDate, visStart); - endCol = dayDiff(endDate, visStart); - } - startCol = Math.max(0, startCol); - endCol = Math.min(colCnt, endCol); - if (startCol < endCol) { - dayBind( - renderCellOverlay(0, startCol, 0, endCol-1) - ); - } - } - - function renderCellOverlay(row0, col0, row1, col1) { // only for all-day? - var rect = coordinateGrid.rect(row0, col0, row1, col1, slotLayer); - return renderOverlay(rect, slotLayer); - } - - function renderSlotOverlay(overlayStart, overlayEnd) { - var dayStart = cloneDate(t.visStart); - var dayEnd = addDays(cloneDate(dayStart), 1); - for (var i=0; i<colCnt; i++) { - var stretchStart = new Date(Math.max(dayStart, overlayStart)); - var stretchEnd = new Date(Math.min(dayEnd, overlayEnd)); - if (stretchStart < stretchEnd) { - var col = i*dis+dit; - var rect = coordinateGrid.rect(0, col, 0, col, slotContent); // only use it for horizontal coords - var top = timePosition(dayStart, stretchStart); - var bottom = timePosition(dayStart, stretchEnd); - rect.top = top; - rect.height = bottom - top; - slotBind( - renderOverlay(rect, slotContent) - ); - } - addDays(dayStart, 1); - addDays(dayEnd, 1); - } - } - - /* Coordinate Utilities - -----------------------------------------------------------------------------*/ - - coordinateGrid = new CoordinateGrid(function(rows, cols) { - var e, n, p; - dayHeadCells.each(function(i, _e) { - e = $(_e); - n = e.offset().left; - if (i) { - p[1] = n; - } - p = [n]; - cols[i] = p; - }); - p[1] = n + e.outerWidth(); - if (opt('allDaySlot')) { - e = allDayRow; - n = e.offset().top; - rows[0] = [n, n+e.outerHeight()]; - } - var slotTableTop = slotContent.offset().top; - var slotScrollerTop = slotScroller.offset().top; - var slotScrollerBottom = slotScrollerTop + slotScroller.outerHeight(); - function constrain(n) { - return Math.max(slotScrollerTop, Math.min(slotScrollerBottom, n)); - } - for (var i=0; i<slotCnt; i++) { - rows.push([ - constrain(slotTableTop + slotHeight*i), - constrain(slotTableTop + slotHeight*(i+1)) - ]); - } - }); - - hoverListener = new HoverListener(coordinateGrid); - - colContentPositions = new HorizontalPositionCache(function(col) { - return dayBodyCellInners.eq(col); - }); - - function colContentLeft(col) { - return colContentPositions.left(col); - } - - function colContentRight(col) { - return colContentPositions.right(col); - } - - function dateCell(date) { // "cell" terminology is now confusing - return { - row: Math.floor(dayDiff(date, t.visStart) / 7), - col: dayOfWeekCol(date.getDay()) - }; - } - - function cellDate(cell) { - var d = colDate(cell.col); - var slotIndex = cell.row; - if (opt('allDaySlot')) { - slotIndex--; - } - if (slotIndex >= 0) { - addMinutes(d, minMinute + slotIndex * opt('slotMinutes')); - } - return d; - } - - function colDate(col) { // returns dates with 00:00:00 - return addDays(cloneDate(t.visStart), col*dis+dit); - } - - function cellIsAllDay(cell) { - return opt('allDaySlot') && !cell.row; - } - - function dayOfWeekCol(dayOfWeek) { - return ((dayOfWeek - Math.max(firstDay, nwe) + colCnt) % colCnt)*dis+dit; - } - - // get the Y coordinate of the given time on the given day (both Date objects) - function timePosition(day, time) { // both date objects. day holds 00:00 of current day - day = cloneDate(day, true); - if (time < addMinutes(cloneDate(day), minMinute)) { - return 0; - } - if (time >= addMinutes(cloneDate(day), maxMinute)) { - return slotTable.height(); - } - var slotMinutes = opt('slotMinutes'), - minutes = time.getHours()*60 + time.getMinutes() - minMinute, - slotI = Math.floor(minutes / slotMinutes), - slotTop = slotTopCache[slotI]; - if (slotTop === undefined) { - slotTop = slotTopCache[slotI] = slotTable.find('tr:eq(' + slotI + ') td div')[0].offsetTop; //.position().top; // need this optimization??? - } - return Math.max(0, Math.round( - slotTop - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes) - )); - } - - function allDayBounds() { - return { - left: axisWidth, - right: viewWidth - gutterWidth - } - } - - function getAllDayRow(index) { - return allDayRow; - } - - function defaultEventEnd(event) { - var start = cloneDate(event.start); - if (event.allDay) { - return start; - } - return addMinutes(start, opt('defaultEventMinutes')); - } - - /* Selection - ---------------------------------------------------------------------------------*/ - - function defaultSelectionEnd(startDate, allDay) { - if (allDay) { - return cloneDate(startDate); - } - return addMinutes(cloneDate(startDate), opt('slotMinutes')); - } - - function renderSelection(startDate, endDate, allDay) { // only for all-day - if (allDay) { - if (opt('allDaySlot')) { - renderDayOverlay(startDate, addDays(cloneDate(endDate), 1), true); - } - }else{ - renderSlotSelection(startDate, endDate); - } - } - - function renderSlotSelection(startDate, endDate) { - var helperOption = opt('selectHelper'); - coordinateGrid.build(); - if (helperOption) { - var col = dayDiff(startDate, t.visStart) * dis + dit; - if (col >= 0 && col < colCnt) { // only works when times are on same day - var rect = coordinateGrid.rect(0, col, 0, col, slotContent); // only for horizontal coords - var top = timePosition(startDate, startDate); - var bottom = timePosition(startDate, endDate); - if (bottom > top) { // protect against selections that are entirely before or after visible range - rect.top = top; - rect.height = bottom - top; - rect.left += 2; - rect.width -= 5; - if ($.isFunction(helperOption)) { - var helperRes = helperOption(startDate, endDate); - if (helperRes) { - rect.position = 'absolute'; - rect.zIndex = 8; - selectionHelper = $(helperRes) - .css(rect) - .appendTo(slotContent); - } - }else{ - rect.isStart = true; // conside rect a "seg" now - rect.isEnd = true; // - selectionHelper = $(slotSegHtml( - { - title: '', - start: startDate, - end: endDate, - className: ['fc-select-helper'], - editable: false - }, - rect - )); - selectionHelper.css('opacity', opt('dragOpacity')); - } - if (selectionHelper) { - slotBind(selectionHelper); - slotContent.append(selectionHelper); - setOuterWidth(selectionHelper, rect.width, true); // needs to be after appended - setOuterHeight(selectionHelper, rect.height, true); - } - } - } - }else{ - renderSlotOverlay(startDate, endDate); - } - } - - function clearSelection() { - clearOverlays(); - if (selectionHelper) { - selectionHelper.remove(); - selectionHelper = null; - } - } - - function slotSelectionMousedown(ev) { - if (ev.which == 1 && opt('selectable')) { // ev.which==1 means left mouse button - unselect(ev); - var dates; - hoverListener.start(function(cell, origCell) { - clearSelection(); - if (cell && (cell.col == origCell.col || !opt('selectHelper')) && !cellIsAllDay(cell)) { - var d1 = cellDate(origCell); - var d2 = cellDate(cell); - dates = [ - d1, - addMinutes(cloneDate(d1), opt('slotMinutes')), - d2, - addMinutes(cloneDate(d2), opt('slotMinutes')) - ].sort(cmp); - renderSlotSelection(dates[0], dates[3]); - }else{ - dates = null; - } - }, ev); - $(document).one('mouseup', function(ev) { - hoverListener.stop(); - if (dates) { - if (+dates[0] == +dates[1]) { - //reportDayClick(dates[0], false, ev); - } - reportSelection(dates[0], dates[3], false, ev); - } - }); - } - } - - function reportDayClick(date, allDay, ev) { - trigger('dayClick', dayBodyCells[dayOfWeekCol(date.getDay())], date, allDay, ev); - } - - /* External Dragging - --------------------------------------------------------------------------------*/ - - function dragStart(_dragElement, ev, ui) { - hoverListener.start(function(cell) { - clearOverlays(); - if (cell) { - if (cellIsAllDay(cell)) { - renderCellOverlay(cell.row, cell.col, cell.row, cell.col); - }else{ - var d1 = cellDate(cell); - var d2 = addMinutes(cloneDate(d1), opt('defaultEventMinutes')); - renderSlotOverlay(d1, d2); - } - } - }, ev); - } - - function dragStop(_dragElement, ev, ui) { - var cell = hoverListener.stop(); - clearOverlays(); - if (cell) { - trigger('drop', _dragElement, cellDate(cell), cellIsAllDay(cell), ev, ui); - } - } - -} - -function AgendaEventRenderer() { - var t = this; - - // exports - t.renderEvents = renderEvents; - t.compileDaySegs = compileDaySegs; // for DayEventRenderer - t.clearEvents = clearEvents; - t.slotSegHtml = slotSegHtml; - t.bindDaySeg = bindDaySeg; - t.setTimeIndicator = setTimeIndicator; - - // imports - DayEventRenderer.call(t); - var opt = t.opt; - var trigger = t.trigger; - //var setOverflowHidden = t.setOverflowHidden; - var isEventDraggable = t.isEventDraggable; - var isEventResizable = t.isEventResizable; - var eventEnd = t.eventEnd; - var reportEvents = t.reportEvents; - var reportEventClear = t.reportEventClear; - var eventElementHandlers = t.eventElementHandlers; - var setHeight = t.setHeight; - var setWidth = t.setWidth; - var getDaySegmentContainer = t.getDaySegmentContainer; - var getSlotJumpersTop = t.getSlotJumpersTop; - var getSlotJumpersBottom = t.getSlotJumpersBottom; - var getslotScroller = t.getslotScroller; - var getSlotContent = t.getSlotContent; - var getSlotSegmentContainer = t.getSlotSegmentContainer; - var getHoverListener = t.getHoverListener; - var getMaxMinute = t.getMaxMinute; - var getMinMinute = t.getMinMinute; - var timePosition = t.timePosition; - var colContentLeft = t.colContentLeft; - var colContentRight = t.colContentRight; - var renderDaySegs = t.renderDaySegs; - var resizableDayEvent = t.resizableDayEvent; // TODO: streamline binding architecture - var getColCnt = t.getColCnt; - var getColWidth = t.getColWidth; - var getSlotHeight = t.getSlotHeight; - var getBodyContent = t.getBodyContent; - var reportEventElement = t.reportEventElement; - var showEvents = t.showEvents; - var hideEvents = t.hideEvents; - var eventDrop = t.eventDrop; - var eventResize = t.eventResize; - var renderDayOverlay = t.renderDayOverlay; - var renderSlotSelection = t.renderSlotSelection; - var clearOverlays = t.clearOverlays; - var calendar = t.calendar; - var formatDate = calendar.formatDate; - var formatDates = calendar.formatDates; - var timeLineInterval; - - /* Rendering - ----------------------------------------------------------------------------*/ - - // draw a horizontal line indicating the current time (#143) - function setTimeIndicator() - { - var container = getBodyContent(); - var timeline = container.children('.fc-timeline'); - var arrow = container.children('.fc-timeline-arrow'); - if (timeline.length == 0 || arrow.length == 0) { // if timeline isn't there, add it - timeline = $('<hr>').addClass('fc-timeline').appendTo(container); - arrow = $('<div>').addClass('fc-timeline-arrow').appendTo(container); - } - - var cur_time = new Date(); - var daycol = $('.fc-today', t.element); - if (daycol.length > 0) { - timeline.show(); - arrow.show(); - } - else { - timeline.hide(); - arrow.hide(); - return; - } - - var secs = (cur_time.getHours() * 60 * 60) + (cur_time.getMinutes() * 60) + cur_time.getSeconds(); - var percents = secs / 86400; // 24 * 60 * 60 = 86400, # of seconds in a day - - timeline.css('top', Math.floor(container.height() * percents - 1) + 'px'); - arrow.css('top', Math.floor(container.height() * percents - 1) - 5 + 'px'); - - var left = daycol.position().left; - var width = daycol.width(); - timeline.css({ left: left + 'px', width: width + 'px' }); - } - - function renderEvents(events, modifiedEventId) { - reportEvents(events); - var i, len=events.length, - dayEvents=[], - slotEvents=[]; - for (i=0; i<len; i++) { - if (events[i].allDay) { - dayEvents.push(events[i]); - }else{ - slotEvents.push(events[i]); - } - } - if (opt('allDaySlot')) { - renderDaySegs(compileDaySegs(dayEvents), modifiedEventId, true); - setHeight(); // no params means set to viewHeight - setWidth(); // no params means set to viewWidth - } - renderSlotSegs(compileSlotSegs(slotEvents), modifiedEventId); - - if (opt('currentTimeIndicator')) { - window.clearInterval(timeLineInterval); - timeLineInterval = window.setInterval(setTimeIndicator, 30000); - setTimeIndicator(); - } - - if(t.addedView) { - t.addedView.renderEvents(events, modifiedEventId); - } - } - - function clearEvents() { - reportEventClear(); - getDaySegmentContainer().empty(); - getSlotSegmentContainer().empty(); - - if(t.addedView) { - t.addedView.clearEvents(); - } - } - - function compileDaySegs(events) { - var levels = stackSegs(sliceSegs(events, $.map(events, exclEndDay), t.visStart, t.visEnd)), - i, levelCnt=levels.length, level, - j, seg, - segs=[]; - for (i=0; i<levelCnt; i++) { - level = levels[i]; - for (j=0; j<level.length; j++) { - seg = level[j]; - seg.row = 0; - seg.level = i; // not needed anymore - segs.push(seg); - } - } - return segs; - } - - function compileSlotSegs(events) { - var colCnt = getColCnt(), - minMinute = getMinMinute(), - maxMinute = getMaxMinute(), - d = addMinutes(cloneDate(t.visStart), minMinute), - visEventEnds = $.map(events, slotEventEnd), - i, col, - j, level, - k, seg, - segs=[]; - for (i=0; i<colCnt; i++) { - col = stackSegs(sliceSegs(events, visEventEnds, d, addMinutes(cloneDate(d), maxMinute-minMinute))); - countForwardSegs(col); - for (j=0; j<col.length; j++) { - level = col[j]; - for (k=0; k<level.length; k++) { - seg = level[k]; - seg.col = i; - seg.level = j; - segs.push(seg); - } - } - addDays(d, 1, true); - } - return segs; - } - - function slotEventEnd(event) { - if (event.end) { - return cloneDate(event.end); - }else{ - return addMinutes(cloneDate(event.start), opt('defaultEventMinutes')); - } - } - - // renders events in the 'time slots' at the bottom - - function renderSlotSegs(segs, modifiedEventId) { - var i, segCnt=segs.length, seg, - event, - classes, - top, bottom, - colI, levelI, forward, - leftmost, - availWidth, - outerWidth, - left, - html='', - eventElements, - eventElement, - triggerRes, - vsideCache={}, - hsideCache={}, - key, val, - contentElement, - height, - slotJumpersTop = getSlotJumpersTop(), - slotJumpersBottom = getSlotJumpersBottom(), - slotSegmentContainer = getSlotSegmentContainer(), - slotScroller = getslotScroller(), - rtl, dis, dit, - colCnt = getColCnt(), - colBoundaries = new Array(colCnt), - jumperReserve = 10; - - if (rtl = opt('isRTL')) { - dis = -1; - dit = colCnt - 1; - }else{ - dis = 1; - dit = 0; - } - - // init column tops array - for(i=0;i<colCnt;i++) { - colBoundaries[i]={positions:new Array()}; - } - - // calculate position/dimensions, create html - for (i=0; i<segCnt; i++) { - seg = segs[i]; - event = seg.event; - top = timePosition(seg.start, seg.start); - bottom = timePosition(seg.start, seg.end); - colI = seg.col; - levelI = seg.level; - forward = seg.forward || 0; - leftmost = colContentLeft(colI*dis + dit); - availWidth = colContentRight(colI*dis + dit) - leftmost; - availWidth = Math.min(availWidth-6, availWidth*.95); // TODO: move this to CSS - if (levelI) { - // indented and thin - outerWidth = availWidth / (levelI + forward + 1); - }else{ - if (forward) { - // moderately wide, aligned left still - outerWidth = ((availWidth / (forward + 1)) - (12/2)) * 2; // 12 is the predicted width of resizer = - }else{ - // can be entire width, aligned left - outerWidth = availWidth; - } - } - left = leftmost + // leftmost possible - (availWidth / (levelI + forward + 1) * levelI) // indentation - * dis + (rtl ? availWidth - outerWidth : 0); // rtl - seg.top = top; - seg.left = left; - seg.outerWidth = outerWidth; - seg.outerHeight = bottom - top; - html += slotSegHtml(event, seg); - } - slotSegmentContainer[0].innerHTML = html; // faster than html() - eventElements = slotSegmentContainer.children(); - - // retrieve elements, run through eventRender callback, bind event handlers - for (i=0; i<segCnt; i++) { - seg = segs[i]; - event = seg.event; - eventElement = $(eventElements[i]); // faster than eq() - triggerRes = trigger('eventRender', event, event, eventElement); - if (triggerRes === false) { - eventElement.remove(); - }else{ - if (triggerRes && triggerRes !== true) { - eventElement.remove(); - eventElement = $(triggerRes) - .css({ - position: 'absolute', - top: seg.top, - left: seg.left - }) - .appendTo(slotSegmentContainer); - } - seg.element = eventElement; - if (event._id === modifiedEventId) { - bindSlotSeg(event, eventElement, seg); - }else{ - eventElement[0]._fci = i; // for lazySegBind - } - reportEventElement(event, eventElement); - } - } - - lazySegBind(slotSegmentContainer, segs, bindSlotSeg); - - // record event sides and title positions - for (i=0; i<segCnt; i++) { - seg = segs[i]; - if (eventElement = seg.element) { - val = vsideCache[key = seg.key = cssKey(eventElement[0])]; - seg.vsides = val === undefined ? (vsideCache[key] = vsides(eventElement, true)) : val; - val = hsideCache[key]; - seg.hsides = val === undefined ? (hsideCache[key] = hsides(eventElement, true)) : val; - contentElement = eventElement.find('div.fc-event-content'); - if (contentElement.length) { - seg.contentTop = contentElement[0].offsetTop; - } - } - } - - // set all positions/dimensions at once - for (i=0; i<segCnt; i++) { - seg = segs[i]; - if (eventElement = seg.element) { - eventElement[0].style.width = Math.max(0, seg.outerWidth - seg.hsides) + 'px'; - height = Math.max(t.getSlotHeight() - seg.vsides, seg.outerHeight - seg.vsides); - eventElement[0].style.height = height + 'px'; - event = seg.event; - if (seg.contentTop !== undefined && height - seg.contentTop < 10) { - // not enough room for title, put it in the time header - eventElement.find('div.fc-event-time') - .text(formatDate(event.start, opt('timeFormat')) + ' - ' + event.title); - //.text(formatDates(event.start, event.end, opt('timeFormat')) + ' - ' + event.title); - eventElement.find('div.fc-event-title') - .remove(); - } - colBoundaries[seg.col].positions.push({top:seg.top, bottom:seg.top+height+seg.vsides}); - trigger('eventAfterRender', event, event, eventElement); - } - } - - // sort column boundaries on top values and set min and max values - for(i=0;i<colCnt;i++) { - var min = null; - var currentCol = colBoundaries[i]; - var currentColPositions = currentCol.positions; - currentColPositions = currentColPositions.sort(function(a,b){return a.top-b.top;}); - $.each(currentColPositions,function(ei,ee){ - if(min==null) - min=ee.bottom; - else - min=Math.min(min,ee.bottom); - }); - currentCol.min=min; - currentCol.max=currentColPositions.length?currentColPositions[currentColPositions.length-1].top:null; - } - - slotScroller.unbind('scroll').scroll(function(){ - var currentPosition = $(this).scrollTop(); - for(i=0;i<colCnt;i++) { - var currentCol = colBoundaries[i]; - if(currentCol.min!=null && currentCol.min<=currentPosition+jumperReserve) - $(slotJumpersTop[i]).css('display',''); - else - $(slotJumpersTop[i]).css('display','none'); - if(currentCol.max!=null && currentCol.max>=currentPosition+slotScroller.height()-jumperReserve) - $(slotJumpersBottom[i]).css('display',''); - else - $(slotJumpersBottom[i]).css('display','none'); - } - }).trigger('scroll'); - slotJumpersTop.each(function(i, jumper){ - $(jumper).unbind('click').click(function(){ - var targetTop=0; - var currentPosition = slotScroller.scrollTop(); - $.each(colBoundaries[i].positions,function(ei,ee){ - if(ee.bottom<=currentPosition+jumperReserve) - targetTop=ee.top; - return ee.top<currentPosition; - }); - slotScroller.scrollTop(targetTop-t.getSlotHeight()); - }); - }); - slotJumpersBottom.each(function(i, jumper){ - $(jumper).unbind('click').click(function(){ - var targetPosition=0; - var currentPosition = slotScroller.scrollTop(); - $.each(colBoundaries[i].positions,function(ei,ee){ - if(ee.top>=currentPosition+slotScroller.height()-jumperReserve) - { - targetPosition = ee; - return false; - } - }); - slotScroller.scrollTop( - targetPosition.bottom-targetPosition.top+t.getSlotHeight()>slotScroller.height()? - targetPosition.top-t.getSlotHeight(): - targetPosition.bottom-slotScroller.height()+t.getSlotHeight()+1 // +1 is a magic independent constant, used just to make the default scroll position look better - ); - }); - }); - - for (i=0; i<segCnt; i++) { - seg = segs[i]; - if(seg.event.source && seg.event.source.background) { - $('td.fc-col' + seg.col, t.element).addClass('fc-source-bg'); - } - } - } - - function slotSegHtml(event, seg) { - var html = "<"; - var url = event.url; - var skinCss = getSkinCss(event, opt); - var skinCssAttr = (skinCss ? " style='" + skinCss + "'" : ''); - var classes = ['fc-event', 'fc-event-skin', 'fc-event-vert']; - if (isEventDraggable(event)) { - classes.push('fc-event-draggable'); - } - if (seg.isStart) { - classes.push('fc-corner-top'); - } - if (seg.isEnd) { - classes.push('fc-corner-bottom'); - } - classes = classes.concat(event.className); - if (event.source) { - classes = classes.concat(event.source.className || []); - } - if (url) { - html += "a href='" + htmlEscape(event.url) + "'"; - }else{ - html += "div"; - } - html += - " class='" + classes.join(' ') + "'" + - " style='position:absolute;z-index:8;top:" + seg.top + "px;left:" + seg.left + "px;" + skinCss + "'" + - ">" + - "<div class='fc-event-inner fc-event-skin'" + skinCssAttr + ">" + - "<div class='fc-event-head fc-event-skin'" + skinCssAttr + ">" + - "<div class='fc-event-time'>" + - htmlEscape(formatDates(event.start, event.end, opt('timeFormat'))) + - "</div>" + - "</div>" + - "<div class='fc-event-content'>" + - "<div class='fc-event-title'>" + - htmlEscape(event.title) + - "</div>" + - "</div>" + - "<div class='fc-event-bg'></div>" + - "</div>"; // close inner - if (seg.isEnd && isEventResizable(event)) { - html += - "<div class='ui-resizable-handle ui-resizable-s'>=</div>"; - } - html += - "</" + (url ? "a" : "div") + ">"; - return html; - } - - function bindDaySeg(event, eventElement, seg) { - if (isEventDraggable(event)) { - draggableDayEvent(event, eventElement, seg.isStart); - } - if (seg.isEnd && isEventResizable(event)) { - resizableDayEvent(event, eventElement, seg); - } - eventElementHandlers(event, eventElement); - // needs to be after, because resizableDayEvent might stopImmediatePropagation on click - } - - function bindSlotSeg(event, eventElement, seg) { - var timeElement = eventElement.find('div.fc-event-time'); - if (isEventDraggable(event)) { - draggableSlotEvent(event, eventElement, timeElement); - } - if (seg.isEnd && isEventResizable(event)) { - resizableSlotEvent(event, eventElement, timeElement); - } - eventElementHandlers(event, eventElement); - } - - /* Dragging - -----------------------------------------------------------------------------------*/ - - // when event starts out FULL-DAY - - function draggableDayEvent(event, eventElement, isStart) { - var origWidth; - var revert; - var allDay=true; - var dayDelta; - var dis = opt('isRTL') ? -1 : 1; - var hoverListener = getHoverListener(); - var colWidth = getColWidth(); - var slotHeight = getSlotHeight(); - var minMinute = getMinMinute(); - eventElement.draggable({ - zIndex: 9, - scroll: false, - opacity: opt('dragOpacity', 'month'), // use whatever the month view was using - revertDuration: opt('dragRevertDuration'), - start: function(ev, ui) { - trigger('eventDragStart', eventElement, event, ev, ui); - //hideEvents(event, eventElement); - origWidth = eventElement.width(); - hoverListener.start(function(cell, origCell, rowDelta, colDelta) { - clearOverlays(); - if (cell) { - //setOverflowHidden(true); - revert = false; - dayDelta = colDelta * dis; - if (!cell.row) { - // on full-days - renderDayOverlay( - addDays(cloneDate(event.start), dayDelta), - addDays(exclEndDay(event), dayDelta) - ); - resetElement(); - }else{ - // mouse is over bottom slots - if (isStart) { - if (allDay) { - // convert event to temporary slot-event - eventElement.width(colWidth - 10); // don't use entire width - setOuterHeight( - eventElement, - slotHeight * Math.round( - (event.end ? ((event.end - event.start) / MINUTE_MS) : opt('defaultEventMinutes')) - / opt('slotMinutes') - ) - ); - eventElement.draggable('option', 'grid', [colWidth, 1]); - allDay = false; - } - else{ - var cellDate = t.cellDate; - if (cell && (cell.col == origCell.col || !opt('selectHelper'))) { - var d1 = cellDate(cell); - var duration = event.end ? minDiff(event.end, event.start) : opt('defaultEventMinutes'); - var d2 = addMinutes(cloneDate(d1, false), duration); - dates = [d1, d2].sort(cmp); - renderSlotSelection(dates[0], dates[1]); - } - } - - }else{ - revert = true; - } - } - revert = revert || (allDay && !dayDelta); - }else{ - resetElement(); - //setOverflowHidden(false); - revert = true; - } - eventElement.draggable('option', 'revert', revert); - }, ev, 'drag'); - }, - stop: function(ev, ui) { - hoverListener.stop(); - clearOverlays(); - trigger('eventDragStop', eventElement, event, ev, ui); - if (revert) { - // hasn't moved or is out of bounds (draggable has already reverted) - resetElement(); - eventElement.css('filter', ''); // clear IE opacity side-effects - //showEvents(event, eventElement); - }else{ - // changed! - var minuteDelta = 0; - if (!allDay) { - minuteDelta = Math.round((eventElement.offset().top - getBodyContent().offset().top) / slotHeight) - * opt('slotMinutes') - + minMinute - - (event.start.getHours() * 60 + event.start.getMinutes()); - } - eventDrop(this, event, dayDelta, minuteDelta, allDay, ev, ui); - } - //setOverflowHidden(false); - } - }); - function resetElement() { - if (!allDay) { - eventElement - .width(origWidth) - .height('') - .draggable('option', 'grid', null); - allDay = true; - } - } - } - - // when event starts out IN TIMESLOTS - - function draggableSlotEvent(event, eventElement, timeElement) { - var origPosition; - var allDay=false; - var dayDelta; - var minuteDelta; - var prevMinuteDelta; - var dis = opt('isRTL') ? -1 : 1; - var hoverListener = getHoverListener(); - var colCnt = getColCnt(); - var colWidth = getColWidth(); - var slotHeight = getSlotHeight(); - eventElement.draggable({ - zIndex: 9, - scroll: false, - grid: [colWidth, slotHeight], - axis: colCnt==1 ? 'y' : false, - opacity: opt('dragOpacity'), - revertDuration: opt('dragRevertDuration'), - start: function(ev, ui) { - trigger('eventDragStart', eventElement, event, ev, ui); - //hideEvents(event, eventElement); - origPosition = eventElement.position(); - minuteDelta = prevMinuteDelta = 0; - hoverListener.start(function(cell, origCell, rowDelta, colDelta) { - eventElement.draggable('option', 'revert', !cell); - clearOverlays(); - if (cell) { - dayDelta = colDelta * dis; - if (opt('allDaySlot') && !cell.row) { - // over full days - if (!allDay) { - // convert to temporary all-day event - allDay = true; - timeElement.hide(); - eventElement.draggable('option', 'grid', null); - } - renderDayOverlay( - addDays(cloneDate(event.start), dayDelta), - addDays(exclEndDay(event), dayDelta) - ); - }else{ - // on slots - resetElement(); - } - } - }, ev, 'drag'); - }, - drag: function(ev, ui) { - ui.position.left = origPosition.left + (dayDelta * dis) * colWidth; - minuteDelta = Math.round((ui.position.top - origPosition.top) / slotHeight) * opt('slotMinutes'); - if (minuteDelta != prevMinuteDelta) { - if (!allDay) { - updateTimeText(minuteDelta); - } - prevMinuteDelta = minuteDelta; - } - }, - stop: function(ev, ui) { - var cell = hoverListener.stop(); - clearOverlays(); - trigger('eventDragStop', eventElement, event, ev, ui); - if (cell && (dayDelta || minuteDelta || allDay)) { - // changed! - eventDrop(this, event, dayDelta, allDay ? 0 : minuteDelta, allDay, ev, ui); - }else{ - // either no change or out-of-bounds (draggable has already reverted) - resetElement(); - eventElement.css('filter', ''); // clear IE opacity side-effects - eventElement.css(origPosition); // sometimes fast drags make event revert to wrong position - updateTimeText(0); - //showEvents(event, eventElement); - } - } - }); - function updateTimeText(minuteDelta) { - var newStart = addMinutes(cloneDate(event.start), minuteDelta); - var newEnd; - if (event.end) { - newEnd = addMinutes(cloneDate(event.end), minuteDelta); - } - timeElement.text(formatDates(newStart, newEnd, opt('timeFormat'))); - } - function resetElement() { - // convert back to original slot-event - if (allDay) { - timeElement.css('display', ''); // show() was causing display=inline - eventElement.draggable('option', 'grid', [colWidth, slotHeight]); - allDay = false; - } - } - } - - /* Resizing - --------------------------------------------------------------------------------------*/ - - function resizableSlotEvent(event, eventElement, timeElement) { - var slotDelta, prevSlotDelta; - var slotHeight = getSlotHeight(); - eventElement.resizable({ - handles: { - s: 'div.ui-resizable-s' - }, - grid: slotHeight, - start: function(ev, ui) { - slotDelta = prevSlotDelta = 0; - //hideEvents(event, eventElement); - eventElement.css('z-index', 9); - trigger('eventResizeStart', this, event, ev, ui); - }, - resize: function(ev, ui) { - // don't rely on ui.size.height, doesn't take grid into account - slotDelta = Math.round((Math.max(slotHeight, eventElement.height()) - ui.originalSize.height) / slotHeight); - if (slotDelta != prevSlotDelta) { - timeElement.text( - formatDates( - event.start, - (!slotDelta && !event.end) ? null : // no change, so don't display time range - addMinutes(eventEnd(event), opt('slotMinutes')*slotDelta), - opt('timeFormat') - ) - ); - prevSlotDelta = slotDelta; - } - }, - stop: function(ev, ui) { - trigger('eventResizeStop', this, event, ev, ui); - - var minutesDelta = opt('slotMinutes')*slotDelta; - if(event.end===null) { - minutesDelta+=opt('defaultEventMinutes'); - } - - if (slotDelta) { - eventResize(this, event, 0, minutesDelta, ev, ui); - }else{ - eventElement.css('z-index', 8); - //showEvents(event, eventElement); - // BUG: if event was really short, need to put title back in span - } - } - }); - } -} - -function countForwardSegs(levels) { - var i, j, k, level, segForward, segBack; - for (i=levels.length-1; i>0; i--) { - level = levels[i]; - for (j=0; j<level.length; j++) { - segForward = level[j]; - for (k=0; k<levels[i-1].length; k++) { - segBack = levels[i-1][k]; - if (segsCollide(segForward, segBack)) { - segBack.forward = Math.max(segBack.forward||0, (segForward.forward||0)+1); - } - } - } - } -} - -function View(element, calendar, viewName) { - var t = this; - - // exports - t.element = element; - t.calendar = calendar; - t.name = viewName; - t.opt = opt; - t.trigger = trigger; - //t.setOverflowHidden = setOverflowHidden; - t.isEventDraggable = isEventDraggable; - t.isEventResizable = isEventResizable; - t.reportEvents = reportEvents; - t.eventEnd = eventEnd; - t.reportEventElement = reportEventElement; - t.reportEventClear = reportEventClear; - t.eventElementHandlers = eventElementHandlers; - t.showEvents = showEvents; - t.hideEvents = hideEvents; - t.eventDrop = eventDrop; - t.eventResize = eventResize; - t.selectedElement = null; - t.selectEvent = selectEvent; - // t.title - // t.start, t.end - // t.visStart, t.visEnd - - // imports - var defaultEventEnd = t.defaultEventEnd; - var normalizeEvent = calendar.normalizeEvent; // in EventManager - var reportEventChange = calendar.reportEventChange; - - // locals - var eventsByID = {}; - var eventElements = []; - var eventElementsByID = {}; - var options = calendar.options; - - function opt(name, viewNameOverride) { - var v = options[name]; - if (typeof v == 'object' && !v.length && !$.isArray(v)) { - return smartProperty(v, viewNameOverride || viewName); - } - return v; - } - - function trigger(name, thisObj) { - return calendar.trigger.apply( - calendar, - [name, thisObj || t].concat(Array.prototype.slice.call(arguments, 2), [t]) - ); - } - - function isEventDraggable(event) { - return isEventEditable(event) && !opt('disableDragging'); - } - - function isEventResizable(event) { // but also need to make sure the seg.isEnd == true - return isEventEditable(event) && !opt('disableResizing'); - } - - function isEventEditable(event) { - return firstDefined(event.editable, (event.source || {}).editable, opt('editable')); - } - - /* Event Data - ------------------------------------------------------------------------------*/ - - // report when view receives new events - function reportEvents(events) { // events are already normalized at this point - eventsByID = {}; - var i, len=events.length, event; - for (i=0; i<len; i++) { - event = events[i]; - if (eventsByID[event._id]) { - eventsByID[event._id].push(event); - }else{ - eventsByID[event._id] = [event]; - } - } - } - - // returns a Date object for an event's end - function eventEnd(event) { - return event.end ? cloneDate(event.end) : defaultEventEnd(event); - } - - /* Event Elements - ------------------------------------------------------------------------------*/ - - // report when view creates an element for an event - function reportEventElement(event, element) { - eventElements.push(element); - if (eventElementsByID[event._id]) { - eventElementsByID[event._id].push(element); - }else{ - eventElementsByID[event._id] = [element]; - } - } - - function reportEventClear() { - eventElements = []; - eventElementsByID = {}; - } - - // attaches eventClick, eventMouseover, eventMouseout - function eventElementHandlers(event, eventElement) { - eventElement - .click(function(ev) { - if (!eventElement.hasClass('ui-draggable-dragging') && - !eventElement.hasClass('ui-resizable-resizing')) { - selectEvent(eventElement, true); - return trigger('eventClick', this, event, ev); - } - }) - .hover( - function(ev) { - trigger('eventMouseover', this, event, ev); - }, - function(ev) { - trigger('eventMouseout', this, event, ev); - } - ); - - eventElement.find('.fc-event-checkbox').click(function(ev) { - trigger('eventCheckClicked', this, $(this), event, ev); - }); - // TODO: don't fire eventMouseover/eventMouseout *while* dragging is occuring (on subject element) - // TODO: same for resizing - } - - function selectEvent(eventElement, noClick) { - if(t.name!='todo' || t.eventSelectLock<0) { - return false; - } - - if(typeof eventElement=='undefined' || eventElement==null || eventElement.length==0) { - eventElement=t.getDaySegmentContainer().find($('.fc-event[data-repeat-hash="'+t.selectedElement+'"]:visible')); - } - - if(eventElement.length==0) { - eventElement=t.element.find('.fc-event:visible:first'); - } - - if(eventElement.length==0) { - trigger('selectEmpty'); - return false; - } - - t.selectedElement=eventElement.attr('data-repeat-hash'); - t.element.find('.fc-event-selected').removeClass('fc-event-selected'); - eventElement.addClass('fc-event-selected'); - - var offset=eventElement.position().top; - if(offset<eventElement.outerHeight() || offset>t.getDaySegmentContainer().parent().height()) - { - var top=t.getDaySegmentContainer().parent().scrollTop(); - t.getDaySegmentContainer().parent().scrollTop(top+offset-(t.getDaySegmentContainer().parent().height()*0.2)); - } - - // Force event click callback, although its not pretty - if(!noClick) { - eventElement.trigger('mouseover').trigger('click'); - } - } - - function showEvents(event, exceptElement) { - eachEventElement(event, exceptElement, 'show'); - } - - function hideEvents(event, exceptElement) { - eachEventElement(event, exceptElement, 'hide'); - } - - function eachEventElement(event, exceptElement, funcName) { - event[funcName](); -// var elements = eventElementsByID[event._id], -// i, len = elements.length; -// for (i=0; i<len; i++) { -// if (!exceptElement || elements[i][0] != exceptElement[0]) { -// elements[i][funcName](); -// } -// } - } - - /* Event Modification Reporting - ---------------------------------------------------------------------------------*/ - - function eventDrop(e, event, dayDelta, minuteDelta, allDay, ev, ui) { - var oldAllDay = event.allDay; - var eventId = event._id; - //moveEvents(eventsByID[eventId], dayDelta, minuteDelta, allDay); - moveEvents([event], dayDelta, minuteDelta, allDay); - trigger( - 'eventDrop', - e, - event, - dayDelta, - minuteDelta, - allDay, - function() { - // TODO: investigate cases where this inverse technique might not work - //moveEvents(eventsByID[eventId], -dayDelta, -minuteDelta, oldAllDay); - moveEvents([event], -dayDelta, -minuteDelta, oldAllDay); - reportEventChange(eventId); - }, - ev, - ui - ); - reportEventChange(eventId); - } - - function eventResize(e, event, dayDelta, minuteDelta, ev, ui) { - var eventId = event._id; - //elongateEvents(eventsByID[eventId], dayDelta, minuteDelta); - elongateEvents([event], dayDelta, minuteDelta); - trigger( - 'eventResize', - e, - event, - dayDelta, - minuteDelta, - function() { - // TODO: investigate cases where this inverse technique might not work - //elongateEvents(eventsByID[eventId], -dayDelta, -minuteDelta); - elongateEvents([event], -dayDelta, -minuteDelta); - reportEventChange(eventId); - }, - ev, - ui - ); - reportEventChange(eventId); - } - - /* Event Modification Math - ---------------------------------------------------------------------------------*/ - - function moveEvents(events, dayDelta, minuteDelta, allDay) { - minuteDelta = minuteDelta || 0; - for (var e, len=events.length, i=0; i<len; i++) { - e = events[i]; - if (allDay !== undefined) { - e.allDay = allDay; - } - addMinutes(addDays(e.start, dayDelta, true), minuteDelta); - if (e.end) { - e.end = addMinutes(addDays(e.end, dayDelta, true), minuteDelta); - } - normalizeEvent(e, options); - } - } - - function elongateEvents(events, dayDelta, minuteDelta) { - minuteDelta = minuteDelta || 0; - for (var e, len=events.length, i=0; i<len; i++) { - e = events[i]; - e.end = addMinutes(addDays(eventEnd(e), dayDelta, true), minuteDelta); - normalizeEvent(e, options); - } - } - -} - -function DayEventRenderer() { - var t = this; - - // exports - t.renderDaySegs = renderDaySegs; - t.resizableDayEvent = resizableDayEvent; - - // imports - var opt = t.opt; - var trigger = t.trigger; - var isEventDraggable = t.isEventDraggable; - var isEventResizable = t.isEventResizable; - var eventEnd = t.eventEnd; - var reportEventElement = t.reportEventElement; - var showEvents = t.showEvents; - var hideEvents = t.hideEvents; - var eventResize = t.eventResize; - var getRowCnt = t.getRowCnt; - var getColCnt = t.getColCnt; - var getColWidth = t.getColWidth; - var allDayRow = t.allDayRow; - var allDayBounds = t.allDayBounds; - var colContentLeft = t.colContentLeft; - var colContentRight = t.colContentRight; - var dayOfWeekCol = t.dayOfWeekCol; - var dateCell = t.dateCell; - var compileDaySegs = t.compileDaySegs; - var getDaySegmentContainer = t.getDaySegmentContainer; - var bindDaySeg = t.bindDaySeg; //TODO: streamline this - var formatDates = t.calendar.formatDates; - var renderDayOverlay = t.renderDayOverlay; - var clearOverlays = t.clearOverlays; - var clearSelection = t.clearSelection; - - /* Rendering - -----------------------------------------------------------------------------*/ - - function renderDaySegs(segs, modifiedEventId, isAllDay) { - var segmentContainer = getDaySegmentContainer(); - var rowDivs; - var rowCnt = getRowCnt(); - var colCnt = getColCnt(); - var i = 0; - var rowI; - var levelI; - var colHeights; - var j; - var segCnt = segs.length; - var seg; - var top; - var k; - segmentContainer[0].innerHTML = daySegHTML(segs); // faster than .html() - daySegElementResolve(segs, segmentContainer.children()); - daySegElementReport(segs); - daySegHandlers(segs, segmentContainer, modifiedEventId); - daySegCalcHSides(segs); - daySegSetWidths(segs); - daySegCalcHeights(segs); - rowDivs = getRowDivs(); - // set row heights, calculate event tops (in relation to row top) - for (rowI=0; rowI<rowCnt; rowI++) { - levelI = 0; - colHeights = []; - for (j=0; j<colCnt; j++) { - colHeights[j] = 0; - } - while (i<segCnt && (seg = segs[i]).row == rowI) { - // loop through segs in a row - top = arrayMax(colHeights.slice(seg.startCol, seg.endCol)); - seg.top = top; - if (typeof seg.outerHeight != "undefined") top += seg.outerHeight; - for (k=seg.startCol; k<seg.endCol; k++) { - colHeights[k] = top; - } - i++; - } - if(isAllDay) { - segmentContainer.parent().height(arrayMax(colHeights) ? arrayMax(colHeights) + 3 : 0); - } - rowDivs[rowI].height(arrayMax(colHeights)); - } - daySegSetTops(segs, getRowTops(rowDivs)); - - $('.fc-source-bg', t.element).removeClass('fc-source-bg'); - if(!isAllDay) { // month or multiweek view - for (i=0; i<segCnt; i++) { - seg = segs[i]; - if(seg.event.source && seg.event.source.background) { - for(c=seg.startCol; c<seg.endCol; c++) { - $('td.fc-day' + (seg.row*7+c), t.element).addClass('fc-source-bg'); - } - } - } - } - else { // agenda views - for (i=0; i<segCnt; i++) { - seg = segs[i]; - if(seg.event.source && seg.event.source.background) { - for(c=seg.startCol; c<seg.endCol; c++) { - $('td.fc-col' + c, t.element).addClass('fc-source-bg'); - } - } - } - } - } - - function renderTempDaySegs(segs, adjustRow, adjustTop) { - var tempContainer = $("<div/>"); - var elements; - var segmentContainer = getDaySegmentContainer(); - var i; - var segCnt = segs.length; - var element; - tempContainer[0].innerHTML = daySegHTML(segs); // faster than .html() - elements = tempContainer.children(); - segmentContainer.append(elements); - daySegElementResolve(segs, elements); - daySegCalcHSides(segs); - daySegSetWidths(segs); - daySegCalcHeights(segs); - daySegSetTops(segs, getRowTops(getRowDivs())); - elements = []; - for (i=0; i<segCnt; i++) { - element = segs[i].element; - if (element) { - if (segs[i].row === adjustRow) { - element.css('top', adjustTop); - } - elements.push(element[0]); - } - } - return $(elements); - } - - function daySegHTML(segs) { // also sets seg.left and seg.outerWidth - var rtl = opt('isRTL'); - var i; - var segCnt=segs.length; - var seg; - var event; - var url; - var classes; - var bounds = allDayBounds(); - var minLeft = bounds.left; - var maxLeft = bounds.right; - var leftCol; - var rightCol; - var left; - var right; - var titleWidth; - var skinCss; - var html = ''; - // calculate desired position/dimensions, create html - for (i=0; i<segCnt; i++) { - seg = segs[i]; - event = seg.event; - classes = ['fc-event', 'fc-event-skin', 'fc-event-hori']; - if (isEventDraggable(event)) { - classes.push('fc-event-draggable'); - } - if (rtl) { - if (seg.isStart) { - classes.push('fc-corner-right'); - } - if (seg.isEnd) { - classes.push('fc-corner-left'); - } - leftCol = dayOfWeekCol(seg.end.getDay()-1); - rightCol = dayOfWeekCol(seg.start.getDay()); - left = seg.isEnd ? colContentLeft(leftCol) : minLeft; - right = seg.isStart ? colContentRight(rightCol) : maxLeft; - }else{ - if (seg.isStart) { - classes.push('fc-corner-left'); - } - if (seg.isEnd) { - classes.push('fc-corner-right'); - } - leftCol = dayOfWeekCol(seg.start.getDay()); - rightCol = dayOfWeekCol(seg.end.getDay()-1); - left = seg.isStart ? colContentLeft(leftCol) : minLeft; - right = seg.isEnd ? colContentRight(rightCol) : maxLeft; - } - titleWidth = right - left - 2 - 2 - 2; - classes = classes.concat(event.className); - if (event.source) { - classes = classes.concat(event.source.className || []); - } - url = event.url; - skinCss = getSkinCss(event, opt); - if (url) { - html += "<a href='" + htmlEscape(url) + "'"; - }else{ - html += "<div"; - } - html += - " class='" + classes.join(' ') + "'" + - " style='position:absolute;z-index:8;left:"+left+"px;" + skinCss + "'" + - ">" + - "<div" + - " class='fc-event-inner fc-event-skin'" + - " style='width:" + titleWidth + "px;z-index:inherit;" + - (skinCss ? skinCss : '') + - "'" + - //(skinCss ? " style='" + skinCss + "'" : '') + - ">"; - if (opt('dayEventSizeStrict')) { - html += "<div class='fc-event-title-strict'>"; - } - if (!event.allDay && seg.isStart && opt('timeFormat')) { - html += - "<span class='fc-event-time'>" + - htmlEscape(formatDates(event.start, event.end, opt('timeFormat'))) + - "</span>"; - } - html += "<span class='fc-event-title'>" + htmlEscape(event.title.replace(/(\r\n|\n|\r)+/gm," ")) + "</span>"; - if (opt('dayEventSizeStrict')) { - html += "</div>"; - } - html += "</div>"; - if (seg.isEnd && isEventResizable(event)) { - html += - "<div class='ui-resizable-handle ui-resizable-" + (rtl ? 'w' : 'e') + "'>" + - " " + // makes hit area a lot better for IE6/7 - "</div>"; - } - html += - "<div class='fc-event-bg'></div>" + - "</" + (url ? "a" : "div" ) + ">"; - seg.left = left; - seg.outerWidth = right - left; - seg.startCol = leftCol; - seg.endCol = rightCol + 1; // needs to be exclusive - } - return html; - } - - function daySegElementResolve(segs, elements) { // sets seg.element - var i; - var segCnt = segs.length; - var seg; - var event; - var element; - var triggerRes; - for (i=0; i<segCnt; i++) { - seg = segs[i]; - event = seg.event; - element = $(elements[i]); // faster than .eq() - triggerRes = trigger('eventRender', event, event, element); - if (triggerRes === false) { - element.remove(); - }else{ - if (triggerRes && triggerRes !== true) { - triggerRes = $(triggerRes) - .css({ - position: 'absolute', - left: seg.left - }); - element.replaceWith(triggerRes); - element = triggerRes; - } - seg.element = element; - } - } - } - - - function daySegElementReport(segs) { - var i; - var segCnt = segs.length; - var seg; - var element; - for (i=0; i<segCnt; i++) { - seg = segs[i]; - element = seg.element; - if (element) { - reportEventElement(seg.event, element); - } - } - } - - - function daySegHandlers(segs, segmentContainer, modifiedEventId) { - var i; - var segCnt = segs.length; - var seg; - var element; - var event; - // retrieve elements, run through eventRender callback, bind handlers - for (i=0; i<segCnt; i++) { - seg = segs[i]; - element = seg.element; - if (element) { - event = seg.event; - if (event._id === modifiedEventId) { - bindDaySeg(event, element, seg); - }else{ - element[0]._fci = i; // for lazySegBind - } - } - } - lazySegBind(segmentContainer, segs, bindDaySeg); - } - - - function daySegCalcHSides(segs) { // also sets seg.key - var i; - var segCnt = segs.length; - var seg; - var element; - var key, val; - var hsideCache = {}; - // record event horizontal sides - for (i=0; i<segCnt; i++) { - seg = segs[i]; - element = seg.element; - if (element) { - key = seg.key = cssKey(element[0]); - val = hsideCache[key]; - if (val === undefined) { - val = hsideCache[key] = hsides(element, true); - } - seg.hsides = val; - } - } - } - - - function daySegSetWidths(segs) { - var i; - var segCnt = segs.length; - var seg; - var element; - for (i=0; i<segCnt; i++) { - seg = segs[i]; - element = seg.element; - if (element) { - element[0].style.width = Math.max(0, seg.outerWidth - seg.hsides) + 'px'; - } - } - } - - - function daySegCalcHeights(segs) { - var i; - var segCnt = segs.length; - var seg; - var element; - var key, val; - var vmarginCache = {}; - // record event heights - for (i=0; i<segCnt; i++) { - seg = segs[i]; - element = seg.element; - if (element) { - key = seg.key; // created in daySegCalcHSides - val = vmarginCache[key]; - if (val === undefined) { - val = vmarginCache[key] = vmargins(element); - } - seg.outerHeight = element[0].offsetHeight + val; - } - else // always set a value (issue #1108 ) - seg.outerHeight = 0; - } - } - - - function getRowDivs() { - var i; - var rowCnt = getRowCnt(); - var rowDivs = []; - for (i=0; i<rowCnt; i++) { - rowDivs[i] = allDayRow(i) - .find('td:first div.fc-day-content > div'); // optimal selector? - } - return rowDivs; - } - - - function getRowTops(rowDivs) { - var i; - var rowCnt = rowDivs.length; - var tops = []; - for (i=0; i<rowCnt; i++) { - tops[i] = rowDivs[i][0].offsetTop; // !!?? but this means the element needs position:relative if in a table cell!!!! - } - return tops; - } - - - function daySegSetTops(segs, rowTops) { // also triggers eventAfterRender - var i; - var segCnt = segs.length; - var seg; - var element; - var event; - for (i=0; i<segCnt; i++) { - seg = segs[i]; - element = seg.element; - if (element) { - element[0].style.top = rowTops[seg.row] + (seg.top||0) + 'px'; - event = seg.event; - trigger('eventAfterRender', event, event, element); - } - } - } - - /* Resizing - -----------------------------------------------------------------------------------*/ - - function resizableDayEvent(event, element, seg) { - var rtl = opt('isRTL'); - var direction = rtl ? 'w' : 'e'; - var handle = element.find('div.ui-resizable-' + direction); - var isResizing = false; - - // TODO: look into using jquery-ui mouse widget for this stuff - disableTextSelection(element); // prevent native <a> selection for IE - element - .mousedown(function(ev) { // prevent native <a> selection for others - ev.preventDefault(); - }) - .click(function(ev) { - if (isResizing) { - ev.preventDefault(); // prevent link from being visited (only method that worked in IE6) - ev.stopImmediatePropagation(); // prevent fullcalendar eventClick handler from being called - // (eventElementHandlers needs to be bound after resizableDayEvent) - } - }); - - handle.mousedown(function(ev) { - if (ev.which != 1) { - return; // needs to be left mouse button - } - isResizing = true; - var hoverListener = t.getHoverListener(); - var rowCnt = getRowCnt(); - var colCnt = getColCnt(); - var dis = rtl ? -1 : 1; - var dit = rtl ? colCnt-1 : 0; - var elementTop = element.css('top'); - var dayDelta; - var helpers; - var eventCopy = $.extend({}, event); - var minCell = dateCell(event.start); - clearSelection(); - $('body') - .css('cursor', direction + '-resize') - .one('mouseup', mouseup); - trigger('eventResizeStart', this, event, ev); - hoverListener.start(function(cell, origCell) { - if (cell) { - var r = Math.max(minCell.row, cell.row); - var c = cell.col; - if (rowCnt == 1) { - r = 0; // hack for all-day area in agenda views - } - if (r == minCell.row) { - if (rtl) { - c = Math.min(minCell.col, c); - }else{ - c = Math.max(minCell.col, c); - } - } - dayDelta = (r*7 + c*dis+dit) - (origCell.row*7 + origCell.col*dis+dit); - var newEnd = addDays(eventEnd(event), dayDelta, true); - if (dayDelta) { - eventCopy.end = newEnd; - var oldHelpers = helpers; - helpers = renderTempDaySegs(compileDaySegs([eventCopy]), seg.row, elementTop); - helpers.find('*').css('cursor', direction + '-resize'); - trigger('eventResizeHelperCreated', this, event, ev, element, helpers); - if (oldHelpers) { - oldHelpers.remove(); - } - //hideEvents(event); - hideEvents(element); - }else{ - if (helpers) { - //showEvents(event); - showEvents(element); - helpers.remove(); - helpers = null; - } - } - clearOverlays(); - renderDayOverlay(event.start, addDays(cloneDate(newEnd), 1)); // coordinate grid already rebuild at hoverListener.start - } - }, ev); - - function mouseup(ev) { - trigger('eventResizeStop', this, event, ev); - $('body').css('cursor', ''); - hoverListener.stop(); - clearOverlays(); - if (dayDelta) { - eventResize(this, event, dayDelta, 0, ev); - // event redraw will clear helpers - } - // otherwise, the drag handler already restored the old events - - setTimeout(function() { // make this happen after the element's click event - isResizing = false; - },0); - } - - }); - } - - -} - -//BUG: unselect needs to be triggered when events are dragged+dropped - -function SelectionManager() { - var t = this; - - - // exports - t.select = select; - t.unselect = unselect; - t.reportSelection = reportSelection; - t.daySelectionMousedown = daySelectionMousedown; - - - // imports - var opt = t.opt; - var trigger = t.trigger; - var defaultSelectionEnd = t.defaultSelectionEnd; - var renderSelection = t.renderSelection; - var clearSelection = t.clearSelection; - - - // locals - var selected = false; - - - - // unselectAuto - if (opt('selectable') && opt('unselectAuto')) { - $(document).mousedown(function(ev) { - var ignore = opt('unselectCancel'); - if (ignore) { - if ($(ev.target).parents(ignore).length) { // could be optimized to stop after first match - return; - } - } - unselect(ev); - }); - } - - - function select(startDate, endDate, allDay) { - unselect(); - if (!endDate) { - endDate = defaultSelectionEnd(startDate, allDay); - } - renderSelection(startDate, endDate, allDay); - reportSelection(startDate, endDate, allDay); - } - - - function unselect(ev) { - if (selected) { - selected = false; - clearSelection(); - trigger('unselect', null, ev); - } - } - - - function reportSelection(startDate, endDate, allDay, ev) { - selected = true; - trigger('select', null, startDate, endDate, allDay, ev); - } - - - function daySelectionMousedown(ev) { // not really a generic manager method, oh well - var cellDate = t.cellDate; - var cellIsAllDay = t.cellIsAllDay; - var hoverListener = t.getHoverListener(); - var reportDayClick = t.reportDayClick; // this is hacky and sort of weird - if (ev.which == 1 && opt('selectable')) { // which==1 means left mouse button - unselect(ev); - var _mousedownElement = this; - var dates; - hoverListener.start(function(cell, origCell) { // TODO: maybe put cellDate/cellIsAllDay info in cell - clearSelection(); - if (cell && cellIsAllDay(cell)) { - dates = [ cellDate(origCell), cellDate(cell) ].sort(cmp); - renderSelection(dates[0], dates[1], true); - }else{ - dates = null; - } - }, ev); - $(document).one('mouseup', function(ev) { - hoverListener.stop(); - if (dates) { - if (+dates[0] == +dates[1]) { - //reportDayClick(dates[0], true, ev); - } - reportSelection(dates[0], dates[1], true, ev); - } - }); - } - } - - -} - -function OverlayManager() { - var t = this; - - - // exports - t.renderOverlay = renderOverlay; - t.clearOverlays = clearOverlays; - - - // locals - var usedOverlays = []; - var unusedOverlays = []; - - - function renderOverlay(rect, parent) { - var e = unusedOverlays.shift(); - if (!e) { - e = $("<div class='fc-cell-overlay' style='position:absolute;z-index:3'/>"); - } - if (e[0].parentNode != parent[0]) { - e.appendTo(parent); - } - usedOverlays.push(e.css(rect).show()); - return e; - } - - - function clearOverlays() { - var e; - while (e = usedOverlays.shift()) { - unusedOverlays.push(e.hide().unbind()); - } - } - - -} - -function CoordinateGrid(buildFunc) { - var t = this; - var rows; - var cols; - - t.build = function() { - rows = []; - cols = []; - buildFunc(rows, cols); - }; - - t.cell = function(x, y) { - var rowCnt = rows.length; - var colCnt = cols.length; - var i, r=-1, c=-1; - for (i=0; i<rowCnt; i++) { - if (y >= rows[i][0] && y < rows[i][1]) { - r = i; - break; - } - } - for (i=0; i<colCnt; i++) { - if (x >= cols[i][0] && x < cols[i][1]) { - c = i; - break; - } - } - return (r>=0 && c>=0) ? { row:r, col:c } : null; - }; - - t.rect = function(row0, col0, row1, col1, originElement) { // row1,col1 is inclusive - var origin = originElement.offset(); - return { - top: rows[row0][0] - origin.top, - left: cols[col0][0] - origin.left, - width: cols[col1][1] - cols[col0][0], - height: rows[row1][1] - rows[row0][0] - }; - }; -} - -function HoverListener(coordinateGrid) { - - var t = this; - var bindType; - var change; - var firstCell; - var cell; - var origEvent; - - t.start = function(_change, ev, _bindType) { - origEvent = ev; - change = _change; - firstCell = cell = null; - coordinateGrid.build(); - mouse(ev); - bindType = _bindType || 'mousemove'; - $(document).bind(bindType, mouse); - }; - - function mouse(ev) { - _fixUIEvent(ev); // see below - if(origEvent.pageX - ev.pageX == 0 && origEvent.pageY - ev.pageY == 0) { - return false; - } - var newCell = coordinateGrid.cell(ev.pageX, ev.pageY); - if (!newCell != !cell || newCell && (newCell.row != cell.row || newCell.col != cell.col)) { - if (newCell) { - if (!firstCell) { - firstCell = newCell; - } - change(newCell, firstCell, newCell.row-firstCell.row, newCell.col-firstCell.col); - }else{ - change(newCell, firstCell); - } - cell = newCell; - } - } - - t.stop = function() { - $(document).unbind(bindType, mouse); - return cell; - }; -} - -// this fix was only necessary for jQuery UI 1.8.16 (and jQuery 1.7 or 1.7.1) -// upgrading to jQuery UI 1.8.17 (and using either jQuery 1.7 or 1.7.1) fixed the problem -// but keep this in here for 1.8.16 users -// and maybe remove it down the line - -function _fixUIEvent(event) { // for issue 1168 - if (event.pageX === undefined) { - event.pageX = event.originalEvent.pageX; - event.pageY = event.originalEvent.pageY; - } -} -function HorizontalPositionCache(getElement) { - - var t = this, - elements = {}, - lefts = {}, - rights = {}; - - function e(i) { - return elements[i] = elements[i] || getElement(i); - } - - t.left = function(i) { - return lefts[i] = lefts[i] === undefined ? e(i).position().left : lefts[i]; - }; - - t.right = function(i) { - return rights[i] = rights[i] === undefined ? t.left(i) + e(i).width() : rights[i]; - }; - - t.clear = function() { - elements = {}; - lefts = {}; - rights = {}; - }; -} - -function addTodayText(cell, todayText) -{ - target = cell.find(".fc-day-text"); - target.html(todayText); -} - -function removeTodayText(cell, todayText) -{ - target = cell.find(".fc-day-text"); - target.html(''); -} - -function addWeekNumber(cell, date) -{ - target = cell.find(".fc-week-number"); - target.html(getWeekNumber(date)); -} - -function removeWeekNumber(cell, date) -{ - target = cell.find(".fc-week-number"); - target.html(''); -} - -function addTodayClass(cell) -{ - var classes = cell.attr('class').split(' '); - var filter = ['fc-state-highlight', 'fc-today', 'fc-widget-content', 'fc-source-bg']; - classes = $.grep(classes, function(el) { - if ($.inArray(el, filter) > -1) { - return false; - } - - return true; - }); - classes.push('fc-widget-header'); - var target = $('.' + classes.join('.')); - target.addClass('fc-today'); -} - -function removeTodayClass(cell) -{ - var classes = cell.attr('class').split(' '); - var filter = ['fc-state-highlight', 'fc-today', 'fc-widget-content', 'fc-source-bg']; - classes = $.grep(classes, function(el) { - if ($.inArray(el, filter) > -1) { - return false; - } - return true; - }); - classes.push('fc-widget-header'); - var target = $('.' + classes.join('.')); - target.removeClass('fc-today'); -} - -function getWeekNumber(date) { - //By tanguy.pruvot at gmail.com (2010) - - //first week of year always contains 4th Jan, or 28 Dec (ISO) - - var jan4 = new Date(date.getFullYear(),0,4 ,date.getHours()); - - //ISO weeks numbers begins on monday, so rotate monday:sunday to 0:6 - var jan4Day = (jan4.getDay() - 1 + 7) % 7; - - var days = Math.round((date - jan4) / 86400000); - var week = Math.floor((days + jan4Day ) / 7)+1; - - //special cases - var thisDay = (date.getDay() - 1 + 7) % 7; - if (date.getMonth()==11 && date.getDate() >= 28) { - - jan4 = new Date(date.getFullYear()+1,0,4 ,date.getHours()); - jan4Day = (jan4.getDay() - 1 + 7) % 7; - - if (thisDay < jan4Day) return 1; - - var prevWeek = new Date(date.valueOf()-(86400000*7)); - return getWeekNumber(prevWeek) + 1; - } - - if (week == 0 && thisDay > 3 && date.getMonth()==0) { - var prevWeek = new Date(date.valueOf()-(86400000*7)); - return getWeekNumber(prevWeek) + 1; - } - - return week; -} - -/* Additional view: list (by bruederli@kolabsys.com) ----------------------------------------------------------------------------------*/ - -function ListEventRenderer() { - var t = this; - - // exports - t.renderEvents = renderEvents; - t.renderEventTime = renderEventTime; - t.compileDaySegs = compileSegs; // for DayEventRenderer - t.clearEvents = clearEvents; - t.lazySegBind = lazySegBind; - t.sortCmp = sortCmp; - - // imports - DayEventRenderer.call(t); - var opt = t.opt; - var trigger = t.trigger; - var reportEvents = t.reportEvents; - var reportEventClear = t.reportEventClear; - var reportEventElement = t.reportEventElement; - var eventElementHandlers = t.eventElementHandlers; - var showEvents = t.showEvents; - var hideEvents = t.hideEvents; - var getListContainer = t.getDaySegmentContainer; - var calendar = t.calendar; - var formatDate = calendar.formatDate; - var formatDates = calendar.formatDates; - - - /* Rendering - --------------------------------------------------------------------*/ - - function clearEvents() { - reportEventClear(); - getListContainer().empty(); - } - - function renderEvents(events, modifiedEventId) { - events.sort(sortCmp); - reportEvents(events); - renderSegs(compileSegs(events), modifiedEventId); - } - - /*function compileSegs(events) { - var segs = []; - var colFormat = opt('titleFormat', 'day'); - var firstDay = opt('firstDay'); - var segmode = opt('listSections'); - var event, i, dd, wd, md, seg, segHash, curSegHash, segDate, curSeg = -1; - var today = clearTime(new Date()); - var weekstart = addDays(cloneDate(today), -((today.getDay() - firstDay + 7) % 7)); - - for (i=0; i < events.length; i++) { - event = events[i]; - var eventEnd = event.end ? cloneDate(event.end) : cloneDate(event.start); - - // skip events out of range - if (eventEnd < t.start || event.start > t.visEnd) - continue; - - // define sections of this event - // create smart sections such as today, tomorrow, this week, next week, next month, ect. - segDate = cloneDate(event.start < t.start && eventEnd > t.start ? t.start : event.start, true); - dd = dayDiff(segDate, today); - wd = Math.floor(dayDiff(segDate, weekstart) / 7); - md = segDate.getMonth() + ((segDate.getYear() - today.getYear()) * 12) - today.getMonth(); - - // build section title - if (segmode == 'smart') { - if (dd < 0) { - segHash = opt('listTexts', 'past'); - } else if (dd == 0) { - segHash = opt('listTexts', 'today'); - } else if (dd == 1) { - segHash = opt('listTexts', 'tomorrow'); - } else if (wd == 0) { - segHash = opt('listTexts', 'thisWeek'); - } else if (wd == 1) { - segHash = opt('listTexts', 'nextWeek'); - } else if (md == 0) { - segHash = opt('listTexts', 'thisMonth'); - } else if (md == 1) { - segHash = opt('listTexts', 'nextMonth'); - } else if (md > 1) { - segHash = opt('listTexts', 'future'); - } - } else if (segmode == 'month') { - segHash = formatDate(segDate, 'MMMM yyyy'); - } else if (segmode == 'week') { - segHash = opt('listTexts', 'week') + formatDate(segDate, ' W'); - } else if (segmode == 'day') { - segHash = formatDate(segDate, colFormat); - } else { - segHash = ''; - } - - // start new segment - if (segHash != curSegHash) { - segs[++curSeg] = { events: [], start: segDate, title: segHash, daydiff: dd, weekdiff: wd, monthdiff: md }; - curSegHash = segHash; - } - - segs[curSeg].events.push(event); - } - - return segs; - }*/ - -function compileSegs(events) { - var segs = {}; - var colFormat = opt('columnFormat', t.name); - var firstDay = opt('firstDay'); - var segmode = opt('listSections'); - var event, i, j, dd, wd, md, seg, segHash, segDate; - var today = clearTime(new Date()); - var weekstart = addDays(cloneDate(today), -((today.getDay() - firstDay + 7) % 7)); - - for (i=0; i < events.length; i++) { - event = events[i]; - var eventEnd = event.end ? cloneDate(event.end) : cloneDate(event.start); - - // skip events out of range - if (eventEnd < t.start || event.start > t.visEnd) - continue; - - var boundEventStart = cloneDate(event.start < t.start ? t.start : event.start, true); - var boundEventEnd = cloneDate(eventEnd > t.visEnd ? t.visEnd : eventEnd, true); - var dayDuration = dayDiff(boundEventEnd, boundEventStart); - - for(j = 0; j <= dayDuration; j++) { - segDate = cloneDate(boundEventStart); - segDate.setDate(segDate.getDate() + j); - - // define sections of this event - // create smart sections such as today, tomorrow, this week, next week, next month, ect. - //segDate = cloneDate(event.start < t.start && eventEnd > t.start ? t.start : event.start, true); - dd = dayDiff(segDate, today); - wd = Math.floor(dayDiff(segDate, weekstart) / 7); - md = segDate.getMonth() + ((segDate.getYear() - today.getYear()) * 12) - today.getMonth(); - - // build section title - if (segmode == 'smart') { - if (dd < 0) { - segHash = opt('listTexts', 'past'); - } else if (dd == 0) { - segHash = opt('listTexts', 'today'); - } else if (dd == 1) { - segHash = opt('listTexts', 'tomorrow'); - } else if (wd == 0) { - segHash = opt('listTexts', 'thisWeek'); - } else if (wd == 1) { - segHash = opt('listTexts', 'nextWeek'); - } else if (md == 0) { - segHash = opt('listTexts', 'thisMonth'); - } else if (md == 1) { - segHash = opt('listTexts', 'nextMonth'); - } else if (md > 1) { - segHash = opt('listTexts', 'future'); - } - } else if (segmode == 'month') { - segHash = formatDate(segDate, 'MMMM yyyy'); - } else if (segmode == 'week') { - segHash = opt('listTexts', 'week') + formatDate(segDate, ' W'); - } else if (segmode == 'day') { - segHash = formatDate(segDate, colFormat); - } else { - segHash = ''; - } - - // start new segment - if (!(segHash in segs)) { - segs[segHash] = { events: [], start: segDate, title: segHash, daydiff: dd, weekdiff: wd, monthdiff: md }; - } - - segs[segHash].events.push(event); - } - } - - return segs; - } - - function sortCmp(a, b) { - /*var datediff = 0; - if(a.start != null && b.start != null) { - datediff = a.start.getTime() - b.start.getTime(); - } - if(datediff == 0 && a.end != null && b.end != null) { - datediff = a.end.getTime() - b.end.getTime(); - } - return datediff;*/ - var retVal = a.start.getTime() - b.start.getTime(); - - if(retVal == 0) { - var aEnd = a.end ? a.end : a.start; - var bEnd = b.end ? b.end : b.start; - retVal = aEnd.getTime() - bEnd.getTime(); - } - - if(retVal == 0) { - if(a.compareString < b.compareString) { - retVal = -1; - } - else if(b.compareString < a.compareString) { - retVal = 1; - } - } - return retVal; - } - - function renderSegs(segs, modifiedEventId) { - var tm = opt('theme') ? 'ui' : 'fc'; - var headerClass = tm + "-widget-header"; - var contentClass = tm + "-widget-content"; - var i, j, seg, event, times, s, skinCss, skinCssAttr, classes, segContainer, eventElement, eventElements, triggerRes; - - for (j=0; j < segs.length; j++) { - seg = segs[j]; - - if (seg.title) { - $('<div class="fc-list-header ' + headerClass + '">' + htmlEscape(seg.title) + '</div>').appendTo(getListContainer()); - } - segContainer = $('<div>').addClass('fc-list-section ' + contentClass).appendTo(getListContainer()); - s = ''; - - for (i=0; i < seg.events.length; i++) { - event = seg.events[i]; - times = renderEventTime(event, seg); - skinCss = getSkinCss(event, opt); - skinCssAttr = (skinCss ? " style='" + skinCss + "'" : ''); - classes = ['fc-event', 'fc-event-skin', 'fc-event-vert', 'fc-corner-top', 'fc-corner-bottom'].concat(event.className); - if (event.source && event.source.className) { - classes = classes.concat(event.source.className); - } - - s += - "<div class='" + classes.join(' ') + "'" + skinCssAttr + ">" + - "<div class='fc-event-inner fc-event-skin'" + skinCssAttr + ">" + - "<div class='fc-event-head fc-event-skin'" + skinCssAttr + ">" + - "<div class='fc-event-time'>" + - (times[0] ? '<span class="fc-col-date">' + times[0] + '</span> ' : '') + - (times[1] ? '<span class="fc-col-time">' + times[1] + '</span>' : '') + - "</div>" + - "</div>" + - "<div class='fc-event-content'>" + - "<div class='fc-event-title'>" + - htmlEscape(event.title.replace(/(\r\n|\n|\r)+/gm," ")) + - "</div>" + - "</div>" + - "<div class='fc-event-bg'></div>" + - "</div>" + // close inner - "</div>"; // close outer - } - - segContainer[0].innerHTML = s; - eventElements = segContainer.children(); - - // retrieve elements, run through eventRender callback, bind event handlers - for (i=0; i < seg.events.length; i++) { - event = seg.events[i]; - eventElement = $(eventElements[i]); // faster than eq() - triggerRes = trigger('eventRender', event, event, eventElement); - if (triggerRes === false) { - eventElement.remove(); - } else { - if (triggerRes && triggerRes !== true) { - eventElement.remove(); - eventElement = $(triggerRes).appendTo(segContainer); - } - if (event._id === modifiedEventId) { - eventElementHandlers(event, eventElement, seg); - } else { - eventElement[0]._fci = i; // for lazySegBind - } - reportEventElement(event, eventElement); - } - } - - lazySegBind(segContainer, seg, eventElementHandlers); - } - - markFirstLast(getListContainer()); - } - - // event time/date range to display - function renderEventTime(event, seg) { - var timeFormat = opt('timeFormat', 'list'); - var timeFormatFull = opt('timeFormat', 'listFull'); - var timeFormatFullAllDay = opt('timeFormat', 'listFullAllDay'); - var dateFormat = opt('columnFormat'); - var segmode = opt('listSections'); - var eventEnd = event.end ? cloneDate(event.end) : cloneDate(event.start); - var duration = eventEnd.getTime() - event.start.getTime(); - var datestr = '', timestr = ''; - - if (segmode == 'smart') { - if (event.start < seg.start) { - datestr = opt('listTexts', 'until') + ' ' + formatDate(eventEnd, (event.allDay || eventEnd.getDate() != seg.start.getDate()) ? dateFormat : timeFormat); - } else if (duration > DAY_MS) { - datestr = formatDates(event.start, eventEnd, dateFormat + '{ – ' + dateFormat + '}'); - } else if (seg.daydiff == 0) { - datestr = opt('listTexts', 'today'); - } else if (seg.daydiff == 1) { - datestr = opt('listTexts', 'tomorrow'); - } else if (seg.weekdiff == 0 || seg.weekdiff == 1) { - datestr = formatDate(event.start, 'dddd'); - } else if (seg.daydiff > 1 || seg.daydiff < 0) { - datestr = formatDate(event.start, dateFormat); - } - } else if (segmode != 'day') { - datestr = formatDates(event.start, eventEnd, dateFormat + (duration > DAY_MS ? '{ – ' + dateFormat + '}' : '')); - } - - if (!datestr && event.allDay) { - if(dayDiff(eventEnd, event.start)) { //spans multiple days - timestr = formatDates(event.start, eventEnd, timeFormatFullAllDay); - } - else { - timestr = opt('allDayText'); - } - } else if ((!datestr || !dayDiff(eventEnd, event.start)) && !event.allDay) { - if(dayDiff(eventEnd, event.start)) //spans multiple days - timestr = formatDates(event.start, eventEnd, timeFormatFull); - else if(duration) - timestr = formatDates(event.start, eventEnd, timeFormat); - else - timestr = formatDates(event.start, null, timeFormat); - } - - return [datestr, timestr]; - } - - function lazySegBind(container, seg, bindHandlers) { - container.unbind('mouseover').mouseover(function(ev) { - var parent = ev.target, e = parent, i, event; - while (parent != this) { - e = parent; - parent = parent.parentNode; - } - if ((i = e._fci) !== undefined) { - e._fci = undefined; - event = seg.events[i]; - bindHandlers(event, container.children().eq(i), seg); - $(ev.target).trigger(ev); - } - ev.stopPropagation(); - }); - } -} - -fcViews.list = ListView; - -function ListView(element, calendar) { - var t = this; - - // exports - t.render = render; - t.select = dummy; - t.unselect = dummy; - t.getDaySegmentContainer = function(){ return body; }; - - // imports - View.call(t, element, calendar, 'list'); - ListEventRenderer.call(t); - var opt = t.opt; - var trigger = t.trigger; - var clearEvents = t.clearEvents; - var reportEventClear = t.reportEventClear; - var formatDates = calendar.formatDates; - var formatDate = calendar.formatDate; - - // overrides - t.setWidth = setWidth; - t.setHeight = setHeight; - - // locals - var body; - var firstDay; - var nwe; - var tm; - var colFormat; - - - function render(date, delta) { - if (delta) { - addDays(date, opt('listPage') * delta); - } - t.start = t.visStart = cloneDate(date, true); - t.end = addDays(cloneDate(t.start), opt('listPage')); - t.visEnd = addDays(cloneDate(t.start), opt('listRange')); - addMinutes(t.visEnd, -1); // set end to 23:59 - t.title = formatDates(date, t.visEnd, opt('titleFormat')); - - updateOptions(); - - if (!body) { - buildSkeleton(); - } else { - clearEvents(); - } - } - - - function updateOptions() { - firstDay = opt('firstDay'); - nwe = opt('weekends') ? 0 : 1; - tm = opt('theme') ? 'ui' : 'fc'; - colFormat = opt('columnFormat', 'day'); - } - - - function buildSkeleton() { - body = $('<div>').addClass('fc-list-content').appendTo(element); - } - - function setHeight(height, dateChanged) { - body.css('height', (height-1)+'px').css('overflow', 'auto'); - } - - function setWidth(width) { - // nothing to be done here - } - - function dummy() { - // Stub. - } - -} - -/* Additional view: table (by bruederli@kolabsys.com) ----------------------------------------------------------------------------------*/ - -function TableEventRenderer() { - var t = this; - - // imports - ListEventRenderer.call(t); - var opt = t.opt; - var sortCmp = t.sortCmp; - var trigger = t.trigger; - var getOrigDate = t.getOrigDate; - var compileSegs = t.compileDaySegs; - var reportEvents = t.reportEvents; - var reportEventClear = t.reportEventClear; - var reportEventElement = t.reportEventElement; - var eventElementHandlers = t.eventElementHandlers; - var renderEventTime = t.renderEventTime; - var showEvents = t.showEvents; - var hideEvents = t.hideEvents; - var getListContainer = t.getDaySegmentContainer; - var lazySegBind = t.lazySegBind; - var calendar = t.calendar; - var formatDate = calendar.formatDate; - var formatDates = calendar.formatDates; - var prevMonth; - var nextMonth; - - // exports - t.renderEvents = renderEvents; - t.scrollToDate = scrollToDate; - t.clearEvents = clearEvents; - t.prevMonthNav = prevMonth; - t.nextMonthNav = nextMonth; - - - /* Rendering - --------------------------------------------------------------------*/ - - function scrollToDate(date) { - var colFormat = opt('columnFormat', t.name); - var currentDate = cloneDate(date, false); - var nextDate; - var segHash; - var currSegHash; - var segFound = false; - - if(currentDate.getDate() == 1) { - getListContainer().parent().scrollTop(0); - } - else { - while(!segFound) { - segHash = formatDate(currentDate, colFormat); - getListContainer().find('td.fc-list-header.fc-widget-header').each(function(){ - currSegHash = $(this).html(); - if(currSegHash == segHash) { - segFound = true; - var offset = $(this).position().top; - var top = getListContainer().parent().scrollTop(); - getListContainer().parent().scrollTop(top + offset); - } - }); - - if(!segFound) { - nextDate = cloneDate(currentDate, false); - nextDate.setDate(nextDate.getDate()+1); - - if(nextDate.getDate() > currentDate.getDate()) { - currentDate = cloneDate(nextDate, false); - } - else { - segFound = true; - getListContainer().parent().scrollTop(getListContainer().height()); - } - } - } - } - } - - function clearEvents() { - reportEventClear(); - getListContainer().children('tbody').remove(); - } - - function renderEvents(events, modifiedEventId) { - events.sort(sortCmp); - reportEvents(events); - renderSegs(compileSegs(events), modifiedEventId); - getListContainer().removeClass('fc-list-smart fc-list-day fc-list-month fc-list-week').addClass('fc-list-' + opt('listSections')); - scrollToDate(getOrigDate()); - } - - function renderSegs(segs, modifiedEventId) { - var tm = opt('theme') ? 'ui' : 'fc'; - var table = getListContainer(); - var headerClass = tm + "-widget-header"; - var contentClass = tm + "-widget-content"; - var segHeader = null; - var tableCols = opt('tableCols'); - var timecol = $.inArray('time', tableCols) >= 0; - var i, j, seg, event, times, s, bg, skinCss, skinCssAttr, skinClasses, rowClasses, segContainer, eventElements, eventElement, triggerRes; - - prevMonth = $('<tbody class="fc-list-header"><tr><td class="fc-list-header fc-month-nav fc-month-prev ' + headerClass + '" colspan="' + tableCols.length + '">' + opt('buttonText', 'prevMonth') + '</td></tr></tbody>').appendTo(table); - prevMonth.click(function(){ - var prevMonthDate = cloneDate(t.getOrigDate(), true); - prevMonthDate.setDate(0); - calendar.gotoDate(prevMonthDate); - trigger('prevClick'); - }); - - for (j in segs) { - seg = segs[j]; - bg = false; - - if (seg.title) { - var segHeader = $('<tbody class="fc-list-header"><tr><td class="fc-list-header ' + headerClass + '" colspan="' + tableCols.length + '">' + htmlEscape(seg.title) + '</td></tr></tbody>').appendTo(table); - } - segContainer = $('<tbody>').addClass('fc-list-section ' + contentClass).appendTo(table); - s = ''; - - for (i=0; i < seg.events.length; i++) { - event = seg.events[i]; - times = renderEventTime(event, seg); - skinCss = getSkinCss(event, opt); - skinCssAttr = (skinCss ? " style='" + skinCss + "'" : ''); - skinClasses = ['fc-event-skin', 'fc-corner-left', 'fc-corner-right', 'fc-corner-top', 'fc-corner-bottom'].concat(event.className); - if (event.source && event.source.className) { - skinClasses = skinClasses.concat(event.source.className); - } - if(event.source && event.source.background) { - bg = true; - } - rowClasses = ['fc-'+dayIDs[event.start.getDay()], 'fc-event', 'fc-event-row']; - if(opt('weekendDays').length>0 && opt('weekendDays').indexOf(segs[j].start.getDay())!=-1) - rowClasses.splice(1, 0, 'fc-weekend-day'); - - if (seg.daydiff == 0) { - if(segHeader) - segHeader.addClass('fc-today'); - rowClasses.push('fc-today'); - rowClasses.push('fc-state-highlight'); - } - - s += "<tr class='" + rowClasses.join(' ') + "'>"; - for (var col, c=0; c < tableCols.length; c++) { - col = tableCols[c]; - if (col == 'handle') { - s += "<td class='fc-event-handle'" + skinCssAttr + "></td>"; - } else if (col == 'title') { - s += "<td class='fc-event-title'>" + (event.title ? htmlEscape(event.title.replace(/(\r\n|\n|\r)+/gm," ")) : ' ') + "</td>"; - } else if (col == 'date') { - s += "<td class='fc-event-date' colspan='" + (times[1] || !timecol ? 1 : 2) + "'>" + htmlEscape(times[0]) + "</td>"; - } else if (col == 'time') { - if (times[1]) { - s += "<td class='fc-event-time' style='text-overflow: ellipsis; overflow: hidden;'>" + htmlEscape(times[1]) + "</td>"; - } - } else { - s += "<td class='fc-event-" + col + "'>" + (event[col] ? htmlEscape(event[col]) : ' ') + "</td>"; - } - } - s += "</tr>"; - - // IE doesn't like innerHTML on tbody elements so we insert every row individually - if (document.all) { - $(s).appendTo(segContainer); - s = ''; - } - } - - if (!document.all) - segContainer[0].innerHTML = s; - - eventElements = segContainer.children(); - - // retrieve elements, run through eventRender callback, bind event handlers - for (i=0; i < seg.events.length; i++) { - event = seg.events[i]; - eventElement = $(eventElements[i]); // faster than eq() - if(bg) { - eventElement.addClass('fc-source-bg'); - } - triggerRes = trigger('eventRender', event, event, eventElement); - if (triggerRes === false) { - eventElement.remove(); - } else { - if (triggerRes && triggerRes !== true) { - eventElement.remove(); - eventElement = $(triggerRes).appendTo(segContainer); - } - if (event._id === modifiedEventId) { - eventElementHandlers(event, eventElement, seg); - } else { - eventElement[0]._fci = i; // for lazySegBind - } - reportEventElement(event, eventElement); - } - trigger('eventAfterRender', event, event, eventElement); - } - - lazySegBind(segContainer, seg, eventElementHandlers); - markFirstLast(segContainer); - segContainer.addClass('fc-day-'+seg.start.getDay()); - } - - nextMonth = $('<tbody class="fc-list-header"><tr><td class="fc-list-header fc-month-nav fc-month-next ' + headerClass + '" colspan="' + tableCols.length + '">' + opt('buttonText', 'nextMonth') + '</td></tr></tbody>').appendTo(table); - nextMonth.click(function(){ - var nextMonthDate = cloneDate(t.getOrigDate(), true); - nextMonthDate.setDate(1); - nextMonthDate.setMonth(nextMonthDate.getMonth() + 1); - calendar.gotoDate(nextMonthDate); - trigger('nextClick'); - }); - - //markFirstLast(table); - } - -} - - -fcViews.table = TableView; - - -function TableView(element, calendar) { - var t = this; - - // exports - t.render = render; - t.select = dummy; - t.unselect = dummy; - t.getDaySegmentContainer = function(){return table;}; - t.getOrigDate = function() {return origDate;}; - t.updateGrid = updateGrid; - t.updateToday = updateToday; - t.setAxisFormat = setAxisFormat; - t.setStartOfBusiness = setStartOfBusiness; - t.setEndOfBusiness = setEndOfBusiness; - t.setWeekendDays = setWeekendDays; - t.setBindingMode = setBindingMode; - t.setSelectable = setSelectable; - - // imports - View.call(t, element, calendar, 'table'); - TableEventRenderer.call(t); - var opt = t.opt; - var trigger = t.trigger; - var clearEvents = t.clearEvents; - var reportEventClear = t.reportEventClear; - var formatDates = calendar.formatDates; - var formatDate = calendar.formatDate; - - // overrides - t.setWidth = setWidth; - t.setHeight = setHeight; - - // locals - var div; - var table; - var firstDay; - var nwe; - var tm; - var colFormat; - var datepicker; - var dateInfo; - var dateInfoNumber; - var dateInfoNumberDiv; - var dateInfoText; - var origDate; - - function render(date, delta) { - /*if (delta) { - addDays(date, opt('listPage') * delta); - } - t.start = t.visStart = cloneDate(date, true); - t.end = addDays(cloneDate(t.start), opt('listPage')); - t.visEnd = addDays(cloneDate(t.start), opt('listRange'));*/ - - origDate = date; - if (delta) { - addMonths(date, delta); - date.setDate(1); - } - t.start = cloneDate(date, true); - t.start.setDate(1); - t.end = addMonths(cloneDate(t.start), 1); - t.visStart = cloneDate(t.start); - t.visEnd = cloneDate(t.end); - - addMinutes(t.visEnd, -1); // set end to 23:59 - t.title = formatDates( - t.visStart, - t.visEnd, - opt('titleFormat') - ); - //t.title = (t.visEnd.getTime() - t.visStart.getTime() < DAY_MS) ? formatDate(date, opt('titleFormat')) : formatDates(date, t.visEnd, opt('titleFormat')); - - updateOptions(); - if (!table) { - buildSkeleton(origDate); - } else { - clearEvents(); - if(opt('showDatepicker')) { - dateInfoNumberDiv.html(origDate.getDate()); - dateInfoText.html(formatDates(origDate, null, opt('titleFormat', 'table'))); - datepicker.datepicker('option','firstDay',firstDay); - datepicker.datepicker('setDate', origDate); - } - } - } - - - function updateOptions() { - firstDay = opt('firstDay'); - nwe = opt('weekends') ? 0 : 1; - tm = opt('theme') ? 'ui' : 'fc'; - colFormat = opt('columnFormat'); - } - - function buildSkeleton(date) { - var tableCols = opt('tableCols'); - var s = - "<table class='fc-border-separate' style='width:100%' cellspacing='0'>" + - "<colgroup>"; - for (var c=0; c < tableCols.length; c++) { - s += "<col class='fc-event-" + tableCols[c] + "' />"; - } - s += "</colgroup>" + - "</table>"; - if(opt('showDatepicker')) { - dateInfo = $('<div>').addClass('fc-table-dateinfo').appendTo(element); - dateInfoNumber = $('<div>').addClass('fc-table-dateinfo-number').appendTo(dateInfo); - dateInfoNumberDiv = $('<div>').appendTo(dateInfoNumber); - dateInfoNumberDiv.html(date.getDate()); - dateInfoText = $('<div>').addClass('fc-table-dateinfo-text').appendTo(dateInfo); - dateInfoText.html(formatDates(origDate, null, opt('titleFormat', 'table'))); - datepicker = $('<div>').addClass('fc-table-datepicker').appendTo(element); - datepicker.datepicker({ - firstDay: opt('firstDay'), - weekendDays: opt('weekendDays'), - defaultDate: date, - showWeek: true, - weekHeader: '', - - onSelect: function(dateText, inst) { - var date = new Date(dateText); - calendar.gotoDate(date); - trigger('datepickerClick', this, date); - }, - }); - } - div = $('<div>').addClass('fc-list-content').appendTo(element); - table = $(s).appendTo(div); - } - - function updateGrid() - { - updateToday(); - setAxisFormat(); - setStartOfBusiness(); - setEndOfBusiness(); - setWeekendDays(); - setBindingMode(); - setSelectable(); - } - - function updateToday() - { - var today = clearTime(new Date()); - var segHash = formatDate(today, colFormat); - - $(table).find('.fc-list-header').each(function() { - $(this).removeClass('fc-today'); - $(this).next().children().removeClass('fc-state-highlight'); - - if(segHash == $(this).find('td').html()) { - $(this).addClass('fc-today'); - $(this).next().children().addClass('fc-state-highlight'); - } - }); - - datepicker.datepicker('refresh'); - } - - function setAxisFormat() - { - // dummy - } - - function setStartOfBusiness() - { - // dummy - } - - function setEndOfBusiness() - { - // dummy - } - - function setWeekendDays() - { - var weekendDays = opt('weekendDays'); - - $(table).find('.fc-list-section').each(function() { - var day=parseInt(this.className.match(/fc-day-(\d)/)[1],10); - if(weekendDays.indexOf(day)==-1) - $(this).children().removeClass('fc-weekend-day'); - else - $(this).children().addClass('fc-weekend-day'); - }); - - if(opt('showDatepicker')) - datepicker.datepicker('option','weekendDays',weekendDays); - } - - function setBindingMode() - { - // dummy - } - - function setSelectable() - { - // dummy - } - - function setHeight(height, dateChanged) { - if(opt('showDatepicker')) { - var datepickerHeight = datepicker.height(); - dateInfoText.css('padding-bottom', datepickerHeight - datepicker.children().outerHeight() + 3); //+3 for paddings - var textHeight = dateInfoText.outerHeight(); - dateInfoNumber.css({'height': datepickerHeight - textHeight, - 'font-size': 145 - textHeight}); - dateInfoNumberDiv.height(145 - textHeight); - } - - div.css('height', (height-div.position().top-2)+'px').css('overflow', 'auto'); - } - - function setWidth(width) { - var outerWidth = Math.floor(element.parent().width() / 2) - 8; - element.css({'left' : width, 'width' : outerWidth}); - } - - function dummy() { - // Stub. - } - -} - -function TodoEventRenderer() { - var t = this; - - // exports - t.renderEvents = renderEvents; - t.clearEvents = clearEvents; - t.renderEventTime = renderEventTime; - t.compileDaySegs = compileSegs; // for DayEventRenderer - t.lazySegBind = lazySegBind; - t.sortCmp = sortCmp; - - // imports - DayEventRenderer.call(t); - var opt = t.opt; - var sortCmp = t.sortCmp; - var trigger = t.trigger; - var compileSegs = t.compileDaySegs; - var reportEvents = t.reportEvents; - var reportEventClear = t.reportEventClear; - var reportEventElement = t.reportEventElement; - var eventElementHandlers = t.eventElementHandlers; - var renderEventTime = t.renderEventTime; - var showEvents = t.showEvents; - var hideEvents = t.hideEvents; - var getListContainer = t.getDaySegmentContainer; - var lazySegBind = t.lazySegBind; - var calendar = t.calendar; - var formatDate = calendar.formatDate; - var formatDates = calendar.formatDates; - var prevMonth; - var nextMonth; - - function compileSegs(events) { - var segs = {}; - var event, i; - - //for (i=0; i < events.length; i++) { - for (i=events.length-1; i > -1; i--) { - event = events[i]; - var segHash = event.repeatHash; - var eventEnd = event.end ? cloneDate(event.end) : cloneDate(event.start); - - // skip events out of range - if ((event.completedOn && event.completedOn < t.start && (opt('showUnstartedEvents') || !event.start || event.completedOn > event.start)) || - (!opt('showUnstartedEvents') && event.start && event.start > t.visEnd)) { - continue; - } - - // start new segment - if (!(segHash in segs)) { - segs[segHash] = { events: [], id: segHash}; - } - - segs[segHash].events.push(event); - } - - return segs; - } - - function reverseSegs(oldSegs) { - var newSegs = {}; - var keys = $.map(oldSegs, function (value, key) { return key; }); - var values = $.map(oldSegs, function (value, key) { return value; }); - - for (i=keys.length-1; i > -1; i--) { - newSegs[keys[i]] = values[i]; - } - - return newSegs; - } - - function sortCmp(a, b) { - /*var sd = a.start.getTime() - b.start.getTime(); - var aEnd = a.end ? a.end : a.start; - var bEnd = b.end ? b.end : b.start; - return sd + (sd ? 0 : aEnd.getTime() - bEnd.getTime());*/ - var aEnd = a.end ? a.end.getTime() : Infinity; - var bEnd = b.end ? b.end.getTime() : Infinity; - var aStart = a.start ? a.start.getTime() : Infinity; - var bStart = b.start ? b.start.getTime() : Infinity; - var aPriority = parseInt(a.priority, 10) || 10; - var bPriority = parseInt(b.priority, 10) || 10; - - var statusSort = { - "NEEDS-ACTION": 1, - "IN-PROCESS": 2, - "COMPLETED": 3, - "CANCELLED": 4 - }; - - if(aEnd < bEnd) { - return -1; - } - else if(bEnd < aEnd) { - return 1; - } - else if(aStart < bStart){ - return -1; - } - else if(bStart < aStart) { - return 1; - } - else if(aPriority < bPriority) { - return -1; - } - else if(bPriority < aPriority) { - return 1; - } - else if(statusSort[a.status] < statusSort[b.status]) { - return -1; - } - else if(statusSort[b.status] < statusSort[a.status]) { - return 1; - } - else if(a.percent < b.percent) { - return -1; - } - else if(b.percent < a.percent) { - return 1; - } - else if(a.compareString < b.compareString) { - return -1; - } - else if(b.compareString < a.compareString) { - return 1; - } - else { - return 0; - } - } - - // event time/date range to display - function renderEventTime(event) { - var timeFormat = opt('timeFormat', 'list'); - return event.end? formatDate(event.end, timeFormat) : ''; - } - - function lazySegBind(container, seg, bindHandlers) { - container.unbind('mouseover').mouseover(function(ev) { - var parent = ev.target, e = parent, i, event; - while (parent != this) { - e = parent; - parent = parent.parentNode; - } - if ((i = e._fci) !== undefined) { - e._fci = undefined; - event = seg.events[i]; - bindHandlers(event, container.children().eq(0), seg); - $(ev.target).trigger(ev); - } - ev.stopPropagation(); - }); - } - - function clearEvents() { - reportEventClear(); - getListContainer().children('tbody').remove(); - } - - function renderEvents(events, modifiedEventId) { - events.sort(sortCmp); - reportEvents(events); - renderSegs(reverseSegs(compileSegs(events)), modifiedEventId); - getListContainer().removeClass('fc-list-smart fc-list-day fc-list-month fc-list-week').addClass('fc-list-' + opt('listSections')); - //t.selectEvent(); - t.applyFilters(); - } - - function renderSegs(segs, modifiedEventId) { - var tm = opt('theme') ? 'ui' : 'fc'; - var table = getListContainer(); - var headerClass = tm + "-widget-header"; - var contentClass = tm + "-widget-content"; - var segHeader = null; - var tableCols = opt('todoCols'); - var timecol = $.inArray('time', tableCols) >= 0; - var i, j, iter, seg, event, times, s, skinCss, skinCssAttr, skinClasses, rowClasses, segContainer, eventElements, eventElement, triggerRes; - - for (j in segs) { - seg = segs[j]; - - segContainer = $('<tbody>').addClass('fc-list-section ' + contentClass).appendTo(table); - s = ''; - - event = seg.events[0]; - iter=0; - if(opt('showUnstartedEvents') && seg.events.length>1) { - for(;iter<seg.events.length; iter++) { - if(seg.events[iter].start<t.end) { - event = seg.events[iter]; - break; - } - } - if(iter==seg.events.length) { - continue; - } - } - - dueTime = renderEventTime(event); - skinCss = getSkinCss(event, opt); - skinCssAttr = (skinCss ? " style='" + skinCss + "'" : ''); - skinClasses = ['fc-event-skin', 'fc-corner-left', 'fc-corner-right', 'fc-corner-top', 'fc-corner-bottom'].concat(event.className); - if (event.source && event.source.className) { - skinClasses = skinClasses.concat(event.source.className); - } - - rowClasses = ['fc-event', 'fc-event-row']; - if(event.end && event.end.getTime() < cloneDate(t.start, true)) { - rowClasses.push('fc-event-pastdue'); - } - else if(event.end && event.end.getTime() < addDays(cloneDate(t.start), 2, false).getTime()) { - rowClasses.push('fc-event-urgent'); - } - if(event.filterStatus) { - rowClasses.push('fc-event-'+event.filterStatus); - } - - s += "<tr class='" + rowClasses.join(' ') + "'>"; - for (var col, c=0; c < tableCols.length; c++) { - col = tableCols[c]; - if (col == 'handle') { - s += "<td class='fc-event-handle'" + skinCssAttr + "></td>"; - } else if (col == 'check') { - s += "<td class='fc-event-check'>" + '<input type="checkbox" class="fc-event-checkbox" data-ind="false"/>' + "</td>"; - } else if (col == 'priority') { - s += "<td class='fc-event-priority fc-event-priority-" + event.renderPriority + "'>" + (event.renderPriority ? ' ' : '') + "</td>"; - } else if (col == 'time') { - s += "<td class='fc-event-time'>" + htmlEscape(dueTime) + "</td>"; - } else if (col == 'title') { - s += "<td class='fc-event-title'>" + htmlEscape(event.title.replace(/(\r\n|\n|\r)+/gm, " ")) + "</td>"; - } else if (col == 'location') { - s += "<td class='fc-event-location'>" + htmlEscape(event.location.replace(/(\r\n|\n|\r)+/gm, " ")) + "</td>"; - } else if (col == 'status') { - s += "<td class='fc-event-status'></td>"; - } else if (col == 'percent') { - s += "<td class='fc-event-percent'>" + event.percent + '%' + "</td>"; - } - else { - s += "<td class='fc-event-" + col + "'>" + (event[col] ? htmlEscape(event[col]) : ' ') + "</td>"; - } - } - s += "</tr>"; - - // IE doesn't like innerHTML on tbody elements so we insert every row individually - if (document.all) { - $(s).appendTo(segContainer); - s = ''; - } - - if (!document.all) - segContainer[0].innerHTML = s; - - eventElements = segContainer.children(); - - // retrieve elements, run through eventRender callback, bind event handlers - eventElement = $(eventElements[0]); // faster than eq() - triggerRes = trigger('eventRender', event, event, eventElement); - if (triggerRes === false) { - eventElement.remove(); - } else { - if (triggerRes && triggerRes !== true) { - eventElement.remove(); - eventElement = $(triggerRes).appendTo(segContainer); - } - if (event._id === modifiedEventId) { - eventElementHandlers(event, eventElement, seg); - } else { - eventElement[0]._fci = iter; // for lazySegBind - } - reportEventElement(event, eventElement); - } - trigger('eventCheckDefault', event, event, eventElement.find('.fc-event-checkbox')); - trigger('eventAfterRender', event, event, eventElement); - - lazySegBind(segContainer, seg, eventElementHandlers); - markFirstLast(segContainer); - } - - //markFirstLast(table); - } - -} - -fcViews.todo = TodoView; - -function TodoView(element, calendar) { - var t = this; - - // exports - t.render = render; - t.select = dummy; - t.unselect = dummy; - t.getDaySegmentContainer = function(){ return table; }; - t.applyFilters = applyFilters; - t.allowSelectEvent = allowSelectEvent; - t.eventSelectLock = 0; - t.updateGrid = updateGrid; - t.updateToday = updateToday; - t.setAxisFormat = setAxisFormat; - t.setStartOfBusiness = setStartOfBusiness; - t.setEndOfBusiness = setEndOfBusiness; - t.setWeekendDays = setWeekendDays; - t.setBindingMode = setBindingMode; - t.setSelectable = setSelectable; - - // imports - View.call(t, element, calendar, 'todo'); - TodoEventRenderer.call(t); - var opt = t.opt; - var trigger = t.trigger; - var clearEvents = t.clearEvents; - var reportEventClear = t.reportEventClear; - var formatDates = calendar.formatDates; - var formatDate = calendar.formatDate; - - // overrides - t.setWidth = setWidth; - t.setHeight = setHeight; - - // locals - var div; - var table; - var filter; - var filterTable; - var firstDay; - var nwe; - var tm; - var colFormat; - var currentDate; - var datepickers; - var dateInfo; - var dateInfoNumber; - var dateInfoNumberDiv; - var dateInfoText; - - function render(date, delta) { - if (delta) { - addMonths(date, delta); - date.setDate(1); - } - currentDate = date; - var start = cloneDate(date, true); - var end = addDays(cloneDate(start), 1); - t.title = formatDate(date, opt('titleFormat')); - t.start = t.visStart = start; - t.end = t.visEnd = end; - - updateOptions(); - if (!table) { - buildSkeleton(date); - initFilters(); - } else { - clearEvents(); - filterTable.find('.fc-filter-table-footer').text(opt('buttonText', 'filtersFooter').replace('%date%', formatDates(date, null, opt('columnFormat', 'todo')))); - if(opt('showDatepicker')) { - dateInfoNumberDiv.html(date.getDate()); - dateInfoText.html(formatDates(date, null, opt('titleFormat', 'todo'))); - - var defaultDate = cloneDate(date, true); - defaultDate.setHours(12); - defaultDate.setDate(1); - defaultDate.setMonth(currentDate.getMonth() - datepickers.length + 1); - - datepickers.forEach(function(e, i){ - defaultDate.setMonth(defaultDate.getMonth() + 1); - e.datepicker('option','firstDay',firstDay); - if((i===0 && datepickers.length<3) || (i===datepickers.length-2 && datepickers.length>2)) - e.datepicker('setDate', date); - else - e.datepicker('setDate', defaultDate); - }); - } - } - } - - function updateOptions() { - firstDay = opt('firstDay'); - nwe = opt('weekends') ? 0 : 1; - tm = opt('theme') ? 'ui' : 'fc'; - colFormat = opt('columnFormat'); - } - - function buildSkeleton(date) { - var tableCols = opt('todoCols'); - var s = - "<table class='fc-border-separate' style='width:100%' cellspacing='0'>" + - "<colgroup>"; - for (var c=0; c < tableCols.length; c++) { - s += "<col class='fc-event-" + tableCols[c] + "' />"; - } - s += "</colgroup>" + - "</table>"; - if(opt('showDatepicker')) { - dateInfo = $('<div>').addClass('fc-table-dateinfo').appendTo(element); - dateInfoNumber = $('<div>').addClass('fc-table-dateinfo-number').appendTo(dateInfo); - dateInfoNumberDiv = $('<div>').appendTo(dateInfoNumber); - dateInfoNumberDiv.html(date.getDate()); - dateInfoText = $('<div>').addClass('fc-table-dateinfo-text').appendTo(dateInfo); - dateInfoText.html(formatDates(date, null, opt('titleFormat', 'todo'))); - - datepickers = [$('<div>').addClass('fc-table-datepicker fc-table-datepicker-current').appendTo(element)]; - datepickers[0].datepicker({ - firstDay: opt('firstDay'), - weekendDays: opt('weekendDays'), - defaultDate: date, - showWeek: true, - weekHeader: '', - - onSelect: function(dateText, inst) { - var date = new Date(dateText); - calendar.gotoDate(date); - trigger('datepickerClick', this, date); - } - }); - } - filter = $('<div>').addClass('fc-filter').appendTo(element); - var ft = '<table class="fc-filter-table">' + - '<tr>' + - '<td class="fc-filter-table-header" colspan="2">'+opt('buttonText', 'filtersHeader')+'</td>' + - '</tr>'; - - if(opt('simpleFilters')) { - ft += '<tr>' + - '<td class="fc-filter-option fc-filter-action" data-type="filterAction">'+ opt('buttonText', 'filterAction') +'</td>' + - '<td class="fc-filter-option fc-filter-completed fc-filter-option-last" data-type="filterCompleted">'+ opt('buttonText', 'filterCompleted') +' *</td>' + - '</tr>'; - } - else { - ft += '<tr>' + - '<td class="fc-filter-option fc-filter-action" data-type="filterAction">'+ opt('buttonText', 'filterAction') +'</td>' + - '<td class="fc-filter-option fc-filter-progress" data-type="filterProgress">'+ opt('buttonText', 'filterProgress') +'</td>' + - '</tr>' + - '<tr>' + - '<td class="fc-filter-option fc-filter-completed" data-type="filterCompleted">'+ opt('buttonText', 'filterCompleted') +' *</td>' + - '<td class="fc-filter-option fc-filter-canceled fc-filter-option-last" data-type="filterCanceled">'+ opt('buttonText', 'filterCanceled') +'</td>' + - '</tr>'; - } - - ft += '<tr>' + - '<td class="fc-filter-table-footer" colspan="2">'+opt('buttonText', 'filtersFooter').replace('%date%', formatDates(date, null, opt('columnFormat', 'todo')))+'</td>' + - '</tr>' + - '</table>'; - filterTable = $(ft).appendTo(filter); - div = $('<div>').addClass('fc-list-content').appendTo(element); - table = $(s).appendTo(div); - } - - function updateGrid() - { - updateToday(); - setAxisFormat(); - setStartOfBusiness(); - setEndOfBusiness(); - setWeekendDays(); - setBindingMode(); - setSelectable(); - } - - function updateToday() - { - if(opt('showDatepicker')) - datepickers.forEach(function(e){ - e.datepicker('refresh'); - }); - } - - function setAxisFormat() - { - // dummy - } - - function setStartOfBusiness() - { - // dummy - } - - function setEndOfBusiness() - { - // dummy - } - - function setWeekendDays() - { - if(opt('showDatepicker')) - datepickers.forEach(function(e){ - e.datepicker('option','weekendDays',opt('weekendDays')); - }); - } - - function setBindingMode() - { - // dummy - } - - function setSelectable() - { - // dummy - } - - function initFilters() { - filterTable.find('.fc-filter-option').each(function() { - if(opt('defaultFilters').indexOf($(this).attr('data-type')) != -1) { - filterToggle($(this)); - } - $(this).click(function(){ - filterToggle($(this)); - }); - }); - } - - function filterToggle(button) { - if(button.hasClass('fc-filter-option-selected')) { - button.removeClass('fc-filter-option-selected'); - } - else { - button.addClass('fc-filter-option-selected'); - } - applyFilters(); - } - - function applyFilters() { - filterTable.find('.fc-filter-option').each(function(){ - if($(this).hasClass('fc-filter-option-selected')) { - t.getDaySegmentContainer().find('.fc-event-' + $(this).attr('data-type')).removeClass('fc-filter-hide'); - } - else { - t.getDaySegmentContainer().find('.fc-event-' + $(this).attr('data-type')).addClass('fc-filter-hide'); - } - }); - - opt('todoOptionalCols').forEach(function(item){ - var itemsFilled = $('.fc-event-'+item.col+':visible').filter(function(){ - return this.innerHTML!==''; - }); - - $('col.fc-event-'+item.col).toggleClass('fc-hidden-empty', !itemsFilled.length); - }); - - //if(!t.getDaySegmentContainer().find('.fc-event-selected:visible').length) { - t.selectEvent(); - //} - } - - function setHeight(height, dateChanged) { - if(opt('showDatepicker')) { - var datepickerHeight = datepickers[0].height(); - dateInfoText.css('padding-bottom', datepickerHeight - datepickers[0].children().outerHeight() + 3); //+3 for paddings - var textHeight = dateInfoText.outerHeight(); - dateInfoNumber.css({'height': datepickerHeight - textHeight, - 'font-size': 145 - textHeight}); - dateInfoNumberDiv.height(145 - textHeight); - } - - div.css({'height': height-div.position().top-2, 'overflow': 'auto'}); - } - - function setWidth(width) { - element.width(width); - var slots = Math.floor((width - dateInfo.outerWidth() - 1) / datepickers[0].outerWidth()); - - if(slots > datepickers.length) { - var defaultDate = cloneDate(currentDate, true); - defaultDate.setHours(12); - defaultDate.setDate(1); - defaultDate.setMonth(currentDate.getMonth() + 1); - - if(datepickers.length==1) { - datepickers.push($('<div>').addClass('fc-table-datepicker fc-table-datepicker-no-default').prependTo(element).datepicker({ - firstDay: opt('firstDay'), - weekendDays: opt('weekendDays'), - defaultDate: cloneDate(defaultDate), - showWeek: true, - weekHeader: '', - hideIfNoPrevNext: true, - - onSelect: function(dateText, inst) { - var date = new Date(dateText); - calendar.gotoDate(date); - trigger('datepickerClick', this, date); - } - })); - } - - defaultDate.setMonth(defaultDate.getMonth() - datepickers.length + 1); - for(var i=datepickers.length; i<slots; i++) { - defaultDate.setMonth(defaultDate.getMonth() - 1); - datepickers.unshift($('<div>').addClass('fc-table-datepicker fc-table-datepicker-no-default').insertBefore(filter).datepicker({ - firstDay: opt('firstDay'), - weekendDays: opt('weekendDays'), - defaultDate: cloneDate(defaultDate), - showWeek: true, - weekHeader: '', - hideIfNoPrevNext: true, - - onSelect: function(dateText, inst) { - var date = new Date(dateText); - calendar.gotoDate(date); - trigger('datepickerClick', this, date); - } - })); - } - } - else { - while(datepickers.length>slots && datepickers.length>1) { - if(datepickers.length==2) - datepickers.pop().remove(); - else - datepickers.shift().remove(); - } - } - - var hiddenWidth = 0; - opt('todoOptionalCols').forEach(function(e){ - hiddenWidth += $('col.fc-event-'+e.col).hasClass('fc-hidden-empty') ? e.width : 0; - }); - opt('todoColThresholds').forEach(function(e){ - $('col.fc-event-'+e.col).toggleClass('fc-hidden-width', width<e.width-hiddenWidth); - }); - } - - function allowSelectEvent(value) { - if(value) - t.eventSelectLock++; - else - t.eventSelectLock--; - } - - function dummy() { - // Stub. - } - -} - -})(jQuery); diff --git a/radicale_web/web/infcloud/lib/ie_base64.js b/radicale_web/web/infcloud/lib/ie_base64.js deleted file mode 100644 index 5baba0d..0000000 --- a/radicale_web/web/infcloud/lib/ie_base64.js +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2010 Nick Galbreath - * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* base64 encode/decode compatible with window.btoa/atob - * - * window.atob/btoa is a Firefox extension to convert binary data (the "b") - * to base64 (ascii, the "a"). - * - * It is also found in Safari and Chrome. It is not available in IE. - * - * if (!window.btoa) window.btoa = base64.encode - * if (!window.atob) window.atob = base64.decode - * - * The original spec's for atob/btoa are a bit lacking - * https://developer.mozilla.org/en/DOM/window.atob - * https://developer.mozilla.org/en/DOM/window.btoa - * - * window.btoa and base64.encode takes a string where charCodeAt is [0,255] - * If any character is not [0,255], then an DOMException(5) is thrown. - * - * window.atob and base64.decode take a base64-encoded string - * If the input length is not a multiple of 4, or contains invalid characters - * then an DOMException(5) is thrown. - */ -var base64 = {}; -base64.PADCHAR = '='; -base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - -base64.makeDOMException = function() { - // sadly in FF,Safari,Chrome you can't make a DOMException - var e, tmp; - - try { - return new DOMException(DOMException.INVALID_CHARACTER_ERR); - } catch (tmp) { - // not available, just passback a duck-typed equiv - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error - // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype - var ex = new Error("DOM Exception 5"); - - // ex.number and ex.description is IE-specific. - ex.code = ex.number = 5; - ex.name = ex.description = "INVALID_CHARACTER_ERR"; - - // Safari/Chrome output format - ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; }; - return ex; - } -} - -base64.getbyte64 = function(s,i) { - // This is oddly fast, except on Chrome/V8. - // Minimal or no improvement in performance by using a - // object with properties mapping chars to value (eg. 'A': 0) - var idx = base64.ALPHA.indexOf(s.charAt(i)); - if (idx === -1) { - throw base64.makeDOMException(); - } - return idx; -} - -base64.decode = function(s) { - // convert to string - s = '' + s; - var getbyte64 = base64.getbyte64; - var pads, i, b10; - var imax = s.length - if (imax === 0) { - return s; - } - - if (imax % 4 !== 0) { - throw base64.makeDOMException(); - } - - pads = 0 - if (s.charAt(imax - 1) === base64.PADCHAR) { - pads = 1; - if (s.charAt(imax - 2) === base64.PADCHAR) { - pads = 2; - } - // either way, we want to ignore this last block - imax -= 4; - } - - var x = []; - for (i = 0; i < imax; i += 4) { - b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | - (getbyte64(s,i+2) << 6) | getbyte64(s,i+3); - x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff)); - } - - switch (pads) { - case 1: - b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6); - x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff)); - break; - case 2: - b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12); - x.push(String.fromCharCode(b10 >> 16)); - break; - } - return x.join(''); -} - -base64.getbyte = function(s,i) { - var x = s.charCodeAt(i); - if (x > 255) { - throw base64.makeDOMException(); - } - return x; -} - -base64.encode = function(s) { - if (arguments.length !== 1) { - throw new SyntaxError("Not enough arguments"); - } - var padchar = base64.PADCHAR; - var alpha = base64.ALPHA; - var getbyte = base64.getbyte; - - var i, b10; - var x = []; - - // convert to string - s = '' + s; - - var imax = s.length - s.length % 3; - - if (s.length === 0) { - return s; - } - for (i = 0; i < imax; i += 3) { - b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2); - x.push(alpha.charAt(b10 >> 18)); - x.push(alpha.charAt((b10 >> 12) & 0x3F)); - x.push(alpha.charAt((b10 >> 6) & 0x3f)); - x.push(alpha.charAt(b10 & 0x3f)); - } - switch (s.length - imax) { - case 1: - b10 = getbyte(s,i) << 16; - x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + - padchar + padchar); - break; - case 2: - b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8); - x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) + - alpha.charAt((b10 >> 6) & 0x3f) + padchar); - break; - } - return x.join(''); -} diff --git a/radicale_web/web/infcloud/lib/jquery-2.1.4.min.js b/radicale_web/web/infcloud/lib/jquery-2.1.4.min.js deleted file mode 100644 index 49990d6..0000000 --- a/radicale_web/web/infcloud/lib/jquery-2.1.4.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ -return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ia={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qa[0].contentDocument,b.write(),b.close(),c=sa(a,b),qa.detach()),ra[a]=c),c}var ua=/^margin/,va=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wa=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)};function xa(a,b,c){var d,e,f,g,h=a.style;return c=c||wa(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),va.test(g)&&ua.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function ya(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),f.removeChild(c),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var za=/^(none|table(?!-c[ea]).+)/,Aa=new RegExp("^("+Q+")(.*)$","i"),Ba=new RegExp("^([+-])=("+Q+")","i"),Ca={position:"absolute",visibility:"hidden",display:"block"},Da={letterSpacing:"0",fontWeight:"400"},Ea=["Webkit","O","Moz","ms"];function Fa(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Ea.length;while(e--)if(b=Ea[e]+c,b in a)return b;return d}function Ga(a,b,c){var d=Aa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Ha(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ia(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wa(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xa(a,b,f),(0>e||null==e)&&(e=a.style[b]),va.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Ha(a,b,c||(g?"border":"content"),d,f)+"px"}function Ja(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",ta(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xa(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fa(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Ba.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fa(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xa(a,b,d)),"normal"===e&&b in Da&&(e=Da[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?za.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Ca,function(){return Ia(a,b,d)}):Ia(a,b,d):void 0},set:function(a,c,d){var e=d&&wa(a);return Ga(a,c,d?Ha(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=ya(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ua.test(a)||(n.cssHooks[a+b].set=Ga)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wa(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Ja(this,!0)},hide:function(){return Ja(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Ka(a,b,c,d,e){return new Ka.prototype.init(a,b,c,d,e)}n.Tween=Ka,Ka.prototype={constructor:Ka,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ka.propHooks[this.prop];return a&&a.get?a.get(this):Ka.propHooks._default.get(this)},run:function(a){var b,c=Ka.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ka.propHooks._default.set(this),this}},Ka.prototype.init.prototype=Ka.prototype,Ka.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Ka.propHooks.scrollTop=Ka.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Ka.prototype.init,n.fx.step={};var La,Ma,Na=/^(?:toggle|show|hide)$/,Oa=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pa=/queueHooks$/,Qa=[Va],Ra={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Oa.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Oa.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sa(){return setTimeout(function(){La=void 0}),La=n.now()}function Ta(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ua(a,b,c){for(var d,e=(Ra[b]||[]).concat(Ra["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Va(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||ta(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Na.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?ta(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ua(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wa(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xa(a,b,c){var d,e,f=0,g=Qa.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=La||Sa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:La||Sa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wa(k,j.opts.specialEasing);g>f;f++)if(d=Qa[f].call(j,a,k,j.opts))return d;return n.map(k,Ua,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xa,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Ra[c]=Ra[c]||[],Ra[c].unshift(b)},prefilter:function(a,b){b?Qa.unshift(a):Qa.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xa(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pa.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Ta(b,!0),a,d,e)}}),n.each({slideDown:Ta("show"),slideUp:Ta("hide"),slideToggle:Ta("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(La=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),La=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ma||(Ma=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Ma),Ma=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Ya,Za,$a=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Za:Ya)), -void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Za={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$a[b]||n.find.attr;$a[b]=function(a,b,d){var e,f;return d||(f=$a[b],$a[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$a[b]=f),e}});var _a=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_a.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ab=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ab," ").indexOf(b)>=0)return!0;return!1}});var bb=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cb=n.now(),db=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var eb=/#.*$/,fb=/([?&])_=[^&]*/,gb=/^(.*?):[ \t]*([^\r\n]*)$/gm,hb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,ib=/^(?:GET|HEAD)$/,jb=/^\/\//,kb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lb={},mb={},nb="*/".concat("*"),ob=a.location.href,pb=kb.exec(ob.toLowerCase())||[];function qb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function rb(a,b,c,d){var e={},f=a===mb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function sb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function tb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function ub(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ob,type:"GET",isLocal:hb.test(pb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":nb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?sb(sb(a,n.ajaxSettings),b):sb(n.ajaxSettings,a)},ajaxPrefilter:qb(lb),ajaxTransport:qb(mb),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=gb.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||ob)+"").replace(eb,"").replace(jb,pb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=kb.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===pb[1]&&h[2]===pb[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(pb[3]||("http:"===pb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),rb(lb,k,b,v),2===t)return v;i=n.event&&k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!ib.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(db.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=fb.test(d)?d.replace(fb,"$1_="+cb++):d+(db.test(d)?"&":"?")+"_="+cb++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+nb+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=rb(mb,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=tb(k,v,f)),u=ub(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var vb=/%20/g,wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&").replace(vb,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Bb=0,Cb={},Db={0:200,1223:204},Eb=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Cb)Cb[a]()}),k.cors=!!Eb&&"withCredentials"in Eb,k.ajax=Eb=!!Eb,n.ajaxTransport(function(a){var b;return k.cors||Eb&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Bb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Cb[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Db[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Cb[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Fb=[],Gb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Fb.pop()||n.expando+"_"+cb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Gb.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Gb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Gb,"$1"+e):b.jsonp!==!1&&(b.url+=(db.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Fb.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Hb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Hb)return Hb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Ib=a.document.documentElement;function Jb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Jb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Ib;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ib})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Jb(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=ya(k.pixelPosition,function(a,c){return c?(c=xa(a,b),va.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Kb=a.jQuery,Lb=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Lb),b&&a.jQuery===n&&(a.jQuery=Kb),n},typeof b===U&&(a.jQuery=a.$=n),n}); diff --git a/radicale_web/web/infcloud/lib/jquery-ui-1.11.4.custom.js b/radicale_web/web/infcloud/lib/jquery-ui-1.11.4.custom.js deleted file mode 100644 index fa650d7..0000000 --- a/radicale_web/web/infcloud/lib/jquery-ui-1.11.4.custom.js +++ /dev/null @@ -1,8226 +0,0 @@ -/*! jQuery UI - v1.11.4 - 2015-03-15 -* http://jqueryui.com -* Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, autocomplete.js, datepicker.js, menu.js, slider.js -* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */ - -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "jquery" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } -}(function( $ ) { -/*! - * jQuery UI Core 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/category/ui-core/ - */ - - -// $.ui might exist from components with no dependencies, e.g., $.ui.position -$.ui = $.ui || {}; - -$.extend( $.ui, { - version: "1.11.4", - - keyCode: { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 - } -}); - -// plugins -$.fn.extend({ - scrollParent: function( includeHidden ) { - var position = this.css( "position" ), - excludeStaticParent = position === "absolute", - overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, - scrollParent = this.parents().filter( function() { - var parent = $( this ); - if ( excludeStaticParent && parent.css( "position" ) === "static" ) { - return false; - } - return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); - }).eq( 0 ); - - return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; - }, - - uniqueId: (function() { - var uuid = 0; - - return function() { - return this.each(function() { - if ( !this.id ) { - this.id = "ui-id-" + ( ++uuid ); - } - }); - }; - })(), - - removeUniqueId: function() { - return this.each(function() { - if ( /^ui-id-\d+$/.test( this.id ) ) { - $( this ).removeAttr( "id" ); - } - }); - } -}); - -// selectors -function focusable( element, isTabIndexNotNaN ) { - var map, mapName, img, - nodeName = element.nodeName.toLowerCase(); - if ( "area" === nodeName ) { - map = element.parentNode; - mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap='#" + mapName + "']" )[ 0 ]; - return !!img && visible( img ); - } - return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ? - !element.disabled : - "a" === nodeName ? - element.href || isTabIndexNotNaN : - isTabIndexNotNaN) && - // the element and all of its ancestors must be visible - visible( element ); -} - -function visible( element ) { - return $.expr.filters.visible( element ) && - !$( element ).parents().addBack().filter(function() { - return $.css( this, "visibility" ) === "hidden"; - }).length; -} - -$.extend( $.expr[ ":" ], { - data: $.expr.createPseudo ? - $.expr.createPseudo(function( dataName ) { - return function( elem ) { - return !!$.data( elem, dataName ); - }; - }) : - // support: jQuery <1.8 - function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - }, - - focusable: function( element ) { - return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); - }, - - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - isTabIndexNaN = isNaN( tabIndex ); - return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); - } -}); - -// support: jQuery <1.8 -if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { - $.each( [ "Width", "Height" ], function( i, name ) { - var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], - type = name.toLowerCase(), - orig = { - innerWidth: $.fn.innerWidth, - innerHeight: $.fn.innerHeight, - outerWidth: $.fn.outerWidth, - outerHeight: $.fn.outerHeight - }; - - function reduce( elem, size, border, margin ) { - $.each( side, function() { - size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; - if ( border ) { - size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; - } - if ( margin ) { - size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; - } - }); - return size; - } - - $.fn[ "inner" + name ] = function( size ) { - if ( size === undefined ) { - return orig[ "inner" + name ].call( this ); - } - - return this.each(function() { - $( this ).css( type, reduce( this, size ) + "px" ); - }); - }; - - $.fn[ "outer" + name] = function( size, margin ) { - if ( typeof size !== "number" ) { - return orig[ "outer" + name ].call( this, size ); - } - - return this.each(function() { - $( this).css( type, reduce( this, size, true, margin ) + "px" ); - }); - }; - }); -} - -// support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} - -// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) -if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { - $.fn.removeData = (function( removeData ) { - return function( key ) { - if ( arguments.length ) { - return removeData.call( this, $.camelCase( key ) ); - } else { - return removeData.call( this ); - } - }; - })( $.fn.removeData ); -} - -// deprecated -$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); - -$.fn.extend({ - focus: (function( orig ) { - return function( delay, fn ) { - return typeof delay === "number" ? - this.each(function() { - var elem = this; - setTimeout(function() { - $( elem ).focus(); - if ( fn ) { - fn.call( elem ); - } - }, delay ); - }) : - orig.apply( this, arguments ); - }; - })( $.fn.focus ), - - disableSelection: (function() { - var eventType = "onselectstart" in document.createElement( "div" ) ? - "selectstart" : - "mousedown"; - - return function() { - return this.bind( eventType + ".ui-disableSelection", function( event ) { - event.preventDefault(); - }); - }; - })(), - - enableSelection: function() { - return this.unbind( ".ui-disableSelection" ); - }, - - zIndex: function( zIndex ) { - if ( zIndex !== undefined ) { - return this.css( "zIndex", zIndex ); - } - - if ( this.length ) { - var elem = $( this[ 0 ] ), position, value; - while ( elem.length && elem[ 0 ] !== document ) { - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> - value = parseInt( elem.css( "zIndex" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - } - - return 0; - } -}); - -// $.ui.plugin is deprecated. Use $.widget() extensions instead. -$.ui.plugin = { - add: function( module, option, set ) { - var i, - proto = $.ui[ module ].prototype; - for ( i in set ) { - proto.plugins[ i ] = proto.plugins[ i ] || []; - proto.plugins[ i ].push( [ option, set[ i ] ] ); - } - }, - call: function( instance, name, args, allowDisconnected ) { - var i, - set = instance.plugins[ name ]; - - if ( !set ) { - return; - } - - if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) { - return; - } - - for ( i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); - } - } - } -}; - - -/*! - * jQuery UI Widget 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/jQuery.widget/ - */ - - -var widget_uuid = 0, - widget_slice = Array.prototype.slice; - -$.cleanData = (function( orig ) { - return function( elems ) { - var events, elem, i; - for ( i = 0; (elem = elems[i]) != null; i++ ) { - try { - - // Only trigger remove when necessary to save time - events = $._data( elem, "events" ); - if ( events && events.remove ) { - $( elem ).triggerHandler( "remove" ); - } - - // http://bugs.jquery.com/ticket/8235 - } catch ( e ) {} - } - orig( elems ); - }; -})( $.cleanData ); - -$.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; - - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; - - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); - } - - // allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - // copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); - - basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( !$.isFunction( value ) ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); - }); - constructor.prototype = $.widget.extend( basePrototype, { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - }); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; - - // redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } - - $.widget.bridge( name, constructor ); - - return constructor; -}; - -$.widget.extend = function( target ) { - var input = widget_slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; - -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = widget_slice.call( arguments, 1 ), - returnValue = this; - - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( options === "instance" ) { - returnValue = instance; - return false; - } - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); - } else { - - // Allow multiple hashes to be passed on init - if ( args.length ) { - options = $.widget.extend.apply( null, [ options ].concat(args) ); - } - - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} ); - if ( instance._init ) { - instance._init(); - } - } else { - $.data( this, fullName, new object( options, this ) ); - } - }); - } - - return returnValue; - }; -}; - -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "<div>", - options: { - disabled: false, - - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = widget_uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - }); - this.document = $( element.style ? - // element within the document - element.ownerDocument : - // element is window or document - element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); - } - - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, - - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); - - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key, - parts, - curOption, - i; - - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } - - if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( arguments.length === 1 ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( arguments.length === 1 ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } - - this._setOptions( options ); - - return this; - }, - _setOptions: function( options ) { - var key; - - for ( key in options ) { - this._setOption( key, options[ key ] ); - } - - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; - - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled", !!value ); - - // If the widget is becoming disabled, then nothing is interactive - if ( value ) { - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - } - - return this; - }, - - enable: function() { - return this._setOptions({ disabled: false }); - }, - disable: function() { - return this._setOptions({ disabled: true }); - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; - - // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // no element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } - - $.each( handlers, function( event, handler ) { - function handlerProxy() { - // allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - - // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } - - var match = event.match( /^([\w:-]*)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, - - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + - this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); - - // Clear the stack to avoid memory leaks (#10056) - this.bindings = $( this.bindings.not( element ).get() ); - this.focusable = $( this.focusable.not( element ).get() ); - this.hoverable = $( this.hoverable.not( element ).get() ); - }, - - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, - - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, - - _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; - - // copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; - -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); - } - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue(function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - }); - } - }; -}); - -var widget = $.widget; - - -/*! - * jQuery UI Mouse 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/mouse/ - */ - - -var mouseHandled = false; -$( document ).mouseup( function() { - mouseHandled = false; -}); - -var mouse = $.widget("ui.mouse", { - version: "1.11.4", - options: { - cancel: "input,textarea,button,select,option", - distance: 1, - delay: 0 - }, - _mouseInit: function() { - var that = this; - - this.element - .bind("mousedown." + this.widgetName, function(event) { - return that._mouseDown(event); - }) - .bind("click." + this.widgetName, function(event) { - if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { - $.removeData(event.target, that.widgetName + ".preventClickEvent"); - event.stopImmediatePropagation(); - return false; - } - }); - - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.unbind("." + this.widgetName); - if ( this._mouseMoveDelegate ) { - this.document - .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) - .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); - } - }, - - _mouseDown: function(event) { - // don't let more than one widget handle mouseStart - if ( mouseHandled ) { - return; - } - - this._mouseMoved = false; - - // we may have missed mouseup (out of window) - (this._mouseStarted && this._mouseUp(event)); - - this._mouseDownEvent = event; - - var that = this, - btnIsLeft = (event.which === 1), - // event.target.nodeName works around a bug in IE 8 with - // disabled inputs (#7620) - elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { - return true; - } - - this.mouseDelayMet = !this.options.delay; - if (!this.mouseDelayMet) { - this._mouseDelayTimer = setTimeout(function() { - that.mouseDelayMet = true; - }, this.options.delay); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = (this._mouseStart(event) !== false); - if (!this._mouseStarted) { - event.preventDefault(); - return true; - } - } - - // Click event may never have fired (Gecko & Opera) - if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { - $.removeData(event.target, this.widgetName + ".preventClickEvent"); - } - - // these delegates are required to keep context - this._mouseMoveDelegate = function(event) { - return that._mouseMove(event); - }; - this._mouseUpDelegate = function(event) { - return that._mouseUp(event); - }; - - this.document - .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .bind( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - event.preventDefault(); - - mouseHandled = true; - return true; - }, - - _mouseMove: function(event) { - // Only check for mouseups outside the document if you've moved inside the document - // at least once. This prevents the firing of mouseup in the case of IE<9, which will - // fire a mousemove event if content is placed under the cursor. See #7778 - // Support: IE <9 - if ( this._mouseMoved ) { - // IE mouseup check - mouseup happened when mouse was out of window - if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { - return this._mouseUp(event); - - // Iframe mouseup check - mouseup occurred in another document - } else if ( !event.which ) { - return this._mouseUp( event ); - } - } - - if ( event.which || event.button ) { - this._mouseMoved = true; - } - - if (this._mouseStarted) { - this._mouseDrag(event); - return event.preventDefault(); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = - (this._mouseStart(this._mouseDownEvent, event) !== false); - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); - } - - return !this._mouseStarted; - }, - - _mouseUp: function(event) { - this.document - .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - if (this._mouseStarted) { - this._mouseStarted = false; - - if (event.target === this._mouseDownEvent.target) { - $.data(event.target, this.widgetName + ".preventClickEvent", true); - } - - this._mouseStop(event); - } - - mouseHandled = false; - return false; - }, - - _mouseDistanceMet: function(event) { - return (Math.max( - Math.abs(this._mouseDownEvent.pageX - event.pageX), - Math.abs(this._mouseDownEvent.pageY - event.pageY) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function(/* event */) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function(/* event */) {}, - _mouseDrag: function(/* event */) {}, - _mouseStop: function(/* event */) {}, - _mouseCapture: function(/* event */) { return true; } -}); - - -/*! - * jQuery UI Position 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/position/ - */ - -(function() { - -$.ui = $.ui || {}; - -var cachedScrollbarWidth, supportsOffsetFractions, - max = Math.max, - abs = Math.abs, - round = Math.round, - rhorizontal = /left|center|right/, - rvertical = /top|center|bottom/, - roffset = /[\+\-]\d+(\.[\d]+)?%?/, - rposition = /^\w+/, - rpercent = /%$/, - _position = $.fn.position; - -function getOffsets( offsets, width, height ) { - return [ - parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), - parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) - ]; -} - -function parseCss( element, property ) { - return parseInt( $.css( element, property ), 10 ) || 0; -} - -function getDimensions( elem ) { - var raw = elem[0]; - if ( raw.nodeType === 9 ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: 0, left: 0 } - }; - } - if ( $.isWindow( raw ) ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: elem.scrollTop(), left: elem.scrollLeft() } - }; - } - if ( raw.preventDefault ) { - return { - width: 0, - height: 0, - offset: { top: raw.pageY, left: raw.pageX } - }; - } - return { - width: elem.outerWidth(), - height: elem.outerHeight(), - offset: elem.offset() - }; -} - -$.position = { - scrollbarWidth: function() { - if ( cachedScrollbarWidth !== undefined ) { - return cachedScrollbarWidth; - } - var w1, w2, - div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), - innerDiv = div.children()[0]; - - $( "body" ).append( div ); - w1 = innerDiv.offsetWidth; - div.css( "overflow", "scroll" ); - - w2 = innerDiv.offsetWidth; - - if ( w1 === w2 ) { - w2 = div[0].clientWidth; - } - - div.remove(); - - return (cachedScrollbarWidth = w1 - w2); - }, - getScrollInfo: function( within ) { - var overflowX = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-x" ), - overflowY = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-y" ), - hasOverflowX = overflowX === "scroll" || - ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), - hasOverflowY = overflowY === "scroll" || - ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); - return { - width: hasOverflowY ? $.position.scrollbarWidth() : 0, - height: hasOverflowX ? $.position.scrollbarWidth() : 0 - }; - }, - getWithinInfo: function( element ) { - var withinElement = $( element || window ), - isWindow = $.isWindow( withinElement[0] ), - isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; - return { - element: withinElement, - isWindow: isWindow, - isDocument: isDocument, - offset: withinElement.offset() || { left: 0, top: 0 }, - scrollLeft: withinElement.scrollLeft(), - scrollTop: withinElement.scrollTop(), - - // support: jQuery 1.6.x - // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows - width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), - height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() - }; - } -}; - -$.fn.position = function( options ) { - if ( !options || !options.of ) { - return _position.apply( this, arguments ); - } - - // make a copy, we don't want to modify arguments - options = $.extend( {}, options ); - - var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, - target = $( options.of ), - within = $.position.getWithinInfo( options.within ), - scrollInfo = $.position.getScrollInfo( within ), - collision = ( options.collision || "flip" ).split( " " ), - offsets = {}; - - dimensions = getDimensions( target ); - if ( target[0].preventDefault ) { - // force left top to allow flipping - options.at = "left top"; - } - targetWidth = dimensions.width; - targetHeight = dimensions.height; - targetOffset = dimensions.offset; - // clone to reuse original targetOffset later - basePosition = $.extend( {}, targetOffset ); - - // force my and at to have valid horizontal and vertical positions - // if a value is missing or invalid, it will be converted to center - $.each( [ "my", "at" ], function() { - var pos = ( options[ this ] || "" ).split( " " ), - horizontalOffset, - verticalOffset; - - if ( pos.length === 1) { - pos = rhorizontal.test( pos[ 0 ] ) ? - pos.concat( [ "center" ] ) : - rvertical.test( pos[ 0 ] ) ? - [ "center" ].concat( pos ) : - [ "center", "center" ]; - } - pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; - pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; - - // calculate offsets - horizontalOffset = roffset.exec( pos[ 0 ] ); - verticalOffset = roffset.exec( pos[ 1 ] ); - offsets[ this ] = [ - horizontalOffset ? horizontalOffset[ 0 ] : 0, - verticalOffset ? verticalOffset[ 0 ] : 0 - ]; - - // reduce to just the positions without the offsets - options[ this ] = [ - rposition.exec( pos[ 0 ] )[ 0 ], - rposition.exec( pos[ 1 ] )[ 0 ] - ]; - }); - - // normalize collision option - if ( collision.length === 1 ) { - collision[ 1 ] = collision[ 0 ]; - } - - if ( options.at[ 0 ] === "right" ) { - basePosition.left += targetWidth; - } else if ( options.at[ 0 ] === "center" ) { - basePosition.left += targetWidth / 2; - } - - if ( options.at[ 1 ] === "bottom" ) { - basePosition.top += targetHeight; - } else if ( options.at[ 1 ] === "center" ) { - basePosition.top += targetHeight / 2; - } - - atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); - basePosition.left += atOffset[ 0 ]; - basePosition.top += atOffset[ 1 ]; - - return this.each(function() { - var collisionPosition, using, - elem = $( this ), - elemWidth = elem.outerWidth(), - elemHeight = elem.outerHeight(), - marginLeft = parseCss( this, "marginLeft" ), - marginTop = parseCss( this, "marginTop" ), - collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, - collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, - position = $.extend( {}, basePosition ), - myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); - - if ( options.my[ 0 ] === "right" ) { - position.left -= elemWidth; - } else if ( options.my[ 0 ] === "center" ) { - position.left -= elemWidth / 2; - } - - if ( options.my[ 1 ] === "bottom" ) { - position.top -= elemHeight; - } else if ( options.my[ 1 ] === "center" ) { - position.top -= elemHeight / 2; - } - - position.left += myOffset[ 0 ]; - position.top += myOffset[ 1 ]; - - // if the browser doesn't support fractions, then round for consistent results - if ( !supportsOffsetFractions ) { - position.left = round( position.left ); - position.top = round( position.top ); - } - - collisionPosition = { - marginLeft: marginLeft, - marginTop: marginTop - }; - - $.each( [ "left", "top" ], function( i, dir ) { - if ( $.ui.position[ collision[ i ] ] ) { - $.ui.position[ collision[ i ] ][ dir ]( position, { - targetWidth: targetWidth, - targetHeight: targetHeight, - elemWidth: elemWidth, - elemHeight: elemHeight, - collisionPosition: collisionPosition, - collisionWidth: collisionWidth, - collisionHeight: collisionHeight, - offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], - my: options.my, - at: options.at, - within: within, - elem: elem - }); - } - }); - - if ( options.using ) { - // adds feedback as second argument to using callback, if present - using = function( props ) { - var left = targetOffset.left - position.left, - right = left + targetWidth - elemWidth, - top = targetOffset.top - position.top, - bottom = top + targetHeight - elemHeight, - feedback = { - target: { - element: target, - left: targetOffset.left, - top: targetOffset.top, - width: targetWidth, - height: targetHeight - }, - element: { - element: elem, - left: position.left, - top: position.top, - width: elemWidth, - height: elemHeight - }, - horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", - vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" - }; - if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { - feedback.horizontal = "center"; - } - if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { - feedback.vertical = "middle"; - } - if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { - feedback.important = "horizontal"; - } else { - feedback.important = "vertical"; - } - options.using.call( this, props, feedback ); - }; - } - - elem.offset( $.extend( position, { using: using } ) ); - }); -}; - -$.ui.position = { - fit: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, - outerWidth = within.width, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = withinOffset - collisionPosLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, - newOverRight; - - // element is wider than within - if ( data.collisionWidth > outerWidth ) { - // element is initially over the left side of within - if ( overLeft > 0 && overRight <= 0 ) { - newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; - position.left += overLeft - newOverRight; - // element is initially over right side of within - } else if ( overRight > 0 && overLeft <= 0 ) { - position.left = withinOffset; - // element is initially over both left and right sides of within - } else { - if ( overLeft > overRight ) { - position.left = withinOffset + outerWidth - data.collisionWidth; - } else { - position.left = withinOffset; - } - } - // too far left -> align with left edge - } else if ( overLeft > 0 ) { - position.left += overLeft; - // too far right -> align with right edge - } else if ( overRight > 0 ) { - position.left -= overRight; - // adjust based on position and margin - } else { - position.left = max( position.left - collisionPosLeft, position.left ); - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollTop : within.offset.top, - outerHeight = data.within.height, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = withinOffset - collisionPosTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, - newOverBottom; - - // element is taller than within - if ( data.collisionHeight > outerHeight ) { - // element is initially over the top of within - if ( overTop > 0 && overBottom <= 0 ) { - newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; - position.top += overTop - newOverBottom; - // element is initially over bottom of within - } else if ( overBottom > 0 && overTop <= 0 ) { - position.top = withinOffset; - // element is initially over both top and bottom of within - } else { - if ( overTop > overBottom ) { - position.top = withinOffset + outerHeight - data.collisionHeight; - } else { - position.top = withinOffset; - } - } - // too far up -> align with top - } else if ( overTop > 0 ) { - position.top += overTop; - // too far down -> align with bottom edge - } else if ( overBottom > 0 ) { - position.top -= overBottom; - // adjust based on position and margin - } else { - position.top = max( position.top - collisionPosTop, position.top ); - } - } - }, - flip: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.offset.left + within.scrollLeft, - outerWidth = within.width, - offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = collisionPosLeft - offsetLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, - myOffset = data.my[ 0 ] === "left" ? - -data.elemWidth : - data.my[ 0 ] === "right" ? - data.elemWidth : - 0, - atOffset = data.at[ 0 ] === "left" ? - data.targetWidth : - data.at[ 0 ] === "right" ? - -data.targetWidth : - 0, - offset = -2 * data.offset[ 0 ], - newOverRight, - newOverLeft; - - if ( overLeft < 0 ) { - newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; - if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { - position.left += myOffset + atOffset + offset; - } - } else if ( overRight > 0 ) { - newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; - if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { - position.left += myOffset + atOffset + offset; - } - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.offset.top + within.scrollTop, - outerHeight = within.height, - offsetTop = within.isWindow ? within.scrollTop : within.offset.top, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = collisionPosTop - offsetTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, - top = data.my[ 1 ] === "top", - myOffset = top ? - -data.elemHeight : - data.my[ 1 ] === "bottom" ? - data.elemHeight : - 0, - atOffset = data.at[ 1 ] === "top" ? - data.targetHeight : - data.at[ 1 ] === "bottom" ? - -data.targetHeight : - 0, - offset = -2 * data.offset[ 1 ], - newOverTop, - newOverBottom; - if ( overTop < 0 ) { - newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; - if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { - position.top += myOffset + atOffset + offset; - } - } else if ( overBottom > 0 ) { - newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; - if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { - position.top += myOffset + atOffset + offset; - } - } - } - }, - flipfit: { - left: function() { - $.ui.position.flip.left.apply( this, arguments ); - $.ui.position.fit.left.apply( this, arguments ); - }, - top: function() { - $.ui.position.flip.top.apply( this, arguments ); - $.ui.position.fit.top.apply( this, arguments ); - } - } -}; - -// fraction support test -(function() { - var testElement, testElementParent, testElementStyle, offsetLeft, i, - body = document.getElementsByTagName( "body" )[ 0 ], - div = document.createElement( "div" ); - - //Create a "fake body" for testing based on method used in jQuery.support - testElement = document.createElement( body ? "div" : "body" ); - testElementStyle = { - visibility: "hidden", - width: 0, - height: 0, - border: 0, - margin: 0, - background: "none" - }; - if ( body ) { - $.extend( testElementStyle, { - position: "absolute", - left: "-1000px", - top: "-1000px" - }); - } - for ( i in testElementStyle ) { - testElement.style[ i ] = testElementStyle[ i ]; - } - testElement.appendChild( div ); - testElementParent = body || document.documentElement; - testElementParent.insertBefore( testElement, testElementParent.firstChild ); - - div.style.cssText = "position: absolute; left: 10.7432222px;"; - - offsetLeft = $( div ).offset().left; - supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11; - - testElement.innerHTML = ""; - testElementParent.removeChild( testElement ); -})(); - -})(); - -var position = $.ui.position; - - -/*! - * jQuery UI Draggable 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/draggable/ - */ - - -$.widget("ui.draggable", $.ui.mouse, { - version: "1.11.4", - widgetEventPrefix: "drag", - options: { - addClasses: true, - appendTo: "parent", - axis: false, - connectToSortable: false, - containment: false, - cursor: "auto", - cursorAt: false, - grid: false, - handle: false, - helper: "original", - iframeFix: false, - opacity: false, - refreshPositions: false, - revert: false, - revertDuration: 500, - scope: "default", - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - snap: false, - snapMode: "both", - snapTolerance: 20, - stack: false, - zIndex: false, - - // callbacks - drag: null, - start: null, - stop: null - }, - _create: function() { - - if ( this.options.helper === "original" ) { - this._setPositionRelative(); - } - if (this.options.addClasses){ - this.element.addClass("ui-draggable"); - } - if (this.options.disabled){ - this.element.addClass("ui-draggable-disabled"); - } - this._setHandleClassName(); - - this._mouseInit(); - }, - - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "handle" ) { - this._removeHandleClassName(); - this._setHandleClassName(); - } - }, - - _destroy: function() { - if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { - this.destroyOnClear = true; - return; - } - this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); - this._removeHandleClassName(); - this._mouseDestroy(); - }, - - _mouseCapture: function(event) { - var o = this.options; - - this._blurActiveElement( event ); - - // among others, prevent a drag on a resizable-handle - if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { - return false; - } - - //Quit if we're not on a valid handle - this.handle = this._getHandle(event); - if (!this.handle) { - return false; - } - - this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); - - return true; - - }, - - _blockFrames: function( selector ) { - this.iframeBlocks = this.document.find( selector ).map(function() { - var iframe = $( this ); - - return $( "<div>" ) - .css( "position", "absolute" ) - .appendTo( iframe.parent() ) - .outerWidth( iframe.outerWidth() ) - .outerHeight( iframe.outerHeight() ) - .offset( iframe.offset() )[ 0 ]; - }); - }, - - _unblockFrames: function() { - if ( this.iframeBlocks ) { - this.iframeBlocks.remove(); - delete this.iframeBlocks; - } - }, - - _blurActiveElement: function( event ) { - var document = this.document[ 0 ]; - - // Only need to blur if the event occurred on the draggable itself, see #10527 - if ( !this.handleElement.is( event.target ) ) { - return; - } - - // support: IE9 - // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe> - try { - - // Support: IE9, IE10 - // If the <body> is blurred, IE will switch windows, see #9520 - if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) { - - // Blur any element that currently has focus, see #4261 - $( document.activeElement ).blur(); - } - } catch ( error ) {} - }, - - _mouseStart: function(event) { - - var o = this.options; - - //Create and append the visible helper - this.helper = this._createHelper(event); - - this.helper.addClass("ui-draggable-dragging"); - - //Cache the helper size - this._cacheHelperProportions(); - - //If ddmanager is used for droppables, set the global draggable - if ($.ui.ddmanager) { - $.ui.ddmanager.current = this; - } - - /* - * - Position generation - - * This block generates everything position related - it's the core of draggables. - */ - - //Cache the margins of the original element - this._cacheMargins(); - - //Store the helper's css position - this.cssPosition = this.helper.css( "position" ); - this.scrollParent = this.helper.scrollParent( true ); - this.offsetParent = this.helper.offsetParent(); - this.hasFixedAncestor = this.helper.parents().filter(function() { - return $( this ).css( "position" ) === "fixed"; - }).length > 0; - - //The element's absolute position on the page minus margins - this.positionAbs = this.element.offset(); - this._refreshOffsets( event ); - - //Generate the original position - this.originalPosition = this.position = this._generatePosition( event, false ); - this.originalPageX = event.pageX; - this.originalPageY = event.pageY; - - //Adjust the mouse offset relative to the helper if "cursorAt" is supplied - (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); - - //Set a containment if given in the options - this._setContainment(); - - //Trigger event + callbacks - if (this._trigger("start", event) === false) { - this._clear(); - return false; - } - - //Recache the helper size - this._cacheHelperProportions(); - - //Prepare the droppable offsets - if ($.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(this, event); - } - - // Reset helper's right/bottom css if they're set and set explicit width/height instead - // as this prevents resizing of elements with right/bottom set (see #7772) - this._normalizeRightBottom(); - - this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position - - //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) - if ( $.ui.ddmanager ) { - $.ui.ddmanager.dragStart(this, event); - } - - return true; - }, - - _refreshOffsets: function( event ) { - this.offset = { - top: this.positionAbs.top - this.margins.top, - left: this.positionAbs.left - this.margins.left, - scroll: false, - parent: this._getParentOffset(), - relative: this._getRelativeOffset() - }; - - this.offset.click = { - left: event.pageX - this.offset.left, - top: event.pageY - this.offset.top - }; - }, - - _mouseDrag: function(event, noPropagation) { - // reset any necessary cached properties (see #5009) - if ( this.hasFixedAncestor ) { - this.offset.parent = this._getParentOffset(); - } - - //Compute the helpers position - this.position = this._generatePosition( event, true ); - this.positionAbs = this._convertPositionTo("absolute"); - - //Call plugins and callbacks and use the resulting position if something is returned - if (!noPropagation) { - var ui = this._uiHash(); - if (this._trigger("drag", event, ui) === false) { - this._mouseUp({}); - return false; - } - this.position = ui.position; - } - - this.helper[ 0 ].style.left = this.position.left + "px"; - this.helper[ 0 ].style.top = this.position.top + "px"; - - if ($.ui.ddmanager) { - $.ui.ddmanager.drag(this, event); - } - - return false; - }, - - _mouseStop: function(event) { - - //If we are using droppables, inform the manager about the drop - var that = this, - dropped = false; - if ($.ui.ddmanager && !this.options.dropBehaviour) { - dropped = $.ui.ddmanager.drop(this, event); - } - - //if a drop comes from outside (a sortable) - if (this.dropped) { - dropped = this.dropped; - this.dropped = false; - } - - 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))) { - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { - if (that._trigger("stop", event) !== false) { - that._clear(); - } - }); - } else { - if (this._trigger("stop", event) !== false) { - this._clear(); - } - } - - return false; - }, - - _mouseUp: function( event ) { - this._unblockFrames(); - - //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) - if ( $.ui.ddmanager ) { - $.ui.ddmanager.dragStop(this, event); - } - - // Only need to focus if the event occurred on the draggable itself, see #10527 - if ( this.handleElement.is( event.target ) ) { - // The interaction is over; whether or not the click resulted in a drag, focus the element - this.element.focus(); - } - - return $.ui.mouse.prototype._mouseUp.call(this, event); - }, - - cancel: function() { - - if (this.helper.is(".ui-draggable-dragging")) { - this._mouseUp({}); - } else { - this._clear(); - } - - return this; - - }, - - _getHandle: function(event) { - return this.options.handle ? - !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : - true; - }, - - _setHandleClassName: function() { - this.handleElement = this.options.handle ? - this.element.find( this.options.handle ) : this.element; - this.handleElement.addClass( "ui-draggable-handle" ); - }, - - _removeHandleClassName: function() { - this.handleElement.removeClass( "ui-draggable-handle" ); - }, - - _createHelper: function(event) { - - var o = this.options, - helperIsFunction = $.isFunction( o.helper ), - helper = helperIsFunction ? - $( o.helper.apply( this.element[ 0 ], [ event ] ) ) : - ( o.helper === "clone" ? - this.element.clone().removeAttr( "id" ) : - this.element ); - - if (!helper.parents("body").length) { - helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); - } - - // http://bugs.jqueryui.com/ticket/9446 - // a helper function can return the original element - // which wouldn't have been set to relative in _create - if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) { - this._setPositionRelative(); - } - - if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { - helper.css("position", "absolute"); - } - - return helper; - - }, - - _setPositionRelative: function() { - if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) { - this.element[ 0 ].style.position = "relative"; - } - }, - - _adjustOffsetFromHelper: function(obj) { - if (typeof obj === "string") { - obj = obj.split(" "); - } - if ($.isArray(obj)) { - obj = { left: +obj[0], top: +obj[1] || 0 }; - } - if ("left" in obj) { - this.offset.click.left = obj.left + this.margins.left; - } - if ("right" in obj) { - this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; - } - if ("top" in obj) { - this.offset.click.top = obj.top + this.margins.top; - } - if ("bottom" in obj) { - this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; - } - }, - - _isRootNode: function( element ) { - return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ]; - }, - - _getParentOffset: function() { - - //Get the offsetParent and cache its position - var po = this.offsetParent.offset(), - document = this.document[ 0 ]; - - // This is a special case where we need to modify a offset calculated on start, since the following happened: - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag - if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { - po.left += this.scrollParent.scrollLeft(); - po.top += this.scrollParent.scrollTop(); - } - - if ( this._isRootNode( this.offsetParent[ 0 ] ) ) { - po = { top: 0, left: 0 }; - } - - return { - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0), - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0) - }; - - }, - - _getRelativeOffset: function() { - if ( this.cssPosition !== "relative" ) { - return { top: 0, left: 0 }; - } - - var p = this.element.position(), - scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); - - return { - top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ), - left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 ) - }; - - }, - - _cacheMargins: function() { - this.margins = { - left: (parseInt(this.element.css("marginLeft"), 10) || 0), - top: (parseInt(this.element.css("marginTop"), 10) || 0), - right: (parseInt(this.element.css("marginRight"), 10) || 0), - bottom: (parseInt(this.element.css("marginBottom"), 10) || 0) - }; - }, - - _cacheHelperProportions: function() { - this.helperProportions = { - width: this.helper.outerWidth(), - height: this.helper.outerHeight() - }; - }, - - _setContainment: function() { - - var isUserScrollable, c, ce, - o = this.options, - document = this.document[ 0 ]; - - this.relativeContainer = null; - - if ( !o.containment ) { - this.containment = null; - return; - } - - if ( o.containment === "window" ) { - this.containment = [ - $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, - $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, - $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, - $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top - ]; - return; - } - - if ( o.containment === "document") { - this.containment = [ - 0, - 0, - $( document ).width() - this.helperProportions.width - this.margins.left, - ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top - ]; - return; - } - - if ( o.containment.constructor === Array ) { - this.containment = o.containment; - return; - } - - if ( o.containment === "parent" ) { - o.containment = this.helper[ 0 ].parentNode; - } - - c = $( o.containment ); - ce = c[ 0 ]; - - if ( !ce ) { - return; - } - - isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) ); - - this.containment = [ - ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), - ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ), - ( isUserScrollable ? 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, - ( isUserScrollable ? 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 - ]; - this.relativeContainer = c; - }, - - _convertPositionTo: function(d, pos) { - - if (!pos) { - pos = this.position; - } - - var mod = d === "absolute" ? 1 : -1, - scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ); - - return { - top: ( - pos.top + // The absolute mouse position - this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod) - ), - left: ( - pos.left + // The absolute mouse position - this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) - ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod) - ) - }; - - }, - - _generatePosition: function( event, constrainPosition ) { - - var containment, co, top, left, - o = this.options, - scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ), - pageX = event.pageX, - pageY = event.pageY; - - // Cache the scroll - if ( !scrollIsRootNode || !this.offset.scroll ) { - this.offset.scroll = { - top: this.scrollParent.scrollTop(), - left: this.scrollParent.scrollLeft() - }; - } - - /* - * - Position constraining - - * Constrain the position to a mix of grid, containment. - */ - - // If we are not dragging yet, we won't check for options - if ( constrainPosition ) { - if ( this.containment ) { - if ( this.relativeContainer ){ - co = this.relativeContainer.offset(); - containment = [ - this.containment[ 0 ] + co.left, - this.containment[ 1 ] + co.top, - this.containment[ 2 ] + co.left, - this.containment[ 3 ] + co.top - ]; - } else { - containment = this.containment; - } - - if (event.pageX - this.offset.click.left < containment[0]) { - pageX = containment[0] + this.offset.click.left; - } - if (event.pageY - this.offset.click.top < containment[1]) { - pageY = containment[1] + this.offset.click.top; - } - if (event.pageX - this.offset.click.left > containment[2]) { - pageX = containment[2] + this.offset.click.left; - } - if (event.pageY - this.offset.click.top > containment[3]) { - pageY = containment[3] + this.offset.click.top; - } - } - - if (o.grid) { - //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) - top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; - 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; - - left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; - 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; - } - - if ( o.axis === "y" ) { - pageX = this.originalPageX; - } - - if ( o.axis === "x" ) { - pageY = this.originalPageY; - } - } - - return { - top: ( - pageY - // The absolute mouse position - this.offset.click.top - // Click offset (relative to the element) - this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top + // The offsetParent's offset without borders (offset + border) - ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) - ), - left: ( - pageX - // The absolute mouse position - this.offset.click.left - // Click offset (relative to the element) - this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left + // The offsetParent's offset without borders (offset + border) - ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) - ) - }; - - }, - - _clear: function() { - this.helper.removeClass("ui-draggable-dragging"); - if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { - this.helper.remove(); - } - this.helper = null; - this.cancelHelperRemoval = false; - if ( this.destroyOnClear ) { - this.destroy(); - } - }, - - _normalizeRightBottom: function() { - if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) { - this.helper.width( this.helper.width() ); - this.helper.css( "right", "auto" ); - } - if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) { - this.helper.height( this.helper.height() ); - this.helper.css( "bottom", "auto" ); - } - }, - - // From now on bulk stuff - mainly helpers - - _trigger: function( type, event, ui ) { - ui = ui || this._uiHash(); - $.ui.plugin.call( this, type, [ event, ui, this ], true ); - - // Absolute position and offset (see #6884 ) have to be recalculated after plugins - if ( /^(drag|start|stop)/.test( type ) ) { - this.positionAbs = this._convertPositionTo( "absolute" ); - ui.offset = this.positionAbs; - } - return $.Widget.prototype._trigger.call( this, type, event, ui ); - }, - - plugins: {}, - - _uiHash: function() { - return { - helper: this.helper, - position: this.position, - originalPosition: this.originalPosition, - offset: this.positionAbs - }; - } - -}); - -$.ui.plugin.add( "draggable", "connectToSortable", { - start: function( event, ui, draggable ) { - var uiSortable = $.extend( {}, ui, { - item: draggable.element - }); - - draggable.sortables = []; - $( draggable.options.connectToSortable ).each(function() { - var sortable = $( this ).sortable( "instance" ); - - if ( sortable && !sortable.options.disabled ) { - draggable.sortables.push( sortable ); - - // refreshPositions is called at drag start to refresh the containerCache - // which is used in drag. This ensures it's initialized and synchronized - // with any changes that might have happened on the page since initialization. - sortable.refreshPositions(); - sortable._trigger("activate", event, uiSortable); - } - }); - }, - stop: function( event, ui, draggable ) { - var uiSortable = $.extend( {}, ui, { - item: draggable.element - }); - - draggable.cancelHelperRemoval = false; - - $.each( draggable.sortables, function() { - var sortable = this; - - if ( sortable.isOver ) { - sortable.isOver = 0; - - // Allow this sortable to handle removing the helper - draggable.cancelHelperRemoval = true; - sortable.cancelHelperRemoval = false; - - // Use _storedCSS To restore properties in the sortable, - // as this also handles revert (#9675) since the draggable - // may have modified them in unexpected ways (#8809) - sortable._storedCSS = { - position: sortable.placeholder.css( "position" ), - top: sortable.placeholder.css( "top" ), - left: sortable.placeholder.css( "left" ) - }; - - sortable._mouseStop(event); - - // Once drag has ended, the sortable should return to using - // its original helper, not the shared helper from draggable - sortable.options.helper = sortable.options._helper; - } else { - // Prevent this Sortable from removing the helper. - // However, don't set the draggable to remove the helper - // either as another connected Sortable may yet handle the removal. - sortable.cancelHelperRemoval = true; - - sortable._trigger( "deactivate", event, uiSortable ); - } - }); - }, - drag: function( event, ui, draggable ) { - $.each( draggable.sortables, function() { - var innermostIntersecting = false, - sortable = this; - - // Copy over variables that sortable's _intersectsWith uses - sortable.positionAbs = draggable.positionAbs; - sortable.helperProportions = draggable.helperProportions; - sortable.offset.click = draggable.offset.click; - - if ( sortable._intersectsWith( sortable.containerCache ) ) { - innermostIntersecting = true; - - $.each( draggable.sortables, function() { - // Copy over variables that sortable's _intersectsWith uses - this.positionAbs = draggable.positionAbs; - this.helperProportions = draggable.helperProportions; - this.offset.click = draggable.offset.click; - - if ( this !== sortable && - this._intersectsWith( this.containerCache ) && - $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) { - innermostIntersecting = false; - } - - return innermostIntersecting; - }); - } - - if ( innermostIntersecting ) { - // If it intersects, we use a little isOver variable and set it once, - // so that the move-in stuff gets fired only once. - if ( !sortable.isOver ) { - sortable.isOver = 1; - - // Store draggable's parent in case we need to reappend to it later. - draggable._parent = ui.helper.parent(); - - sortable.currentItem = ui.helper - .appendTo( sortable.element ) - .data( "ui-sortable-item", true ); - - // Store helper option to later restore it - sortable.options._helper = sortable.options.helper; - - sortable.options.helper = function() { - return ui.helper[ 0 ]; - }; - - // Fire the start events of the sortable with our passed browser event, - // and our own helper (so it doesn't create a new one) - event.target = sortable.currentItem[ 0 ]; - sortable._mouseCapture( event, true ); - sortable._mouseStart( event, true, true ); - - // Because the browser event is way off the new appended portlet, - // modify necessary variables to reflect the changes - sortable.offset.click.top = draggable.offset.click.top; - sortable.offset.click.left = draggable.offset.click.left; - sortable.offset.parent.left -= draggable.offset.parent.left - - sortable.offset.parent.left; - sortable.offset.parent.top -= draggable.offset.parent.top - - sortable.offset.parent.top; - - draggable._trigger( "toSortable", event ); - - // Inform draggable that the helper is in a valid drop zone, - // used solely in the revert option to handle "valid/invalid". - draggable.dropped = sortable.element; - - // Need to refreshPositions of all sortables in the case that - // adding to one sortable changes the location of the other sortables (#9675) - $.each( draggable.sortables, function() { - this.refreshPositions(); - }); - - // hack so receive/update callbacks work (mostly) - draggable.currentItem = draggable.element; - sortable.fromOutside = draggable; - } - - if ( sortable.currentItem ) { - sortable._mouseDrag( event ); - // Copy the sortable's position because the draggable's can potentially reflect - // a relative position, while sortable is always absolute, which the dragged - // element has now become. (#8809) - ui.position = sortable.position; - } - } else { - // If it doesn't intersect with the sortable, and it intersected before, - // we fake the drag stop of the sortable, but make sure it doesn't remove - // the helper by using cancelHelperRemoval. - if ( sortable.isOver ) { - - sortable.isOver = 0; - sortable.cancelHelperRemoval = true; - - // Calling sortable's mouseStop would trigger a revert, - // so revert must be temporarily false until after mouseStop is called. - sortable.options._revert = sortable.options.revert; - sortable.options.revert = false; - - sortable._trigger( "out", event, sortable._uiHash( sortable ) ); - sortable._mouseStop( event, true ); - - // restore sortable behaviors that were modfied - // when the draggable entered the sortable area (#9481) - sortable.options.revert = sortable.options._revert; - sortable.options.helper = sortable.options._helper; - - if ( sortable.placeholder ) { - sortable.placeholder.remove(); - } - - // Restore and recalculate the draggable's offset considering the sortable - // may have modified them in unexpected ways. (#8809, #10669) - ui.helper.appendTo( draggable._parent ); - draggable._refreshOffsets( event ); - ui.position = draggable._generatePosition( event, true ); - - draggable._trigger( "fromSortable", event ); - - // Inform draggable that the helper is no longer in a valid drop zone - draggable.dropped = false; - - // Need to refreshPositions of all sortables just in case removing - // from one sortable changes the location of other sortables (#9675) - $.each( draggable.sortables, function() { - this.refreshPositions(); - }); - } - } - }); - } -}); - -$.ui.plugin.add("draggable", "cursor", { - start: function( event, ui, instance ) { - var t = $( "body" ), - o = instance.options; - - if (t.css("cursor")) { - o._cursor = t.css("cursor"); - } - t.css("cursor", o.cursor); - }, - stop: function( event, ui, instance ) { - var o = instance.options; - if (o._cursor) { - $("body").css("cursor", o._cursor); - } - } -}); - -$.ui.plugin.add("draggable", "opacity", { - start: function( event, ui, instance ) { - var t = $( ui.helper ), - o = instance.options; - if (t.css("opacity")) { - o._opacity = t.css("opacity"); - } - t.css("opacity", o.opacity); - }, - stop: function( event, ui, instance ) { - var o = instance.options; - if (o._opacity) { - $(ui.helper).css("opacity", o._opacity); - } - } -}); - -$.ui.plugin.add("draggable", "scroll", { - start: function( event, ui, i ) { - if ( !i.scrollParentNotHidden ) { - i.scrollParentNotHidden = i.helper.scrollParent( false ); - } - - if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) { - i.overflowOffset = i.scrollParentNotHidden.offset(); - } - }, - drag: function( event, ui, i ) { - - var o = i.options, - scrolled = false, - scrollParent = i.scrollParentNotHidden[ 0 ], - document = i.document[ 0 ]; - - if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) { - if ( !o.axis || o.axis !== "x" ) { - if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) { - scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed; - } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) { - scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed; - } - } - - if ( !o.axis || o.axis !== "y" ) { - if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) { - scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed; - } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) { - scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed; - } - } - - } else { - - if (!o.axis || o.axis !== "x") { - if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); - } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); - } - } - - if (!o.axis || o.axis !== "y") { - if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); - } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); - } - } - - } - - if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { - $.ui.ddmanager.prepareOffsets(i, event); - } - - } -}); - -$.ui.plugin.add("draggable", "snap", { - start: function( event, ui, i ) { - - var o = i.options; - - i.snapElements = []; - - $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { - var $t = $(this), - $o = $t.offset(); - if (this !== i.element[0]) { - i.snapElements.push({ - item: this, - width: $t.outerWidth(), height: $t.outerHeight(), - top: $o.top, left: $o.left - }); - } - }); - - }, - drag: function( event, ui, inst ) { - - var ts, bs, ls, rs, l, r, t, b, i, first, - o = inst.options, - d = o.snapTolerance, - x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, - y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; - - for (i = inst.snapElements.length - 1; i >= 0; i--){ - - l = inst.snapElements[i].left - inst.margins.left; - r = l + inst.snapElements[i].width; - t = inst.snapElements[i].top - inst.margins.top; - b = t + inst.snapElements[i].height; - - if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { - if (inst.snapElements[i].snapping) { - (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); - } - inst.snapElements[i].snapping = false; - continue; - } - - if (o.snapMode !== "inner") { - ts = Math.abs(t - y2) <= d; - bs = Math.abs(b - y1) <= d; - ls = Math.abs(l - x2) <= d; - rs = Math.abs(r - x1) <= d; - if (ts) { - ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top; - } - if (bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top; - } - if (ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left; - } - if (rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left; - } - } - - first = (ts || bs || ls || rs); - - if (o.snapMode !== "outer") { - ts = Math.abs(t - y1) <= d; - bs = Math.abs(b - y2) <= d; - ls = Math.abs(l - x1) <= d; - rs = Math.abs(r - x2) <= d; - if (ts) { - ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top; - } - if (bs) { - ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top; - } - if (ls) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left; - } - if (rs) { - ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left; - } - } - - if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { - (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); - } - inst.snapElements[i].snapping = (ts || bs || ls || rs || first); - - } - - } -}); - -$.ui.plugin.add("draggable", "stack", { - start: function( event, ui, instance ) { - var min, - o = instance.options, - group = $.makeArray($(o.stack)).sort(function(a, b) { - return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0); - }); - - if (!group.length) { return; } - - min = parseInt($(group[0]).css("zIndex"), 10) || 0; - $(group).each(function(i) { - $(this).css("zIndex", min + i); - }); - this.css("zIndex", (min + group.length)); - } -}); - -$.ui.plugin.add("draggable", "zIndex", { - start: function( event, ui, instance ) { - var t = $( ui.helper ), - o = instance.options; - - if (t.css("zIndex")) { - o._zIndex = t.css("zIndex"); - } - t.css("zIndex", o.zIndex); - }, - stop: function( event, ui, instance ) { - var o = instance.options; - - if (o._zIndex) { - $(ui.helper).css("zIndex", o._zIndex); - } - } -}); - -var draggable = $.ui.draggable; - - -/*! - * jQuery UI Droppable 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/droppable/ - */ - - -$.widget( "ui.droppable", { - version: "1.11.4", - widgetEventPrefix: "drop", - options: { - accept: "*", - activeClass: false, - addClasses: true, - greedy: false, - hoverClass: false, - scope: "default", - tolerance: "intersect", - - // callbacks - activate: null, - deactivate: null, - drop: null, - out: null, - over: null - }, - _create: function() { - - var proportions, - o = this.options, - accept = o.accept; - - this.isover = false; - this.isout = true; - - this.accept = $.isFunction( accept ) ? accept : function( d ) { - return d.is( accept ); - }; - - this.proportions = function( /* valueToWrite */ ) { - if ( arguments.length ) { - // Store the droppable's proportions - proportions = arguments[ 0 ]; - } else { - // Retrieve or derive the droppable's proportions - return proportions ? - proportions : - proportions = { - width: this.element[ 0 ].offsetWidth, - height: this.element[ 0 ].offsetHeight - }; - } - }; - - this._addToManager( o.scope ); - - o.addClasses && this.element.addClass( "ui-droppable" ); - - }, - - _addToManager: function( scope ) { - // Add the reference and positions to the manager - $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || []; - $.ui.ddmanager.droppables[ scope ].push( this ); - }, - - _splice: function( drop ) { - var i = 0; - for ( ; i < drop.length; i++ ) { - if ( drop[ i ] === this ) { - drop.splice( i, 1 ); - } - } - }, - - _destroy: function() { - var drop = $.ui.ddmanager.droppables[ this.options.scope ]; - - this._splice( drop ); - - this.element.removeClass( "ui-droppable ui-droppable-disabled" ); - }, - - _setOption: function( key, value ) { - - if ( key === "accept" ) { - this.accept = $.isFunction( value ) ? value : function( d ) { - return d.is( value ); - }; - } else if ( key === "scope" ) { - var drop = $.ui.ddmanager.droppables[ this.options.scope ]; - - this._splice( drop ); - this._addToManager( value ); - } - - this._super( key, value ); - }, - - _activate: function( event ) { - var draggable = $.ui.ddmanager.current; - if ( this.options.activeClass ) { - this.element.addClass( this.options.activeClass ); - } - if ( draggable ){ - this._trigger( "activate", event, this.ui( draggable ) ); - } - }, - - _deactivate: function( event ) { - var draggable = $.ui.ddmanager.current; - if ( this.options.activeClass ) { - this.element.removeClass( this.options.activeClass ); - } - if ( draggable ){ - this._trigger( "deactivate", event, this.ui( draggable ) ); - } - }, - - _over: function( event ) { - - var draggable = $.ui.ddmanager.current; - - // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { - return; - } - - if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { - if ( this.options.hoverClass ) { - this.element.addClass( this.options.hoverClass ); - } - this._trigger( "over", event, this.ui( draggable ) ); - } - - }, - - _out: function( event ) { - - var draggable = $.ui.ddmanager.current; - - // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { - return; - } - - if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { - if ( this.options.hoverClass ) { - this.element.removeClass( this.options.hoverClass ); - } - this._trigger( "out", event, this.ui( draggable ) ); - } - - }, - - _drop: function( event, custom ) { - - var draggable = custom || $.ui.ddmanager.current, - childrenIntersection = false; - - // Bail if draggable and droppable are same element - if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) { - return false; - } - - this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() { - var inst = $( this ).droppable( "instance" ); - if ( - inst.options.greedy && - !inst.options.disabled && - inst.options.scope === draggable.options.scope && - inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) && - $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event ) - ) { childrenIntersection = true; return false; } - }); - if ( childrenIntersection ) { - return false; - } - - if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { - if ( this.options.activeClass ) { - this.element.removeClass( this.options.activeClass ); - } - if ( this.options.hoverClass ) { - this.element.removeClass( this.options.hoverClass ); - } - this._trigger( "drop", event, this.ui( draggable ) ); - return this.element; - } - - return false; - - }, - - ui: function( c ) { - return { - draggable: ( c.currentItem || c.element ), - helper: c.helper, - position: c.position, - offset: c.positionAbs - }; - } - -}); - -$.ui.intersect = (function() { - function isOverAxis( x, reference, size ) { - return ( x >= reference ) && ( x < ( reference + size ) ); - } - - return function( draggable, droppable, toleranceMode, event ) { - - if ( !droppable.offset ) { - return false; - } - - var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left, - y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top, - x2 = x1 + draggable.helperProportions.width, - y2 = y1 + draggable.helperProportions.height, - l = droppable.offset.left, - t = droppable.offset.top, - r = l + droppable.proportions().width, - b = t + droppable.proportions().height; - - switch ( toleranceMode ) { - case "fit": - return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b ); - case "intersect": - return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half - x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half - t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half - y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half - case "pointer": - return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width ); - case "touch": - return ( - ( y1 >= t && y1 <= b ) || // Top edge touching - ( y2 >= t && y2 <= b ) || // Bottom edge touching - ( y1 < t && y2 > b ) // Surrounded vertically - ) && ( - ( x1 >= l && x1 <= r ) || // Left edge touching - ( x2 >= l && x2 <= r ) || // Right edge touching - ( x1 < l && x2 > r ) // Surrounded horizontally - ); - default: - return false; - } - }; -})(); - -/* - This manager tracks offsets of draggables and droppables -*/ -$.ui.ddmanager = { - current: null, - droppables: { "default": [] }, - prepareOffsets: function( t, event ) { - - var i, j, - m = $.ui.ddmanager.droppables[ t.options.scope ] || [], - type = event ? event.type : null, // workaround for #2317 - list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack(); - - droppablesLoop: for ( i = 0; i < m.length; i++ ) { - - // No disabled and non-accepted - if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) { - continue; - } - - // Filter out elements in the current dragged item - for ( j = 0; j < list.length; j++ ) { - if ( list[ j ] === m[ i ].element[ 0 ] ) { - m[ i ].proportions().height = 0; - continue droppablesLoop; - } - } - - m[ i ].visible = m[ i ].element.css( "display" ) !== "none"; - if ( !m[ i ].visible ) { - continue; - } - - // Activate the droppable if used directly from draggables - if ( type === "mousedown" ) { - m[ i ]._activate.call( m[ i ], event ); - } - - m[ i ].offset = m[ i ].element.offset(); - m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); - - } - - }, - drop: function( draggable, event ) { - - var dropped = false; - // Create a copy of the droppables in case the list changes during the drop (#9116) - $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() { - - if ( !this.options ) { - return; - } - if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) { - dropped = this._drop.call( this, event ) || dropped; - } - - if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) { - this.isout = true; - this.isover = false; - this._deactivate.call( this, event ); - } - - }); - return dropped; - - }, - dragStart: function( draggable, event ) { - // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) - draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { - if ( !draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } - }); - }, - drag: function( draggable, event ) { - - // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. - if ( draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } - - // Run through all droppables and check their positions based on specific tolerance options - $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() { - - if ( this.options.disabled || this.greedyChild || !this.visible ) { - return; - } - - var parentInstance, scope, parent, - intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ), - c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null ); - if ( !c ) { - return; - } - - if ( this.options.greedy ) { - // find droppable parents with same scope - scope = this.options.scope; - parent = this.element.parents( ":data(ui-droppable)" ).filter(function() { - return $( this ).droppable( "instance" ).options.scope === scope; - }); - - if ( parent.length ) { - parentInstance = $( parent[ 0 ] ).droppable( "instance" ); - parentInstance.greedyChild = ( c === "isover" ); - } - } - - // we just moved into a greedy child - if ( parentInstance && c === "isover" ) { - parentInstance.isover = false; - parentInstance.isout = true; - parentInstance._out.call( parentInstance, event ); - } - - this[ c ] = true; - this[c === "isout" ? "isover" : "isout"] = false; - this[c === "isover" ? "_over" : "_out"].call( this, event ); - - // we just moved out of a greedy child - if ( parentInstance && c === "isout" ) { - parentInstance.isout = false; - parentInstance.isover = true; - parentInstance._over.call( parentInstance, event ); - } - }); - - }, - dragStop: function( draggable, event ) { - draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); - // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) - if ( !draggable.options.refreshPositions ) { - $.ui.ddmanager.prepareOffsets( draggable, event ); - } - } -}; - -var droppable = $.ui.droppable; - - -/*! - * jQuery UI Resizable 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/resizable/ - */ - - -$.widget("ui.resizable", $.ui.mouse, { - version: "1.11.4", - widgetEventPrefix: "resize", - options: { - alsoResize: false, - animate: false, - animateDuration: "slow", - animateEasing: "swing", - aspectRatio: false, - autoHide: false, - containment: false, - ghost: false, - grid: false, - handles: "e,s,se", - helper: false, - maxHeight: null, - maxWidth: null, - minHeight: 10, - minWidth: 10, - // See #7960 - zIndex: 90, - - // callbacks - resize: null, - start: null, - stop: null - }, - - _num: function( value ) { - return parseInt( value, 10 ) || 0; - }, - - _isNumber: function( value ) { - return !isNaN( parseInt( value, 10 ) ); - }, - - _hasScroll: function( el, a ) { - - if ( $( el ).css( "overflow" ) === "hidden") { - return false; - } - - var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", - has = false; - - if ( el[ scroll ] > 0 ) { - return true; - } - - // TODO: determine which cases actually cause this to happen - // if the element doesn't have the scroll set, see if it's possible to - // set the scroll - el[ scroll ] = 1; - has = ( el[ scroll ] > 0 ); - el[ scroll ] = 0; - return has; - }, - - _create: function() { - - var n, i, handle, axis, hname, - that = this, - o = this.options; - this.element.addClass("ui-resizable"); - - $.extend(this, { - _aspectRatio: !!(o.aspectRatio), - aspectRatio: o.aspectRatio, - originalElement: this.element, - _proportionallyResizeElements: [], - _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null - }); - - // Wrap the element if it cannot hold child nodes - if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) { - - this.element.wrap( - $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ - position: this.element.css("position"), - width: this.element.outerWidth(), - height: this.element.outerHeight(), - top: this.element.css("top"), - left: this.element.css("left") - }) - ); - - this.element = this.element.parent().data( - "ui-resizable", this.element.resizable( "instance" ) - ); - - this.elementIsWrapper = true; - - this.element.css({ - marginLeft: this.originalElement.css("marginLeft"), - marginTop: this.originalElement.css("marginTop"), - marginRight: this.originalElement.css("marginRight"), - marginBottom: this.originalElement.css("marginBottom") - }); - this.originalElement.css({ - marginLeft: 0, - marginTop: 0, - marginRight: 0, - marginBottom: 0 - }); - // support: Safari - // Prevent Safari textarea resize - this.originalResizeStyle = this.originalElement.css("resize"); - this.originalElement.css("resize", "none"); - - this._proportionallyResizeElements.push( this.originalElement.css({ - position: "static", - zoom: 1, - display: "block" - }) ); - - // support: IE9 - // avoid IE jump (hard set the margin) - this.originalElement.css({ margin: this.originalElement.css("margin") }); - - this._proportionallyResize(); - } - - 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" - } ); - - this._handles = $(); - if ( this.handles.constructor === String ) { - - if ( this.handles === "all") { - this.handles = "n,e,s,w,se,sw,ne,nw"; - } - - n = this.handles.split(","); - this.handles = {}; - - for (i = 0; i < n.length; i++) { - - handle = $.trim(n[i]); - hname = "ui-resizable-" + handle; - axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); - - axis.css({ zIndex: o.zIndex }); - - // TODO : What's going on here? - if ("se" === handle) { - axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); - } - - this.handles[handle] = ".ui-resizable-" + handle; - this.element.append(axis); - } - - } - - this._renderAxis = function(target) { - - var i, axis, padPos, padWrapper; - - target = target || this.element; - - for (i in this.handles) { - - if (this.handles[i].constructor === String) { - this.handles[i] = this.element.children( this.handles[ i ] ).first().show(); - } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) { - this.handles[ i ] = $( this.handles[ i ] ); - this._on( this.handles[ i ], { "mousedown": that._mouseDown }); - } - - if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) { - - axis = $(this.handles[i], this.element); - - padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); - - padPos = [ "padding", - /ne|nw|n/.test(i) ? "Top" : - /se|sw|s/.test(i) ? "Bottom" : - /^e$/.test(i) ? "Right" : "Left" ].join(""); - - target.css(padPos, padWrapper); - - this._proportionallyResize(); - } - - this._handles = this._handles.add( this.handles[ i ] ); - } - }; - - // TODO: make renderAxis a prototype function - this._renderAxis(this.element); - - this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) ); - this._handles.disableSelection(); - - this._handles.mouseover(function() { - if (!that.resizing) { - if (this.className) { - axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); - } - that.axis = axis && axis[1] ? axis[1] : "se"; - } - }); - - if (o.autoHide) { - this._handles.hide(); - $(this.element) - .addClass("ui-resizable-autohide") - .mouseenter(function() { - if (o.disabled) { - return; - } - $(this).removeClass("ui-resizable-autohide"); - that._handles.show(); - }) - .mouseleave(function() { - if (o.disabled) { - return; - } - if (!that.resizing) { - $(this).addClass("ui-resizable-autohide"); - that._handles.hide(); - } - }); - } - - this._mouseInit(); - }, - - _destroy: function() { - - this._mouseDestroy(); - - var wrapper, - _destroy = function(exp) { - $(exp) - .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") - .removeData("resizable") - .removeData("ui-resizable") - .unbind(".resizable") - .find(".ui-resizable-handle") - .remove(); - }; - - // TODO: Unwrap at same DOM position - if (this.elementIsWrapper) { - _destroy(this.element); - wrapper = this.element; - this.originalElement.css({ - position: wrapper.css("position"), - width: wrapper.outerWidth(), - height: wrapper.outerHeight(), - top: wrapper.css("top"), - left: wrapper.css("left") - }).insertAfter( wrapper ); - wrapper.remove(); - } - - this.originalElement.css("resize", this.originalResizeStyle); - _destroy(this.originalElement); - - return this; - }, - - _mouseCapture: function(event) { - var i, handle, - capture = false; - - for (i in this.handles) { - handle = $(this.handles[i])[0]; - if (handle === event.target || $.contains(handle, event.target)) { - capture = true; - } - } - - return !this.options.disabled && capture; - }, - - _mouseStart: function(event) { - - var curleft, curtop, cursor, - o = this.options, - el = this.element; - - this.resizing = true; - - this._renderProxy(); - - curleft = this._num(this.helper.css("left")); - curtop = this._num(this.helper.css("top")); - - if (o.containment) { - curleft += $(o.containment).scrollLeft() || 0; - curtop += $(o.containment).scrollTop() || 0; - } - - this.offset = this.helper.offset(); - this.position = { left: curleft, top: curtop }; - - this.size = this._helper ? { - width: this.helper.width(), - height: this.helper.height() - } : { - width: el.width(), - height: el.height() - }; - - this.originalSize = this._helper ? { - width: el.outerWidth(), - height: el.outerHeight() - } : { - width: el.width(), - height: el.height() - }; - - this.sizeDiff = { - width: el.outerWidth() - el.width(), - height: el.outerHeight() - el.height() - }; - - this.originalPosition = { left: curleft, top: curtop }; - this.originalMousePosition = { left: event.pageX, top: event.pageY }; - - this.aspectRatio = (typeof o.aspectRatio === "number") ? - o.aspectRatio : - ((this.originalSize.width / this.originalSize.height) || 1); - - cursor = $(".ui-resizable-" + this.axis).css("cursor"); - $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); - - el.addClass("ui-resizable-resizing"); - this._propagate("start", event); - return true; - }, - - _mouseDrag: function(event) { - - var data, props, - smp = this.originalMousePosition, - a = this.axis, - dx = (event.pageX - smp.left) || 0, - dy = (event.pageY - smp.top) || 0, - trigger = this._change[a]; - - this._updatePrevProperties(); - - if (!trigger) { - return false; - } - - data = trigger.apply(this, [ event, dx, dy ]); - - this._updateVirtualBoundaries(event.shiftKey); - if (this._aspectRatio || event.shiftKey) { - data = this._updateRatio(data, event); - } - - data = this._respectSize(data, event); - - this._updateCache(data); - - this._propagate("resize", event); - - props = this._applyChanges(); - - if ( !this._helper && this._proportionallyResizeElements.length ) { - this._proportionallyResize(); - } - - if ( !$.isEmptyObject( props ) ) { - this._updatePrevProperties(); - this._trigger( "resize", event, this.ui() ); - this._applyChanges(); - } - - return false; - }, - - _mouseStop: function(event) { - - this.resizing = false; - var pr, ista, soffseth, soffsetw, s, left, top, - o = this.options, that = this; - - if (this._helper) { - - pr = this._proportionallyResizeElements; - ista = pr.length && (/textarea/i).test(pr[0].nodeName); - soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height; - soffsetw = ista ? 0 : that.sizeDiff.width; - - s = { - width: (that.helper.width() - soffsetw), - height: (that.helper.height() - soffseth) - }; - left = (parseInt(that.element.css("left"), 10) + - (that.position.left - that.originalPosition.left)) || null; - top = (parseInt(that.element.css("top"), 10) + - (that.position.top - that.originalPosition.top)) || null; - - if (!o.animate) { - this.element.css($.extend(s, { top: top, left: left })); - } - - that.helper.height(that.size.height); - that.helper.width(that.size.width); - - if (this._helper && !o.animate) { - this._proportionallyResize(); - } - } - - $("body").css("cursor", "auto"); - - this.element.removeClass("ui-resizable-resizing"); - - this._propagate("stop", event); - - if (this._helper) { - this.helper.remove(); - } - - return false; - - }, - - _updatePrevProperties: function() { - this.prevPosition = { - top: this.position.top, - left: this.position.left - }; - this.prevSize = { - width: this.size.width, - height: this.size.height - }; - }, - - _applyChanges: function() { - var props = {}; - - if ( this.position.top !== this.prevPosition.top ) { - props.top = this.position.top + "px"; - } - if ( this.position.left !== this.prevPosition.left ) { - props.left = this.position.left + "px"; - } - if ( this.size.width !== this.prevSize.width ) { - props.width = this.size.width + "px"; - } - if ( this.size.height !== this.prevSize.height ) { - props.height = this.size.height + "px"; - } - - this.helper.css( props ); - - return props; - }, - - _updateVirtualBoundaries: function(forceAspectRatio) { - var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, - o = this.options; - - b = { - minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0, - maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity, - minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0, - maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity - }; - - if (this._aspectRatio || forceAspectRatio) { - pMinWidth = b.minHeight * this.aspectRatio; - pMinHeight = b.minWidth / this.aspectRatio; - pMaxWidth = b.maxHeight * this.aspectRatio; - pMaxHeight = b.maxWidth / this.aspectRatio; - - if (pMinWidth > b.minWidth) { - b.minWidth = pMinWidth; - } - if (pMinHeight > b.minHeight) { - b.minHeight = pMinHeight; - } - if (pMaxWidth < b.maxWidth) { - b.maxWidth = pMaxWidth; - } - if (pMaxHeight < b.maxHeight) { - b.maxHeight = pMaxHeight; - } - } - this._vBoundaries = b; - }, - - _updateCache: function(data) { - this.offset = this.helper.offset(); - if (this._isNumber(data.left)) { - this.position.left = data.left; - } - if (this._isNumber(data.top)) { - this.position.top = data.top; - } - if (this._isNumber(data.height)) { - this.size.height = data.height; - } - if (this._isNumber(data.width)) { - this.size.width = data.width; - } - }, - - _updateRatio: function( data ) { - - var cpos = this.position, - csize = this.size, - a = this.axis; - - if (this._isNumber(data.height)) { - data.width = (data.height * this.aspectRatio); - } else if (this._isNumber(data.width)) { - data.height = (data.width / this.aspectRatio); - } - - if (a === "sw") { - data.left = cpos.left + (csize.width - data.width); - data.top = null; - } - if (a === "nw") { - data.top = cpos.top + (csize.height - data.height); - data.left = cpos.left + (csize.width - data.width); - } - - return data; - }, - - _respectSize: function( data ) { - - var o = this._vBoundaries, - a = this.axis, - ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), - ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), - isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width), - isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height), - dw = this.originalPosition.left + this.originalSize.width, - dh = this.position.top + this.size.height, - cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); - if (isminw) { - data.width = o.minWidth; - } - if (isminh) { - data.height = o.minHeight; - } - if (ismaxw) { - data.width = o.maxWidth; - } - if (ismaxh) { - data.height = o.maxHeight; - } - - if (isminw && cw) { - data.left = dw - o.minWidth; - } - if (ismaxw && cw) { - data.left = dw - o.maxWidth; - } - if (isminh && ch) { - data.top = dh - o.minHeight; - } - if (ismaxh && ch) { - data.top = dh - o.maxHeight; - } - - // Fixing jump error on top/left - bug #2330 - if (!data.width && !data.height && !data.left && data.top) { - data.top = null; - } else if (!data.width && !data.height && !data.top && data.left) { - data.left = null; - } - - return data; - }, - - _getPaddingPlusBorderDimensions: function( element ) { - var i = 0, - widths = [], - borders = [ - element.css( "borderTopWidth" ), - element.css( "borderRightWidth" ), - element.css( "borderBottomWidth" ), - element.css( "borderLeftWidth" ) - ], - paddings = [ - element.css( "paddingTop" ), - element.css( "paddingRight" ), - element.css( "paddingBottom" ), - element.css( "paddingLeft" ) - ]; - - for ( ; i < 4; i++ ) { - widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 ); - widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 ); - } - - return { - height: widths[ 0 ] + widths[ 2 ], - width: widths[ 1 ] + widths[ 3 ] - }; - }, - - _proportionallyResize: function() { - - if (!this._proportionallyResizeElements.length) { - return; - } - - var prel, - i = 0, - element = this.helper || this.element; - - for ( ; i < this._proportionallyResizeElements.length; i++) { - - prel = this._proportionallyResizeElements[i]; - - // TODO: Seems like a bug to cache this.outerDimensions - // considering that we are in a loop. - if (!this.outerDimensions) { - this.outerDimensions = this._getPaddingPlusBorderDimensions( prel ); - } - - prel.css({ - height: (element.height() - this.outerDimensions.height) || 0, - width: (element.width() - this.outerDimensions.width) || 0 - }); - - } - - }, - - _renderProxy: function() { - - var el = this.element, o = this.options; - this.elementOffset = el.offset(); - - if (this._helper) { - - this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); - - this.helper.addClass(this._helper).css({ - width: this.element.outerWidth() - 1, - height: this.element.outerHeight() - 1, - position: "absolute", - left: this.elementOffset.left + "px", - top: this.elementOffset.top + "px", - zIndex: ++o.zIndex //TODO: Don't modify option - }); - - this.helper - .appendTo("body") - .disableSelection(); - - } else { - this.helper = this.element; - } - - }, - - _change: { - e: function(event, dx) { - return { width: this.originalSize.width + dx }; - }, - w: function(event, dx) { - var cs = this.originalSize, sp = this.originalPosition; - return { left: sp.left + dx, width: cs.width - dx }; - }, - n: function(event, dx, dy) { - var cs = this.originalSize, sp = this.originalPosition; - return { top: sp.top + dy, height: cs.height - dy }; - }, - s: function(event, dx, dy) { - return { height: this.originalSize.height + dy }; - }, - se: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), - this._change.e.apply(this, [ event, dx, dy ])); - }, - sw: function(event, dx, dy) { - return $.extend(this._change.s.apply(this, arguments), - this._change.w.apply(this, [ event, dx, dy ])); - }, - ne: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), - this._change.e.apply(this, [ event, dx, dy ])); - }, - nw: function(event, dx, dy) { - return $.extend(this._change.n.apply(this, arguments), - this._change.w.apply(this, [ event, dx, dy ])); - } - }, - - _propagate: function(n, event) { - $.ui.plugin.call(this, n, [ event, this.ui() ]); - (n !== "resize" && this._trigger(n, event, this.ui())); - }, - - plugins: {}, - - ui: function() { - return { - originalElement: this.originalElement, - element: this.element, - helper: this.helper, - position: this.position, - size: this.size, - originalSize: this.originalSize, - originalPosition: this.originalPosition - }; - } - -}); - -/* - * Resizable Extensions - */ - -$.ui.plugin.add("resizable", "animate", { - - stop: function( event ) { - var that = $(this).resizable( "instance" ), - o = that.options, - pr = that._proportionallyResizeElements, - ista = pr.length && (/textarea/i).test(pr[0].nodeName), - soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height, - soffsetw = ista ? 0 : that.sizeDiff.width, - style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, - left = (parseInt(that.element.css("left"), 10) + - (that.position.left - that.originalPosition.left)) || null, - top = (parseInt(that.element.css("top"), 10) + - (that.position.top - that.originalPosition.top)) || null; - - that.element.animate( - $.extend(style, top && left ? { top: top, left: left } : {}), { - duration: o.animateDuration, - easing: o.animateEasing, - step: function() { - - var data = { - width: parseInt(that.element.css("width"), 10), - height: parseInt(that.element.css("height"), 10), - top: parseInt(that.element.css("top"), 10), - left: parseInt(that.element.css("left"), 10) - }; - - if (pr && pr.length) { - $(pr[0]).css({ width: data.width, height: data.height }); - } - - // propagating resize, and updating values for each animation step - that._updateCache(data); - that._propagate("resize", event); - - } - } - ); - } - -}); - -$.ui.plugin.add( "resizable", "containment", { - - start: function() { - var element, p, co, ch, cw, width, height, - that = $( this ).resizable( "instance" ), - o = that.options, - el = that.element, - oc = o.containment, - ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc; - - if ( !ce ) { - return; - } - - that.containerElement = $( ce ); - - if ( /document/.test( oc ) || oc === document ) { - that.containerOffset = { - left: 0, - top: 0 - }; - that.containerPosition = { - left: 0, - top: 0 - }; - - that.parentData = { - element: $( document ), - left: 0, - top: 0, - width: $( document ).width(), - height: $( document ).height() || document.body.parentNode.scrollHeight - }; - } else { - element = $( ce ); - p = []; - $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) { - p[ i ] = that._num( element.css( "padding" + name ) ); - }); - - that.containerOffset = element.offset(); - that.containerPosition = element.position(); - that.containerSize = { - height: ( element.innerHeight() - p[ 3 ] ), - width: ( element.innerWidth() - p[ 1 ] ) - }; - - co = that.containerOffset; - ch = that.containerSize.height; - cw = that.containerSize.width; - width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw ); - height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ; - - that.parentData = { - element: ce, - left: co.left, - top: co.top, - width: width, - height: height - }; - } - }, - - resize: function( event ) { - var woset, hoset, isParent, isOffsetRelative, - that = $( this ).resizable( "instance" ), - o = that.options, - co = that.containerOffset, - cp = that.position, - pRatio = that._aspectRatio || event.shiftKey, - cop = { - top: 0, - left: 0 - }, - ce = that.containerElement, - continueResize = true; - - if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) { - cop = co; - } - - if ( cp.left < ( that._helper ? co.left : 0 ) ) { - that.size.width = that.size.width + - ( that._helper ? - ( that.position.left - co.left ) : - ( that.position.left - cop.left ) ); - - if ( pRatio ) { - that.size.height = that.size.width / that.aspectRatio; - continueResize = false; - } - that.position.left = o.helper ? co.left : 0; - } - - if ( cp.top < ( that._helper ? co.top : 0 ) ) { - that.size.height = that.size.height + - ( that._helper ? - ( that.position.top - co.top ) : - that.position.top ); - - if ( pRatio ) { - that.size.width = that.size.height * that.aspectRatio; - continueResize = false; - } - that.position.top = that._helper ? co.top : 0; - } - - isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 ); - isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) ); - - if ( isParent && isOffsetRelative ) { - that.offset.left = that.parentData.left + that.position.left; - that.offset.top = that.parentData.top + that.position.top; - } else { - that.offset.left = that.element.offset().left; - that.offset.top = that.element.offset().top; - } - - woset = Math.abs( that.sizeDiff.width + - (that._helper ? - that.offset.left - cop.left : - (that.offset.left - co.left)) ); - - hoset = Math.abs( that.sizeDiff.height + - (that._helper ? - that.offset.top - cop.top : - (that.offset.top - co.top)) ); - - if ( woset + that.size.width >= that.parentData.width ) { - that.size.width = that.parentData.width - woset; - if ( pRatio ) { - that.size.height = that.size.width / that.aspectRatio; - continueResize = false; - } - } - - if ( hoset + that.size.height >= that.parentData.height ) { - that.size.height = that.parentData.height - hoset; - if ( pRatio ) { - that.size.width = that.size.height * that.aspectRatio; - continueResize = false; - } - } - - if ( !continueResize ) { - that.position.left = that.prevPosition.left; - that.position.top = that.prevPosition.top; - that.size.width = that.prevSize.width; - that.size.height = that.prevSize.height; - } - }, - - stop: function() { - var that = $( this ).resizable( "instance" ), - o = that.options, - co = that.containerOffset, - cop = that.containerPosition, - ce = that.containerElement, - helper = $( that.helper ), - ho = helper.offset(), - w = helper.outerWidth() - that.sizeDiff.width, - h = helper.outerHeight() - that.sizeDiff.height; - - if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) { - $( this ).css({ - left: ho.left - cop.left - co.left, - width: w, - height: h - }); - } - - if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) { - $( this ).css({ - left: ho.left - cop.left - co.left, - width: w, - height: h - }); - } - } -}); - -$.ui.plugin.add("resizable", "alsoResize", { - - start: function() { - var that = $(this).resizable( "instance" ), - o = that.options; - - $(o.alsoResize).each(function() { - var el = $(this); - el.data("ui-resizable-alsoresize", { - width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), - left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) - }); - }); - }, - - resize: function(event, ui) { - var that = $(this).resizable( "instance" ), - o = that.options, - os = that.originalSize, - op = that.originalPosition, - delta = { - height: (that.size.height - os.height) || 0, - width: (that.size.width - os.width) || 0, - top: (that.position.top - op.top) || 0, - left: (that.position.left - op.left) || 0 - }; - - $(o.alsoResize).each(function() { - var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, - css = el.parents(ui.originalElement[0]).length ? - [ "width", "height" ] : - [ "width", "height", "top", "left" ]; - - $.each(css, function(i, prop) { - var sum = (start[prop] || 0) + (delta[prop] || 0); - if (sum && sum >= 0) { - style[prop] = sum || null; - } - }); - - el.css(style); - }); - }, - - stop: function() { - $(this).removeData("resizable-alsoresize"); - } -}); - -$.ui.plugin.add("resizable", "ghost", { - - start: function() { - - var that = $(this).resizable( "instance" ), o = that.options, cs = that.size; - - that.ghost = that.originalElement.clone(); - that.ghost - .css({ - opacity: 0.25, - display: "block", - position: "relative", - height: cs.height, - width: cs.width, - margin: 0, - left: 0, - top: 0 - }) - .addClass("ui-resizable-ghost") - .addClass(typeof o.ghost === "string" ? o.ghost : ""); - - that.ghost.appendTo(that.helper); - - }, - - resize: function() { - var that = $(this).resizable( "instance" ); - if (that.ghost) { - that.ghost.css({ - position: "relative", - height: that.size.height, - width: that.size.width - }); - } - }, - - stop: function() { - var that = $(this).resizable( "instance" ); - if (that.ghost && that.helper) { - that.helper.get(0).removeChild(that.ghost.get(0)); - } - } - -}); - -$.ui.plugin.add("resizable", "grid", { - - resize: function() { - var outerDimensions, - that = $(this).resizable( "instance" ), - o = that.options, - cs = that.size, - os = that.originalSize, - op = that.originalPosition, - a = that.axis, - grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid, - gridX = (grid[0] || 1), - gridY = (grid[1] || 1), - ox = Math.round((cs.width - os.width) / gridX) * gridX, - oy = Math.round((cs.height - os.height) / gridY) * gridY, - newWidth = os.width + ox, - newHeight = os.height + oy, - isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), - isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), - isMinWidth = o.minWidth && (o.minWidth > newWidth), - isMinHeight = o.minHeight && (o.minHeight > newHeight); - - o.grid = grid; - - if (isMinWidth) { - newWidth += gridX; - } - if (isMinHeight) { - newHeight += gridY; - } - if (isMaxWidth) { - newWidth -= gridX; - } - if (isMaxHeight) { - newHeight -= gridY; - } - - if (/^(se|s|e)$/.test(a)) { - that.size.width = newWidth; - that.size.height = newHeight; - } else if (/^(ne)$/.test(a)) { - that.size.width = newWidth; - that.size.height = newHeight; - that.position.top = op.top - oy; - } else if (/^(sw)$/.test(a)) { - that.size.width = newWidth; - that.size.height = newHeight; - that.position.left = op.left - ox; - } else { - if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) { - outerDimensions = that._getPaddingPlusBorderDimensions( this ); - } - - if ( newHeight - gridY > 0 ) { - that.size.height = newHeight; - that.position.top = op.top - oy; - } else { - newHeight = gridY - outerDimensions.height; - that.size.height = newHeight; - that.position.top = op.top + os.height - newHeight; - } - if ( newWidth - gridX > 0 ) { - that.size.width = newWidth; - that.position.left = op.left - ox; - } else { - newWidth = gridX - outerDimensions.width; - that.size.width = newWidth; - that.position.left = op.left + os.width - newWidth; - } - } - } - -}); - -var resizable = $.ui.resizable; - - -/*! - * jQuery UI Menu 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/menu/ - */ - - -var menu = $.widget( "ui.menu", { - version: "1.11.4", - defaultElement: "<ul>", - delay: 300, - options: { - icons: { - submenu: "ui-icon-carat-1-e" - }, - items: "> *", - menus: "ul", - position: { - my: "left-1 top", - at: "right top" - }, - role: "menu", - - // callbacks - blur: null, - focus: null, - select: null - }, - - _create: function() { - this.activeMenu = this.element; - - // Flag used to prevent firing of the click handler - // as the event bubbles up through nested menus - this.mouseHandled = false; - this.element - .uniqueId() - .addClass( "ui-menu ui-widget ui-widget-content" ) - .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) - .attr({ - role: this.options.role, - tabIndex: 0 - }); - - if ( this.options.disabled ) { - this.element - .addClass( "ui-state-disabled" ) - .attr( "aria-disabled", "true" ); - } - - this._on({ - // Prevent focus from sticking to links inside menu after clicking - // them (focus should always stay on UL during navigation). - "mousedown .ui-menu-item": function( event ) { - event.preventDefault(); - }, - "click .ui-menu-item": function( event ) { - var target = $( event.target ); - if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { - this.select( event ); - - // Only set the mouseHandled flag if the event will bubble, see #9469. - if ( !event.isPropagationStopped() ) { - this.mouseHandled = true; - } - - // Open submenu on click - if ( target.has( ".ui-menu" ).length ) { - this.expand( event ); - } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) { - - // Redirect focus to the menu - this.element.trigger( "focus", [ true ] ); - - // If the active item is on the top level, let it stay active. - // Otherwise, blur the active item since it is no longer visible. - if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { - clearTimeout( this.timer ); - } - } - } - }, - "mouseenter .ui-menu-item": function( event ) { - // Ignore mouse events while typeahead is active, see #10458. - // Prevents focusing the wrong item when typeahead causes a scroll while the mouse - // is over an item in the menu - if ( this.previousFilter ) { - return; - } - var target = $( event.currentTarget ); - // Remove ui-state-active class from siblings of the newly focused menu item - // to avoid a jump caused by adjacent elements both having a class with a border - target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" ); - this.focus( event, target ); - }, - mouseleave: "collapseAll", - "mouseleave .ui-menu": "collapseAll", - focus: function( event, keepActiveItem ) { - // If there's already an active item, keep it active - // If not, activate the first item - var item = this.active || this.element.find( this.options.items ).eq( 0 ); - - if ( !keepActiveItem ) { - this.focus( event, item ); - } - }, - blur: function( event ) { - this._delay(function() { - if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { - this.collapseAll( event ); - } - }); - }, - keydown: "_keydown" - }); - - this.refresh(); - - // Clicks outside of a menu collapse any open menus - this._on( this.document, { - click: function( event ) { - if ( this._closeOnDocumentClick( event ) ) { - this.collapseAll( event ); - } - - // Reset the mouseHandled flag - this.mouseHandled = false; - } - }); - }, - - _destroy: function() { - // Destroy (sub)menus - this.element - .removeAttr( "aria-activedescendant" ) - .find( ".ui-menu" ).addBack() - .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" ) - .removeAttr( "role" ) - .removeAttr( "tabIndex" ) - .removeAttr( "aria-labelledby" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-disabled" ) - .removeUniqueId() - .show(); - - // Destroy menu items - this.element.find( ".ui-menu-item" ) - .removeClass( "ui-menu-item" ) - .removeAttr( "role" ) - .removeAttr( "aria-disabled" ) - .removeUniqueId() - .removeClass( "ui-state-hover" ) - .removeAttr( "tabIndex" ) - .removeAttr( "role" ) - .removeAttr( "aria-haspopup" ) - .children().each( function() { - var elem = $( this ); - if ( elem.data( "ui-menu-submenu-carat" ) ) { - elem.remove(); - } - }); - - // Destroy menu dividers - this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); - }, - - _keydown: function( event ) { - var match, prev, character, skip, - preventDefault = true; - - switch ( event.keyCode ) { - case $.ui.keyCode.PAGE_UP: - this.previousPage( event ); - break; - case $.ui.keyCode.PAGE_DOWN: - this.nextPage( event ); - break; - case $.ui.keyCode.HOME: - this._move( "first", "first", event ); - break; - case $.ui.keyCode.END: - this._move( "last", "last", event ); - break; - case $.ui.keyCode.UP: - this.previous( event ); - break; - case $.ui.keyCode.DOWN: - this.next( event ); - break; - case $.ui.keyCode.LEFT: - this.collapse( event ); - break; - case $.ui.keyCode.RIGHT: - if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { - this.expand( event ); - } - break; - case $.ui.keyCode.ENTER: - case $.ui.keyCode.SPACE: - this._activate( event ); - break; - case $.ui.keyCode.ESCAPE: - this.collapse( event ); - break; - default: - preventDefault = false; - prev = this.previousFilter || ""; - character = String.fromCharCode( event.keyCode ); - skip = false; - - clearTimeout( this.filterTimer ); - - if ( character === prev ) { - skip = true; - } else { - character = prev + character; - } - - match = this._filterMenuItems( character ); - match = skip && match.index( this.active.next() ) !== -1 ? - this.active.nextAll( ".ui-menu-item" ) : - match; - - // If no matches on the current filter, reset to the last character pressed - // to move down the menu to the first item that starts with that character - if ( !match.length ) { - character = String.fromCharCode( event.keyCode ); - match = this._filterMenuItems( character ); - } - - if ( match.length ) { - this.focus( event, match ); - this.previousFilter = character; - this.filterTimer = this._delay(function() { - delete this.previousFilter; - }, 1000 ); - } else { - delete this.previousFilter; - } - } - - if ( preventDefault ) { - event.preventDefault(); - } - }, - - _activate: function( event ) { - if ( !this.active.is( ".ui-state-disabled" ) ) { - if ( this.active.is( "[aria-haspopup='true']" ) ) { - this.expand( event ); - } else { - this.select( event ); - } - } - }, - - refresh: function() { - var menus, items, - that = this, - icon = this.options.icons.submenu, - submenus = this.element.find( this.options.menus ); - - this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ); - - // Initialize nested menus - submenus.filter( ":not(.ui-menu)" ) - .addClass( "ui-menu ui-widget ui-widget-content ui-front" ) - .hide() - .attr({ - role: this.options.role, - "aria-hidden": "true", - "aria-expanded": "false" - }) - .each(function() { - var menu = $( this ), - item = menu.parent(), - submenuCarat = $( "<span>" ) - .addClass( "ui-menu-icon ui-icon " + icon ) - .data( "ui-menu-submenu-carat", true ); - - item - .attr( "aria-haspopup", "true" ) - .prepend( submenuCarat ); - menu.attr( "aria-labelledby", item.attr( "id" ) ); - }); - - menus = submenus.add( this.element ); - items = menus.find( this.options.items ); - - // Initialize menu-items containing spaces and/or dashes only as dividers - items.not( ".ui-menu-item" ).each(function() { - var item = $( this ); - if ( that._isDivider( item ) ) { - item.addClass( "ui-widget-content ui-menu-divider" ); - } - }); - - // Don't refresh list items that are already adapted - items.not( ".ui-menu-item, .ui-menu-divider" ) - .addClass( "ui-menu-item" ) - .uniqueId() - .attr({ - tabIndex: -1, - role: this._itemRole() - }); - - // Add aria-disabled attribute to any disabled menu item - items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); - - // If the active item has been removed, blur the menu - if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - this.blur(); - } - }, - - _itemRole: function() { - return { - menu: "menuitem", - listbox: "option" - }[ this.options.role ]; - }, - - _setOption: function( key, value ) { - if ( key === "icons" ) { - this.element.find( ".ui-menu-icon" ) - .removeClass( this.options.icons.submenu ) - .addClass( value.submenu ); - } - if ( key === "disabled" ) { - this.element - .toggleClass( "ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - } - this._super( key, value ); - }, - - focus: function( event, item ) { - var nested, focused; - this.blur( event, event && event.type === "focus" ); - - this._scrollIntoView( item ); - - this.active = item.first(); - focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" ); - // Only update aria-activedescendant if there's a role - // otherwise we assume focus is managed elsewhere - if ( this.options.role ) { - this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); - } - - // Highlight active parent menu item, if any - this.active - .parent() - .closest( ".ui-menu-item" ) - .addClass( "ui-state-active" ); - - if ( event && event.type === "keydown" ) { - this._close(); - } else { - this.timer = this._delay(function() { - this._close(); - }, this.delay ); - } - - nested = item.children( ".ui-menu" ); - if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) { - this._startOpening(nested); - } - this.activeMenu = item.parent(); - - this._trigger( "focus", event, { item: item } ); - }, - - _scrollIntoView: function( item ) { - var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; - if ( this._hasScroll() ) { - borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; - paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; - offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; - scroll = this.activeMenu.scrollTop(); - elementHeight = this.activeMenu.height(); - itemHeight = item.outerHeight(); - - if ( offset < 0 ) { - this.activeMenu.scrollTop( scroll + offset ); - } else if ( offset + itemHeight > elementHeight ) { - this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); - } - } - }, - - blur: function( event, fromFocus ) { - if ( !fromFocus ) { - clearTimeout( this.timer ); - } - - if ( !this.active ) { - return; - } - - this.active.removeClass( "ui-state-focus" ); - this.active = null; - - this._trigger( "blur", event, { item: this.active } ); - }, - - _startOpening: function( submenu ) { - clearTimeout( this.timer ); - - // Don't open if already open fixes a Firefox bug that caused a .5 pixel - // shift in the submenu position when mousing over the carat icon - if ( submenu.attr( "aria-hidden" ) !== "true" ) { - return; - } - - this.timer = this._delay(function() { - this._close(); - this._open( submenu ); - }, this.delay ); - }, - - _open: function( submenu ) { - var position = $.extend({ - of: this.active - }, this.options.position ); - - clearTimeout( this.timer ); - this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) - .hide() - .attr( "aria-hidden", "true" ); - - submenu - .show() - .removeAttr( "aria-hidden" ) - .attr( "aria-expanded", "true" ) - .position( position ); - }, - - collapseAll: function( event, all ) { - clearTimeout( this.timer ); - this.timer = this._delay(function() { - // If we were passed an event, look for the submenu that contains the event - var currentMenu = all ? this.element : - $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); - - // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway - if ( !currentMenu.length ) { - currentMenu = this.element; - } - - this._close( currentMenu ); - - this.blur( event ); - this.activeMenu = currentMenu; - }, this.delay ); - }, - - // With no arguments, closes the currently active menu - if nothing is active - // it closes all menus. If passed an argument, it will search for menus BELOW - _close: function( startMenu ) { - if ( !startMenu ) { - startMenu = this.active ? this.active.parent() : this.element; - } - - startMenu - .find( ".ui-menu" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ) - .end() - .find( ".ui-state-active" ).not( ".ui-state-focus" ) - .removeClass( "ui-state-active" ); - }, - - _closeOnDocumentClick: function( event ) { - return !$( event.target ).closest( ".ui-menu" ).length; - }, - - _isDivider: function( item ) { - - // Match hyphen, em dash, en dash - return !/[^\-\u2014\u2013\s]/.test( item.text() ); - }, - - collapse: function( event ) { - var newItem = this.active && - this.active.parent().closest( ".ui-menu-item", this.element ); - if ( newItem && newItem.length ) { - this._close(); - this.focus( event, newItem ); - } - }, - - expand: function( event ) { - var newItem = this.active && - this.active - .children( ".ui-menu " ) - .find( this.options.items ) - .first(); - - if ( newItem && newItem.length ) { - this._open( newItem.parent() ); - - // Delay so Firefox will not hide activedescendant change in expanding submenu from AT - this._delay(function() { - this.focus( event, newItem ); - }); - } - }, - - next: function( event ) { - this._move( "next", "first", event ); - }, - - previous: function( event ) { - this._move( "prev", "last", event ); - }, - - isFirstItem: function() { - return this.active && !this.active.prevAll( ".ui-menu-item" ).length; - }, - - isLastItem: function() { - return this.active && !this.active.nextAll( ".ui-menu-item" ).length; - }, - - _move: function( direction, filter, event ) { - var next; - if ( this.active ) { - if ( direction === "first" || direction === "last" ) { - next = this.active - [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) - .eq( -1 ); - } else { - next = this.active - [ direction + "All" ]( ".ui-menu-item" ) - .eq( 0 ); - } - } - if ( !next || !next.length || !this.active ) { - next = this.activeMenu.find( this.options.items )[ filter ](); - } - - this.focus( event, next ); - }, - - nextPage: function( event ) { - var item, base, height; - - if ( !this.active ) { - this.next( event ); - return; - } - if ( this.isLastItem() ) { - return; - } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.height(); - this.active.nextAll( ".ui-menu-item" ).each(function() { - item = $( this ); - return item.offset().top - base - height < 0; - }); - - this.focus( event, item ); - } else { - this.focus( event, this.activeMenu.find( this.options.items ) - [ !this.active ? "first" : "last" ]() ); - } - }, - - previousPage: function( event ) { - var item, base, height; - if ( !this.active ) { - this.next( event ); - return; - } - if ( this.isFirstItem() ) { - return; - } - if ( this._hasScroll() ) { - base = this.active.offset().top; - height = this.element.height(); - this.active.prevAll( ".ui-menu-item" ).each(function() { - item = $( this ); - return item.offset().top - base + height > 0; - }); - - this.focus( event, item ); - } else { - this.focus( event, this.activeMenu.find( this.options.items ).first() ); - } - }, - - _hasScroll: function() { - return this.element.outerHeight() < this.element.prop( "scrollHeight" ); - }, - - select: function( event ) { - // TODO: It should never be possible to not have an active item at this - // point, but the tests don't trigger mouseenter before click. - this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); - var ui = { item: this.active }; - if ( !this.active.has( ".ui-menu" ).length ) { - this.collapseAll( event, true ); - } - this._trigger( "select", event, ui ); - }, - - _filterMenuItems: function(character) { - var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ), - regex = new RegExp( "^" + escapedCharacter, "i" ); - - return this.activeMenu - .find( this.options.items ) - - // Only match on items, not dividers or other content (#10571) - .filter( ".ui-menu-item" ) - .filter(function() { - return regex.test( $.trim( $( this ).text() ) ); - }); - } -}); - - -/*! - * jQuery UI Autocomplete 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/autocomplete/ - */ - - -$.widget( "ui.autocomplete", { - version: "1.11.4", - defaultElement: "<input>", - options: { - appendTo: null, - autoFocus: false, - delay: 300, - minLength: 1, - position: { - my: "left top", - at: "left bottom", - collision: "none" - }, - source: null, - - // callbacks - change: null, - close: null, - focus: null, - open: null, - response: null, - search: null, - select: null - }, - - requestIndex: 0, - pending: 0, - - _create: function() { - // Some browsers only repeat keydown events, not keypress events, - // so we use the suppressKeyPress flag to determine if we've already - // handled the keydown event. #7269 - // Unfortunately the code for & in keypress is the same as the up arrow, - // so we use the suppressKeyPressRepeat flag to avoid handling keypress - // events when we know the keydown event was used to modify the - // search term. #7799 - var suppressKeyPress, suppressKeyPressRepeat, suppressInput, - nodeName = this.element[ 0 ].nodeName.toLowerCase(), - isTextarea = nodeName === "textarea", - isInput = nodeName === "input"; - - this.isMultiLine = - // Textareas are always multi-line - isTextarea ? true : - // Inputs are always single-line, even if inside a contentEditable element - // IE also treats inputs as contentEditable - isInput ? false : - // All other element types are determined by whether or not they're contentEditable - this.element.prop( "isContentEditable" ); - - this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; - this.isNewMenu = true; - - this.element - .addClass( "ui-autocomplete-input" ) - .attr( "autocomplete", "off" ); - - this._on( this.element, { - keydown: function( event ) { - if ( this.element.prop( "readOnly" ) ) { - suppressKeyPress = true; - suppressInput = true; - suppressKeyPressRepeat = true; - return; - } - - suppressKeyPress = false; - suppressInput = false; - suppressKeyPressRepeat = false; - var keyCode = $.ui.keyCode; - switch ( event.keyCode ) { - case keyCode.PAGE_UP: - suppressKeyPress = true; - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - suppressKeyPress = true; - this._move( "nextPage", event ); - break; - case keyCode.UP: - suppressKeyPress = true; - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - suppressKeyPress = true; - this._keyEvent( "next", event ); - break; - case keyCode.ENTER: - // when menu is open and has focus - if ( this.menu.active ) { - // #6055 - Opera still allows the keypress to occur - // which causes forms to submit - suppressKeyPress = true; - event.preventDefault(); - this.menu.select( event ); - } - break; - case keyCode.TAB: - if ( this.menu.active ) { - this.menu.select( event ); - } - break; - case keyCode.ESCAPE: - if ( this.menu.element.is( ":visible" ) ) { - if ( !this.isMultiLine ) { - this._value( this.term ); - } - this.close( event ); - // Different browsers have different default behavior for escape - // Single press can mean undo or clear - // Double press in IE means clear the whole form - event.preventDefault(); - } - break; - default: - suppressKeyPressRepeat = true; - // search timeout should be triggered before the input value is changed - this._searchTimeout( event ); - break; - } - }, - keypress: function( event ) { - if ( suppressKeyPress ) { - suppressKeyPress = false; - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { - event.preventDefault(); - } - return; - } - if ( suppressKeyPressRepeat ) { - return; - } - - // replicate some key handlers to allow them to repeat in Firefox and Opera - var keyCode = $.ui.keyCode; - switch ( event.keyCode ) { - case keyCode.PAGE_UP: - this._move( "previousPage", event ); - break; - case keyCode.PAGE_DOWN: - this._move( "nextPage", event ); - break; - case keyCode.UP: - this._keyEvent( "previous", event ); - break; - case keyCode.DOWN: - this._keyEvent( "next", event ); - break; - } - }, - input: function( event ) { - if ( suppressInput ) { - suppressInput = false; - event.preventDefault(); - return; - } - this._searchTimeout( event ); - }, - focus: function() { - this.selectedItem = null; - this.previous = this._value(); - }, - blur: function( event ) { - if ( this.cancelBlur ) { - delete this.cancelBlur; - return; - } - - clearTimeout( this.searching ); - this.close( event ); - this._change( event ); - } - }); - - this._initSource(); - this.menu = $( "<ul>" ) - .addClass( "ui-autocomplete ui-front" ) - .appendTo( this._appendTo() ) - .menu({ - // disable ARIA support, the live region takes care of that - role: null - }) - .hide() - .menu( "instance" ); - - this._on( this.menu.element, { - mousedown: function( event ) { - // prevent moving focus out of the text field - event.preventDefault(); - - // IE doesn't prevent moving focus even with event.preventDefault() - // so we set a flag to know when we should ignore the blur event - this.cancelBlur = true; - this._delay(function() { - delete this.cancelBlur; - }); - - // clicking on the scrollbar causes focus to shift to the body - // but we can't detect a mouseup or a click immediately afterward - // so we have to track the next mousedown and close the menu if - // the user clicks somewhere outside of the autocomplete - var menuElement = this.menu.element[ 0 ]; - if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { - this._delay(function() { - var that = this; - this.document.one( "mousedown", function( event ) { - if ( event.target !== that.element[ 0 ] && - event.target !== menuElement && - !$.contains( menuElement, event.target ) ) { - that.close(); - } - }); - }); - } - }, - menufocus: function( event, ui ) { - var label, item; - // support: Firefox - // Prevent accidental activation of menu items in Firefox (#7024 #9118) - if ( this.isNewMenu ) { - this.isNewMenu = false; - if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { - this.menu.blur(); - - this.document.one( "mousemove", function() { - $( event.target ).trigger( event.originalEvent ); - }); - - return; - } - } - - item = ui.item.data( "ui-autocomplete-item" ); - if ( false !== this._trigger( "focus", event, { item: item } ) ) { - // use value to match what will end up in the input, if it was a key event - if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { - this._value( item.value ); - } - } - - // Announce the value in the liveRegion - label = ui.item.attr( "aria-label" ) || item.value; - if ( label && $.trim( label ).length ) { - this.liveRegion.children().hide(); - $( "<div>" ).text( label ).appendTo( this.liveRegion ); - } - }, - menuselect: function( event, ui ) { - var item = ui.item.data( "ui-autocomplete-item" ), - previous = this.previous; - - // only trigger when focus was lost (click on menu) - if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) { - this.element.focus(); - this.previous = previous; - // #6109 - IE triggers two focus events and the second - // is asynchronous, so we need to reset the previous - // term synchronously and asynchronously :-( - this._delay(function() { - this.previous = previous; - this.selectedItem = item; - }); - } - - if ( false !== this._trigger( "select", event, { item: item } ) ) { - this._value( item.value ); - } - // reset the term after the select event - // this allows custom select handling to work properly - this.term = this._value(); - - this.close( event ); - this.selectedItem = item; - } - }); - - this.liveRegion = $( "<span>", { - role: "status", - "aria-live": "assertive", - "aria-relevant": "additions" - }) - .addClass( "ui-helper-hidden-accessible" ) - .appendTo( this.document[ 0 ].body ); - - // turning off autocomplete prevents the browser from remembering the - // value when navigating through history, so we re-enable autocomplete - // if the page is unloaded before the widget is destroyed. #7790 - this._on( this.window, { - beforeunload: function() { - this.element.removeAttr( "autocomplete" ); - } - }); - }, - - _destroy: function() { - clearTimeout( this.searching ); - this.element - .removeClass( "ui-autocomplete-input" ) - .removeAttr( "autocomplete" ); - this.menu.element.remove(); - this.liveRegion.remove(); - }, - - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "source" ) { - this._initSource(); - } - if ( key === "appendTo" ) { - this.menu.element.appendTo( this._appendTo() ); - } - if ( key === "disabled" && value && this.xhr ) { - this.xhr.abort(); - } - }, - - _appendTo: function() { - var element = this.options.appendTo; - - if ( element ) { - element = element.jquery || element.nodeType ? - $( element ) : - this.document.find( element ).eq( 0 ); - } - - if ( !element || !element[ 0 ] ) { - element = this.element.closest( ".ui-front" ); - } - - if ( !element.length ) { - element = this.document[ 0 ].body; - } - - return element; - }, - - _initSource: function() { - var array, url, - that = this; - if ( $.isArray( this.options.source ) ) { - array = this.options.source; - this.source = function( request, response ) { - response( $.ui.autocomplete.filter( array, request.term ) ); - }; - } else if ( typeof this.options.source === "string" ) { - url = this.options.source; - this.source = function( request, response ) { - if ( that.xhr ) { - that.xhr.abort(); - } - that.xhr = $.ajax({ - url: url, - data: request, - dataType: "json", - success: function( data ) { - response( data ); - }, - error: function() { - response([]); - } - }); - }; - } else { - this.source = this.options.source; - } - }, - - _searchTimeout: function( event ) { - clearTimeout( this.searching ); - this.searching = this._delay(function() { - - // Search if the value has changed, or if the user retypes the same value (see #7434) - var equalValues = this.term === this._value(), - menuVisible = this.menu.element.is( ":visible" ), - modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; - - if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) { - this.selectedItem = null; - this.search( null, event ); - } - }, this.options.delay ); - }, - - search: function( value, event ) { - value = value != null ? value : this._value(); - - // always save the actual value, not the one passed as an argument - this.term = this._value(); - - if ( value.length < this.options.minLength ) { - return this.close( event ); - } - - if ( this._trigger( "search", event ) === false ) { - return; - } - - return this._search( value ); - }, - - _search: function( value ) { - this.pending++; - this.element.addClass( "ui-autocomplete-loading" ); - this.cancelSearch = false; - - this.source( { term: value }, this._response() ); - }, - - _response: function() { - var index = ++this.requestIndex; - - return $.proxy(function( content ) { - if ( index === this.requestIndex ) { - this.__response( content ); - } - - this.pending--; - if ( !this.pending ) { - this.element.removeClass( "ui-autocomplete-loading" ); - } - }, this ); - }, - - __response: function( content ) { - if ( content ) { - content = this._normalize( content ); - } - this._trigger( "response", null, { content: content } ); - if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { - this._suggest( content ); - this._trigger( "open" ); - } else { - // use ._close() instead of .close() so we don't cancel future searches - this._close(); - } - }, - - close: function( event ) { - this.cancelSearch = true; - this._close( event ); - }, - - _close: function( event ) { - if ( this.menu.element.is( ":visible" ) ) { - this.menu.element.hide(); - this.menu.blur(); - this.isNewMenu = true; - this._trigger( "close", event ); - } - }, - - _change: function( event ) { - if ( this.previous !== this._value() ) { - this._trigger( "change", event, { item: this.selectedItem } ); - } - }, - - _normalize: function( items ) { - // assume all items have the right format when the first item is complete - if ( items.length && items[ 0 ].label && items[ 0 ].value ) { - return items; - } - return $.map( items, function( item ) { - if ( typeof item === "string" ) { - return { - label: item, - value: item - }; - } - return $.extend( {}, item, { - label: item.label || item.value, - value: item.value || item.label - }); - }); - }, - - _suggest: function( items ) { - var ul = this.menu.element.empty(); - this._renderMenu( ul, items ); - this.isNewMenu = true; - this.menu.refresh(); - - // size and position menu - ul.show(); - this._resizeMenu(); - ul.position( $.extend({ - of: this.element - }, this.options.position ) ); - - if ( this.options.autoFocus ) { - this.menu.next(); - } - }, - - _resizeMenu: function() { - var ul = this.menu.element; - ul.outerWidth( Math.max( - // Firefox wraps long text (possibly a rounding bug) - // so we add 1px to avoid the wrapping (#7513) - ul.width( "" ).outerWidth() + 1, - this.element.outerWidth() - ) ); - }, - - _renderMenu: function( ul, items ) { - var that = this; - $.each( items, function( index, item ) { - that._renderItemData( ul, item ); - }); - }, - - _renderItemData: function( ul, item ) { - return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); - }, - - _renderItem: function( ul, item ) { - return $( "<li>" ).text( item.label ).appendTo( ul ); - }, - - _move: function( direction, event ) { - if ( !this.menu.element.is( ":visible" ) ) { - this.search( null, event ); - return; - } - if ( this.menu.isFirstItem() && /^previous/.test( direction ) || - this.menu.isLastItem() && /^next/.test( direction ) ) { - - if ( !this.isMultiLine ) { - this._value( this.term ); - } - - this.menu.blur(); - return; - } - this.menu[ direction ]( event ); - }, - - widget: function() { - return this.menu.element; - }, - - _value: function() { - return this.valueMethod.apply( this.element, arguments ); - }, - - _keyEvent: function( keyEvent, event ) { - if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { - this._move( keyEvent, event ); - - // prevents moving cursor to beginning/end of the text field in some browsers - event.preventDefault(); - } - } -}); - -$.extend( $.ui.autocomplete, { - escapeRegex: function( value ) { - return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); - }, - filter: function( array, term ) { - var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" ); - return $.grep( array, function( value ) { - return matcher.test( value.label || value.value || value ); - }); - } -}); - -// live region extension, adding a `messages` option -// NOTE: This is an experimental API. We are still investigating -// a full solution for string manipulation and internationalization. -$.widget( "ui.autocomplete", $.ui.autocomplete, { - options: { - messages: { - noResults: "No search results.", - results: function( amount ) { - return amount + ( amount > 1 ? " results are" : " result is" ) + - " available, use up and down arrow keys to navigate."; - } - } - }, - - __response: function( content ) { - var message; - this._superApply( arguments ); - if ( this.options.disabled || this.cancelSearch ) { - return; - } - if ( content && content.length ) { - message = this.options.messages.results( content.length ); - } else { - message = this.options.messages.noResults; - } - this.liveRegion.children().hide(); - $( "<div>" ).text( message ).appendTo( this.liveRegion ); - } -}); - -var autocomplete = $.ui.autocomplete; - - -/*! - * jQuery UI Datepicker 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/datepicker/ - */ - - -$.extend($.ui, { datepicker: { version: "1.11.4" } }); - -var datepicker_instActive; - -function datepicker_getZindex( elem ) { - var position, value; - while ( elem.length && elem[ 0 ] !== document ) { - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> - value = parseInt( elem.css( "zIndex" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - - return 0; -} -/* Date picker manager. - Use the singleton instance of this class, $.datepicker, to interact with the date picker. - Settings for (groups of) date pickers are maintained in an instance object, - allowing multiple different settings on the same page. */ - -function Datepicker() { - this._curInst = null; // The current instance in use - this._keyEvent = false; // If the last event was a key event - this._disabledInputs = []; // List of date picker inputs that have been disabled - this._datepickerShowing = false; // True if the popup picker is showing , false if not - this._inDialog = false; // True if showing within a "dialog", false if not - this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division - this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class - this._appendClass = "ui-datepicker-append"; // The name of the append marker class - this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class - this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class - this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class - this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class - this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class - this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class - this.regional = []; // Available regional settings, indexed by language code - this.regional[""] = { // Default regional settings - closeText: "Done", // Display text for close link - prevText: "Prev", // Display text for previous month link - nextText: "Next", // Display text for next month link - currentText: "Today", // Display text for current month link - monthNames: ["January","February","March","April","May","June", - "July","August","September","October","November","December"], // Names of months for drop-down and formatting - monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting - dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting - dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting - dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday - weekHeader: "Wk", // Column header for week of the year - dateFormat: "mm/dd/yy", // See format options on parseDate - firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... - weekendDays: [0, 6], //List of days considered as weekend, Sun = 0, Mon = 1, ... - isRTL: false, // True if right-to-left language, false if left-to-right - showMonthAfterYear: false, // True if the year select precedes month, false for month then year - yearSuffix: "" // Additional text to append to the year in the month headers - }; - this._defaults = { // Global defaults for all the date picker instances - showOn: "focus", // "focus" for popup on focus, - // "button" for trigger button, or "both" for either - showAnim: "fadeIn", // Name of jQuery animation for popup - showOptions: {}, // Options for enhanced animations - defaultDate: null, // Used when field is blank: actual date, - // +/-number for offset from today, null for today - appendText: "", // Display text following the input box, e.g. showing the format - buttonText: "...", // Text for trigger button - buttonImage: "", // URL for trigger button image - buttonImageOnly: false, // True if the image appears alone, false if it appears on a button - hideIfNoPrevNext: false, // True to hide next/previous month links - // if not applicable, false to just disable them - navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links - gotoCurrent: false, // True if today link goes back to current selection instead - changeMonth: false, // True if month can be selected directly, false if only prev/next - changeYear: false, // True if year can be selected directly, false if only prev/next - yearRange: "c-10:c+10", // Range of years to display in drop-down, - // either relative to today's year (-nn:+nn), relative to currently displayed year - // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) - showOtherMonths: false, // True to show dates in other months, false to leave blank - selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable - showWeek: false, // True to show week of the year, false to not show it - calculateWeek: this.iso8601Week, // How to calculate the week of the year, - // takes a Date and returns the number of the week for it - shortYearCutoff: "+10", // Short year values < this are in the current century, - // > this are in the previous century, - // string value starting with "+" for current year + value - minDate: null, // The earliest selectable date, or null for no limit - maxDate: null, // The latest selectable date, or null for no limit - duration: "fast", // Duration of display/closure - beforeShowDay: null, // Function that takes a date and returns an array with - // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", - // [2] = cell title (optional), e.g. $.datepicker.noWeekends - beforeShow: null, // Function that takes an input field and - // returns a set of custom settings for the date picker - onSelect: null, // Define a callback function when a date is selected - onChangeMonthYear: null, // Define a callback function when the month or year is changed - onClose: null, // Define a callback function when the datepicker is closed - numberOfMonths: 1, // Number of months to show at a time - showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) - stepMonths: 1, // Number of months to step back/forward - stepBigMonths: 12, // Number of months to step back/forward for the big links - altField: "", // Selector for an alternate field to store selected dates into - altFormat: "", // The date format to use for the alternate field - constrainInput: true, // The input is constrained by the current date format - showButtonPanel: false, // True to show button panel, false to not show it - autoSize: false, // True to size the input for the date format, false to leave as is - disabled: false // The initial disabled state - }; - $.extend(this._defaults, this.regional[""]); - this.regional.en = $.extend( true, {}, this.regional[ "" ]); - this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); - this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); -} - -$.extend(Datepicker.prototype, { - /* Class name added to elements to indicate already configured with a date picker. */ - markerClassName: "hasDatepicker", - - //Keep track of the maximum number of rows displayed (see #7043) - maxRows: 4, - - // TODO rename to "widget" when switching to widget factory - _widgetDatepicker: function() { - return this.dpDiv; - }, - - /* Override the default settings for all instances of the date picker. - * @param settings object - the new settings to use as defaults (anonymous object) - * @return the manager object - */ - setDefaults: function(settings) { - datepicker_extendRemove(this._defaults, settings || {}); - return this; - }, - - /* Attach the date picker to a jQuery selection. - * @param target element - the target input field or division or span - * @param settings object - the new settings to use for this date picker instance (anonymous) - */ - _attachDatepicker: function(target, settings) { - var nodeName, inline, inst; - nodeName = target.nodeName.toLowerCase(); - inline = (nodeName === "div" || nodeName === "span"); - if (!target.id) { - this.uuid += 1; - target.id = "dp" + this.uuid; - } - inst = this._newInst($(target), inline); - inst.settings = $.extend({}, settings || {}); - if (nodeName === "input") { - this._connectDatepicker(target, inst); - } else if (inline) { - this._inlineDatepicker(target, inst); - } - }, - - /* Create a new instance object. */ - _newInst: function(target, inline) { - var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars - return {id: id, input: target, // associated target - selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection - drawMonth: 0, drawYear: 0, // month being drawn - inline: inline, // is datepicker inline or not - dpDiv: (!inline ? this.dpDiv : // presentation div - datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; - }, - - /* Attach the date picker to an input field. */ - _connectDatepicker: function(target, inst) { - var input = $(target); - inst.append = $([]); - inst.trigger = $([]); - if (input.hasClass(this.markerClassName)) { - return; - } - this._attachments(input, inst); - input.addClass(this.markerClassName).keydown(this._doKeyDown). - keypress(this._doKeyPress).keyup(this._doKeyUp); - this._autoSize(inst); - $.data(target, "datepicker", inst); - //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) - if( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - }, - - /* Make attachments based on settings. */ - _attachments: function(input, inst) { - var showOn, buttonText, buttonImage, - appendText = this._get(inst, "appendText"), - isRTL = this._get(inst, "isRTL"); - - if (inst.append) { - inst.append.remove(); - } - if (appendText) { - inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); - input[isRTL ? "before" : "after"](inst.append); - } - - input.unbind("focus", this._showDatepicker); - - if (inst.trigger) { - inst.trigger.remove(); - } - - showOn = this._get(inst, "showOn"); - if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field - input.focus(this._showDatepicker); - } - if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked - buttonText = this._get(inst, "buttonText"); - buttonImage = this._get(inst, "buttonImage"); - inst.trigger = $(this._get(inst, "buttonImageOnly") ? - $("<img/>").addClass(this._triggerClass). - attr({ src: buttonImage, alt: buttonText, title: buttonText }) : - $("<button type='button'></button>").addClass(this._triggerClass). - html(!buttonImage ? buttonText : $("<img/>").attr( - { src:buttonImage, alt:buttonText, title:buttonText }))); - input[isRTL ? "before" : "after"](inst.trigger); - inst.trigger.click(function() { - if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { - $.datepicker._hideDatepicker(); - } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { - $.datepicker._hideDatepicker(); - $.datepicker._showDatepicker(input[0]); - } else { - $.datepicker._showDatepicker(input[0]); - } - return false; - }); - } - }, - - /* Apply the maximum length for the date format. */ - _autoSize: function(inst) { - if (this._get(inst, "autoSize") && !inst.inline) { - var findMax, max, maxI, i, - date = new Date(2009, 12 - 1, 20), // Ensure double digits - dateFormat = this._get(inst, "dateFormat"); - - if (dateFormat.match(/[DM]/)) { - findMax = function(names) { - max = 0; - maxI = 0; - for (i = 0; i < names.length; i++) { - if (names[i].length > max) { - max = names[i].length; - maxI = i; - } - } - return maxI; - }; - date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? - "monthNames" : "monthNamesShort")))); - date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? - "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); - } - inst.input.attr("size", this._formatDate(inst, date).length); - } - }, - - /* Attach an inline date picker to a div. */ - _inlineDatepicker: function(target, inst) { - var divSpan = $(target); - if (divSpan.hasClass(this.markerClassName)) { - return; - } - divSpan.addClass(this.markerClassName).append(inst.dpDiv); - $.data(target, "datepicker", inst); - this._setDate(inst, this._getDefaultDate(inst), true); - this._updateDatepicker(inst); - this._updateAlternate(inst); - //If disabled option is true, disable the datepicker before showing it (see ticket #5665) - if( inst.settings.disabled ) { - this._disableDatepicker( target ); - } - // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements - // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height - inst.dpDiv.css( "display", "block" ); - }, - - /* Pop-up the date picker in a "dialog" box. - * @param input element - ignored - * @param date string or Date - the initial date to display - * @param onSelect function - the function to call when a date is selected - * @param settings object - update the dialog date picker instance's settings (anonymous object) - * @param pos int[2] - coordinates for the dialog's position within the screen or - * event - with x/y coordinates or - * leave empty for default (screen centre) - * @return the manager object - */ - _dialogDatepicker: function(input, date, onSelect, settings, pos) { - var id, browserWidth, browserHeight, scrollX, scrollY, - inst = this._dialogInst; // internal instance - - if (!inst) { - this.uuid += 1; - id = "dp" + this.uuid; - this._dialogInput = $("<input type='text' id='" + id + - "' style='position: absolute; top: -100px; width: 0px;'/>"); - this._dialogInput.keydown(this._doKeyDown); - $("body").append(this._dialogInput); - inst = this._dialogInst = this._newInst(this._dialogInput, false); - inst.settings = {}; - $.data(this._dialogInput[0], "datepicker", inst); - } - datepicker_extendRemove(inst.settings, settings || {}); - date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); - this._dialogInput.val(date); - - this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); - if (!this._pos) { - browserWidth = document.documentElement.clientWidth; - browserHeight = document.documentElement.clientHeight; - scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; - scrollY = document.documentElement.scrollTop || document.body.scrollTop; - this._pos = // should use actual width/height below - [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; - } - - // move input on screen for focus, but hidden behind dialog - this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); - inst.settings.onSelect = onSelect; - this._inDialog = true; - this.dpDiv.addClass(this._dialogClass); - this._showDatepicker(this._dialogInput[0]); - if ($.blockUI) { - $.blockUI(this.dpDiv); - } - $.data(this._dialogInput[0], "datepicker", inst); - return this; - }, - - /* Detach a datepicker from its control. - * @param target element - the target input field or division or span - */ - _destroyDatepicker: function(target) { - var nodeName, - $target = $(target), - inst = $.data(target, "datepicker"); - - if (!$target.hasClass(this.markerClassName)) { - return; - } - - nodeName = target.nodeName.toLowerCase(); - $.removeData(target, "datepicker"); - if (nodeName === "input") { - inst.append.remove(); - inst.trigger.remove(); - $target.removeClass(this.markerClassName). - unbind("focus", this._showDatepicker). - unbind("keydown", this._doKeyDown). - unbind("keypress", this._doKeyPress). - unbind("keyup", this._doKeyUp); - } else if (nodeName === "div" || nodeName === "span") { - $target.removeClass(this.markerClassName).empty(); - } - - if ( datepicker_instActive === inst ) { - datepicker_instActive = null; - } - }, - - /* Enable the date picker to a jQuery selection. - * @param target element - the target input field or division or span - */ - _enableDatepicker: function(target) { - var nodeName, inline, - $target = $(target), - inst = $.data(target, "datepicker"); - - if (!$target.hasClass(this.markerClassName)) { - return; - } - - nodeName = target.nodeName.toLowerCase(); - if (nodeName === "input") { - target.disabled = false; - inst.trigger.filter("button"). - each(function() { this.disabled = false; }).end(). - filter("img").css({opacity: "1.0", cursor: ""}); - } else if (nodeName === "div" || nodeName === "span") { - inline = $target.children("." + this._inlineClass); - inline.children().removeClass("ui-state-disabled"); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - prop("disabled", false); - } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value === target ? null : value); }); // delete entry - }, - - /* Disable the date picker to a jQuery selection. - * @param target element - the target input field or division or span - */ - _disableDatepicker: function(target) { - var nodeName, inline, - $target = $(target), - inst = $.data(target, "datepicker"); - - if (!$target.hasClass(this.markerClassName)) { - return; - } - - nodeName = target.nodeName.toLowerCase(); - if (nodeName === "input") { - target.disabled = true; - inst.trigger.filter("button"). - each(function() { this.disabled = true; }).end(). - filter("img").css({opacity: "0.5", cursor: "default"}); - } else if (nodeName === "div" || nodeName === "span") { - inline = $target.children("." + this._inlineClass); - inline.children().addClass("ui-state-disabled"); - inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). - prop("disabled", true); - } - this._disabledInputs = $.map(this._disabledInputs, - function(value) { return (value === target ? null : value); }); // delete entry - this._disabledInputs[this._disabledInputs.length] = target; - }, - - /* Is the first field in a jQuery collection disabled as a datepicker? - * @param target element - the target input field or division or span - * @return boolean - true if disabled, false if enabled - */ - _isDisabledDatepicker: function(target) { - if (!target) { - return false; - } - for (var i = 0; i < this._disabledInputs.length; i++) { - if (this._disabledInputs[i] === target) { - return true; - } - } - return false; - }, - - /* Retrieve the instance data for the target control. - * @param target element - the target input field or division or span - * @return object - the associated instance data - * @throws error if a jQuery problem getting data - */ - _getInst: function(target) { - try { - return $.data(target, "datepicker"); - } - catch (err) { - throw "Missing instance data for this datepicker"; - } - }, - - /* Update or retrieve the settings for a date picker attached to an input field or division. - * @param target element - the target input field or division or span - * @param name object - the new settings to update or - * string - the name of the setting to change or retrieve, - * when retrieving also "all" for all instance settings or - * "defaults" for all global defaults - * @param value any - the new value for the setting - * (omit if above is an object or to retrieve a value) - */ - _optionDatepicker: function(target, name, value) { - var settings, date, minDate, maxDate, - inst = this._getInst(target); - - if (arguments.length === 2 && typeof name === "string") { - return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : - (inst ? (name === "all" ? $.extend({}, inst.settings) : - this._get(inst, name)) : null)); - } - - settings = name || {}; - if (typeof name === "string") { - settings = {}; - settings[name] = value; - } - - if (inst) { - if (this._curInst === inst) { - this._hideDatepicker(); - } - - date = this._getDateDatepicker(target, true); - minDate = this._getMinMaxDate(inst, "min"); - maxDate = this._getMinMaxDate(inst, "max"); - datepicker_extendRemove(inst.settings, settings); - // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided - if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { - inst.settings.minDate = this._formatDate(inst, minDate); - } - if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { - inst.settings.maxDate = this._formatDate(inst, maxDate); - } - if ( "disabled" in settings ) { - if ( settings.disabled ) { - this._disableDatepicker(target); - } else { - this._enableDatepicker(target); - } - } - this._attachments($(target), inst); - this._autoSize(inst); - this._setDate(inst, date); - this._updateAlternate(inst); - this._updateDatepicker(inst); - } - }, - - // change method deprecated - _changeDatepicker: function(target, name, value) { - this._optionDatepicker(target, name, value); - }, - - /* Redraw the date picker attached to an input field or division. - * @param target element - the target input field or division or span - */ - _refreshDatepicker: function(target) { - var inst = this._getInst(target); - if (inst) { - this._updateDatepicker(inst); - } - }, - - /* Set the dates for a jQuery selection. - * @param target element - the target input field or division or span - * @param date Date - the new date - */ - _setDateDatepicker: function(target, date) { - var inst = this._getInst(target); - if (inst) { - this._setDate(inst, date); - this._updateDatepicker(inst); - this._updateAlternate(inst); - } - }, - - /* Get the date(s) for the first entry in a jQuery selection. - * @param target element - the target input field or division or span - * @param noDefault boolean - true if no default date is to be used - * @return Date - the current date - */ - _getDateDatepicker: function(target, noDefault) { - var inst = this._getInst(target); - if (inst && !inst.inline) { - this._setDateFromField(inst, noDefault); - } - return (inst ? this._getDate(inst) : null); - }, - - /* Handle keystrokes. */ - _doKeyDown: function(event) { - var onSelect, dateStr, sel, - inst = $.datepicker._getInst(event.target), - handled = true, - isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); - - inst._keyEvent = true; - if ($.datepicker._datepickerShowing) { - switch (event.keyCode) { - case 9: $.datepicker._hideDatepicker(); - handled = false; - break; // hide on tab out - case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + - $.datepicker._currentClass + ")", inst.dpDiv); - if (sel[0]) { - $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); - } - - onSelect = $.datepicker._get(inst, "onSelect"); - if (onSelect) { - dateStr = $.datepicker._formatDate(inst); - - // trigger custom callback - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); - } else { - $.datepicker._hideDatepicker(); - } - - return false; // don't submit the form - case 27: $.datepicker._hideDatepicker(); - break; // hide on escape - case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, "stepBigMonths") : - -$.datepicker._get(inst, "stepMonths")), "M"); - break; // previous month/year on page up/+ ctrl - case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, "stepBigMonths") : - +$.datepicker._get(inst, "stepMonths")), "M"); - break; // next month/year on page down/+ ctrl - case 35: if (event.ctrlKey || event.metaKey) { - $.datepicker._clearDate(event.target); - } - handled = event.ctrlKey || event.metaKey; - break; // clear on ctrl or command +end - case 36: if (event.ctrlKey || event.metaKey) { - $.datepicker._gotoToday(event.target); - } - handled = event.ctrlKey || event.metaKey; - break; // current on ctrl or command +home - case 37: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); - } - handled = event.ctrlKey || event.metaKey; - // -1 day on ctrl or command +left - if (event.originalEvent.altKey) { - $.datepicker._adjustDate(event.target, (event.ctrlKey ? - -$.datepicker._get(inst, "stepBigMonths") : - -$.datepicker._get(inst, "stepMonths")), "M"); - } - // next month/year on alt +left on Mac - break; - case 38: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, -7, "D"); - } - handled = event.ctrlKey || event.metaKey; - break; // -1 week on ctrl or command +up - case 39: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); - } - handled = event.ctrlKey || event.metaKey; - // +1 day on ctrl or command +right - if (event.originalEvent.altKey) { - $.datepicker._adjustDate(event.target, (event.ctrlKey ? - +$.datepicker._get(inst, "stepBigMonths") : - +$.datepicker._get(inst, "stepMonths")), "M"); - } - // next month/year on alt +right - break; - case 40: if (event.ctrlKey || event.metaKey) { - $.datepicker._adjustDate(event.target, +7, "D"); - } - handled = event.ctrlKey || event.metaKey; - break; // +1 week on ctrl or command +down - default: handled = false; - } - } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home - $.datepicker._showDatepicker(this); - } else { - handled = false; - } - - if (handled) { - event.preventDefault(); - event.stopPropagation(); - } - }, - - /* Filter entered characters - based on date format. */ - _doKeyPress: function(event) { - var chars, chr, - inst = $.datepicker._getInst(event.target); - - if ($.datepicker._get(inst, "constrainInput")) { - chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); - chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); - return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); - } - }, - - /* Synchronise manual entry and field/alternate field. */ - _doKeyUp: function(event) { - var date, - inst = $.datepicker._getInst(event.target); - - if (inst.input.val() !== inst.lastVal) { - try { - date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), - (inst.input ? inst.input.val() : null), - $.datepicker._getFormatConfig(inst)); - - if (date) { // only if valid - $.datepicker._setDateFromField(inst); - $.datepicker._updateAlternate(inst); - $.datepicker._updateDatepicker(inst); - } - } - catch (err) { - } - } - return true; - }, - - /* Pop-up the date picker for a given input field. - * If false returned from beforeShow event handler do not show. - * @param input element - the input field attached to the date picker or - * event - if triggered by focus - */ - _showDatepicker: function(input) { - input = input.target || input; - if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger - input = $("input", input.parentNode)[0]; - } - - if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here - return; - } - - var inst, beforeShow, beforeShowSettings, isFixed, - offset, showAnim, duration; - - inst = $.datepicker._getInst(input); - if ($.datepicker._curInst && $.datepicker._curInst !== inst) { - $.datepicker._curInst.dpDiv.stop(true, true); - if ( inst && $.datepicker._datepickerShowing ) { - $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); - } - } - - beforeShow = $.datepicker._get(inst, "beforeShow"); - beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; - if(beforeShowSettings === false){ - return; - } - datepicker_extendRemove(inst.settings, beforeShowSettings); - - inst.lastVal = null; - $.datepicker._lastInput = input; - $.datepicker._setDateFromField(inst); - - if ($.datepicker._inDialog) { // hide cursor - input.value = ""; - } - if (!$.datepicker._pos) { // position below input - $.datepicker._pos = $.datepicker._findPos(input); - $.datepicker._pos[1] += input.offsetHeight; // add the height - } - - isFixed = false; - $(input).parents().each(function() { - isFixed |= $(this).css("position") === "fixed"; - return !isFixed; - }); - - offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; - $.datepicker._pos = null; - //to avoid flashes on Firefox - inst.dpDiv.empty(); - // determine sizing offscreen - inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); - $.datepicker._updateDatepicker(inst); - // fix width for dynamic number of date pickers - // and adjust position before showing - offset = $.datepicker._checkOffset(inst, offset, isFixed); - inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? - "static" : (isFixed ? "fixed" : "absolute")), display: "none", - left: offset.left + "px", top: offset.top + "px"}); - - if (!inst.inline) { - showAnim = $.datepicker._get(inst, "showAnim"); - duration = $.datepicker._get(inst, "duration"); - inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); - $.datepicker._datepickerShowing = true; - - if ( $.effects && $.effects.effect[ showAnim ] ) { - inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); - } else { - inst.dpDiv[showAnim || "show"](showAnim ? duration : null); - } - - if ( $.datepicker._shouldFocusInput( inst ) ) { - inst.input.focus(); - } - - $.datepicker._curInst = inst; - } - }, - - /* Generate the date picker content. */ - _updateDatepicker: function(inst) { - this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) - datepicker_instActive = inst; // for delegate hover events - inst.dpDiv.empty().append(this._generateHTML(inst)); - this._attachHandlers(inst); - - var origyearshtml, - numMonths = this._getNumberOfMonths(inst), - cols = numMonths[1], - width = 17, - activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); - - if ( activeCell.length > 0 ) { - datepicker_handleMouseover.apply( activeCell.get( 0 ) ); - } - - inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); - if (cols > 1) { - inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); - } - inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + - "Class"]("ui-datepicker-multi"); - inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + - "Class"]("ui-datepicker-rtl"); - - if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { - inst.input.focus(); - } - - // deffered render of the years select (to avoid flashes on Firefox) - if( inst.yearshtml ){ - origyearshtml = inst.yearshtml; - setTimeout(function(){ - //assure that inst.yearshtml didn't change. - if( origyearshtml === inst.yearshtml && inst.yearshtml ){ - inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); - } - origyearshtml = inst.yearshtml = null; - }, 0); - } - - var afterUpdate = this._get(inst, "afterUpdate"); - if(afterUpdate) - afterUpdate.apply((inst.input ? inst.input[0] : null), [inst]); - }, - - // #6694 - don't focus the input if it's already focused - // this breaks the change event in IE - // Support: IE and jQuery <1.9 - _shouldFocusInput: function( inst ) { - return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); - }, - - /* Check positioning to remain on screen. */ - _checkOffset: function(inst, offset, isFixed) { - var dpWidth = inst.dpDiv.outerWidth(), - dpHeight = inst.dpDiv.outerHeight(), - inputWidth = inst.input ? inst.input.outerWidth() : 0, - inputHeight = inst.input ? inst.input.outerHeight() : 0, - viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), - viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); - - offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); - offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; - offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; - - // now check if datepicker is showing outside window viewport - move to a better place if so. - offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? - Math.abs(offset.left + dpWidth - viewWidth) : 0); - offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? - Math.abs(dpHeight + inputHeight) : 0); - - return offset; - }, - - /* Find an object's position on the screen. */ - _findPos: function(obj) { - var position, - inst = this._getInst(obj), - isRTL = this._get(inst, "isRTL"); - - while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { - obj = obj[isRTL ? "previousSibling" : "nextSibling"]; - } - - position = $(obj).offset(); - return [position.left, position.top]; - }, - - /* Hide the date picker from view. - * @param input element - the input field attached to the date picker - */ - _hideDatepicker: function(input) { - var showAnim, duration, postProcess, onClose, - inst = this._curInst; - - if (!inst || (input && inst !== $.data(input, "datepicker"))) { - return; - } - - if (this._datepickerShowing) { - showAnim = this._get(inst, "showAnim"); - duration = this._get(inst, "duration"); - postProcess = function() { - $.datepicker._tidyDialog(inst); - }; - - // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed - if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { - inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); - } else { - inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : - (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); - } - - if (!showAnim) { - postProcess(); - } - this._datepickerShowing = false; - - onClose = this._get(inst, "onClose"); - if (onClose) { - onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); - } - - this._lastInput = null; - if (this._inDialog) { - this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); - if ($.blockUI) { - $.unblockUI(); - $("body").append(this.dpDiv); - } - } - this._inDialog = false; - } - }, - - /* Tidy up after a dialog display. */ - _tidyDialog: function(inst) { - inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); - }, - - /* Close date picker if clicked elsewhere. */ - _checkExternalClick: function(event) { - if (!$.datepicker._curInst) { - return; - } - - var $target = $(event.target), - inst = $.datepicker._getInst($target[0]); - - if ( ( ( $target[0].id !== $.datepicker._mainDivId && - $target.parents("#" + $.datepicker._mainDivId).length === 0 && - !$target.hasClass($.datepicker.markerClassName) && - !$target.closest("." + $.datepicker._triggerClass).length && - $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || - ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { - $.datepicker._hideDatepicker(); - } - }, - - /* Adjust one of the date sub-fields. */ - _adjustDate: function(id, offset, period) { - var target = $(id), - inst = this._getInst(target[0]); - - if (this._isDisabledDatepicker(target[0])) { - return; - } - this._adjustInstDate(inst, offset + - (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning - period); - this._updateDatepicker(inst); - }, - - /* Action for current link. */ - _gotoToday: function(id) { - var date, - target = $(id), - inst = this._getInst(target[0]); - - if (this._get(inst, "gotoCurrent") && inst.currentDay) { - inst.selectedDay = inst.currentDay; - inst.drawMonth = inst.selectedMonth = inst.currentMonth; - inst.drawYear = inst.selectedYear = inst.currentYear; - } else { - date = new Date(); - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - } - this._notifyChange(inst); - this._adjustDate(target); - }, - - /* Action for selecting a new month/year. */ - _selectMonthYear: function(id, select, period) { - var target = $(id), - inst = this._getInst(target[0]); - - inst["selected" + (period === "M" ? "Month" : "Year")] = - inst["draw" + (period === "M" ? "Month" : "Year")] = - parseInt(select.options[select.selectedIndex].value,10); - - this._notifyChange(inst); - this._adjustDate(target); - }, - - /* Action for selecting a day. */ - _selectDay: function(id, month, year, td) { - var inst, - target = $(id); - - if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { - return; - } - - inst = this._getInst(target[0]); - inst.selectedDay = inst.currentDay = $("a", td).html(); - inst.selectedMonth = inst.currentMonth = month; - inst.selectedYear = inst.currentYear = year; - this._selectDate(id, this._formatDate(inst, - inst.currentDay, inst.currentMonth, inst.currentYear)); - }, - - /* Erase the input field and hide the date picker. */ - _clearDate: function(id) { - var target = $(id); - this._selectDate(target, ""); - }, - - /* Update the input field with the selected date. */ - _selectDate: function(id, dateStr) { - var onSelect, - target = $(id), - inst = this._getInst(target[0]); - - dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); - if (inst.input) { - inst.input.val(dateStr); - } - this._updateAlternate(inst); - - onSelect = this._get(inst, "onSelect"); - if (onSelect) { - onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback - } else if (inst.input) { - inst.input.trigger("change"); // fire the change event - } - - if (inst.inline){ - this._updateDatepicker(inst); - } else { - this._hideDatepicker(); - this._lastInput = inst.input[0]; - if (typeof(inst.input[0]) !== "object") { - inst.input.focus(); // restore focus - } - this._lastInput = null; - } - }, - - /* Update any alternate field to synchronise with the main field. */ - _updateAlternate: function(inst) { - var altFormat, date, dateStr, - altField = this._get(inst, "altField"); - - if (altField) { // update alternate field too - altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); - date = this._getDate(inst); - dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); - $(altField).each(function() { $(this).val(dateStr); }); - } - }, - - /* Set as beforeShowDay function to prevent selection of weekends. - * @param date Date - the date to customise - * @return [boolean, string] - is this date selectable?, what is its CSS class? - */ - noWeekends: function(date) { - var day = date.getDay(); - return [(day > 0 && day < 6), ""]; - }, - - /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. - * @param date Date - the date to get the week for - * @return number - the number of the week within the year that contains this date - */ - iso8601Week: function(date) { - var time, - checkDate = new Date(date.getTime()); - - // Find Thursday of this week starting on Monday - checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); - - time = checkDate.getTime(); - checkDate.setMonth(0); // Compare with Jan 1 - checkDate.setDate(1); - return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; - }, - - /* Parse a string value into a date object. - * See formatDate below for the possible formats. - * - * @param format string - the expected format of the date - * @param value string - the date in the above format - * @param settings Object - attributes include: - * shortYearCutoff number - the cutoff year for determining the century (optional) - * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - * dayNames string[7] - names of the days from Sunday (optional) - * monthNamesShort string[12] - abbreviated names of the months (optional) - * monthNames string[12] - names of the months (optional) - * @return Date - the extracted date value or null if value is blank - */ - parseDate: function (format, value, settings) { - if (format == null || value == null) { - throw "Invalid arguments"; - } - - value = (typeof value === "object" ? value.toString() : value + ""); - if (value === "") { - return null; - } - - var iFormat, dim, extra, - iValue = 0, - shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, - shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : - new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), - dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, - dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, - monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, - monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, - year = -1, - month = -1, - day = -1, - doy = -1, - literal = false, - date, - // Check whether a format character is doubled - lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); - if (matches) { - iFormat++; - } - return matches; - }, - // Extract a number from the string value - getNumber = function(match) { - var isDoubled = lookAhead(match), - size = (match === "@" ? 14 : (match === "!" ? 20 : - (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), - minSize = (match === "y" ? size : 1), - digits = new RegExp("^\\d{" + minSize + "," + size + "}"), - num = value.substring(iValue).match(digits); - if (!num) { - throw "Missing number at position " + iValue; - } - iValue += num[0].length; - return parseInt(num[0], 10); - }, - // Extract a name from the string value and convert to an index - getName = function(match, shortNames, longNames) { - var index = -1, - names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { - return [ [k, v] ]; - }).sort(function (a, b) { - return -(a[1].length - b[1].length); - }); - - $.each(names, function (i, pair) { - var name = pair[1]; - if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { - index = pair[0]; - iValue += name.length; - return false; - } - }); - if (index !== -1) { - return index + 1; - } else { - throw "Unknown name at position " + iValue; - } - }, - // Confirm that a literal character matches the string value - checkLiteral = function() { - if (value.charAt(iValue) !== format.charAt(iFormat)) { - throw "Unexpected literal at position " + iValue; - } - iValue++; - }; - - for (iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) { - if (format.charAt(iFormat) === "'" && !lookAhead("'")) { - literal = false; - } else { - checkLiteral(); - } - } else { - switch (format.charAt(iFormat)) { - case "d": - day = getNumber("d"); - break; - case "D": - getName("D", dayNamesShort, dayNames); - break; - case "o": - doy = getNumber("o"); - break; - case "m": - month = getNumber("m"); - break; - case "M": - month = getName("M", monthNamesShort, monthNames); - break; - case "y": - year = getNumber("y"); - break; - case "@": - date = new Date(getNumber("@")); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "!": - date = new Date((getNumber("!") - this._ticksTo1970) / 10000); - year = date.getFullYear(); - month = date.getMonth() + 1; - day = date.getDate(); - break; - case "'": - if (lookAhead("'")){ - checkLiteral(); - } else { - literal = true; - } - break; - default: - checkLiteral(); - } - } - } - - if (iValue < value.length){ - extra = value.substr(iValue); - if (!/^\s+/.test(extra)) { - throw "Extra/unparsed characters found in date: " + extra; - } - } - - if (year === -1) { - year = new Date().getFullYear(); - } else if (year < 100) { - year += new Date().getFullYear() - new Date().getFullYear() % 100 + - (year <= shortYearCutoff ? 0 : -100); - } - - if (doy > -1) { - month = 1; - day = doy; - do { - dim = this._getDaysInMonth(year, month - 1); - if (day <= dim) { - break; - } - month++; - day -= dim; - } while (true); - } - - date = this._daylightSavingAdjust(new Date(year, month - 1, day)); - if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { - throw "Invalid date"; // E.g. 31/02/00 - } - return date; - }, - - /* Standard date formats. */ - ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) - COOKIE: "D, dd M yy", - ISO_8601: "yy-mm-dd", - RFC_822: "D, d M y", - RFC_850: "DD, dd-M-y", - RFC_1036: "D, d M y", - RFC_1123: "D, d M yy", - RFC_2822: "D, d M yy", - RSS: "D, d M y", // RFC 822 - TICKS: "!", - TIMESTAMP: "@", - W3C: "yy-mm-dd", // ISO 8601 - - _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + - Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), - - /* Format a date object into a string value. - * The format can be combinations of the following: - * d - day of month (no leading zero) - * dd - day of month (two digit) - * o - day of year (no leading zeros) - * oo - day of year (three digit) - * D - day name short - * DD - day name long - * m - month of year (no leading zero) - * mm - month of year (two digit) - * M - month name short - * MM - month name long - * y - year (two digit) - * yy - year (four digit) - * @ - Unix timestamp (ms since 01/01/1970) - * ! - Windows ticks (100ns since 01/01/0001) - * "..." - literal text - * '' - single quote - * - * @param format string - the desired format of the date - * @param date Date - the date value to format - * @param settings Object - attributes include: - * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) - * dayNames string[7] - names of the days from Sunday (optional) - * monthNamesShort string[12] - abbreviated names of the months (optional) - * monthNames string[12] - names of the months (optional) - * @return string - the date in the above format - */ - formatDate: function (format, date, settings) { - if (!date) { - return ""; - } - - var iFormat, - dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, - dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, - monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, - monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, - // Check whether a format character is doubled - lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); - if (matches) { - iFormat++; - } - return matches; - }, - // Format a number, with leading zero if necessary - formatNumber = function(match, value, len) { - var num = "" + value; - if (lookAhead(match)) { - while (num.length < len) { - num = "0" + num; - } - } - return num; - }, - // Format a name, short or long as requested - formatName = function(match, value, shortNames, longNames) { - return (lookAhead(match) ? longNames[value] : shortNames[value]); - }, - output = "", - literal = false; - - if (date) { - for (iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) { - if (format.charAt(iFormat) === "'" && !lookAhead("'")) { - literal = false; - } else { - output += format.charAt(iFormat); - } - } else { - switch (format.charAt(iFormat)) { - case "d": - output += formatNumber("d", date.getDate(), 2); - break; - case "D": - output += formatName("D", date.getDay(), dayNamesShort, dayNames); - break; - case "o": - output += formatNumber("o", - Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); - break; - case "m": - output += formatNumber("m", date.getMonth() + 1, 2); - break; - case "M": - output += formatName("M", date.getMonth(), monthNamesShort, monthNames); - break; - case "y": - output += (lookAhead("y") ? date.getFullYear() : - (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); - break; - case "@": - output += date.getTime(); - break; - case "!": - output += date.getTime() * 10000 + this._ticksTo1970; - break; - case "'": - if (lookAhead("'")) { - output += "'"; - } else { - literal = true; - } - break; - default: - output += format.charAt(iFormat); - } - } - } - } - return output; - }, - - /* Extract all possible characters from the date format. */ - _possibleChars: function (format) { - var iFormat, - chars = "", - literal = false, - // Check whether a format character is doubled - lookAhead = function(match) { - var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); - if (matches) { - iFormat++; - } - return matches; - }; - - for (iFormat = 0; iFormat < format.length; iFormat++) { - if (literal) { - if (format.charAt(iFormat) === "'" && !lookAhead("'")) { - literal = false; - } else { - chars += format.charAt(iFormat); - } - } else { - switch (format.charAt(iFormat)) { - case "d": case "m": case "y": case "@": - chars += "0123456789"; - break; - case "D": case "M": - return null; // Accept anything - case "'": - if (lookAhead("'")) { - chars += "'"; - } else { - literal = true; - } - break; - default: - chars += format.charAt(iFormat); - } - } - } - return chars; - }, - - /* Get a setting value, defaulting if necessary. */ - _get: function(inst, name) { - return inst.settings[name] !== undefined ? - inst.settings[name] : this._defaults[name]; - }, - - /* Parse existing date and initialise date picker. */ - _setDateFromField: function(inst, noDefault) { - if (inst.input.val() === inst.lastVal) { - return; - } - - var dateFormat = this._get(inst, "dateFormat"), - dates = inst.lastVal = inst.input ? inst.input.val() : null, - defaultDate = this._getDefaultDate(inst), - date = defaultDate, - settings = this._getFormatConfig(inst); - - try { - date = this.parseDate(dateFormat, dates, settings) || defaultDate; - } catch (event) { - dates = (noDefault ? "" : dates); - } - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - inst.currentDay = (dates ? date.getDate() : 0); - inst.currentMonth = (dates ? date.getMonth() : 0); - inst.currentYear = (dates ? date.getFullYear() : 0); - this._adjustInstDate(inst); - }, - - /* Retrieve the default date shown on opening. */ - _getDefaultDate: function(inst) { - return this._restrictMinMax(inst, - this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); - }, - - /* A date may be specified as an exact value or a relative one. */ - _determineDate: function(inst, date, defaultDate) { - var offsetNumeric = function(offset) { - var date = new Date(); - date.setDate(date.getDate() + offset); - return date; - }, - offsetString = function(offset) { - try { - return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), - offset, $.datepicker._getFormatConfig(inst)); - } - catch (e) { - // Ignore - } - - var date = (offset.toLowerCase().match(/^c/) ? - $.datepicker._getDate(inst) : null) || new Date(), - year = date.getFullYear(), - month = date.getMonth(), - day = date.getDate(), - pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, - matches = pattern.exec(offset); - - while (matches) { - switch (matches[2] || "d") { - case "d" : case "D" : - day += parseInt(matches[1],10); break; - case "w" : case "W" : - day += parseInt(matches[1],10) * 7; break; - case "m" : case "M" : - month += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); - break; - case "y": case "Y" : - year += parseInt(matches[1],10); - day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); - break; - } - matches = pattern.exec(offset); - } - return new Date(year, month, day); - }, - newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : - (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); - - newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); - if (newDate) { - newDate.setHours(0); - newDate.setMinutes(0); - newDate.setSeconds(0); - newDate.setMilliseconds(0); - } - return this._daylightSavingAdjust(newDate); - }, - - /* Handle switch to/from daylight saving. - * Hours may be non-zero on daylight saving cut-over: - * > 12 when midnight changeover, but then cannot generate - * midnight datetime, so jump to 1AM, otherwise reset. - * @param date (Date) the date to check - * @return (Date) the corrected date - */ - _daylightSavingAdjust: function(date) { - if (!date) { - return null; - } - date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); - return date; - }, - - /* Set the date(s) directly. */ - _setDate: function(inst, date, noChange) { - var clear = !date, - origMonth = inst.selectedMonth, - origYear = inst.selectedYear, - newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); - - inst.selectedDay = inst.currentDay = newDate.getDate(); - inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); - inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); - if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { - this._notifyChange(inst); - } - this._adjustInstDate(inst); - if (inst.input) { - inst.input.val(clear ? "" : this._formatDate(inst)); - } - }, - - /* Retrieve the date(s) directly. */ - _getDate: function(inst) { - var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : - this._daylightSavingAdjust(new Date( - inst.currentYear, inst.currentMonth, inst.currentDay))); - return startDate; - }, - - /* Attach the onxxx handlers. These are declared statically so - * they work with static code transformers like Caja. - */ - _attachHandlers: function(inst) { - var stepMonths = this._get(inst, "stepMonths"), - id = "#" + inst.id.replace( /\\\\/g, "\\" ); - inst.dpDiv.find("[data-handler]").map(function () { - var handler = { - prev: function () { - $.datepicker._adjustDate(id, -stepMonths, "M"); - }, - next: function () { - $.datepicker._adjustDate(id, +stepMonths, "M"); - }, - hide: function () { - $.datepicker._hideDatepicker(); - }, - today: function () { - $.datepicker._gotoToday(id); - }, - selectDay: function () { - $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); - return false; - }, - selectMonth: function () { - $.datepicker._selectMonthYear(id, this, "M"); - return false; - }, - selectYear: function () { - $.datepicker._selectMonthYear(id, this, "Y"); - return false; - } - }; - $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); - }); - }, - - /* Generate the HTML for the current state of the date picker. */ - _generateHTML: function(inst) { - var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, - controls, buttonPanel, firstDay, weekendDays, showWeek, dayNames, dayNamesMin, - monthNames, monthNamesShort, beforeShowDay, showOtherMonths, - selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, - cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, - printDate, dRow, tbody, daySettings, otherMonth, unselectable, - tempDate = new Date(), - today = this._daylightSavingAdjust( - new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time - isRTL = this._get(inst, "isRTL"), - showButtonPanel = this._get(inst, "showButtonPanel"), - hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), - navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), - numMonths = this._getNumberOfMonths(inst), - showCurrentAtPos = this._get(inst, "showCurrentAtPos"), - stepMonths = this._get(inst, "stepMonths"), - isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), - currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : - new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), - minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - drawMonth = inst.drawMonth - showCurrentAtPos, - drawYear = inst.drawYear; - - if (drawMonth < 0) { - drawMonth += 12; - drawYear--; - } - if (maxDate) { - maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), - maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); - maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); - while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { - drawMonth--; - if (drawMonth < 0) { - drawMonth = 11; - drawYear--; - } - } - } - inst.drawMonth = drawMonth; - inst.drawYear = drawYear; - - prevText = this._get(inst, "prevText"); - prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), - this._getFormatConfig(inst))); - - prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? - "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + - " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : - (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>")); - - nextText = this._get(inst, "nextText"); - nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, - this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), - this._getFormatConfig(inst))); - - next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? - "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + - " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : - (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>")); - - currentText = this._get(inst, "currentText"); - gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); - currentText = (!navigationAsDateFormat ? currentText : - this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); - - 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'>" + - this._get(inst, "closeText") + "</button>" : ""); - - buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + - (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'" + - ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; - - firstDay = parseInt(this._get(inst, "firstDay"),10); - firstDay = (isNaN(firstDay) ? 0 : firstDay); - - weekendDays = this._get(inst, "weekendDays"); - showWeek = this._get(inst, "showWeek"); - dayNames = this._get(inst, "dayNames"); - dayNamesMin = this._get(inst, "dayNamesMin"); - monthNames = this._get(inst, "monthNames"); - monthNamesShort = this._get(inst, "monthNamesShort"); - beforeShowDay = this._get(inst, "beforeShowDay"); - showOtherMonths = this._get(inst, "showOtherMonths"); - selectOtherMonths = this._get(inst, "selectOtherMonths"); - defaultDate = this._getDefaultDate(inst); - html = ""; - dow; - for (row = 0; row < numMonths[0]; row++) { - group = ""; - this.maxRows = 4; - for (col = 0; col < numMonths[1]; col++) { - selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); - cornerClass = " ui-corner-all"; - calender = ""; - if (isMultiMonth) { - calender += "<div class='ui-datepicker-group"; - if (numMonths[1] > 1) { - switch (col) { - case 0: calender += " ui-datepicker-group-first"; - cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; - case numMonths[1]-1: calender += " ui-datepicker-group-last"; - cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; - default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; - } - } - calender += "'>"; - } - calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + - (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + - (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + - this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, - row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers - "</div><table class='ui-datepicker-calendar'><thead>" + - "<tr>"; - thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); - for (dow = 0; dow < 7; dow++) { // days of the week - day = (dow + firstDay) % 7; - thead += "<th scope='col'" + (weekendDays.indexOf(day)!=-1 ? " class='ui-datepicker-week-end'" : "") + ">" + - "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; - } - calender += thead + "</tr></thead><tbody>"; - daysInMonth = this._getDaysInMonth(drawYear, drawMonth); - if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { - inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); - } - leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; - curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate - numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) - this.maxRows = numRows; - printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); - for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows - calender += "<tr>"; - tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + - this._get(inst, "calculateWeek")(printDate) + "</td>"); - for (dow = 0; dow < 7; dow++) { // create date picker days - daySettings = (beforeShowDay ? - beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); - otherMonth = (printDate.getMonth() !== drawMonth); - unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || - (minDate && printDate < minDate) || (maxDate && printDate > maxDate); - tbody += "<td class='" + - (weekendDays.indexOf((dow + firstDay) % 7)!=-1 ? " ui-datepicker-week-end" : "") + // highlight weekends - (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months - ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key - (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? - // or defaultDate is current printedDate and defaultDate is selectedDate - " " + this._dayOverClass : "") + // highlight selected day - (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days - (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates - (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day - (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) - ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title - (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions - (otherMonth && !showOtherMonths ? " " : // display for other months - (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + - (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + - (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day - (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months - "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date - printDate.setDate(printDate.getDate() + 1); - printDate = this._daylightSavingAdjust(printDate); - } - calender += tbody + "</tr>"; - } - drawMonth++; - if (drawMonth > 11) { - drawMonth = 0; - drawYear++; - } - calender += "</tbody></table>" + (isMultiMonth ? "</div>" + - ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); - group += calender; - } - html += group; - } - html += buttonPanel; - inst._keyEvent = false; - return html; - }, - - /* Generate the month and year header. */ - _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort) { - - var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, - changeMonth = this._get(inst, "changeMonth"), - changeYear = this._get(inst, "changeYear"), - showMonthAfterYear = this._get(inst, "showMonthAfterYear"), - html = "<div class='ui-datepicker-title'>", - monthHtml = ""; - - // month selection - if (secondary || !changeMonth) { - monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; - } else { - inMinYear = (minDate && minDate.getFullYear() === drawYear); - inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); - monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; - for ( month = 0; month < 12; month++) { - if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { - monthHtml += "<option value='" + month + "'" + - (month === drawMonth ? " selected='selected'" : "") + - ">" + monthNamesShort[month] + "</option>"; - } - } - monthHtml += "</select>"; - } - - if (!showMonthAfterYear) { - html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); - } - - // year selection - if ( !inst.yearshtml ) { - inst.yearshtml = ""; - if (secondary || !changeYear) { - html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; - } else { - // determine range of years to display - years = this._get(inst, "yearRange").split(":"); - thisYear = new Date().getFullYear(); - determineYear = function(value) { - var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : - (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : - parseInt(value, 10))); - return (isNaN(year) ? thisYear : year); - }; - year = determineYear(years[0]); - endYear = Math.max(year, determineYear(years[1] || "")); - year = (minDate ? Math.max(year, minDate.getFullYear()) : year); - endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); - inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; - for (; year <= endYear; year++) { - inst.yearshtml += "<option value='" + year + "'" + - (year === drawYear ? " selected='selected'" : "") + - ">" + year + "</option>"; - } - inst.yearshtml += "</select>"; - - html += inst.yearshtml; - inst.yearshtml = null; - } - } - - html += this._get(inst, "yearSuffix"); - if (showMonthAfterYear) { - html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; - } - html += "</div>"; // Close datepicker_header - return html; - }, - - /* Adjust one of the date sub-fields. */ - _adjustInstDate: function(inst, offset, period) { - var year = inst.drawYear + (period === "Y" ? offset : 0), - month = inst.drawMonth + (period === "M" ? offset : 0), - day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), - date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); - - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - if (period === "M" || period === "Y") { - this._notifyChange(inst); - } - }, - - /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function(inst, date) { - var minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - newDate = (minDate && date < minDate ? minDate : date); - return (maxDate && newDate > maxDate ? maxDate : newDate); - }, - - /* Notify change of month/year. */ - _notifyChange: function(inst) { - var onChange = this._get(inst, "onChangeMonthYear"); - if (onChange) { - onChange.apply((inst.input ? inst.input[0] : null), - [inst.selectedYear, inst.selectedMonth + 1, inst]); - } - }, - - /* Determine the number of months to show. */ - _getNumberOfMonths: function(inst) { - var numMonths = this._get(inst, "numberOfMonths"); - return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); - }, - - /* Determine the current maximum date - ensure no time components are set. */ - _getMinMaxDate: function(inst, minMax) { - return this._determineDate(inst, this._get(inst, minMax + "Date"), null); - }, - - /* Find the number of days in a given month. */ - _getDaysInMonth: function(year, month) { - return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); - }, - - /* Find the day of the week of the first of a month. */ - _getFirstDayOfMonth: function(year, month) { - return new Date(year, month, 1).getDay(); - }, - - /* Determines if we should allow a "next/prev" month display change. */ - _canAdjustMonth: function(inst, offset, curYear, curMonth) { - var numMonths = this._getNumberOfMonths(inst), - date = this._daylightSavingAdjust(new Date(curYear, - curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); - - if (offset < 0) { - date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); - } - return this._isInRange(inst, date); - }, - - /* Is the given date in the accepted range? */ - _isInRange: function(inst, date) { - var yearSplit, currentYear, - minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - minYear = null, - maxYear = null, - years = this._get(inst, "yearRange"); - if (years){ - yearSplit = years.split(":"); - currentYear = new Date().getFullYear(); - minYear = parseInt(yearSplit[0], 10); - maxYear = parseInt(yearSplit[1], 10); - if ( yearSplit[0].match(/[+\-].*/) ) { - minYear += currentYear; - } - if ( yearSplit[1].match(/[+\-].*/) ) { - maxYear += currentYear; - } - } - - return ((!minDate || date.getTime() >= minDate.getTime()) && - (!maxDate || date.getTime() <= maxDate.getTime()) && - (!minYear || date.getFullYear() >= minYear) && - (!maxYear || date.getFullYear() <= maxYear)); - }, - - /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function(inst) { - var shortYearCutoff = this._get(inst, "shortYearCutoff"); - shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - return {shortYearCutoff: shortYearCutoff, - dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), - monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; - }, - - /* Format the given date for display. */ - _formatDate: function(inst, day, month, year) { - if (!day) { - inst.currentDay = inst.selectedDay; - inst.currentMonth = inst.selectedMonth; - inst.currentYear = inst.selectedYear; - } - var date = (day ? (typeof day === "object" ? day : - this._daylightSavingAdjust(new Date(year, month, day))) : - this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); - } -}); - -/* - * Bind hover events for datepicker elements. - * Done via delegate so the binding only occurs once in the lifetime of the parent div. - * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. - */ -function datepicker_bindHover(dpDiv) { - var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; - return dpDiv.delegate(selector, "mouseout", function() { - $(this).removeClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).removeClass("ui-datepicker-prev-hover"); - } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).removeClass("ui-datepicker-next-hover"); - } - }) - .delegate( selector, "mouseover", datepicker_handleMouseover ); -} - -function datepicker_handleMouseover() { - if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { - $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); - $(this).addClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).addClass("ui-datepicker-prev-hover"); - } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).addClass("ui-datepicker-next-hover"); - } - } -} - -/* jQuery extend now ignores nulls! */ -function datepicker_extendRemove(target, props) { - $.extend(target, props); - for (var name in props) { - if (props[name] == null) { - target[name] = props[name]; - } - } - return target; -} - -/* Invoke the datepicker functionality. - @param options string - a command, optionally followed by additional parameters or - Object - settings for attaching new datepicker functionality - @return jQuery object */ -$.fn.datepicker = function(options){ - - /* Verify an empty collection wasn't passed - Fixes #6976 */ - if ( !this.length ) { - return this; - } - - /* Initialise the date picker. */ - if (!$.datepicker.initialized) { - $(document).mousedown($.datepicker._checkExternalClick); - $.datepicker.initialized = true; - } - - /* Append datepicker main container to body if not exist. */ - if ($("#"+$.datepicker._mainDivId).length === 0) { - $("body").append($.datepicker.dpDiv); - } - - var otherArgs = Array.prototype.slice.call(arguments, 1); - if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); - } - if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); - } - return this.each(function() { - typeof options === "string" ? - $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this].concat(otherArgs)) : - $.datepicker._attachDatepicker(this, options); - }); -}; - -$.datepicker = new Datepicker(); // singleton instance -$.datepicker.initialized = false; -$.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.11.4"; - -var datepicker = $.datepicker; - - -/*! - * jQuery UI Slider 1.11.4 - * http://jqueryui.com - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/slider/ - */ - - -var slider = $.widget( "ui.slider", $.ui.mouse, { - version: "1.11.4", - widgetEventPrefix: "slide", - - options: { - animate: false, - distance: 0, - max: 100, - min: 0, - orientation: "horizontal", - range: false, - step: 1, - value: 0, - values: null, - - // callbacks - change: null, - slide: null, - start: null, - stop: null - }, - - // number of pages in a slider - // (how many times can you page up/down to go through the whole range) - numPages: 5, - - _create: function() { - this._keySliding = false; - this._mouseSliding = false; - this._animateOff = true; - this._handleIndex = null; - this._detectOrientation(); - this._mouseInit(); - this._calculateNewMax(); - - this.element - .addClass( "ui-slider" + - " ui-slider-" + this.orientation + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all"); - - this._refresh(); - this._setOption( "disabled", this.options.disabled ); - - this._animateOff = false; - }, - - _refresh: function() { - this._createRange(); - this._createHandles(); - this._setupEvents(); - this._refreshValue(); - }, - - _createHandles: function() { - var i, handleCount, - options = this.options, - existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), - handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>", - handles = []; - - handleCount = ( options.values && options.values.length ) || 1; - - if ( existingHandles.length > handleCount ) { - existingHandles.slice( handleCount ).remove(); - existingHandles = existingHandles.slice( 0, handleCount ); - } - - for ( i = existingHandles.length; i < handleCount; i++ ) { - handles.push( handle ); - } - - this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); - - this.handle = this.handles.eq( 0 ); - - this.handles.each(function( i ) { - $( this ).data( "ui-slider-handle-index", i ); - }); - }, - - _createRange: function() { - var options = this.options, - classes = ""; - - if ( options.range ) { - if ( options.range === true ) { - if ( !options.values ) { - options.values = [ this._valueMin(), this._valueMin() ]; - } else if ( options.values.length && options.values.length !== 2 ) { - options.values = [ options.values[0], options.values[0] ]; - } else if ( $.isArray( options.values ) ) { - options.values = options.values.slice(0); - } - } - - if ( !this.range || !this.range.length ) { - this.range = $( "<div></div>" ) - .appendTo( this.element ); - - classes = "ui-slider-range" + - // note: this isn't the most fittingly semantic framework class for this element, - // but worked best visually with a variety of themes - " ui-widget-header ui-corner-all"; - } else { - this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) - // Handle range switching from true to min/max - .css({ - "left": "", - "bottom": "" - }); - } - - this.range.addClass( classes + - ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); - } else { - if ( this.range ) { - this.range.remove(); - } - this.range = null; - } - }, - - _setupEvents: function() { - this._off( this.handles ); - this._on( this.handles, this._handleEvents ); - this._hoverable( this.handles ); - this._focusable( this.handles ); - }, - - _destroy: function() { - this.handles.remove(); - if ( this.range ) { - this.range.remove(); - } - - this.element - .removeClass( "ui-slider" + - " ui-slider-horizontal" + - " ui-slider-vertical" + - " ui-widget" + - " ui-widget-content" + - " ui-corner-all" ); - - this._mouseDestroy(); - }, - - _mouseCapture: function( event ) { - var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, - that = this, - o = this.options; - - if ( o.disabled ) { - return false; - } - - this.elementSize = { - width: this.element.outerWidth(), - height: this.element.outerHeight() - }; - this.elementOffset = this.element.offset(); - - position = { x: event.pageX, y: event.pageY }; - normValue = this._normValueFromMouse( position ); - distance = this._valueMax() - this._valueMin() + 1; - this.handles.each(function( i ) { - var thisDistance = Math.abs( normValue - that.values(i) ); - if (( distance > thisDistance ) || - ( distance === thisDistance && - (i === that._lastChangedValue || that.values(i) === o.min ))) { - distance = thisDistance; - closestHandle = $( this ); - index = i; - } - }); - - allowed = this._start( event, index ); - if ( allowed === false ) { - return false; - } - this._mouseSliding = true; - - this._handleIndex = index; - - closestHandle - .addClass( "ui-state-active" ) - .focus(); - - offset = closestHandle.offset(); - mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); - this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { - left: event.pageX - offset.left - ( closestHandle.width() / 2 ), - top: event.pageY - offset.top - - ( closestHandle.height() / 2 ) - - ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - - ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + - ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) - }; - - if ( !this.handles.hasClass( "ui-state-hover" ) ) { - this._slide( event, index, normValue ); - } - this._animateOff = true; - return true; - }, - - _mouseStart: function() { - return true; - }, - - _mouseDrag: function( event ) { - var position = { x: event.pageX, y: event.pageY }, - normValue = this._normValueFromMouse( position ); - - this._slide( event, this._handleIndex, normValue ); - - return false; - }, - - _mouseStop: function( event ) { - this.handles.removeClass( "ui-state-active" ); - this._mouseSliding = false; - - this._stop( event, this._handleIndex ); - this._change( event, this._handleIndex ); - - this._handleIndex = null; - this._clickOffset = null; - this._animateOff = false; - - return false; - }, - - _detectOrientation: function() { - this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; - }, - - _normValueFromMouse: function( position ) { - var pixelTotal, - pixelMouse, - percentMouse, - valueTotal, - valueMouse; - - if ( this.orientation === "horizontal" ) { - pixelTotal = this.elementSize.width; - pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); - } else { - pixelTotal = this.elementSize.height; - pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); - } - - percentMouse = ( pixelMouse / pixelTotal ); - if ( percentMouse > 1 ) { - percentMouse = 1; - } - if ( percentMouse < 0 ) { - percentMouse = 0; - } - if ( this.orientation === "vertical" ) { - percentMouse = 1 - percentMouse; - } - - valueTotal = this._valueMax() - this._valueMin(); - valueMouse = this._valueMin() + percentMouse * valueTotal; - - return this._trimAlignValue( valueMouse ); - }, - - _start: function( event, index ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - return this._trigger( "start", event, uiHash ); - }, - - _slide: function( event, index, newVal ) { - var otherVal, - newValues, - allowed; - - if ( this.options.values && this.options.values.length ) { - otherVal = this.values( index ? 0 : 1 ); - - if ( ( this.options.values.length === 2 && this.options.range === true ) && - ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) - ) { - newVal = otherVal; - } - - if ( newVal !== this.values( index ) ) { - newValues = this.values(); - newValues[ index ] = newVal; - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal, - values: newValues - } ); - otherVal = this.values( index ? 0 : 1 ); - if ( allowed !== false ) { - this.values( index, newVal ); - } - } - } else { - if ( newVal !== this.value() ) { - // A slide can be canceled by returning false from the slide callback - allowed = this._trigger( "slide", event, { - handle: this.handles[ index ], - value: newVal - } ); - if ( allowed !== false ) { - this.value( newVal ); - } - } - } - }, - - _stop: function( event, index ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - - this._trigger( "stop", event, uiHash ); - }, - - _change: function( event, index ) { - if ( !this._keySliding && !this._mouseSliding ) { - var uiHash = { - handle: this.handles[ index ], - value: this.value() - }; - if ( this.options.values && this.options.values.length ) { - uiHash.value = this.values( index ); - uiHash.values = this.values(); - } - - //store the last changed value index for reference when handles overlap - this._lastChangedValue = index; - - this._trigger( "change", event, uiHash ); - } - }, - - value: function( newValue ) { - if ( arguments.length ) { - this.options.value = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, 0 ); - return; - } - - return this._value(); - }, - - values: function( index, newValue ) { - var vals, - newValues, - i; - - if ( arguments.length > 1 ) { - this.options.values[ index ] = this._trimAlignValue( newValue ); - this._refreshValue(); - this._change( null, index ); - return; - } - - if ( arguments.length ) { - if ( $.isArray( arguments[ 0 ] ) ) { - vals = this.options.values; - newValues = arguments[ 0 ]; - for ( i = 0; i < vals.length; i += 1 ) { - vals[ i ] = this._trimAlignValue( newValues[ i ] ); - this._change( null, i ); - } - this._refreshValue(); - } else { - if ( this.options.values && this.options.values.length ) { - return this._values( index ); - } else { - return this.value(); - } - } - } else { - return this._values(); - } - }, - - _setOption: function( key, value ) { - var i, - valsLength = 0; - - if ( key === "range" && this.options.range === true ) { - if ( value === "min" ) { - this.options.value = this._values( 0 ); - this.options.values = null; - } else if ( value === "max" ) { - this.options.value = this._values( this.options.values.length - 1 ); - this.options.values = null; - } - } - - if ( $.isArray( this.options.values ) ) { - valsLength = this.options.values.length; - } - - if ( key === "disabled" ) { - this.element.toggleClass( "ui-state-disabled", !!value ); - } - - this._super( key, value ); - - switch ( key ) { - case "orientation": - this._detectOrientation(); - this.element - .removeClass( "ui-slider-horizontal ui-slider-vertical" ) - .addClass( "ui-slider-" + this.orientation ); - this._refreshValue(); - - // Reset positioning from previous orientation - this.handles.css( value === "horizontal" ? "bottom" : "left", "" ); - break; - case "value": - this._animateOff = true; - this._refreshValue(); - this._change( null, 0 ); - this._animateOff = false; - break; - case "values": - this._animateOff = true; - this._refreshValue(); - for ( i = 0; i < valsLength; i += 1 ) { - this._change( null, i ); - } - this._animateOff = false; - break; - case "step": - case "min": - case "max": - this._animateOff = true; - this._calculateNewMax(); - this._refreshValue(); - this._animateOff = false; - break; - case "range": - this._animateOff = true; - this._refresh(); - this._animateOff = false; - break; - } - }, - - //internal value getter - // _value() returns value trimmed by min and max, aligned by step - _value: function() { - var val = this.options.value; - val = this._trimAlignValue( val ); - - return val; - }, - - //internal values getter - // _values() returns array of values trimmed by min and max, aligned by step - // _values( index ) returns single value trimmed by min and max, aligned by step - _values: function( index ) { - var val, - vals, - i; - - if ( arguments.length ) { - val = this.options.values[ index ]; - val = this._trimAlignValue( val ); - - return val; - } else if ( this.options.values && this.options.values.length ) { - // .slice() creates a copy of the array - // this copy gets trimmed by min and max and then returned - vals = this.options.values.slice(); - for ( i = 0; i < vals.length; i += 1) { - vals[ i ] = this._trimAlignValue( vals[ i ] ); - } - - return vals; - } else { - return []; - } - }, - - // returns the step-aligned value that val is closest to, between (inclusive) min and max - _trimAlignValue: function( val ) { - if ( val <= this._valueMin() ) { - return this._valueMin(); - } - if ( val >= this._valueMax() ) { - return this._valueMax(); - } - var step = ( this.options.step > 0 ) ? this.options.step : 1, - valModStep = (val - this._valueMin()) % step, - alignValue = val - valModStep; - - if ( Math.abs(valModStep) * 2 >= step ) { - alignValue += ( valModStep > 0 ) ? step : ( -step ); - } - - // Since JavaScript has problems with large floats, round - // the final value to 5 digits after the decimal point (see #4124) - return parseFloat( alignValue.toFixed(5) ); - }, - - _calculateNewMax: function() { - var max = this.options.max, - min = this._valueMin(), - step = this.options.step, - aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step; - max = aboveMin + min; - this.max = parseFloat( max.toFixed( this._precision() ) ); - }, - - _precision: function() { - var precision = this._precisionOf( this.options.step ); - if ( this.options.min !== null ) { - precision = Math.max( precision, this._precisionOf( this.options.min ) ); - } - return precision; - }, - - _precisionOf: function( num ) { - var str = num.toString(), - decimal = str.indexOf( "." ); - return decimal === -1 ? 0 : str.length - decimal - 1; - }, - - _valueMin: function() { - return this.options.min; - }, - - _valueMax: function() { - return this.max; - }, - - _refreshValue: function() { - var lastValPercent, valPercent, value, valueMin, valueMax, - oRange = this.options.range, - o = this.options, - that = this, - animate = ( !this._animateOff ) ? o.animate : false, - _set = {}; - - if ( this.options.values && this.options.values.length ) { - this.handles.each(function( i ) { - valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; - _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - if ( that.options.range === true ) { - if ( that.orientation === "horizontal" ) { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } else { - if ( i === 0 ) { - that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); - } - if ( i === 1 ) { - that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } - } - lastValPercent = valPercent; - }); - } else { - value = this.value(); - valueMin = this._valueMin(); - valueMax = this._valueMax(); - valPercent = ( valueMax !== valueMin ) ? - ( value - valueMin ) / ( valueMax - valueMin ) * 100 : - 0; - _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; - this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); - - if ( oRange === "min" && this.orientation === "horizontal" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); - } - if ( oRange === "max" && this.orientation === "horizontal" ) { - this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - if ( oRange === "min" && this.orientation === "vertical" ) { - this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); - } - if ( oRange === "max" && this.orientation === "vertical" ) { - this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); - } - } - }, - - _handleEvents: { - keydown: function( event ) { - var allowed, curVal, newVal, step, - index = $( event.target ).data( "ui-slider-handle-index" ); - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - case $.ui.keyCode.END: - case $.ui.keyCode.PAGE_UP: - case $.ui.keyCode.PAGE_DOWN: - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - event.preventDefault(); - if ( !this._keySliding ) { - this._keySliding = true; - $( event.target ).addClass( "ui-state-active" ); - allowed = this._start( event, index ); - if ( allowed === false ) { - return; - } - } - break; - } - - step = this.options.step; - if ( this.options.values && this.options.values.length ) { - curVal = newVal = this.values( index ); - } else { - curVal = newVal = this.value(); - } - - switch ( event.keyCode ) { - case $.ui.keyCode.HOME: - newVal = this._valueMin(); - break; - case $.ui.keyCode.END: - newVal = this._valueMax(); - break; - case $.ui.keyCode.PAGE_UP: - newVal = this._trimAlignValue( - curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages ) - ); - break; - case $.ui.keyCode.PAGE_DOWN: - newVal = this._trimAlignValue( - curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) ); - break; - case $.ui.keyCode.UP: - case $.ui.keyCode.RIGHT: - if ( curVal === this._valueMax() ) { - return; - } - newVal = this._trimAlignValue( curVal + step ); - break; - case $.ui.keyCode.DOWN: - case $.ui.keyCode.LEFT: - if ( curVal === this._valueMin() ) { - return; - } - newVal = this._trimAlignValue( curVal - step ); - break; - } - - this._slide( event, index, newVal ); - }, - keyup: function( event ) { - var index = $( event.target ).data( "ui-slider-handle-index" ); - - if ( this._keySliding ) { - this._keySliding = false; - this._stop( event, index ); - this._change( event, index ); - $( event.target ).removeClass( "ui-state-active" ); - } - } - } -}); - - - -}));
\ No newline at end of file diff --git a/radicale_web/web/infcloud/lib/jquery.autosize.js b/radicale_web/web/infcloud/lib/jquery.autosize.js deleted file mode 100644 index b0a3f00..0000000 --- a/radicale_web/web/infcloud/lib/jquery.autosize.js +++ /dev/null @@ -1,258 +0,0 @@ -/*! - Autosize v1.18.0 - 2013-10-20 - Automatically adjust textarea height based on user input. - (c) 2013 Jack Moore - http://www.jacklmoore.com/autosize - license: http://www.opensource.org/licenses/mit-license.php -*/ -(function (factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else { - // Browser globals: jQuery or jQuery-like library, such as Zepto - factory(window.jQuery || window.$); - } -}(function ($) { - var - defaults = { - className: 'autosizejs', - append: '', - callback: false, - resizeDelay: 10 - }, - - // border:0 is unnecessary, but avoids a bug in FireFox on OSX - copy = '<textarea tabindex="-1" style="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; padding: 0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; overflow:hidden; transition:none; -webkit-transition:none; -moz-transition:none;"/>', - - // line-height is conditionally included because IE7/IE8/old Opera do not return the correct value. - typographyStyles = [ - 'fontFamily', - 'fontSize', - 'fontWeight', - 'fontStyle', - 'letterSpacing', - 'textTransform', - 'wordSpacing', - 'textIndent' - ], - - // to keep track which textarea is being mirrored when adjust() is called. - mirrored, - - // the mirror element, which is used to calculate what size the mirrored element should be. - mirror = $(copy).data('autosize', true)[0]; - - // test that line-height can be accurately copied. - mirror.style.lineHeight = '99px'; - if ($(mirror).css('lineHeight') === '99px') { - typographyStyles.push('lineHeight'); - } - mirror.style.lineHeight = ''; - - $.fn.autosize = function (options) { - if (!this.length) { - return this; - } - - options = $.extend({}, defaults, options || {}); - - if (mirror.parentNode !== document.body) { - $(document.body).append(mirror); - } - - return this.each(function () { - var - ta = this, - $ta = $(ta), - maxHeight, - minHeight, - boxOffset = 0, - callback = $.isFunction(options.callback), - originalStyles = { - height: options.defaultStyles!=undefined && options.defaultStyles['height']!=undefined ? options.defaultStyles['height'] : ta.style.height, - overflow: options.defaultStyles!=undefined && options.defaultStyles['overflow']!=undefined ? options.defaultStyles['overflow'] : ta.style.overflow, - overflowY: options.defaultStyles!=undefined && options.defaultStyles['overflow-y']!=undefined ? options.defaultStyles['overflow-y'] : ta.style.overflowY, - wordWrap: options.defaultStyles!=undefined && options.defaultStyles['word-wrap']!=undefined ? options.defaultStyles['word-wrap'] : ta.style.wordWrap, - resize: options.defaultStyles!=undefined && options.defaultStyles['resize']!=undefined ? options.defaultStyles['resize'] : ta.style.resize - }, - timeout, - width = $ta.width(); - - if ($ta.data('autosize')) { - // exit if autosize has already been applied, or if the textarea is the mirror element. - return; - } - $ta.data('autosize', true); - - if ($ta.css('box-sizing') === 'border-box' || $ta.css('-moz-box-sizing') === 'border-box' || $ta.css('-webkit-box-sizing') === 'border-box'){ - boxOffset = $ta.outerHeight() - $ta.height(); - } - - // IE8 and lower return 'auto', which parses to NaN, if no min-height is set. - minHeight = Math.max(parseInt($ta.css('minHeight'), 10) - boxOffset || 0, originalStyles.height); - - $ta.css({ - overflow: 'hidden', - overflowY: 'hidden', - wordWrap: 'break-word', // horizontal overflow is hidden, so break-word is necessary for handling words longer than the textarea width - resize: (originalStyles.resize === 'none' || originalStyles.resize === 'vertical') ? 'none' : 'horizontal' - }); - - // The mirror width must exactly match the textarea width, so using getBoundingClientRect because it doesn't round the sub-pixel value. - function setWidth() { - var style, width; - - if ('getComputedStyle' in window) { - style = window.getComputedStyle(ta, null); - width = ta.getBoundingClientRect().width; - - $.each(['paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'], function(i,val){ - width -= parseInt(style[val],10); - }); - - mirror.style.width = width + 'px'; - } - else { - // window.getComputedStyle, getBoundingClientRect returning a width are unsupported and unneeded in IE8 and lower. - mirror.style.width = Math.max($ta.width(), 0) + 'px'; - } - } - - function initMirror() { - var styles = {}; - - mirrored = ta; - mirror.className = options.className; - maxHeight = parseInt($ta.css('maxHeight'), 10); - - // mirror is a duplicate textarea located off-screen that - // is automatically updated to contain the same text as the - // original textarea. mirror always has a height of 0. - // This gives a cross-browser supported way getting the actual - // height of the text, through the scrollTop property. - $.each(typographyStyles, function(i,val){ - styles[val] = $ta.css(val); - }); - $(mirror).css(styles); - - setWidth(); - - // Chrome-specific fix: - // When the textarea y-overflow is hidden, Chrome doesn't reflow the text to account for the space - // made available by removing the scrollbar. This workaround triggers the reflow for Chrome. - if (window.chrome) { - var width = ta.style.width; - ta.style.width = '0px'; - var ignore = ta.offsetWidth; - ta.style.width = width; - } - } - - // Using mainly bare JS in this function because it is going - // to fire very often while typing, and needs to very efficient. - function adjust() { - var height, original; - - if (mirrored !== ta) { - initMirror(); - } else { - setWidth(); - } - - mirror.value = ta.value + options.append; - mirror.style.overflowY = ta.style.overflowY; - original = parseInt(ta.style.height,10); - - // Setting scrollTop to zero is needed in IE8 and lower for the next step to be accurately applied - mirror.scrollTop = 0; - - mirror.scrollTop = 9e4; - - // Using scrollTop rather than scrollHeight because scrollHeight is non-standard and includes padding. - height = mirror.scrollTop; - - if (maxHeight && height > maxHeight) { - ta.style.overflowY = 'scroll'; - height = maxHeight; - } else { - ta.style.overflowY = 'hidden'; - if (height < minHeight) { - height = minHeight; - } - } - - height += boxOffset; - - if (original !== height) { - ta.style.height = height + 'px'; - if (callback) { - options.callback.call(ta,ta); - } - } - } - - function resize () { - clearTimeout(timeout); - timeout = setTimeout(function(){ - var newWidth = $ta.width(); - - if (newWidth !== width) { - width = newWidth; - adjust(); - } - }, parseInt(options.resizeDelay,10)); - } - - if ('onpropertychange' in ta) { - if ('oninput' in ta) { - // Detects IE9. IE9 does not fire onpropertychange or oninput for deletions, - // so binding to onkeyup to catch most of those occasions. There is no way that I - // know of to detect something like 'cut' in IE9. - $ta.on('input.autosize keyup.autosize', adjust); - } else { - // IE7 / IE8 - $ta.on('propertychange.autosize', function(){ - if(event.propertyName === 'value'){ - adjust(); - } - }); - } - } else { - // Modern Browsers - $ta.on('input.autosize', adjust); - } - - // Set options.resizeDelay to false if using fixed-width textarea elements. - // Uses a timeout and width check to reduce the amount of times adjust needs to be called after window resize. - - if (options.resizeDelay !== false) { - $(window).on('resize.autosize', resize); - } - - // Event for manual triggering if needed. - // Should only be needed when the value of the textarea is changed through JavaScript rather than user input. - $ta.on('autosize.resize', adjust); - - // Event for manual triggering that also forces the styles to update as well. - // Should only be needed if one of typography styles of the textarea change, and the textarea is already the target of the adjust method. - $ta.on('autosize.resizeIncludeStyle', function() { - mirrored = null; - adjust(); - }); - - $ta.on('autosize.destroy', function(){ - mirrored = null; - clearTimeout(timeout); - $(window).off('resize', resize); - $ta - .off('autosize') - .off('.autosize') - .css(originalStyles) - .removeData('autosize'); - }); - - // Call adjust in case the textarea already contains text. - adjust(); - }); - }; -})); diff --git a/radicale_web/web/infcloud/lib/jquery.browser.js b/radicale_web/web/infcloud/lib/jquery.browser.js deleted file mode 100644 index c2eba36..0000000 --- a/radicale_web/web/infcloud/lib/jquery.browser.js +++ /dev/null @@ -1,43 +0,0 @@ -// jQuery.browser from 1.8.x -// Limit scope pollution from any deprecated API -(function() { - -var matched, browser; - -// Use of jQuery.browser is frowned upon. -// More details: http://api.jquery.com/jQuery.browser -// jQuery.uaMatch maintained for back-compat -jQuery.uaMatch = function( ua ) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || - /(webkit)[ \/]([\w.]+)/.exec( ua ) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || - /(msie) ([\w.]+)/.exec( ua ) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; -}; - -matched = jQuery.uaMatch( navigator.userAgent ); -browser = {}; - -if ( matched.browser ) { - browser[ matched.browser ] = true; - browser.version = matched.version; -} - -// Chrome is Webkit, but Webkit is also Safari. -if ( browser.chrome ) { - browser.webkit = true; -} else if ( browser.webkit ) { - browser.safari = true; -} - -jQuery.browser = browser; - -})(); diff --git a/radicale_web/web/infcloud/lib/jquery.placeholder-1.1.9.js b/radicale_web/web/infcloud/lib/jquery.placeholder-1.1.9.js deleted file mode 100644 index f1ecba8..0000000 --- a/radicale_web/web/infcloud/lib/jquery.placeholder-1.1.9.js +++ /dev/null @@ -1,195 +0,0 @@ -/***************************************************************************** -jQuery Placeholder 1.1.9 (with minor modifications for CardDavMATE & CalDavZAP) - -Copyright (c) 2010 Michael J. Ryan (http://tracker1.info/) - -Dual licensed under the MIT and GPL licenses: - http://www.opensource.org/licenses/mit-license.php - http://www.gnu.org/licenses/gpl.html - ------------------------------------------------------------------------------- - -Sets up a watermark for inputted fields... this will create a LABEL.watermark -tag immediately following the input tag, the positioning will be set absolute, -and it will be positioned to match the input tag. - -To activate: - - $('input[placeholder],textarea[placeholder]').placeholder(); - - -NOTE, when changing a value via script: - - $('#input_id').val('new value').change(); //force change event, so placeholder sets properly - - -To style the tags as appropriate (you'll want to make sure the font matches): - - label.placeholder { - cursor: text; <--- display a cursor to match the text input - - padding: 4px 4px 4px 4px; <--- this should match the border+padding - for the input field(s) - color: #999999; <--- this will display as faded - } - -You'll also want to have the color set for browsers with native support - input:placeholder, textarea:placeholder { - color: #999999; - } - input::-webkit-input-placeholder, textarea::-webkit-input-placeholder { - color: #999999; - } - ------------------------------------------------------------------------------- - -Thanks to... - http://www.alistapart.com/articles/makingcompactformsmoreaccessible - http://plugins.jquery.com/project/overlabel - - This works similar to the overlabel, but creates the actual label tag - based on the placeholder attribute on the input tag, instead of - relying on the markup to provide it. - -*****************************************************************************/ -(function($){ - - var ph = "PLACEHOLDER-INPUT"; - var phl = "PLACEHOLDER-LABEL"; - var boundEvents = false; - var default_options = { - labelClass: 'placeholder' - }; - - //check for native support for placeholder attribute, if so stub methods and return - var input = document.createElement("input"); - if ('placeholder' in input) { - $.fn.placeholder = $.fn.unplaceholder = function(){}; //empty function - delete input; //cleanup IE memory - return; - }; - delete input; - - //bind to resize to fix placeholders when the page resizes (fields are hidden/displayed, which can change positioning). - $(window).resize(checkResize); - - - $.fn.placeholder = function(options) { - bindEvents(); - - var opts = $.extend(default_options, options) - - this.each(function(){ - var rnd=Math.random().toString(32).replace(/\./,'') - ,input=$(this) - ,label=$('<label style="position:absolute;display:none;top:0;left:0;"></label>'); - - if (!input.attr('placeholder') || input.data(ph) === ph) return; //already watermarked - - //make sure the input tag has an ID assigned, if not, assign one. - if (!input.attr('id')) input.attr('id', 'input_' + rnd); - - label .attr('id',input.attr('id') + "_placeholder") - .data(ph, '#' + input.attr('id')) //reference to the input tag - .attr('for',input.attr('id')) - .addClass(opts.labelClass) - .addClass(opts.labelClass + '-for-' + this.tagName.toLowerCase()) //ex: watermark-for-textarea - .addClass(phl) - .text(input.attr('placeholder')); - - input - .data(phl, '#' + label.attr('id')) //set a reference to the label - .data(ph,ph) //set that the field is watermarked - .addClass(ph) //add the watermark class - .after(label) //add the label field to the page - - //setup overlay - itemFocus.call(this); - itemBlur.call(this); - }); - }; - - $.fn.unplaceholder = function(){ - this.each(function(){ - var input=$(this), - label=$(input.data(phl)); - - if (input.data(ph) !== ph) return; - - label.remove(); - input.removeData(ph).removeData(phl).removeClass(ph).unbind('change',itemChange); - }); - }; - - function bindEvents() { - if (boundEvents) return; - - //prepare live bindings if not already done. - $(document).on('reset', 'form', function(){$(this).find('.'+ph).each(itemBlur);}); - $(document).on('keydown mousedown mouseclick focus focusin', '.'+ph, itemFocus); - $(document).on('blur focusout', '.'+ph, itemBlur); - $(document).on('change', '.'+ph, itemChange); - $(document).on('click mouseup', '.'+phl, function(){$($(this).data(ph)).focus();}); - - bound = true; - boundEvents = true; - }; - - function itemChange() { - var input = $(this); - if (!!input.val()) { - $(input.data(phl)).hide(); - return; - } - if (input.data(ph+'FOCUSED') != 1) { - showPHL(input); - } - } - - function itemFocus() { - $($(this).data(ph+'FOCUSED',1).data(phl)).hide(); - }; - - function itemBlur() { - var that = this; - showPHL($(this).removeData(ph+'FOCUSED')); - - //use timeout to let other validators/formatters directly bound to blur/focusout work - setTimeout(function(){ - var input = $(that); - - //if the item wasn't refocused, test the item - if (input.data(ph+'FOCUSED') != 1) { - showPHL(input); - } - }, 200); - }; - - function showPHL(input, forced) { - var label = $(input.data(phl)); - - //if not already shown, and needs to be, show it. - if ((forced || label.css('display') == 'none') && !input.val()) - label - .text(input.attr('placeholder')) - .css('top', input.position().top + 'px') - .css('left', input.position().left + 'px') - .css('display', 'block'); - - //console.dir({ 'input': { 'id':input.attr('id'), 'pos': input.position() }}); - } - - var cr; - function checkResize() { - if (cr) window.clearTimeout(cr); - cr = window.setTimeout(checkResize2, 50); - } - function checkResize2() { - $('.' + ph).each(function(){ - var input = $(this); - var focused = $(this).data(ph+'FOCUSED'); - if (!focused) showPHL(input, true); - }); - } - -}(jQuery));
\ No newline at end of file diff --git a/radicale_web/web/infcloud/lib/jquery.quicksearch.js b/radicale_web/web/infcloud/lib/jquery.quicksearch.js deleted file mode 100644 index fe2f0a5..0000000 --- a/radicale_web/web/infcloud/lib/jquery.quicksearch.js +++ /dev/null @@ -1,205 +0,0 @@ -(function($, window, document, undefined) { - $.fn.quicksearch = function (target, opt) { - - var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({ - delay: 100, - selector: null, - stripeRows: null, - loader: null, - noResults: '', - matchedResultsCount: 0, - bind: 'keyup', - onBefore: function () { - return; - }, - onAfter: function () { - return; - }, - show: function () { - this.style.display = ""; - }, - hide: function () { - this.style.display = "none"; - }, - prepareQuery: function (val) { - return val.toLowerCase().split(' '); - }, - testQuery: function (query, txt, _row) { - for (var i = 0; i < query.length; i += 1) { - if (txt.indexOf(query[i]) === -1) { - return false; - } - } - return true; - } - }, opt); - - this.go = function () { - - var i = 0, - numMatchedRows = 0, - noresults = true, - query = options.prepareQuery(val), - val_empty = (val.replace(' ', '').length === 0); - - for (var i = 0, len = rowcache.length; i < len; i++) { - if (val_empty || options.testQuery(query, cache[i], rowcache[i])) { - options.show.apply(rowcache[i]); - noresults = false; - numMatchedRows++; - } else { - options.hide.apply(rowcache[i]); - } - } - - if (noresults) { - this.results(false); - } else { - this.results(true); - this.stripe(); - } - - this.matchedResultsCount = numMatchedRows; - this.loader(false); - options.onAfter(); - - return this; - }; - - /* - * External API so that users can perform search programatically. - * */ - this.search = function (submittedVal) { - val = submittedVal; - e.trigger(); - }; - - /* - * External API to get the number of matched results as seen in - * https://github.com/ruiz107/quicksearch/commit/f78dc440b42d95ce9caed1d087174dd4359982d6 - * */ - this.currentMatchedResults = function() { - return this.matchedResultsCount; - }; - - this.stripe = function () { - - if (typeof options.stripeRows === "object" && options.stripeRows !== null) - { - var joined = options.stripeRows.join(' '); - var stripeRows_length = options.stripeRows.length; - - jq_results.not(':hidden').each(function (i) { - $(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]); - }); - } - - return this; - }; - - this.strip = function (input) { - return $.trim(input.toLowerCase()); - }; - - this.strip_html = function (input) { - var output = input.replace(new RegExp('<[^<]+\>', 'g'), ""); - output = $.trim(output.toLowerCase()); - return output; - }; - - this.results = function (bool) { - if (typeof options.noResults === "string" && options.noResults !== "") { - if (bool) { - $(options.noResults).hide(); - } else { - $(options.noResults).show(); - } - } - return this; - }; - - this.loader = function (bool) { - if (typeof options.loader === "string" && options.loader !== "") { - (bool) ? $(options.loader).show() : $(options.loader).hide(); - } - return this; - }; - - this.cache = function () { - var type = $.type(target); - - // Target is a string - selector for HTML elements - if(type==='string') - jq_results = $(target); - // Target is an array of objects - else if(type==='array') { - jq_results=target.slice(); - } - // Target is an object containing ... - else if(type==='object') { - jq_results = []; - $.each(target, function(key, val){ - // ... arrays of objects - if(val instanceof Array) - $.merge(jq_results,val); - // ... other objects - else - jq_results.push(val); - }); - } - - // if (typeof options.noResults==="string" && options.noResults!=="") { - // jq_results = jq_results.not(options.noResults); - // } - - // var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults); - - cache = $.map(jq_results, function (item) { - return (type==='string') ? e.strip_html(item.innerHTML) : (typeof item.searchvalue==='string') ? e.strip(item.searchvalue) : ''; - }); - - rowcache = $.map(jq_results, function (item) { - return item; - }); - - /* - * Modified fix for sync-ing "val". - * Original fix https://github.com/michaellwest/quicksearch/commit/4ace4008d079298a01f97f885ba8fa956a9703d1 - * */ - val = val || this.val() || ""; - - return this.go(); - }; - - this.trigger = function () { - this.loader(true); - options.onBefore(); - - window.clearTimeout(timeout); - timeout = window.setTimeout(function () { - e.go(); - }, options.delay); - - return this; - }; - - this.cache(); - this.results(true); - this.stripe(); - this.loader(false); - - return this.each(function () { - - /* - * Changed from .bind to .on. - * */ - $(this).on(options.bind, function () { - - val = $(this).val(); - e.trigger(); - }); - }); - - }; - -}(jQuery, this, document)); diff --git a/radicale_web/web/infcloud/lib/jquery.tagsinput.js b/radicale_web/web/infcloud/lib/jquery.tagsinput.js deleted file mode 100644 index 1493079..0000000 --- a/radicale_web/web/infcloud/lib/jquery.tagsinput.js +++ /dev/null @@ -1,436 +0,0 @@ -/* - - jQuery Tags Input Plugin 1.3.3 (with minor modifications for CardDavMATE) - - Copyright (c) 2011 XOXCO, Inc - - Documentation for this plugin lives here: - http://xoxco.com/clickable/jquery-tags-input - - Licensed under the MIT license: - http://www.opensource.org/licenses/mit-license.php - - ben@xoxco.com - -*/ - -(function($){ - var tags_settings=new Array(); - var tags_callbacks=new Array(); - - String.prototype.escapeCustom=function(inputDelimiter) - { - var value=(this==undefined ? '' : this), - output=''; - - for(var i=0; i<value.length; i++) - { - if(value[i]==inputDelimiter || value[i]=='\\') - output+='\\'; - - output+=value[i]; - } - return output; - } - - // split and unescape values - String.prototype.splitCustom=function(inputDelimiter) - { - var outputArray=new Array(), - value=this, - j=0; - - for(var i=0; i<value.length; i++) - { - if(value[i]==inputDelimiter) - { - if(outputArray[j]==undefined) - outputArray[j]=''; - ++j; - continue; - } - else if(value[i]=='\\') - ++i; - - outputArray[j]=(outputArray[j]==undefined ? '' : outputArray[j])+value[i]; - } - return outputArray; - } - - $.fn.doAutosize=function(o) - { - var minWidth=$(this).data('minwidth'), - maxWidth=$(this).data('maxwidth'), - val='', - input=$(this), - testSubject=$('#'+$(this).data('tester_id')); - - if(val===(val=input.val())) - return; - - // Enter new content into testSubject - var escaped=val.replace(/\s/g,' '); // get proper width for values with leading spaces (or only spaces) - testSubject.html(escaped); - - // Calculate new width + whether to change - var testerWidth=testSubject.width(), - newWidth=(testerWidth+o.comfortZone)>=minWidth ? testerWidth+o.comfortZone : minWidth, - currentWidth=input.width(), - isValidWidthChange=(newWidth<currentWidth && newWidth>=minWidth) || (newWidth>minWidth && newWidth<maxWidth); - - // Animate width - if(isValidWidthChange) - input.width(newWidth); - }; - - $.fn.resetAutosize=function(options) - { - // alert(JSON.stringify(options)); - var minWidth=$(this).data('minwidth') || options.minInputWidth || $(this).width(), - maxWidth=$(this).data('maxwidth') || options.maxInputWidth || ($(this).closest('.tagsinput').width()-options.inputPadding), - val='', - input=$(this), - testSubject=$('<tester/>').css({ - position: 'absolute', - top: -9999, - left: -9999, - width: 'auto', - fontSize: input.css('fontSize'), - fontFamily: input.css('fontFamily'), - fontWeight: input.css('fontWeight'), - letterSpacing: input.css('letterSpacing'), - whiteSpace: 'nowrap' - }), - testerId=$(this).attr('id')+'_autosize_tester'; - - if(!$('#'+testerId).length>0) - { - testSubject.attr('id', testerId); - testSubject.appendTo('body'); - } - - input.data('minwidth', minWidth); - input.data('maxwidth', maxWidth); - input.data('tester_id', testerId); - input.css('width', minWidth); - }; - - $.fn.addTag=function(value, options) - { - options=jQuery.extend({focus: false, callback: true, imported: false}, options); - - this.each(function() - { - var id=$(this).attr('id'); - - if(tags_settings[id].allowDelimiterInValue==true) - var tagslist=$(this).val().splitCustom(tags_settings[id].delimiter); - else - var tagslist=$(this).val().split(delimiter[id]); - - if(tagslist[0]=='') - tagslist=new Array(); - - if(options.trimInput==true) - value=jQuery.trim(value); - - var skipTag=false; - var duplicate=$(tagslist).tagExist(value); - if(tags_callbacks[id] && tags_callbacks[id]['validateTag']) - skipTag=!tags_callbacks[id]['validateTag'].call(this, value, options.imported, duplicate); - if(!skipTag && options.unique) - skipTag=duplicate; - - if(skipTag) - $(this).parent().find('#'+id+'_tag').addClass('not_valid'); //Marks fake input as not_valid to let styling it - - if(value!='' && skipTag!=true) - { - $('<span>').addClass('tag').append( - $('<span>').text(value), - $('<a>', { - href: '#', - title: 'Removing tag', - text: 'x' - }).click(function(){return $('#'+id).removeTag(value)}) - ).insertBefore($(this).parent().find('#'+id+'_addTag')); - - tagslist.push(value); - - var tmpRef=$(this).parent().find('#'+id+'_tag'); - tmpRef.val(''); - if(options.focus) - tmpRef.focus(); - else - tmpRef.blur(); - - $.fn.tagsInput.updateTagsField(this, tagslist); - - if(options.callback && tags_callbacks[id] && tags_callbacks[id]['onAddTag']) - { - var f=tags_callbacks[id]['onAddTag']; - f.call(this, value); - } - if(tags_callbacks[id] && tags_callbacks[id]['onChange']) - { - var i=tagslist.length; - var f=tags_callbacks[id]['onChange']; - f.call(this, tagslist[i-1], options.imported); - } - } - }); - return false; - }; - - $.fn.removeTag = function(value) - { - this.each(function() - { - var id=$(this).attr('id'); - - if(tags_settings[id].allowDelimiterInValue==true) - var old=$(this).val().splitCustom(tags_settings[id].delimiter); - else - var old=$(this).val().split(delimiter[id]); - - $(this).parent().find('#'+id+'_tagsinput .tag').remove(); - - var str=''; - for(i=0; i<old.length; i++) - if(old[i]!=value) - str=(str=='' ? '' : str+tags_settings[id].delimiter)+(tags_settings[id].allowDelimiterInValue==true ? old[i].escapeCustom(tags_settings[id].delimiter) : old[i]); - - $.fn.tagsInput.importTags(this, str); - if(tags_callbacks[id] && tags_callbacks[id]['onRemoveTag']) - { - var f=tags_callbacks[id]['onRemoveTag']; - f.call(this, value); - } - }); - return false; - }; - - $.fn.tagExist=function(val) - { - return (jQuery.inArray(val, $(this))>=0); //true when tag exists, false when not - }; - - // clear all existing tags and import new ones from a string - $.fn.importTags=function(str) - { - $(this).parent().find('#'+$(this).attr('id')+'_tagsinput .tag').remove(); - $.fn.tagsInput.importTags(this, str); - } - - $.fn.tagsInput=function(options) - { - var settings=jQuery.extend({ - interactive: true, - defaultText: 'add a tag', - useNativePlaceholder:false, - minChars: 0, - width: '300px', - height: '100px', - autocomplete: {selectFirst: false}, - hide: true, - delimiter: ',', - allowDelimiterInValue: false, - trimInput: true, - unique: true, - removeWithBackspace: true, - color: '#000000', - placeholderColor: '#666666', - autosize: true, - comfortZone: 20, - inputPadding: 6*2 - }, options); - - this.each(function() - { - if(settings.hide) - $(this).hide(); - - var id=$(this).attr('id'); - var data=jQuery.extend({ - real_inputObj: $(this), - pid: id, - real_input: '#'+id, - holder: '#'+id+'_tagsinput', - input_wrapper: '#'+id+'_addTag', - fake_input: '#'+id+'_tag' - }, settings); - - tags_settings[id]={delimiter: data.delimiter, allowDelimiterInValue: data.allowDelimiterInValue}; - - if(settings.onAddTag || settings.onRemoveTag || settings.onChange || settings.validateTag) - { - tags_callbacks[id] = new Array(); - tags_callbacks[id]['onAddTag'] = settings.onAddTag; - tags_callbacks[id]['onRemoveTag'] = settings.onRemoveTag; - tags_callbacks[id]['onChange'] = settings.onChange; - tags_callbacks[id]['validateTag'] = settings.validateTag; - } - - var markup='<div id="'+id+'_tagsinput" class="tagsinput"><div id="'+id+'_addTag">'; - if(settings.interactive) - markup=markup+'<div class="input_container"><input id="'+id+'_tag" type="text" value=""'+(settings.useNativePlaceholder==true ? ' placeholder="'+settings.defaultText+'" data-default=""' : ' data-default="'+settings.defaultText+'"')+' /></div>'; - markup=markup+'</div><div class="tags_clear"></div></div>'; - - var tmpMarkupObj=$(markup).insertAfter(this); - - if(settings.width!=null) - tmpMarkupObj.css('width', settings.width); - if(settings.height!=null) - tmpMarkupObj.css('height', settings.height); - - if($(this).val()!='') - $.fn.tagsInput.importTags($(this), $(this).val()); - - if(settings.interactive) - { - tmpMarkupObj.val(tmpMarkupObj.attr('data-default')); - tmpMarkupObj.css('color', settings.placeholderColor); - tmpMarkupObj.resetAutosize(settings); - - tmpMarkupObj.bind('click', data, function(event) - { - $(this).find(event.data.fake_input).focus(); - }); - - tmpMarkupObj.find(data.fake_input).bind('focus', data, function(event) - { - if($(this).val() == $(this).attr('data-default')) - $(this).val(''); - - $(this).css('color', settings.color); - }); - - if(settings.autocomplete_url!=undefined) - { - var autocomplete_options={source: settings.autocomplete_url}; - for(var attrname in settings.autocomplete) - autocomplete_options[attrname]=settings.autocomplete[attrname]; - - if(jQuery.Autocompleter!==undefined) - { - tmpMarkupObj.find(data.fake_input).autocomplete(settings.autocomplete_url, settings.autocomplete); - tmpMarkupObj.find(data.fake_input).bind('result', data, function(event, data, formatted) - { - if(data) - event.data.real_inputObj.addTag(data[0] + "", {focus: true, unique: settings.unique, trimInput: settings.trimInput}); - }); - } - else if(jQuery.ui.autocomplete!==undefined) - { - tmpMarkupObj.find(data.fake_input).autocomplete(autocomplete_options); - tmpMarkupObj.find(data.fake_input).bind('autocompleteselect', data, function(event,ui) - { - event.data.real_inputObj.addTag(ui.item.value, {focus: true, unique: settings.unique, trimInput: settings.trimInput}); - return false; - }); - } - - // if a user tabs out of the field, create a new tag - // this is only available if autocomplete is not used. - tmpMarkupObj.find(data.fake_input).bind('blur', data, function(event) - { - var d=$(this).attr('data-default'); - - if($(this).val()!='' && $(this).val()!=d) - { - if((event.data.minChars<=$(this).val().length) && (!event.data.maxChars || (event.data.maxChars>=$(this).val().length))) - event.data.real_inputObj.addTag($(this).val(), {focus: true, unique: settings.unique, trimInput: settings.trimInput}); - } - else - $(this).val($(this).attr('data-default')); - - $(this).css('color', settings.placeholderColor); - return false; - }); - } - - // if user types a comma, create a new tag - tmpMarkupObj.find(data.fake_input).bind('keypress', data, function(event) - { - if(settings.allowDelimiterInValue==false && event.which==event.data.delimiter.charCodeAt(0) || event.which==13) - { - event.preventDefault(); - if((event.data.minChars<=$(this).val().length) && (!event.data.maxChars || (event.data.maxChars>=$(this).val().length))) - event.data.real_inputObj.addTag($(event.data.fake_input).val(), {focus: true, unique: settings.unique, trimInput: settings.trimInput}); - $(this).resetAutosize(settings); - return false; - } - else if(event.data.autosize) - $(this).doAutosize(settings); - }); - - //Delete last tag on backspace - data.removeWithBackspace && tmpMarkupObj.find(data.fake_input).bind('keydown', data, function(event) - { - if($(this).closest('.tagsinput').hasClass('readonly')==false && event.keyCode==8 && $(this).val()=='') - { - event.preventDefault(); - var last_tag=$(this).closest('.tagsinput').find('.tag:last').text(); - var id=$(this).attr('id').replace(/_tag$/, ''); - last_tag=last_tag.replace(/x$/, ''); - event.data.real_inputObj.removeTag(last_tag); - $(this).trigger('focus'); - } - }); - - tmpMarkupObj.find(data.fake_input).blur(); - - //Removes the not_valid class when user changes the value of the fake input - if(data.unique) - { - tmpMarkupObj.find(data.fake_input).keydown(function(event) - { - if(event.keyCode==8 || String.fromCharCode(event.which).match(/\w+|[áéíóúÁÉÍÓÚñÑ,/]+/)) - $(this).removeClass('not_valid'); - }); - } - } // if settings.interactive - - // store settings - $(this).data('tagsOptions', settings); - - return false; - }); - return this; - }; - - $.fn.tagsInput.updateTagsField=function(obj, tagslist) - { - var id = $(obj).attr('id'); - - if(tags_settings[id].allowDelimiterInValue==true) - for(var i=0;i<tagslist.length;i++) - tagslist[i]=tagslist[i].escapeCustom(tags_settings[id].delimiter); - - $(obj).val(tagslist.join(tags_settings[id].delimiter)); - }; - - $.fn.tagsInput.importTags=function(obj, val) - { - var settings=jQuery.extend({ - trimInput: true, - unique: true - }, $(obj).data('tagsOptions')); - - $(obj).val(''); - var id=$(obj).attr('id'); - - if(tags_settings[id].allowDelimiterInValue==true) - var tags=val.splitCustom(tags_settings[id].delimiter); - else - var tags=val.split(delimiter[id]); - - for(var i=0; i<tags.length; i++) - $(obj).addTag(tags[i], {focus: true, unique: settings.unique, trimInput: settings.trimInput, callback: false, imported: true}); - if(tags_callbacks[id] && tags_callbacks[id]['onChange']) - { - var f=tags_callbacks[id]['onChange']; - f.call(obj, tags[i], true); - } - }; -})(jQuery); diff --git a/radicale_web/web/infcloud/lib/rrule.js b/radicale_web/web/infcloud/lib/rrule.js deleted file mode 100644 index ed2689e..0000000 --- a/radicale_web/web/infcloud/lib/rrule.js +++ /dev/null @@ -1,1910 +0,0 @@ -/*! - * rrule.js - Library for working with recurrence rules for calendar dates. - * https://github.com/jakubroztocil/rrule - * - * Copyright 2010, Jakub Roztocil and Lars Schoning - * Licenced under the BSD licence. - * https://github.com/jakubroztocil/rrule/blob/master/LICENCE - * - * Based on: - * python-dateutil - Extensions to the standard Python datetime module. - * Copyright (c) 2003-2011 - Gustavo Niemeyer <gustavo@niemeyer.net> - * Copyright (c) 2012 - Tomi Pieviläinen <tomi.pievilainen@iki.fi> - * https://github.com/jakubroztocil/rrule/blob/master/LICENCE - * - */ -(function(root){ - -var serverSide = typeof module !== 'undefined' && module.exports; - - -var getnlp = function() { - if (!getnlp._nlp) { - if (serverSide) { - // Lazy, runtime import to avoid circular refs. - getnlp._nlp = require('./nlp') - } else if (!(getnlp._nlp = root._RRuleNLP)) { - throw new Error( - 'You need to include rrule/nlp.js for fromText/toText to work.' - ) - } - } - return getnlp._nlp; -}; - - -//============================================================================= -// Date utilities -//============================================================================= - -/** - * General date-related utilities. - * Also handles several incompatibilities between JavaScript and Python - * - */ -var dateutil = { - - MONTH_DAYS: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], - - /** - * Number of milliseconds of one day - */ - ONE_DAY: 1000 * 60 * 60 * 24, - - /** - * @see: <http://docs.python.org/library/datetime.html#datetime.MAXYEAR> - */ - MAXYEAR: 9999, - - /** - * Python uses 1-Jan-1 as the base for calculating ordinals but we don't - * want to confuse the JS engine with milliseconds > Number.MAX_NUMBER, - * therefore we use 1-Jan-1970 instead - */ - ORDINAL_BASE: new Date(1970, 0, 1), - - /** - * Python: MO-SU: 0 - 6 - * JS: SU-SAT 0 - 6 - */ - PY_WEEKDAYS: [6, 0, 1, 2, 3, 4, 5], - - /** - * py_date.timetuple()[7] - */ - getYearDay: function(date) { - var dateNoTime = new Date( - date.getFullYear(), date.getMonth(), date.getDate()); - return Math.ceil( - (dateNoTime - new Date(date.getFullYear(), 0, 1)) - / dateutil.ONE_DAY) + 1; - }, - - isLeapYear: function(year) { - if (year instanceof Date) { - year = year.getFullYear(); - } - return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0); - }, - - /** - * @return {Number} the date's timezone offset in ms - */ - tzOffset: function(date) { - return date.getTimezoneOffset() * 60 * 1000 - }, - - /** - * @see: <http://www.mcfedries.com/JavaScript/DaysBetween.asp> - */ - daysBetween: function(date1, date2) { - // The number of milliseconds in one day - // Convert both dates to milliseconds - var date1_ms = date1.getTime() - dateutil.tzOffset(date1); - var date2_ms = date2.getTime() - dateutil.tzOffset(date2); - // Calculate the difference in milliseconds - var difference_ms = Math.abs(date1_ms - date2_ms); - // Convert back to days and return - return Math.round(difference_ms / dateutil.ONE_DAY); - }, - - /** - * @see: <http://docs.python.org/library/datetime.html#datetime.date.toordinal> - */ - toOrdinal: function(date) { - return dateutil.daysBetween(date, dateutil.ORDINAL_BASE); - }, - - /** - * @see - <http://docs.python.org/library/datetime.html#datetime.date.fromordinal> - */ - fromOrdinal: function(ordinal) { - var millisecsFromBase = ordinal * dateutil.ONE_DAY; - return new Date(dateutil.ORDINAL_BASE.getTime() - - dateutil.tzOffset(dateutil.ORDINAL_BASE) - + millisecsFromBase - + dateutil.tzOffset(new Date(millisecsFromBase))); - }, - - /** - * @see: <http://docs.python.org/library/calendar.html#calendar.monthrange> - */ - monthRange: function(year, month) { - var date = new Date(year, month, 1); - return [dateutil.getWeekday(date), dateutil.getMonthDays(date)]; - }, - - getMonthDays: function(date) { - var month = date.getMonth(); - return month == 1 && dateutil.isLeapYear(date) - ? 29 - : dateutil.MONTH_DAYS[month]; - }, - - /** - * @return {Number} python-like weekday - */ - getWeekday: function(date) { - return dateutil.PY_WEEKDAYS[date.getDay()]; - }, - - /** - * @see: <http://docs.python.org/library/datetime.html#datetime.datetime.combine> - */ - combine: function(date, time) { - time = time || date; - return new Date( - date.getFullYear(), date.getMonth(), date.getDate(), - time.getHours(), time.getMinutes(), time.getSeconds() - ); - }, - - clone: function(date) { - var dolly = new Date(date.getTime()); - dolly.setMilliseconds(0); - return dolly; - }, - - cloneDates: function(dates) { - var clones = []; - for (var i = 0; i < dates.length; i++) { - clones.push(dateutil.clone(dates[i])); - } - return clones; - }, - - /** - * Sorts an array of Date or dateutil.Time objects - */ - sort: function(dates) { - dates.sort(function(a, b){ - return a.getTime() - b.getTime(); - }); - }, - - timeToUntilString: function(time) { - var date = new Date(time); - var comp, comps = [ - date.getUTCFullYear(), - date.getUTCMonth() + 1, - date.getUTCDate(), - 'T', - date.getUTCHours(), - date.getUTCMinutes(), - date.getUTCSeconds(), - 'Z' - ]; - for (var i = 0; i < comps.length; i++) { - comp = comps[i]; - if (!/[TZ]/.test(comp) && comp < 10) { - comps[i] = '0' + String(comp); - } - } - return comps.join(''); - }, - - untilStringToDate: function(until) { - var re = /^(\d{4})(\d{2})(\d{2})(T(\d{2})(\d{2})(\d{2})Z)?$/; - var bits = re.exec(until); - if (!bits) { - throw new Error('Invalid UNTIL value: ' + until) - } - return new Date( - Date.UTC(bits[1], - bits[2] - 1, - bits[3], - bits[5] || 0, - bits[6] || 0, - bits[7] || 0 - )); - } - -}; - -dateutil.Time = function(hour, minute, second) { - this.hour = hour; - this.minute = minute; - this.second = second; -}; - -dateutil.Time.prototype = { - getHours: function() { - return this.hour; - }, - getMinutes: function() { - return this.minute; - }, - getSeconds: function() { - return this.second; - }, - getTime: function() { - return ((this.hour * 60 * 60) - + (this.minute * 60) - + this.second) - * 1000; - } -}; - - -//============================================================================= -// Helper functions -//============================================================================= - - -/** - * Simplified version of python's range() - */ -var range = function(start, end) { - if (arguments.length === 1) { - end = start; - start = 0; - } - var rang = []; - for (var i = start; i < end; i++) { - rang.push(i); - } - return rang; -}; -var repeat = function(value, times) { - var i = 0, array = []; - if (value instanceof Array) { - for (; i < times; i++) { - array[i] = [].concat(value); - } - } else { - for (; i < times; i++) { - array[i] = value; - } - } - return array; -}; - - -/** - * closure/goog/math/math.js:modulo - * Copyright 2006 The Closure Library Authors. - * The % operator in JavaScript returns the remainder of a / b, but differs from - * some other languages in that the result will have the same sign as the - * dividend. For example, -1 % 8 == -1, whereas in some other languages - * (such as Python) the result would be 7. This function emulates the more - * correct modulo behavior, which is useful for certain applications such as - * calculating an offset index in a circular list. - * - * @param {number} a The dividend. - * @param {number} b The divisor. - * @return {number} a % b where the result is between 0 and b (either 0 <= x < b - * or b < x <= 0, depending on the sign of b). - */ -var pymod = function(a, b) { - var r = a % b; - // If r and b differ in sign, add b to wrap the result to the correct sign. - return (r * b < 0) ? r + b : r; -}; - - -/** - * @see: <http://docs.python.org/library/functions.html#divmod> - */ -var divmod = function(a, b) { - return {div: Math.floor(a / b), mod: pymod(a, b)}; -}; - - -/** - * Python-like boolean - * @return {Boolean} value of an object/primitive, taking into account - * the fact that in Python an empty list's/tuple's - * boolean value is False, whereas in JS it's true - */ -var plb = function(obj) { - return (obj instanceof Array && obj.length == 0) - ? false - : Boolean(obj); -}; - - -/** - * Return true if a value is in an array - */ -var contains = function(arr, val) { - return arr.indexOf(val) != -1; -}; - - -//============================================================================= -// Date masks -//============================================================================= - -// Every mask is 7 days longer to handle cross-year weekly periods. - -var M365MASK = [].concat( - repeat(1, 31), repeat(2, 28), repeat(3, 31), - repeat(4, 30), repeat(5, 31), repeat(6, 30), - repeat(7, 31), repeat(8, 31), repeat(9, 30), - repeat(10, 31), repeat(11, 30), repeat(12, 31), - repeat(1, 7) -); -var M366MASK = [].concat( - repeat(1, 31), repeat(2, 29), repeat(3, 31), - repeat(4, 30), repeat(5, 31), repeat(6, 30), - repeat(7, 31), repeat(8, 31), repeat(9, 30), - repeat(10, 31), repeat(11, 30), repeat(12, 31), - repeat(1, 7) -); - -var - M28 = range(1, 29), - M29 = range(1, 30), - M30 = range(1, 31), - M31 = range(1, 32); -var MDAY366MASK = [].concat( - M31, M29, M31, - M30, M31, M30, - M31, M31, M30, - M31, M30, M31, - M31.slice(0, 7) -); -var MDAY365MASK = [].concat( - M31, M28, M31, - M30, M31, M30, - M31, M31, M30, - M31, M30, M31, - M31.slice(0, 7) -); - -M28 = range(-28, 0); -M29 = range(-29, 0); -M30 = range(-30, 0); -M31 = range(-31, 0); -var NMDAY366MASK = [].concat( - M31, M29, M31, - M30, M31, M30, - M31, M31, M30, - M31, M30, M31, - M31.slice(0, 7) -); -var NMDAY365MASK = [].concat( - M31, M28, M31, - M30, M31, M30, - M31, M31, M30, - M31, M30, M31, - M31.slice(0, 7) -); - -var M366RANGE = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366]; -var M365RANGE = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; - -var WDAYMASK = (function() { - for (var wdaymask = [], i = 0; i < 55; i++) { - wdaymask = wdaymask.concat(range(7)); - } - return wdaymask; -}()); - - -//============================================================================= -// Weekday -//============================================================================= - -var Weekday = function(weekday, n) { - if (n === 0) { - throw new Error('Can\'t create weekday with n == 0'); - } - this.weekday = weekday; - this.n = n; -}; - -Weekday.prototype = { - - // __call__ - Cannot call the object directly, do it through - // e.g. RRule.TH.nth(-1) instead, - nth: function(n) { - return this.n == n ? this : new Weekday(this.weekday, n); - }, - - // __eq__ - equals: function(other) { - return this.weekday == other.weekday && this.n == other.n; - }, - - // __repr__ - toString: function() { - var s = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'][this.weekday]; - if (this.n) { - s = (this.n > 0 ? '+' : '') + String(this.n) + s; - } - return s; - }, - - getJsWeekday: function() { - return this.weekday == 6 ? 0 : this.weekday + 1; - } - -}; - - -//============================================================================= -// RRule -//============================================================================= - -/** - * - * @param {Object?} options - see <http://labix.org/python-dateutil/#head-cf004ee9a75592797e076752b2a889c10f445418> - * The only required option is `freq`, one of RRule.YEARLY, RRule.MONTHLY, ... - * @constructor - */ -var RRule = function(options, noCache) { - - // RFC string - this._string = null; - - options = options || {}; - - this._cache = noCache ? null : { - all: false, - before: [], - after: [], - between: [] - }; - - // used by toString() - this.origOptions = {}; - - var invalid = [], - keys = Object.keys(options), - defaultKeys = Object.keys(RRule.DEFAULT_OPTIONS); - - // Shallow copy for origOptions and check for invalid - keys.forEach(function(key) { - this.origOptions[key] = options[key]; - if (!contains(defaultKeys, key)) invalid.push(key); - }, this); - - if (invalid.length) { - throw new Error('Invalid options: ' + invalid.join(', ')) - } - - if (!RRule.FREQUENCIES[options.freq] && options.byeaster === null) { - throw new Error('Invalid frequency: ' + String(options.freq)) - } - - // Merge in default options - defaultKeys.forEach(function(key) { - if (!contains(keys, key)) options[key] = RRule.DEFAULT_OPTIONS[key]; - }); - - var opts = this.options = options; - - if (opts.byeaster !== null) { - opts.freq = RRule.YEARLY; - } - - if (!opts.dtstart) { - opts.dtstart = new Date(); - opts.dtstart.setMilliseconds(0); - } - - if (opts.wkst === null) { - opts.wkst = RRule.MO.weekday; - } else if (typeof opts.wkst == 'number') { - // cool, just keep it like that - } else { - opts.wkst = opts.wkst.weekday; - } - - if (opts.bysetpos !== null) { - if (typeof opts.bysetpos == 'number') { - opts.bysetpos = [opts.bysetpos]; - } - for (var i = 0; i < opts.bysetpos.length; i++) { - var v = opts.bysetpos[i]; - if (v == 0 || !(-366 <= v && v <= 366)) { - throw new Error( - 'bysetpos must be between 1 and 366,' + - ' or between -366 and -1' - ); - } - } - } - - if (!(plb(opts.byweekno) || plb(opts.byyearday) - || plb(opts.bymonthday) || opts.byweekday !== null - || opts.byeaster !== null)) - { - switch (opts.freq) { - case RRule.YEARLY: - if (!opts.bymonth) { - opts.bymonth = opts.dtstart.getMonth() + 1; - } - opts.bymonthday = opts.dtstart.getDate(); - break; - case RRule.MONTHLY: - opts.bymonthday = opts.dtstart.getDate(); - break; - case RRule.WEEKLY: - opts.byweekday = dateutil.getWeekday( - opts.dtstart); - break; - } - } - - // bymonth - if (opts.bymonth !== null - && !(opts.bymonth instanceof Array)) { - opts.bymonth = [opts.bymonth]; - } - - // byyearday - if (opts.byyearday !== null - && !(opts.byyearday instanceof Array)) { - opts.byyearday = [opts.byyearday]; - } - - // bymonthday - if (opts.bymonthday === null) { - opts.bymonthday = []; - opts.bynmonthday = []; - } else if (opts.bymonthday instanceof Array) { - var bymonthday = [], bynmonthday = []; - - for (i = 0; i < opts.bymonthday.length; i++) { - var v = opts.bymonthday[i]; - if (v > 0) { - bymonthday.push(v); - } else if (v < 0) { - bynmonthday.push(v); - } - } - opts.bymonthday = bymonthday; - opts.bynmonthday = bynmonthday; - } else { - if (opts.bymonthday < 0) { - opts.bynmonthday = [opts.bymonthday]; - opts.bymonthday = []; - } else { - opts.bynmonthday = []; - opts.bymonthday = [opts.bymonthday]; - } - } - - // byweekno - if (opts.byweekno !== null - && !(opts.byweekno instanceof Array)) { - opts.byweekno = [opts.byweekno]; - } - - // byweekday / bynweekday - if (opts.byweekday === null) { - opts.bynweekday = null; - } else if (typeof opts.byweekday == 'number') { - opts.byweekday = [opts.byweekday]; - opts.bynweekday = null; - - } else if (opts.byweekday instanceof Weekday) { - - if (!opts.byweekday.n || opts.freq > RRule.MONTHLY) { - opts.byweekday = [opts.byweekday.weekday]; - opts.bynweekday = null; - } else { - opts.bynweekday = [ - [opts.byweekday.weekday, - opts.byweekday.n] - ]; - opts.byweekday = null; - } - - } else { - var byweekday = [], bynweekday = []; - - for (i = 0; i < opts.byweekday.length; i++) { - var wday = opts.byweekday[i]; - - if (typeof wday == 'number') { - byweekday.push(wday); - } else if (!wday.n || opts.freq > RRule.MONTHLY) { - byweekday.push(wday.weekday); - } else { - bynweekday.push([wday.weekday, wday.n]); - } - } - opts.byweekday = plb(byweekday) ? byweekday : null; - opts.bynweekday = plb(bynweekday) ? bynweekday : null; - } - - // byhour - if (opts.byhour === null) { - opts.byhour = (opts.freq < RRule.HOURLY) - ? [opts.dtstart.getHours()] - : null; - } else if (typeof opts.byhour == 'number') { - opts.byhour = [opts.byhour]; - } - - // byminute - if (opts.byminute === null) { - opts.byminute = (opts.freq < RRule.MINUTELY) - ? [opts.dtstart.getMinutes()] - : null; - } else if (typeof opts.byminute == 'number') { - opts.byminute = [opts.byminute]; - } - - // bysecond - if (opts.bysecond === null) { - opts.bysecond = (opts.freq < RRule.SECONDLY) - ? [opts.dtstart.getSeconds()] - : null; - } else if (typeof opts.bysecond == 'number') { - opts.bysecond = [opts.bysecond]; - } - - if (opts.freq >= RRule.HOURLY) { - this.timeset = null; - } else { - this.timeset = []; - for (i = 0; i < opts.byhour.length; i++) { - var hour = opts.byhour[i]; - for (var j = 0; j < opts.byminute.length; j++) { - var minute = opts.byminute[j]; - for (var k = 0; k < opts.bysecond.length; k++) { - var second = opts.bysecond[k]; - // python: - // datetime.time(hour, minute, second, - // tzinfo=self._tzinfo)) - this.timeset.push(new dateutil.Time(hour, minute, second)); - } - } - } - dateutil.sort(this.timeset); - } - -}; -//}}} - -// RRule class 'constants' - -RRule.FREQUENCIES = [ - 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY', - 'HOURLY', 'MINUTELY', 'SECONDLY' -]; - -RRule.YEARLY = 0; -RRule.MONTHLY = 1; -RRule.WEEKLY = 2; -RRule.DAILY = 3; -RRule.HOURLY = 4; -RRule.MINUTELY = 5; -RRule.SECONDLY = 6; - -RRule.MO = new Weekday(0); -RRule.TU = new Weekday(1); -RRule.WE = new Weekday(2); -RRule.TH = new Weekday(3); -RRule.FR = new Weekday(4); -RRule.SA = new Weekday(5); -RRule.SU = new Weekday(6); - -RRule.DEFAULT_OPTIONS = { - freq: null, - dtstart: null, - interval: 1, - wkst: RRule.MO, - count: null, - until: null, - bysetpos: null, - bymonth: null, - bymonthday: null, - byyearday: null, - byweekno: null, - byweekday: null, - byhour: null, - byminute: null, - bysecond: null, - byeaster: null -}; - - - -RRule.parseText = function(text, language) { - return getnlp().parseText(text, language) -}; - -RRule.fromText = function(text, language) { - return getnlp().fromText(text, language) -}; - -RRule.optionsToString = function(options) { - var key, keys, defaultKeys, value, strValues, pairs = []; - - keys = Object.keys(options); - defaultKeys = Object.keys(RRule.DEFAULT_OPTIONS); - - for (var i = 0; i < keys.length; i++) { - - if (!contains(defaultKeys, keys[i])) continue; - - key = keys[i].toUpperCase(); - value = options[keys[i]]; - strValues = []; - - if (value === null || value instanceof Array && !value.length) { - continue; - } - - switch (key) { - case 'FREQ': - value = RRule.FREQUENCIES[options.freq]; - break; - case 'WKST': - value = value.toString(); - break; - case 'BYWEEKDAY': - /* - NOTE: BYWEEKDAY is a special case. - RRule() deconstructs the rule.options.byweekday array - into an array of Weekday arguments. - On the other hand, rule.origOptions is an array of Weekdays. - We need to handle both cases here. - It might be worth change RRule to keep the Weekdays. - - Also, BYWEEKDAY (used by RRule) vs. BYDAY (RFC) - - */ - key = 'BYDAY'; - if (!(value instanceof Array)) { - value = [value]; - } - for (var wday, j = 0; j < value.length; j++) { - wday = value[j]; - if (wday instanceof Weekday) { - // good - } else if (wday instanceof Array) { - wday = new Weekday(wday[0], wday[1]); - } else { - wday = new Weekday(wday); - } - strValues[j] = wday.toString(); - } - value = strValues; - break; - case'DTSTART': - case'UNTIL': - value = dateutil.timeToUntilString(value); - break; - default: - if (value instanceof Array) { - for (var j = 0; j < value.length; j++) { - strValues[j] = String(value[j]); - } - value = strValues; - } else { - value = String(value); - } - - } - pairs.push([key, value]); - } - - var strings = []; - for (var i = 0; i < pairs.length; i++) { - var attr = pairs[i]; - strings.push(attr[0] + '=' + attr[1].toString()); - } - return strings.join(';'); - -}; - -RRule.prototype = { - - /** - * @param {Function} iterator - optional function that will be called - * on each date that is added. It can return false - * to stop the iteration. - * @return Array containing all recurrences. - */ - all: function(iterator) { - if (iterator) { - return this._iter(new CallbackIterResult('all', {}, iterator)); - } else { - var result = this._cacheGet('all'); - if (result === false) { - result = this._iter(new IterResult('all', {})); - this._cacheAdd('all', result); - } - return result; - } - }, - - /** - * Returns all the occurrences of the rrule between after and before. - * The inc keyword defines what happens if after and/or before are - * themselves occurrences. With inc == True, they will be included in the - * list, if they are found in the recurrence set. - * @return Array - */ - between: function(after, before, inc, iterator) { - var args = { - before: before, - after: after, - inc: inc - } - - if (iterator) { - return this._iter( - new CallbackIterResult('between', args, iterator)); - } else { - var result = this._cacheGet('between', args); - if (result === false) { - result = this._iter(new IterResult('between', args)); - this._cacheAdd('between', result, args); - } - return result; - } - }, - - /** - * Returns the last recurrence before the given datetime instance. - * The inc keyword defines what happens if dt is an occurrence. - * With inc == True, if dt itself is an occurrence, it will be returned. - * @return Date or null - */ - before: function(dt, inc) { - var args = { - dt: dt, - inc: inc - }, - result = this._cacheGet('before', args); - if (result === false) { - result = this._iter(new IterResult('before', args)); - this._cacheAdd('before', result, args); - } - return result; - }, - - /** - * Returns the first recurrence after the given datetime instance. - * The inc keyword defines what happens if dt is an occurrence. - * With inc == True, if dt itself is an occurrence, it will be returned. - * @return Date or null - */ - after: function(dt, inc) { - var args = { - dt: dt, - inc: inc - }, - result = this._cacheGet('after', args); - if (result === false) { - result = this._iter(new IterResult('after', args)); - this._cacheAdd('after', result, args); - } - return result; - }, - - /** - * Returns the number of recurrences in this set. It will have go trough - * the whole recurrence, if this hasn't been done before. - */ - count: function() { - return this.all().length; - }, - - /** - * Converts the rrule into its string representation - * @see <http://www.ietf.org/rfc/rfc2445.txt> - * @return String - */ - toString: function() { - return RRule.optionsToString(this.origOptions); - }, - - /** - * Will convert all rules described in nlp:ToText - * to text. - */ - toText: function(gettext, language) { - return getnlp().toText(this, gettext, language); - }, - - isFullyConvertibleToText: function() { - return getnlp().isFullyConvertible(this) - }, - - /** - * @param {String} what - all/before/after/between - * @param {Array,Date} value - an array of dates, one date, or null - * @param {Object?} args - _iter arguments - */ - _cacheAdd: function(what, value, args) { - - if (!this._cache) return; - - if (value) { - value = (value instanceof Date) - ? dateutil.clone(value) - : dateutil.cloneDates(value); - } - - if (what == 'all') { - this._cache.all = value; - } else { - args._value = value; - this._cache[what].push(args); - } - - }, - - /** - * @return false - not in the cache - * null - cached, but zero occurrences (before/after) - * Date - cached (before/after) - * [] - cached, but zero occurrences (all/between) - * [Date1, DateN] - cached (all/between) - */ - _cacheGet: function(what, args) { - - if (!this._cache) { - return false; - } - - var cached = false; - - if (what == 'all') { - cached = this._cache.all; - } else { - // Let's see whether we've already called the - // 'what' method with the same 'args' - loopItems: - for (var item, i = 0; i < this._cache[what].length; i++) { - item = this._cache[what][i]; - for (var k in args) { - if (args.hasOwnProperty(k) - && String(args[k]) != String(item[k])) { - continue loopItems; - } - } - cached = item._value; - break; - } - } - - if (!cached && this._cache.all) { - // Not in the cache, but we already know all the occurrences, - // so we can find the correct dates from the cached ones. - var iterResult = new IterResult(what, args); - for (var i = 0; i < this._cache.all.length; i++) { - if (!iterResult.accept(this._cache.all[i])) { - break; - } - } - cached = iterResult.getValue(); - this._cacheAdd(what, cached, args); - } - - return cached instanceof Array - ? dateutil.cloneDates(cached) - : (cached instanceof Date - ? dateutil.clone(cached) - : cached); - }, - - /** - * @return a RRule instance with the same freq and options - * as this one (cache is not cloned) - */ - clone: function() { - return new RRule(this.origOptions); - }, - - _iter: function(iterResult) { - - /* Since JavaScript doesn't have the python's yield operator (<1.7), - we use the IterResult object that tells us when to stop iterating. - - */ - - var dtstart = this.options.dtstart; - - var - year = dtstart.getFullYear(), - month = dtstart.getMonth() + 1, - day = dtstart.getDate(), - hour = dtstart.getHours(), - minute = dtstart.getMinutes(), - second = dtstart.getSeconds(), - weekday = dateutil.getWeekday(dtstart), - yearday = dateutil.getYearDay(dtstart); - - // Some local variables to speed things up a bit - var - freq = this.options.freq, - interval = this.options.interval, - wkst = this.options.wkst, - until = this.options.until, - bymonth = this.options.bymonth, - byweekno = this.options.byweekno, - byyearday = this.options.byyearday, - byweekday = this.options.byweekday, - byeaster = this.options.byeaster, - bymonthday = this.options.bymonthday, - bynmonthday = this.options.bynmonthday, - bysetpos = this.options.bysetpos, - byhour = this.options.byhour, - byminute = this.options.byminute, - bysecond = this.options.bysecond; - - var ii = new Iterinfo(this); - ii.rebuild(year, month); - - var getdayset = {}; - getdayset[RRule.YEARLY] = ii.ydayset; - getdayset[RRule.MONTHLY] = ii.mdayset; - getdayset[RRule.WEEKLY] = ii.wdayset; - getdayset[RRule.DAILY] = ii.ddayset; - getdayset[RRule.HOURLY] = ii.ddayset; - getdayset[RRule.MINUTELY] = ii.ddayset; - getdayset[RRule.SECONDLY] = ii.ddayset; - - getdayset = getdayset[freq]; - - var timeset; - if (freq < RRule.HOURLY) { - timeset = this.timeset; - } else { - var gettimeset = {}; - gettimeset[RRule.HOURLY] = ii.htimeset; - gettimeset[RRule.MINUTELY] = ii.mtimeset; - gettimeset[RRule.SECONDLY] = ii.stimeset; - gettimeset = gettimeset[freq]; - if ((freq >= RRule.HOURLY && plb(byhour) && !contains(byhour, hour)) || - (freq >= RRule.MINUTELY && plb(byminute) && !contains(byminute, minute)) || - (freq >= RRule.SECONDLY && plb(bysecond) && !contains(bysecond, minute))) - { - timeset = []; - } else { - timeset = gettimeset.call(ii, hour, minute, second); - } - } - - var filtered, total = 0, count = this.options.count; - - var iterNo = 0; - - var i, j, k, dm, div, mod, tmp, pos, dayset, start, end, fixday; - - while (true) { - - // Get dayset with the right frequency - tmp = getdayset.call(ii, year, month, day); - dayset = tmp[0]; start = tmp[1]; end = tmp[2]; - - // Do the "hard" work ;-) - filtered = false; - for (j = start; j < end; j++) { - - i = dayset[j]; - - if ((plb(bymonth) && !contains(bymonth, ii.mmask[i])) || - (plb(byweekno) && !ii.wnomask[i]) || - (plb(byweekday) && !contains(byweekday, ii.wdaymask[i])) || - (plb(ii.nwdaymask) && !ii.nwdaymask[i]) || - (byeaster !== null && !contains(ii.eastermask, i)) || - ( - (plb(bymonthday) || plb(bynmonthday)) && - !contains(bymonthday, ii.mdaymask[i]) && - !contains(bynmonthday, ii.nmdaymask[i]) - ) - || - ( - plb(byyearday) - && - ( - ( - i < ii.yearlen && - !contains(byyearday, i + 1) && - !contains(byyearday, -ii.yearlen + i) - ) - || - ( - i >= ii.yearlen && - !contains(byyearday, i + 1 - ii.yearlen) && - !contains(byyearday, -ii.nextyearlen + i - ii.yearlen) - ) - ) - ) - ) - { - dayset[i] = null; - filtered = true; - } - } - - // Output results - if (plb(bysetpos) && plb(timeset)) { - - var daypos, timepos, poslist = []; - - for (i, j = 0; j < bysetpos.length; j++) { - var pos = bysetpos[j]; - if (pos < 0) { - daypos = Math.floor(pos / timeset.length); - timepos = pymod(pos, timeset.length); - } else { - daypos = Math.floor((pos - 1) / timeset.length); - timepos = pymod((pos - 1), timeset.length); - } - - try { - tmp = []; - for (k = start; k < end; k++) { - var val = dayset[k]; - if (val === null) { - continue; - } - tmp.push(val); - } - if (daypos < 0) { - // we're trying to emulate python's aList[-n] - i = tmp.slice(daypos)[0]; - } else { - i = tmp[daypos]; - } - - var time = timeset[timepos]; - - var date = dateutil.fromOrdinal(ii.yearordinal + i); - var res = dateutil.combine(date, time); - // XXX: can this ever be in the array? - // - compare the actual date instead? - if (!contains(poslist, res)) { - poslist.push(res); - } - } catch (e) {} - } - - dateutil.sort(poslist); - - for (j = 0; j < poslist.length; j++) { - var res = poslist[j]; - if (until && res > until) { - this._len = total; - return iterResult.getValue(); - } else if (res >= dtstart) { - ++total; - if (!iterResult.accept(res)) { - return iterResult.getValue(); - } - if (count) { - --count; - if (!count) { - this._len = total; - return iterResult.getValue(); - } - } - } - } - - } else { - for (j = start; j < end; j++) { - i = dayset[j]; - if (i !== null) { - var date = dateutil.fromOrdinal(ii.yearordinal + i); - for (k = 0; k < timeset.length; k++) { - var time = timeset[k]; - var res = dateutil.combine(date, time); - if (until && res > until) { - this._len = total; - return iterResult.getValue(); - } else if (res >= dtstart) { - ++total; - if (!iterResult.accept(res)) { - return iterResult.getValue(); - } - if (count) { - --count; - if (!count) { - this._len = total; - return iterResult.getValue(); - } - } - } - } - } - } - } - - // Handle frequency and interval - fixday = false; - if (freq == RRule.YEARLY) { - year += interval; - if (year > dateutil.MAXYEAR) { - this._len = total; - return iterResult.getValue(); - } - ii.rebuild(year, month); - } else if (freq == RRule.MONTHLY) { - month += interval; - if (month > 12) { - div = Math.floor(month / 12); - mod = pymod(month, 12); - month = mod; - year += div; - if (month == 0) { - month = 12; - --year; - } - if (year > dateutil.MAXYEAR) { - this._len = total; - return iterResult.getValue(); - } - } - ii.rebuild(year, month); - } else if (freq == RRule.WEEKLY) { - if (wkst > weekday) { - day += -(weekday + 1 + (6 - wkst)) + interval * 7; - } else { - day += -(weekday - wkst) + interval * 7; - } - weekday = wkst; - fixday = true; - } else if (freq == RRule.DAILY) { - day += interval; - fixday = true; - } else if (freq == RRule.HOURLY) { - if (filtered) { - // Jump to one iteration before next day - hour += Math.floor((23 - hour) / interval) * interval; - } - while (true) { - hour += interval; - dm = divmod(hour, 24); - div = dm.div; - mod = dm.mod; - if (div) { - hour = mod; - day += div; - fixday = true; - } - if (!plb(byhour) || contains(byhour, hour)) { - break; - } - } - timeset = gettimeset.call(ii, hour, minute, second); - } else if (freq == RRule.MINUTELY) { - if (filtered) { - // Jump to one iteration before next day - minute += Math.floor( - (1439 - (hour * 60 + minute)) / interval) * interval; - } - while(true) { - minute += interval; - dm = divmod(minute, 60); - div = dm.div; - mod = dm.mod; - if (div) { - minute = mod; - hour += div; - dm = divmod(hour, 24); - div = dm.div; - mod = dm.mod; - if (div) { - hour = mod; - day += div; - fixday = true; - filtered = false; - } - } - if ((!plb(byhour) || contains(byhour, hour)) && - (!plb(byminute) || contains(byminute, minute))) { - break; - } - } - timeset = gettimeset.call(ii, hour, minute, second); - } else if (freq == RRule.SECONDLY) { - if (filtered) { - // Jump to one iteration before next day - second += Math.floor( - (86399 - (hour * 3600 + minute * 60 + second)) - / interval) * interval; - } - while (true) { - second += interval; - dm = divmod(second, 60); - div = dm.div; - mod = dm.mod; - if (div) { - second = mod; - minute += div; - dm = divmod(minute, 60); - div = dm.div; - mod = dm.mod; - if (div) { - minute = mod; - hour += div; - dm = divmod(hour, 24); - div = dm.div; - mod = dm.mod; - if (div) { - hour = mod; - day += div; - fixday = true; - } - } - } - if ((!plb(byhour) || contains(byhour, hour)) && - (!plb(byminute) || contains(byminute, minute)) && - (!plb(bysecond) || contains(bysecond, second))) - { - break; - } - } - timeset = gettimeset.call(ii, hour, minute, second); - } - - if (fixday && day > 28) { - var daysinmonth = dateutil.monthRange(year, month - 1)[1]; - if (day > daysinmonth) { - while (day > daysinmonth) { - day -= daysinmonth; - ++month; - if (month == 13) { - month = 1; - ++year; - if (year > dateutil.MAXYEAR) { - this._len = total; - return iterResult.getValue(); - } - } - daysinmonth = dateutil.monthRange(year, month - 1)[1]; - } - ii.rebuild(year, month); - } - } - } - } - -}; - - -RRule.parseString = function(rfcString) { - rfcString = rfcString.replace(/^\s+|\s+$/, ''); - if (!rfcString.length) { - return null; - } - - var i, j, key, value, attr, - attrs = rfcString.split(';'), - options = {}; - - for (i = 0; i < attrs.length; i++) { - attr = attrs[i].split('='); - key = attr[0]; - value = attr[1]; - switch (key) { - case 'FREQ': - options.freq = RRule[value]; - break; - case 'WKST': - options.wkst = RRule[value]; - break; - case 'COUNT': - case 'INTERVAL': - case 'BYSETPOS': - case 'BYMONTH': - case 'BYMONTHDAY': - case 'BYYEARDAY': - case 'BYWEEKNO': - case 'BYHOUR': - case 'BYMINUTE': - case 'BYSECOND': - if (value.indexOf(',') != -1) { - value = value.split(','); - for (j = 0; j < value.length; j++) { - if (/^[+-]?\d+$/.test(value[j])) { - value[j] = Number(value[j]); - } - } - } else if (/^[+-]?\d+$/.test(value)) { - value = Number(value); - } - key = key.toLowerCase(); - options[key] = value; - break; - case 'BYDAY': // => byweekday - var n, wday, day, days = value.split(','); - options.byweekday = []; - for (j = 0; j < days.length; j++) { - day = days[j]; - if (day.length == 2) { // MO, TU, ... - wday = RRule[day]; // wday instanceof Weekday - options.byweekday.push(wday); - } else { // -1MO, +3FR, 1SO, ... - day = day.match(/^([+-]?\d)([A-Z]{2})$/); - n = Number(day[1]); - wday = day[2]; - wday = RRule[wday].weekday; - options.byweekday.push(new Weekday(wday, n)); - } - } - break; - case 'DTSTART': - options.dtstart = dateutil.untilStringToDate(value); - break; - case 'UNTIL': - options.until = dateutil.untilStringToDate(value); - break; - case 'BYEASTER': - options.byeaster = Number(value); - break; - default: - throw new Error("Unknown RRULE property '" + key + "'"); - } - } - return options; -}; - - -RRule.fromString = function(string) { - return new RRule(RRule.parseString(string)); -}; - - -//============================================================================= -// Iterinfo -//============================================================================= - -var Iterinfo = function(rrule) { - this.rrule = rrule; - this.lastyear = null; - this.lastmonth = null; - this.yearlen = null; - this.nextyearlen = null; - this.yearordinal = null; - this.yearweekday = null; - this.mmask = null; - this.mrange = null; - this.mdaymask = null; - this.nmdaymask = null; - this.wdaymask = null; - this.wnomask = null; - this.nwdaymask = null; - this.eastermask = null; -}; - -Iterinfo.prototype.easter = function(y, offset) { - offset = offset || 0; - - var a = y % 19, - b = Math.floor(y / 100), - c = y % 100, - d = Math.floor(b / 4), - e = b % 4, - f = Math.floor((b + 8) / 25), - g = Math.floor((b - f + 1) / 3), - h = Math.floor(19 * a + b - d - g + 15) % 30, - i = Math.floor(c / 4), - k = c % 4, - l = Math.floor(32 + 2 * e + 2 * i - h - k) % 7, - m = Math.floor((a + 11 * h + 22 * l) / 451), - month = Math.floor((h + l - 7 * m + 114) / 31), - day = (h + l - 7 * m + 114) % 31 + 1, - date = Date.UTC(y, month - 1, day + offset), - yearStart = Date.UTC(y, 0, 1); - - return [ Math.ceil((date - yearStart) / (1000 * 60 * 60 * 24)) ]; -} - -Iterinfo.prototype.rebuild = function(year, month) { - - var rr = this.rrule; - - if (year != this.lastyear) { - - this.yearlen = dateutil.isLeapYear(year) ? 366 : 365; - this.nextyearlen = dateutil.isLeapYear(year + 1) ? 366 : 365; - var firstyday = new Date(year, 0, 1); - - this.yearordinal = dateutil.toOrdinal(firstyday); - this.yearweekday = dateutil.getWeekday(firstyday); - - var wday = dateutil.getWeekday(new Date(year, 0, 1)); - - if (this.yearlen == 365) { - this.mmask = [].concat(M365MASK); - this.mdaymask = [].concat(MDAY365MASK); - this.nmdaymask = [].concat(NMDAY365MASK); - this.wdaymask = WDAYMASK.slice(wday); - this.mrange = [].concat(M365RANGE); - } else { - this.mmask = [].concat(M366MASK); - this.mdaymask = [].concat(MDAY366MASK); - this.nmdaymask = [].concat(NMDAY366MASK); - this.wdaymask = WDAYMASK.slice(wday); - this.mrange = [].concat(M366RANGE); - } - - if (!plb(rr.options.byweekno)) { - this.wnomask = null; - } else { - this.wnomask = repeat(0, this.yearlen + 7); - var no1wkst, firstwkst, wyearlen; - no1wkst = firstwkst = pymod( - 7 - this.yearweekday + rr.options.wkst, 7); - if (no1wkst >= 4) { - no1wkst = 0; - // Number of days in the year, plus the days we got - // from last year. - wyearlen = this.yearlen + pymod( - this.yearweekday - rr.options.wkst, 7); - } else { - // Number of days in the year, minus the days we - // left in last year. - wyearlen = this.yearlen - no1wkst; - } - var div = Math.floor(wyearlen / 7); - var mod = pymod(wyearlen, 7); - var numweeks = Math.floor(div + (mod / 4)); - for (var n, i, j = 0; j < rr.options.byweekno.length; j++) { - n = rr.options.byweekno[j]; - if (n < 0) { - n += numweeks + 1; - } if (!(0 < n && n <= numweeks)) { - continue; - } if (n > 1) { - i = no1wkst + (n - 1) * 7; - if (no1wkst != firstwkst) { - i -= 7-firstwkst; - } - } else { - i = no1wkst; - } - for (var k = 0; k < 7; k++) { - this.wnomask[i] = 1; - i++; - if (this.wdaymask[i] == rr.options.wkst) { - break; - } - } - } - - if (contains(rr.options.byweekno, 1)) { - // Check week number 1 of next year as well - // orig-TODO : Check -numweeks for next year. - var i = no1wkst + numweeks * 7; - if (no1wkst != firstwkst) { - i -= 7 - firstwkst; - } - if (i < this.yearlen) { - // If week starts in next year, we - // don't care about it. - for (var j = 0; j < 7; j++) { - this.wnomask[i] = 1; - i += 1; - if (this.wdaymask[i] == rr.options.wkst) { - break; - } - } - } - } - - if (no1wkst) { - // Check last week number of last year as - // well. If no1wkst is 0, either the year - // started on week start, or week number 1 - // got days from last year, so there are no - // days from last year's last week number in - // this year. - var lnumweeks; - if (!contains(rr.options.byweekno, -1)) { - var lyearweekday = dateutil.getWeekday( - new Date(year - 1, 0, 1)); - var lno1wkst = pymod( - 7 - lyearweekday + rr.options.wkst, 7); - var lyearlen = dateutil.isLeapYear(year - 1) ? 366 : 365; - if (lno1wkst >= 4) { - lno1wkst = 0; - lnumweeks = Math.floor( - 52 - + pymod( - lyearlen + pymod( - lyearweekday - rr.options.wkst, 7), 7) - / 4); - } else { - lnumweeks = Math.floor( - 52 + pymod(this.yearlen - no1wkst, 7) / 4); - } - } else { - lnumweeks = -1; - } - if (contains(rr.options.byweekno, lnumweeks)) { - for (var i = 0; i < no1wkst; i++) { - this.wnomask[i] = 1; - } - } - } - } - } - - if (plb(rr.options.bynweekday) - && (month != this.lastmonth || year != this.lastyear)) { - var ranges = []; - if (rr.options.freq == RRule.YEARLY) { - if (plb(rr.options.bymonth)) { - for (j = 0; j < rr.options.bymonth.length; j++) { - month = rr.options.bymonth[j]; - ranges.push(this.mrange.slice(month - 1, month + 1)); - } - } else { - ranges = [[0, this.yearlen]]; - } - } else if (rr.options.freq == RRule.MONTHLY) { - ranges = [this.mrange.slice(month - 1, month + 1)]; - } - if (plb(ranges)) { - // Weekly frequency won't get here, so we may not - // care about cross-year weekly periods. - this.nwdaymask = repeat(0, this.yearlen); - - for (var j = 0; j < ranges.length; j++) { - var rang = ranges[j]; - var first = rang[0], last = rang[1]; - last -= 1; - for (var k = 0; k < rr.options.bynweekday.length; k++) { - var wday = rr.options.bynweekday[k][0], - n = rr.options.bynweekday[k][1]; - if (n < 0) { - i = last + (n + 1) * 7; - i -= pymod(this.wdaymask[i] - wday, 7); - } else { - i = first + (n - 1) * 7; - i += pymod(7 - this.wdaymask[i] + wday, 7); - } - if (first <= i && i <= last) { - this.nwdaymask[i] = 1; - } - } - } - - } - - this.lastyear = year; - this.lastmonth = month; - } - - if (rr.options.byeaster !== null) { - this.eastermask = this.easter(year, rr.options.byeaster); - } -}; - -Iterinfo.prototype.ydayset = function(year, month, day) { - return [range(this.yearlen), 0, this.yearlen]; -}; - -Iterinfo.prototype.mdayset = function(year, month, day) { - var set = repeat(null, this.yearlen); - var start = this.mrange[month-1]; - var end = this.mrange[month]; - for (var i = start; i < end; i++) { - set[i] = i; - } - return [set, start, end]; -}; - -Iterinfo.prototype.wdayset = function(year, month, day) { - - // We need to handle cross-year weeks here. - var set = repeat(null, this.yearlen + 7); - var i = dateutil.toOrdinal( - new Date(year, month - 1, day)) - this.yearordinal; - var start = i; - for (var j = 0; j < 7; j++) { - set[i] = i; - ++i; - if (this.wdaymask[i] == this.rrule.options.wkst) { - break; - } - } - return [set, start, i]; -}; - -Iterinfo.prototype.ddayset = function(year, month, day) { - var set = repeat(null, this.yearlen); - var i = dateutil.toOrdinal( - new Date(year, month - 1, day)) - this.yearordinal; - set[i] = i; - return [set, i, i + 1]; -}; - -Iterinfo.prototype.htimeset = function(hour, minute, second) { - var set = [], rr = this.rrule; - for (var i = 0; i < rr.options.byminute.length; i++) { - minute = rr.options.byminute[i]; - for (var j = 0; j < rr.options.bysecond.length; j++) { - second = rr.options.bysecond[j]; - set.push(new dateutil.Time(hour, minute, second)); - } - } - dateutil.sort(set); - return set; -}; - -Iterinfo.prototype.mtimeset = function(hour, minute, second) { - var set = [], rr = this.rrule; - for (var j = 0; j < rr.options.bysecond.length; j++) { - second = rr.options.bysecond[j]; - set.push(new dateutil.Time(hour, minute, second)); - } - dateutil.sort(set); - return set; -}; - -Iterinfo.prototype.stimeset = function(hour, minute, second) { - return [new dateutil.Time(hour, minute, second)]; -}; - - -//============================================================================= -// Results -//============================================================================= - -/** - * This class helps us to emulate python's generators, sorta. - */ -var IterResult = function(method, args) { - this.init(method, args) -}; - -IterResult.prototype = { - - init: function(method, args) { - this.method = method; - this.args = args; - - this._result = []; - - this.minDate = null; - this.maxDate = null; - - if (method == 'between') { - this.maxDate = args.inc - ? args.before - : new Date(args.before.getTime() - 1); - this.minDate = args.inc - ? args.after - : new Date(args.after.getTime() + 1); - } else if (method == 'before') { - this.maxDate = args.inc ? args.dt : new Date(args.dt.getTime() - 1); - } else if (method == 'after') { - this.minDate = args.inc ? args.dt : new Date(args.dt.getTime() + 1); - } - }, - - /** - * Possibly adds a date into the result. - * - * @param {Date} date - the date isn't necessarly added to the result - * list (if it is too late/too early) - * @return {Boolean} true if it makes sense to continue the iteration; - * false if we're done. - */ - accept: function(date) { - var tooEarly = this.minDate && date < this.minDate, - tooLate = this.maxDate && date > this.maxDate; - - if (this.method == 'between') { - if (tooEarly) - return true; - if (tooLate) - return false; - } else if (this.method == 'before') { - if (tooLate) - return false; - } else if (this.method == 'after') { - if (tooEarly) - return true; - this.add(date); - return false; - } - - return this.add(date); - - }, - - /** - * - * @param {Date} date that is part of the result. - * @return {Boolean} whether we are interested in more values. - */ - add: function(date) { - this._result.push(date); - return true; - }, - - /** - * 'before' and 'after' return only one date, whereas 'all' - * and 'between' an array. - * @return {Date,Array?} - */ - getValue: function() { - switch (this.method) { - case 'all': - case 'between': - return this._result; - case 'before': - case 'after': - return this._result.length - ? this._result[this._result.length - 1] - : null; - } - } - -}; - - -/** - * IterResult subclass that calls a callback function on each add, - * and stops iterating when the callback returns false. - */ -var CallbackIterResult = function(method, args, iterator) { - var allowedMethods = ['all', 'between']; - if (!contains(allowedMethods, method)) { - throw new Error('Invalid method "' + method - + '". Only all and between works with iterator.'); - } - this.add = function(date) { - if (iterator(date, this._result.length)) { - this._result.push(date); - return true; - } - return false; - - }; - - this.init(method, args); - -}; -CallbackIterResult.prototype = IterResult.prototype; - - -//============================================================================= -// Export -//============================================================================= - -if (serverSide) { - module.exports = { - RRule: RRule - // rruleset: rruleset - } -} -if (typeof ender === 'undefined') { - root['RRule'] = RRule; - // root['rruleset'] = rruleset; -} - -if (typeof define === "function" && define.amd) { - /*global define:false */ - define("rrule", [], function () { - return RRule; - }); -} - -}(this)); diff --git a/radicale_web/web/infcloud/lib/sha256.js b/radicale_web/web/infcloud/lib/sha256.js deleted file mode 100644 index 529db30..0000000 --- a/radicale_web/web/infcloud/lib/sha256.js +++ /dev/null @@ -1,16 +0,0 @@ -/* -CryptoJS v3.1.2 -code.google.com/p/crypto-js -(c) 2009-2013 by Jeff Mott. All rights reserved. -code.google.com/p/crypto-js/wiki/License -*/ -var CryptoJS=CryptoJS||function(h,s){var f={},t=f.lib={},g=function(){},j=t.Base={extend:function(a){g.prototype=this;var c=new g;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, -q=t.WordArray=j.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=s?c:4*a.length},toString:function(a){return(a||u).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%4)for(var e=0;e<a;e++)c[b+e>>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535<d.length)for(e=0;e<a;e+=4)c[b+e>>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< -32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=j.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d<a;d+=4)c.push(4294967296*h.random()|0);return new q.init(c,a)}}),v=f.enc={},u=v.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++){var e=c[b>>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b+=2)d[b>>>3]|=parseInt(a.substr(b, -2),16)<<24-4*(b%8);return new q.init(d,c/2)}},k=v.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++)d.push(String.fromCharCode(c[b>>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b++)d[b>>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new q.init(d,c)}},l=v.Utf8={stringify:function(a){try{return decodeURIComponent(escape(k.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return k.parse(unescape(encodeURIComponent(a)))}}, -x=t.BufferedBlockAlgorithm=j.extend({reset:function(){this._data=new q.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=l.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var m=0;m<a;m+=e)this._doProcessBlock(d,m);m=d.splice(0,a);c.sigBytes-=b}return new q.init(m,b)},clone:function(){var a=j.clone.call(this); -a._data=this._data.clone();return a},_minBufferSize:0});t.Hasher=x.extend({cfg:j.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){x.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(c,d){return(new a.init(d)).finalize(c)}},_createHmacHelper:function(a){return function(c,d){return(new w.HMAC.init(a, -d)).finalize(c)}}});var w=f.algo={};return f}(Math); -(function(h){for(var s=CryptoJS,f=s.lib,t=f.WordArray,g=f.Hasher,f=s.algo,j=[],q=[],v=function(a){return 4294967296*(a-(a|0))|0},u=2,k=0;64>k;){var l;a:{l=u;for(var x=h.sqrt(l),w=2;w<=x;w++)if(!(l%w)){l=!1;break a}l=!0}l&&(8>k&&(j[k]=v(h.pow(u,0.5))),q[k]=v(h.pow(u,1/3)),k++);u++}var a=[],f=f.SHA256=g.extend({_doReset:function(){this._hash=new t.init(j.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],m=b[2],h=b[3],p=b[4],j=b[5],k=b[6],l=b[7],n=0;64>n;n++){if(16>n)a[n]= -c[d+n]|0;else{var r=a[n-15],g=a[n-2];a[n]=((r<<25|r>>>7)^(r<<14|r>>>18)^r>>>3)+a[n-7]+((g<<15|g>>>17)^(g<<13|g>>>19)^g>>>10)+a[n-16]}r=l+((p<<26|p>>>6)^(p<<21|p>>>11)^(p<<7|p>>>25))+(p&j^~p&k)+q[n]+a[n];g=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&m^f&m);l=k;k=j;j=p;p=h+r|0;h=m;m=f;f=e;e=r+g|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+m|0;b[3]=b[3]+h|0;b[4]=b[4]+p|0;b[5]=b[5]+j|0;b[6]=b[6]+k|0;b[7]=b[7]+l|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes; -d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=g.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=g._createHelper(f);s.HmacSHA256=g._createHmacHelper(f)})(Math); diff --git a/radicale_web/web/infcloud/lib/spectrum.js b/radicale_web/web/infcloud/lib/spectrum.js deleted file mode 100644 index 4b99b07..0000000 --- a/radicale_web/web/infcloud/lib/spectrum.js +++ /dev/null @@ -1,2027 +0,0 @@ -// Spectrum Colorpicker v1.2.0 -// https://github.com/bgrins/spectrum -// Author: Brian Grinstead -// License: MIT - -(function (window, $, undefined) { - var defaultOpts = { - - // Callbacks - beforeShow: noop, - move: noop, - change: noop, - show: noop, - hide: noop, - - // Options - color: false, - flat: false, - showInput: false, - allowEmpty: false, - showButtons: true, - clickoutFiresChange: false, - showInitial: false, - showPalette: false, - showPaletteOnly: false, - showSelectionPalette: true, - localStorageKey: false, - appendTo: "body", - maxSelectionSize: 7, - cancelText: "cancel", - chooseText: "choose", - preferredFormat: false, - className: "", - showAlpha: false, - theme: "sp-light", - palette: ['fff', '000'], - selectionPalette: [], - disabled: false - }, - spectrums = [], - IE = !!/msie/i.exec( window.navigator.userAgent ), - rgbaSupport = (function() { - function contains( str, substr ) { - return !!~('' + str).indexOf(substr); - } - - var elem = document.createElement('div'); - var style = elem.style; - style.cssText = 'background-color:rgba(0,0,0,.5)'; - return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla'); - })(), - inputTypeColorSupport = (function() { - var colorInput = $("<input type='color' value='!' />")[0]; - return colorInput.type === "color" && colorInput.value !== "!"; - })(), - replaceInput = [ - "<div class='sp-replacer'>", - "<div class='sp-preview'><div class='sp-preview-inner'></div></div>", - "<div class='sp-dd'>▼</div>", - "</div>" - ].join(''), - markup = (function () { - - // IE does not support gradients with multiple stops, so we need to simulate - // that for the rainbow slider with 8 divs that each have a single gradient - var gradientFix = ""; - if (IE) { - for (var i = 1; i <= 6; i++) { - gradientFix += "<div class='sp-" + i + "'></div>"; - } - } - - return [ - "<div class='sp-container sp-hidden'>", - "<div class='sp-arrow'></div>", - "<div class='sp-palette-container'>", - "<div class='sp-palette sp-thumb sp-cf'></div>", - "</div>", - "<div class='sp-picker-container'>", - "<div class='sp-top sp-cf'>", - "<div class='sp-fill'></div>", - "<div class='sp-top-inner'>", - "<div class='sp-color'>", - "<div class='sp-sat'>", - "<div class='sp-val'>", - "<div class='sp-dragger'></div>", - "</div>", - "</div>", - "</div>", - "<div class='sp-clear sp-clear-display' title='Clear Color Selection'>", - "</div>", - "<div class='sp-hue'>", - "<div class='sp-slider'></div>", - gradientFix, - "</div>", - "</div>", - "<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>", - "</div>", - "<div class='sp-input-container sp-cf'>", - "<input class='sp-input' type='text' spellcheck='false' />", - "<img data-type='invalidColor' style='margin-top: 1px;margin-left: -20px;display: inline;vertical-align: top;' src='images/error_b.svg' alt='invalid'>", - "</div>", - "<div class='sp-initial sp-thumb sp-cf'></div>", - "<div class='sp-button-container sp-cf'>", - "<input type='button' class='sp-choose' />", - "<input type='button' class='sp-cancel' />", - "</div>", - "</div>", - "</div>" - ].join(""); - })(); - - function paletteTemplate (p, color, className) { - var html = []; - for (var i = 0; i < p.length; i++) { - var current = p[i]; - if(current) { - var tiny = tinycolor(current); - var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light"; - c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : ""; - - var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter(); - html.push('<span title="' + tiny.toRgbString() + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>'); - } else { - var cls = 'sp-clear-display'; - html.push('<span title="No Color Selected" data-color="" style="background-color:transparent;" class="' + cls + '"></span>'); - } - } - return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>"; - } - - function hideAll() { - for (var i = 0; i < spectrums.length; i++) { - if (spectrums[i]) { - spectrums[i].hide(); - } - } - } - - function instanceOptions(o, callbackContext) { - var opts = $.extend({}, defaultOpts, o); - opts.callbacks = { - 'move': bind(opts.move, callbackContext), - 'change': bind(opts.change, callbackContext), - 'show': bind(opts.show, callbackContext), - 'hide': bind(opts.hide, callbackContext), - 'beforeShow': bind(opts.beforeShow, callbackContext) - }; - - return opts; - } - - function spectrum(element, o) { - - var opts = instanceOptions(o, element), - flat = opts.flat, - showSelectionPalette = opts.showSelectionPalette, - localStorageKey = opts.localStorageKey, - theme = opts.theme, - callbacks = opts.callbacks, - resize = throttle(reflow, 10), - visible = false, - dragWidth = 0, - dragHeight = 0, - dragHelperHeight = 0, - slideHeight = 0, - slideWidth = 0, - alphaWidth = 0, - alphaSlideHelperWidth = 0, - slideHelperHeight = 0, - currentHue = 0, - currentSaturation = 0, - currentValue = 0, - currentAlpha = 1, - palette = opts.palette.slice(0), - paletteArray = $.isArray(palette[0]) ? palette : [palette], - selectionPalette = opts.selectionPalette.slice(0), - maxSelectionSize = opts.maxSelectionSize, - draggingClass = "sp-dragging", - shiftMovementDirection = null; - - var doc = element.ownerDocument, - body = doc.body, - boundElement = $(element), - disabled = false, - container = $(markup, doc).addClass(theme), - dragger = container.find(".sp-color"), - dragHelper = container.find(".sp-dragger"), - slider = container.find(".sp-hue"), - slideHelper = container.find(".sp-slider"), - alphaSliderInner = container.find(".sp-alpha-inner"), - alphaSlider = container.find(".sp-alpha"), - alphaSlideHelper = container.find(".sp-alpha-handle"), - textInput = container.find(".sp-input"), - invalidImage = container.find('img[data-type="invalidColor"]'), - paletteContainer = container.find(".sp-palette"), - initialColorContainer = container.find(".sp-initial"), - cancelButton = container.find(".sp-cancel"), - clearButton = container.find(".sp-clear"), - chooseButton = container.find(".sp-choose"), - isInput = boundElement.is("input"), - isInputTypeColor = isInput && inputTypeColorSupport && boundElement.attr("type") === "color", - shouldReplace = isInput && !flat, - replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className) : $([]), - offsetElement = (shouldReplace) ? replacer : boundElement, - previewElement = replacer.find(".sp-preview-inner"), - initialColor = opts.color || (isInput && boundElement.val()), - colorOnShow = false, - preferredFormat = opts.preferredFormat, - currentPreferredFormat = preferredFormat, - clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange, - isEmpty = !initialColor, - allowEmpty = opts.allowEmpty && !isInputTypeColor; - - function applyOptions() { - - if (opts.showPaletteOnly) { - opts.showPalette = true; - } - - container.toggleClass("sp-flat", flat); - container.toggleClass("sp-input-disabled", !opts.showInput); - container.toggleClass("sp-alpha-enabled", opts.showAlpha); - container.toggleClass("sp-clear-enabled", allowEmpty); - container.toggleClass("sp-buttons-disabled", !opts.showButtons); - container.toggleClass("sp-palette-disabled", !opts.showPalette); - container.toggleClass("sp-palette-only", opts.showPaletteOnly); - container.toggleClass("sp-initial-disabled", !opts.showInitial); - container.addClass(opts.className); - - reflow(); - } - - function initialize() { - - if (IE) { - container.find("*:not(input)").attr("unselectable", "on"); - } - - applyOptions(); - - if (shouldReplace) { - boundElement.after(replacer).hide(); - } - - if (!allowEmpty) { - clearButton.hide(); - } - - if (flat) { - boundElement.after(container).hide(); - } - else { - - var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo); - if (appendTo.length !== 1) { - appendTo = $("body"); - } - - appendTo.append(container); - } - - if (localStorageKey && window.localStorage) { - - // Migrate old palettes over to new format. May want to remove this eventually. - try { - var oldPalette = window.localStorage[localStorageKey].split(",#"); - if (oldPalette.length > 1) { - delete window.localStorage[localStorageKey]; - $.each(oldPalette, function(i, c) { - addColorToSelectionPalette(c); - }); - } - } - catch(e) { } - - try { - selectionPalette = window.localStorage[localStorageKey].split(";"); - } - catch (e) { } - } - - offsetElement.bind("click.spectrum touchstart.spectrum", function (e) { - if (!disabled) { - toggle(); - } - - e.stopPropagation(); - - if (!$(e.target).is("input")) { - e.preventDefault(); - } - }); - - if(boundElement.is(":disabled") || (opts.disabled === true)) { - disable(); - } - - // Prevent clicks from bubbling up to document. This would cause it to be hidden. - container.click(stopPropagation); - - // Handle user typed input - textInput.change(setFromTextInput); - textInput.bind("paste", function () { - setTimeout(setFromTextInput, 1); - }); - textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } }); - - cancelButton.val(opts.cancelText); - cancelButton.bind("click.spectrum", function (e) { - e.stopPropagation(); - e.preventDefault(); - hide("cancel"); - }); - - - clearButton.bind("click.spectrum", function (e) { - e.stopPropagation(); - e.preventDefault(); - - isEmpty = true; - - move(); - if(flat) { - //for the flat style, this is a change event - updateOriginalInput(true); - } - }); - - - chooseButton.val(opts.chooseText); - chooseButton.bind("click.spectrum", function (e) { - e.stopPropagation(); - e.preventDefault(); - - if (isValid()) { - updateOriginalInput(true); - hide(); - } - }); - - draggable(alphaSlider, function (dragX, dragY, e) { - currentAlpha = (dragX / alphaWidth); - isEmpty = false; - if (e.shiftKey) { - currentAlpha = Math.round(currentAlpha * 10) / 10; - } - - move(); - }); - - draggable(slider, function (dragX, dragY) { - currentHue = parseFloat(dragY / slideHeight); - isEmpty = false; - move(); - }, dragStart, dragStop); - - draggable(dragger, function (dragX, dragY, e) { - - // shift+drag should snap the movement to either the x or y axis. - if (!e.shiftKey) { - shiftMovementDirection = null; - } - else if (!shiftMovementDirection) { - var oldDragX = currentSaturation * dragWidth; - var oldDragY = dragHeight - (currentValue * dragHeight); - var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY); - - shiftMovementDirection = furtherFromX ? "x" : "y"; - } - - var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x"; - var setValue = !shiftMovementDirection || shiftMovementDirection === "y"; - - if (setSaturation) { - currentSaturation = parseFloat(dragX / dragWidth); - } - if (setValue) { - currentValue = parseFloat((dragHeight - dragY) / dragHeight); - } - - isEmpty = false; - - move(); - - }, dragStart, dragStop); - - if (!!initialColor) { - set(initialColor); - - // In case color was black - update the preview UI and set the format - // since the set function will not run (default color is black). - updateUI(); - currentPreferredFormat = preferredFormat || tinycolor(initialColor).format; - - addColorToSelectionPalette(initialColor); - } - else { - updateUI(); - } - - if (flat) { - show(); - } - - function palletElementClick(e) { - if (e.data && e.data.ignore) { - set($(this).data("color")); - move(); - } - else { - set($(this).data("color")); - updateOriginalInput(true); - move(); - hide(); - } - - return false; - } - - var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum"; - paletteContainer.delegate(".sp-thumb-el", paletteEvent, palletElementClick); - initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, palletElementClick); - } - - function addColorToSelectionPalette(color) { - if (showSelectionPalette) { - var colorRgb = tinycolor(color).toRgbString(); - if ($.inArray(colorRgb, selectionPalette) === -1) { - selectionPalette.push(colorRgb); - while(selectionPalette.length > maxSelectionSize) { - selectionPalette.shift(); - } - } - - if (localStorageKey && window.localStorage) { - try { - window.localStorage[localStorageKey] = selectionPalette.join(";"); - } - catch(e) { } - } - } - } - - function getUniqueSelectionPalette() { - var unique = []; - var p = selectionPalette; - var paletteLookup = {}; - var rgb; - - if (opts.showPalette) { - - for (var i = 0; i < paletteArray.length; i++) { - for (var j = 0; j < paletteArray[i].length; j++) { - rgb = tinycolor(paletteArray[i][j]).toRgbString(); - paletteLookup[rgb] = true; - } - } - - for (i = 0; i < p.length; i++) { - rgb = tinycolor(p[i]).toRgbString(); - - if (!paletteLookup.hasOwnProperty(rgb)) { - unique.push(p[i]); - paletteLookup[rgb] = true; - } - } - } - - return unique.reverse().slice(0, opts.maxSelectionSize); - } - - function drawPalette() { - - var currentColor = get(); - - var html = $.map(paletteArray, function (palette, i) { - return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i); - }); - - if (selectionPalette) { - html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection")); - } - - paletteContainer.html(html.join("")); - } - - function drawInitial() { - if (opts.showInitial) { - var initial = colorOnShow; - var current = get(); - initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial")); - } - } - - function dragStart() { - if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) { - reflow(); - } - container.addClass(draggingClass); - shiftMovementDirection = null; - } - - function dragStop() { - container.removeClass(draggingClass); - } - - function setFromTextInput() { - - var value = textInput.val(); - - if ((value === null || value === "") && allowEmpty) { - set(null); - } - else { - var tiny = tinycolor(value); - if (tiny.ok) { - set(tiny); - } - else { - textInput.addClass("sp-validation-error"); - invalidImage.css('display','inline'); - } - } - } - - function toggle() { - if (visible) { - hide(); - } - else { - show(); - } - } - - function show() { - var event = $.Event('beforeShow.spectrum'); - - if (visible) { - reflow(); - return; - } - - boundElement.trigger(event, [ get() ]); - - if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) { - return; - } - - hideAll(); - visible = true; - - $(doc).bind("click.spectrum", hide); - $(window).bind("resize.spectrum", resize); - replacer.addClass("sp-active"); - container.removeClass("sp-hidden"); - - if (opts.showPalette) { - drawPalette(); - } - reflow(); - updateUI(); - - colorOnShow = get(); - - drawInitial(); - callbacks.show(colorOnShow); - boundElement.trigger('show.spectrum', [ colorOnShow ]); - } - - function hide(e) { - - // Return on right click - if (e && e.type == "click" && e.button == 2) { return; } - - // Return if hiding is unnecessary - if (!visible || flat) { return; } - visible = false; - - $(doc).unbind("click.spectrum", hide); - $(window).unbind("resize.spectrum", resize); - - replacer.removeClass("sp-active"); - container.addClass("sp-hidden"); - - var colorHasChanged = !tinycolor.equals(get(), colorOnShow); - - if (colorHasChanged) { - if (clickoutFiresChange && e !== "cancel") { - updateOriginalInput(true); - } - else { - revert(); - } - } - - callbacks.hide(get()); - boundElement.trigger('hide.spectrum', [ get() ]); - } - - function revert() { - set(colorOnShow, true); - } - - function set(color, ignoreFormatChange) { - if (tinycolor.equals(color, get())) { - return; - } - - var newColor; - if (!color && allowEmpty) { - isEmpty = true; - } else { - isEmpty = false; - newColor = tinycolor(color); - var newHsv = newColor.toHsv(); - - currentHue = (newHsv.h % 360) / 360; - currentSaturation = newHsv.s; - currentValue = newHsv.v; - currentAlpha = newHsv.a; - } - updateUI(); - - if (newColor && newColor.ok && !ignoreFormatChange) { - currentPreferredFormat = preferredFormat || newColor.format; - } - } - - function get(opts) { - opts = opts || { }; - - if (allowEmpty && isEmpty) { - return null; - } - - return tinycolor.fromRatio({ - h: currentHue, - s: currentSaturation, - v: currentValue, - a: Math.round(currentAlpha * 100) / 100 - }, { format: opts.format || currentPreferredFormat }); - } - - function isValid() { - return !textInput.hasClass("sp-validation-error"); - } - - function move() { - updateUI(); - - callbacks.move(get()); - boundElement.trigger('move.spectrum', [ get() ]); - } - - function updateUI() { - - textInput.removeClass("sp-validation-error"); - invalidImage.css('display','none'); - - updateHelperLocations(); - - // Update dragger background color (gradients take care of saturation and value). - var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 }); - dragger.css("background-color", flatColor.toHexString()); - - // Get a format that alpha will be included in (hex and names ignore alpha) - var format = currentPreferredFormat; - if (currentAlpha < 1) { - if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") { - format = "rgb"; - } - } - - var realColor = get({ format: format }), - displayColor = ''; - - //reset background info for preview element - previewElement.removeClass("sp-clear-display"); - previewElement.css('background-color', 'transparent'); - - if (!realColor && allowEmpty) { - // Update the replaced elements background with icon indicating no color selection - previewElement.addClass("sp-clear-display"); - } - else { - var realHex = realColor.toHexString(), - realRgb = realColor.toRgbString(); - - // Update the replaced elements background color (with actual selected color) - if (rgbaSupport || realColor.alpha === 1) { - previewElement.css("background-color", realRgb); - } - else { - previewElement.css("background-color", "transparent"); - previewElement.css("filter", realColor.toFilter()); - } - - if (opts.showAlpha) { - var rgb = realColor.toRgb(); - rgb.a = 0; - var realAlpha = tinycolor(rgb).toRgbString(); - var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")"; - - if (IE) { - alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex)); - } - else { - alphaSliderInner.css("background", "-webkit-" + gradient); - alphaSliderInner.css("background", "-moz-" + gradient); - alphaSliderInner.css("background", "-ms-" + gradient); - alphaSliderInner.css("background", gradient); - } - } - - displayColor = realColor.toString(format); - } - // Update the text entry input as it changes happen - if (opts.showInput) { - textInput.val(displayColor); - } - - if (opts.showPalette) { - drawPalette(); - } - - drawInitial(); - } - - function updateHelperLocations() { - var s = currentSaturation; - var v = currentValue; - - if(allowEmpty && isEmpty) { - //if selected color is empty, hide the helpers - alphaSlideHelper.hide(); - slideHelper.hide(); - dragHelper.hide(); - } - else { - //make sure helpers are visible - alphaSlideHelper.show(); - slideHelper.show(); - dragHelper.show(); - - // Where to show the little circle in that displays your current selected color - var dragX = s * dragWidth; - var dragY = dragHeight - (v * dragHeight); - dragX = Math.max( - -dragHelperHeight, - Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight) - ); - dragY = Math.max( - -dragHelperHeight, - Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight) - ); - dragHelper.css({ - "top": dragY, - "left": dragX - }); - - var alphaX = currentAlpha * alphaWidth; - alphaSlideHelper.css({ - "left": alphaX - (alphaSlideHelperWidth / 2) - }); - - // Where to show the bar that displays your current selected hue - var slideY = (currentHue) * slideHeight; - slideHelper.css({ - "top": slideY - slideHelperHeight - }); - } - } - - function updateOriginalInput(fireCallback) { - var color = get(), - displayColor = '', - hasChanged = !tinycolor.equals(color, colorOnShow); - - if(color) { - displayColor = color.toString(currentPreferredFormat); - // Update the selection palette with the current color - addColorToSelectionPalette(color); - } - - if (isInput) { - boundElement.val(displayColor); - } - - colorOnShow = color; - - if (fireCallback && hasChanged) { - callbacks.change(color); - boundElement.trigger('change', [ color ]); - } - } - - function reflow() { - dragWidth = dragger.width(); - dragHeight = dragger.height(); - dragHelperHeight = dragHelper.height(); - slideWidth = slider.width(); - slideHeight = slider.height(); - slideHelperHeight = slideHelper.height(); - alphaWidth = alphaSlider.width(); - alphaSlideHelperWidth = alphaSlideHelper.width(); - - if (!flat) { - container.css("position", "absolute"); - container.offset(getOffset(container, offsetElement)); - } - - updateHelperLocations(); - } - - function destroy() { - boundElement.show(); - offsetElement.unbind("click.spectrum touchstart.spectrum"); - container.remove(); - replacer.remove(); - spectrums[spect.id] = null; - } - - function option(optionName, optionValue) { - if(optionName === undefined) { - return $.extend({}, opts); - } - if(optionValue === undefined) { - return opts[optionName]; - } - opts[optionName] = optionValue; - applyOptions(); - - if(optionName=='showInput') - { - // Get a format that alpha will be included in (hex and names ignore alpha) - var format = currentPreferredFormat; - if (currentAlpha < 1) { - if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") { - format = "rgb"; - } - } - - textInput.val(get({ format: format }).toString(format)); - } - } - - function enable() { - disabled = false; - boundElement.attr("disabled", false); - offsetElement.removeClass("sp-disabled"); - } - - function disable() { - hide(); - disabled = true; - boundElement.attr("disabled", true); - offsetElement.addClass("sp-disabled"); - } - - initialize(); - - var spect = { - show: show, - hide: hide, - toggle: toggle, - reflow: reflow, - option: option, - enable: enable, - disable: disable, - set: function (c) { - set(c); - updateOriginalInput(); - }, - get: get, - destroy: destroy, - container: container - }; - - spect.id = spectrums.push(spect) - 1; - - return spect; - } - - /** - * checkOffset - get the offset below/above and left/right element depending on screen position - * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js - */ - function getOffset(picker, input) { - var extraY = 0; - var dpWidth = picker.outerWidth(); - var dpHeight = picker.outerHeight(); - var inputHeight = input.outerHeight(); - var doc = picker[0].ownerDocument; - var docElem = doc.documentElement; - var viewWidth = docElem.clientWidth + $(doc).scrollLeft(); - var viewHeight = docElem.clientHeight + $(doc).scrollTop(); - var offset = input.offset(); - offset.top += inputHeight; - - offset.left -= - Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? - Math.abs(offset.left + dpWidth - viewWidth) : 0); - - offset.top -= - Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? - Math.abs(dpHeight + inputHeight - extraY) : extraY)); - - return offset; - } - - /** - * noop - do nothing - */ - function noop() { - - } - - /** - * stopPropagation - makes the code only doing this a little easier to read in line - */ - function stopPropagation(e) { - e.stopPropagation(); - } - - /** - * Create a function bound to a given object - * Thanks to underscore.js - */ - function bind(func, obj) { - var slice = Array.prototype.slice; - var args = slice.call(arguments, 2); - return function () { - return func.apply(obj, args.concat(slice.call(arguments))); - }; - } - - /** - * Lightweight drag helper. Handles containment within the element, so that - * when dragging, the x is within [0,element.width] and y is within [0,element.height] - */ - function draggable(element, onmove, onstart, onstop) { - onmove = onmove || function () { }; - onstart = onstart || function () { }; - onstop = onstop || function () { }; - var doc = element.ownerDocument || document; - var dragging = false; - var offset = {}; - var maxHeight = 0; - var maxWidth = 0; - var hasTouch = ('ontouchstart' in window); - - var duringDragEvents = {}; - duringDragEvents["selectstart"] = prevent; - duringDragEvents["dragstart"] = prevent; - duringDragEvents["touchmove mousemove"] = move; - duringDragEvents["touchend mouseup"] = stop; - - function prevent(e) { - if (e.stopPropagation) { - e.stopPropagation(); - } - if (e.preventDefault) { - e.preventDefault(); - } - e.returnValue = false; - } - - function move(e) { - if (dragging) { - // Mouseup happened outside of window - if (IE && document.documentMode < 9 && !e.button) { - return stop(); - } - - var touches = e.originalEvent.touches; - var pageX = touches ? touches[0].pageX : e.pageX; - var pageY = touches ? touches[0].pageY : e.pageY; - - var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth)); - var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight)); - - if (hasTouch) { - // Stop scrolling in iOS - prevent(e); - } - - onmove.apply(element, [dragX, dragY, e]); - } - } - function start(e) { - var rightclick = (e.which) ? (e.which == 3) : (e.button == 2); - var touches = e.originalEvent.touches; - - if (!rightclick && !dragging) { - if (onstart.apply(element, arguments) !== false) { - dragging = true; - maxHeight = $(element).height(); - maxWidth = $(element).width(); - offset = $(element).offset(); - - $(doc).bind(duringDragEvents); - $(doc.body).addClass("sp-dragging"); - - if (!hasTouch) { - move(e); - } - - prevent(e); - } - } - } - function stop() { - if (dragging) { - $(doc).unbind(duringDragEvents); - $(doc.body).removeClass("sp-dragging"); - onstop.apply(element, arguments); - } - dragging = false; - } - - $(element).bind("touchstart mousedown", start); - } - - function throttle(func, wait, debounce) { - var timeout; - return function () { - var context = this, args = arguments; - var throttler = function () { - timeout = null; - func.apply(context, args); - }; - if (debounce) clearTimeout(timeout); - if (debounce || !timeout) timeout = setTimeout(throttler, wait); - }; - } - - - function log(){/* jshint -W021 */if(window.console){if(Function.prototype.bind)log=Function.prototype.bind.call(console.log,console);else log=function(){Function.prototype.apply.call(console.log,console,arguments);};log.apply(this,arguments);}} - - /** - * Define a jQuery plugin - */ - var dataID = "spectrum.id"; - $.fn.spectrum = function (opts, extra) { - - if (typeof opts == "string") { - - var returnValue = this; - var args = Array.prototype.slice.call( arguments, 1 ); - - this.each(function () { - var spect = spectrums[$(this).data(dataID)]; - if (spect) { - - var method = spect[opts]; - if (!method) { - throw new Error( "Spectrum: no such method: '" + opts + "'" ); - } - - if (opts == "get") { - returnValue = spect.get(); - } - else if (opts == "container") { - returnValue = spect.container; - } - else if (opts == "option") { - returnValue = spect.option.apply(spect, args); - } - else if (opts == "destroy") { - spect.destroy(); - $(this).removeData(dataID); - } - else { - method.apply(spect, args); - } - } - }); - - return returnValue; - } - - // Initializing a new instance of spectrum - return this.spectrum("destroy").each(function () { - var spect = spectrum(this, opts); - $(this).data(dataID, spect.id); - }); - }; - - $.fn.spectrum.load = true; - $.fn.spectrum.loadOpts = {}; - $.fn.spectrum.draggable = draggable; - $.fn.spectrum.defaults = defaultOpts; - - $.spectrum = { }; - $.spectrum.localization = { }; - $.spectrum.palettes = { }; - - $.fn.spectrum.processNativeColorInputs = function () { - if (!inputTypeColorSupport) { - $("input[type=color]").spectrum({ - preferredFormat: "hex6" - }); - } - }; - - // TinyColor v0.9.16 - // https://github.com/bgrins/TinyColor - // 2013-08-10, Brian Grinstead, MIT License - - (function() { - - var trimLeft = /^[\s,#]+/, - trimRight = /\s+$/, - tinyCounter = 0, - math = Math, - mathRound = math.round, - mathMin = math.min, - mathMax = math.max, - mathRandom = math.random; - - function tinycolor (color, opts) { - - color = (color) ? color : ''; - opts = opts || { }; - - // If input is already a tinycolor, return itself - if (typeof color == "object" && color.hasOwnProperty("_tc_id")) { - return color; - } - - var rgb = inputToRGB(color); - var r = rgb.r, - g = rgb.g, - b = rgb.b, - a = rgb.a, - roundA = mathRound(100*a) / 100, - format = opts.format || rgb.format; - - // Don't let the range of [0,255] come back in [0,1]. - // Potentially lose a little bit of precision here, but will fix issues where - // .5 gets interpreted as half of the total, instead of half of 1 - // If it was supposed to be 128, this was already taken care of by `inputToRgb` - if (r < 1) { r = mathRound(r); } - if (g < 1) { g = mathRound(g); } - if (b < 1) { b = mathRound(b); } - - return { - ok: rgb.ok, - format: format, - _tc_id: tinyCounter++, - alpha: a, - getAlpha: function() { - return a; - }, - setAlpha: function(value) { - a = boundAlpha(value); - roundA = mathRound(100*a) / 100; - }, - toHsv: function() { - var hsv = rgbToHsv(r, g, b); - return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: a }; - }, - toHsvString: function() { - var hsv = rgbToHsv(r, g, b); - var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100); - return (a == 1) ? - "hsv(" + h + ", " + s + "%, " + v + "%)" : - "hsva(" + h + ", " + s + "%, " + v + "%, "+ roundA + ")"; - }, - toHsl: function() { - var hsl = rgbToHsl(r, g, b); - return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: a }; - }, - toHslString: function() { - var hsl = rgbToHsl(r, g, b); - var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100); - return (a == 1) ? - "hsl(" + h + ", " + s + "%, " + l + "%)" : - "hsla(" + h + ", " + s + "%, " + l + "%, "+ roundA + ")"; - }, - toHex: function(allow3Char) { - return rgbToHex(r, g, b, allow3Char); - }, - toHexString: function(allow3Char) { - return '#' + rgbToHex(r, g, b, allow3Char); - }, - toRgb: function() { - return { r: mathRound(r), g: mathRound(g), b: mathRound(b), a: a }; - }, - toRgbString: function() { - return (a == 1) ? - "rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" : - "rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + roundA + ")"; - }, - toPercentageRgb: function() { - return { r: mathRound(bound01(r, 255) * 100) + "%", g: mathRound(bound01(g, 255) * 100) + "%", b: mathRound(bound01(b, 255) * 100) + "%", a: a }; - }, - toPercentageRgbString: function() { - return (a == 1) ? - "rgb(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%)" : - "rgba(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%, " + roundA + ")"; - }, - toName: function() { - if (a === 0) { - return "transparent"; - } - - return hexNames[rgbToHex(r, g, b, true)] || false; - }, - toFilter: function(secondColor) { - var hex = rgbToHex(r, g, b); - var secondHex = hex; - var alphaHex = Math.round(parseFloat(a) * 255).toString(16); - var secondAlphaHex = alphaHex; - var gradientType = opts && opts.gradientType ? "GradientType = 1, " : ""; - - if (secondColor) { - var s = tinycolor(secondColor); - secondHex = s.toHex(); - secondAlphaHex = Math.round(parseFloat(s.alpha) * 255).toString(16); - } - - return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr=#" + pad2(alphaHex) + hex + ",endColorstr=#" + pad2(secondAlphaHex) + secondHex + ")"; - }, - toString: function(format) { - var formatSet = !!format; - format = format || this.format; - - var formattedString = false; - var hasAlphaAndFormatNotSet = !formatSet && a < 1 && a > 0; - var formatWithAlpha = hasAlphaAndFormatNotSet && (format === "hex" || format === "hex6" || format === "hex3" || format === "name"); - - if (format === "rgb") { - formattedString = this.toRgbString(); - } - if (format === "prgb") { - formattedString = this.toPercentageRgbString(); - } - if (format === "hex" || format === "hex6") { - formattedString = this.toHexString(); - } - if (format === "hex3") { - formattedString = this.toHexString(true); - } - if (format === "name") { - formattedString = this.toName(); - } - if (format === "hsl") { - formattedString = this.toHslString(); - } - if (format === "hsv") { - formattedString = this.toHsvString(); - } - - if (formatWithAlpha) { - return this.toRgbString(); - } - - return formattedString || this.toHexString(); - } - }; - } - - // If input is an object, force 1 into "1.0" to handle ratios properly - // String input requires "1.0" as input, so 1 will be treated as 1 - tinycolor.fromRatio = function(color, opts) { - if (typeof color == "object") { - var newColor = {}; - for (var i in color) { - if (color.hasOwnProperty(i)) { - if (i === "a") { - newColor[i] = color[i]; - } - else { - newColor[i] = convertToPercentage(color[i]); - } - } - } - color = newColor; - } - - return tinycolor(color, opts); - }; - - // Given a string or object, convert that input to RGB - // Possible string inputs: - // - // "red" - // "#f00" or "f00" - // "#ff0000" or "ff0000" - // "rgb 255 0 0" or "rgb (255, 0, 0)" - // "rgb 1.0 0 0" or "rgb (1, 0, 0)" - // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" - // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" - // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" - // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" - // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" - // - function inputToRGB(color) { - - var rgb = { r: 0, g: 0, b: 0 }; - var a = 1; - var ok = false; - var format = false; - - if (typeof color == "string") { - color = stringInputToObject(color); - } - - if (typeof color == "object") { - if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) { - rgb = rgbToRgb(color.r, color.g, color.b); - ok = true; - format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"; - } - else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) { - color.s = convertToPercentage(color.s); - color.v = convertToPercentage(color.v); - rgb = hsvToRgb(color.h, color.s, color.v); - ok = true; - format = "hsv"; - } - else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) { - color.s = convertToPercentage(color.s); - color.l = convertToPercentage(color.l); - rgb = hslToRgb(color.h, color.s, color.l); - ok = true; - format = "hsl"; - } - - if (color.hasOwnProperty("a")) { - a = color.a; - } - } - - a = boundAlpha(a); - - return { - ok: ok, - format: color.format || format, - r: mathMin(255, mathMax(rgb.r, 0)), - g: mathMin(255, mathMax(rgb.g, 0)), - b: mathMin(255, mathMax(rgb.b, 0)), - a: a - }; - } - - - // Conversion Functions - // -------------------- - - // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from: - // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript> - - // `rgbToRgb` - // Handle bounds / percentage checking to conform to CSS color spec - // <http://www.w3.org/TR/css3-color/> - // *Assumes:* r, g, b in [0, 255] or [0, 1] - // *Returns:* { r, g, b } in [0, 255] - function rgbToRgb(r, g, b){ - return { - r: bound01(r, 255) * 255, - g: bound01(g, 255) * 255, - b: bound01(b, 255) * 255 - }; - } - - // `rgbToHsl` - // Converts an RGB color value to HSL. - // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1] - // *Returns:* { h, s, l } in [0,1] - function rgbToHsl(r, g, b) { - - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - - var max = mathMax(r, g, b), min = mathMin(r, g, b); - var h, s, l = (max + min) / 2; - - if(max == min) { - h = s = 0; // achromatic - } - else { - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch(max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - - h /= 6; - } - - return { h: h, s: s, l: l }; - } - - // `hslToRgb` - // Converts an HSL color value to RGB. - // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] - // *Returns:* { r, g, b } in the set [0, 255] - function hslToRgb(h, s, l) { - var r, g, b; - - h = bound01(h, 360); - s = bound01(s, 100); - l = bound01(l, 100); - - function hue2rgb(p, q, t) { - if(t < 0) t += 1; - if(t > 1) t -= 1; - if(t < 1/6) return p + (q - p) * 6 * t; - if(t < 1/2) return q; - if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; - return p; - } - - if(s === 0) { - r = g = b = l; // achromatic - } - else { - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hue2rgb(p, q, h + 1/3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1/3); - } - - return { r: r * 255, g: g * 255, b: b * 255 }; - } - - // `rgbToHsv` - // Converts an RGB color value to HSV - // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] - // *Returns:* { h, s, v } in [0,1] - function rgbToHsv(r, g, b) { - - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - - var max = mathMax(r, g, b), min = mathMin(r, g, b); - var h, s, v = max; - - var d = max - min; - s = max === 0 ? 0 : d / max; - - if(max == min) { - h = 0; // achromatic - } - else { - switch(max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - return { h: h, s: s, v: v }; - } - - // `hsvToRgb` - // Converts an HSV color value to RGB. - // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] - // *Returns:* { r, g, b } in the set [0, 255] - function hsvToRgb(h, s, v) { - - h = bound01(h, 360) * 6; - s = bound01(s, 100); - v = bound01(v, 100); - - var i = math.floor(h), - f = h - i, - p = v * (1 - s), - q = v * (1 - f * s), - t = v * (1 - (1 - f) * s), - mod = i % 6, - r = [v, q, p, p, t, v][mod], - g = [t, v, v, q, p, p][mod], - b = [p, p, t, v, v, q][mod]; - - return { r: r * 255, g: g * 255, b: b * 255 }; - } - - // `rgbToHex` - // Converts an RGB color to hex - // Assumes r, g, and b are contained in the set [0, 255] - // Returns a 3 or 6 character hex - function rgbToHex(r, g, b, allow3Char) { - - var hex = [ - pad2(mathRound(r).toString(16)), - pad2(mathRound(g).toString(16)), - pad2(mathRound(b).toString(16)) - ]; - - // Return a 3 character hex if possible - if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { - return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); - } - - return hex.join(""); - } - - // `equals` - // Can be called with any tinycolor input - tinycolor.equals = function (color1, color2) { - if (!color1 || !color2) { return false; } - return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); - }; - tinycolor.random = function() { - return tinycolor.fromRatio({ - r: mathRandom(), - g: mathRandom(), - b: mathRandom() - }); - }; - - - // Modification Functions - // ---------------------- - // Thanks to less.js for some of the basics here - // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js> - - tinycolor.desaturate = function (color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.s -= amount / 100; - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); - }; - tinycolor.saturate = function (color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.s += amount / 100; - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); - }; - tinycolor.greyscale = function(color) { - return tinycolor.desaturate(color, 100); - }; - tinycolor.lighten = function(color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.l += amount / 100; - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); - }; - tinycolor.darken = function (color, amount) { - amount = (amount === 0) ? 0 : (amount || 10); - var hsl = tinycolor(color).toHsl(); - hsl.l -= amount / 100; - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); - }; - tinycolor.complement = function(color) { - var hsl = tinycolor(color).toHsl(); - hsl.h = (hsl.h + 180) % 360; - return tinycolor(hsl); - }; - - - // Combination Functions - // --------------------- - // Thanks to jQuery xColor for some of the ideas behind these - // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js> - - tinycolor.triad = function(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [ - tinycolor(color), - tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l }) - ]; - }; - tinycolor.tetrad = function(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [ - tinycolor(color), - tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }), - tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l }) - ]; - }; - tinycolor.splitcomplement = function(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [ - tinycolor(color), - tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}), - tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l}) - ]; - }; - tinycolor.analogous = function(color, results, slices) { - results = results || 6; - slices = slices || 30; - - var hsl = tinycolor(color).toHsl(); - var part = 360 / slices; - var ret = [tinycolor(color)]; - - for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) { - hsl.h = (hsl.h + part) % 360; - ret.push(tinycolor(hsl)); - } - return ret; - }; - tinycolor.monochromatic = function(color, results) { - results = results || 6; - var hsv = tinycolor(color).toHsv(); - var h = hsv.h, s = hsv.s, v = hsv.v; - var ret = []; - var modification = 1 / results; - - while (results--) { - ret.push(tinycolor({ h: h, s: s, v: v})); - v = (v + modification) % 1; - } - - return ret; - }; - - - // Readability Functions - // --------------------- - // <http://www.w3.org/TR/AERT#color-contrast> - - // `readability` - // Analyze the 2 colors and returns an object with the following properties: - // `brightness`: difference in brightness between the two colors - // `color`: difference in color/hue between the two colors - tinycolor.readability = function(color1, color2) { - var a = tinycolor(color1).toRgb(); - var b = tinycolor(color2).toRgb(); - var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000; - var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000; - var colorDiff = ( - Math.max(a.r, b.r) - Math.min(a.r, b.r) + - Math.max(a.g, b.g) - Math.min(a.g, b.g) + - Math.max(a.b, b.b) - Math.min(a.b, b.b) - ); - - return { - brightness: Math.abs(brightnessA - brightnessB), - color: colorDiff - }; - }; - - // `readable` - // http://www.w3.org/TR/AERT#color-contrast - // Ensure that foreground and background color combinations provide sufficient contrast. - // *Example* - // tinycolor.readable("#000", "#111") => false - tinycolor.readable = function(color1, color2) { - var readability = tinycolor.readability(color1, color2); - return readability.brightness > 125 && readability.color > 500; - }; - - // `mostReadable` - // Given a base color and a list of possible foreground or background - // colors for that base, returns the most readable color. - // *Example* - // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000" - tinycolor.mostReadable = function(baseColor, colorList) { - var bestColor = null; - var bestScore = 0; - var bestIsReadable = false; - for (var i=0; i < colorList.length; i++) { - - // We normalize both around the "acceptable" breaking point, - // but rank brightness constrast higher than hue. - - var readability = tinycolor.readability(baseColor, colorList[i]); - var readable = readability.brightness > 125 && readability.color > 500; - var score = 3 * (readability.brightness / 125) + (readability.color / 500); - - if ((readable && ! bestIsReadable) || - (readable && bestIsReadable && score > bestScore) || - ((! readable) && (! bestIsReadable) && score > bestScore)) { - bestIsReadable = readable; - bestScore = score; - bestColor = tinycolor(colorList[i]); - } - } - return bestColor; - }; - - - // Big List of Colors - // ------------------ - // <http://www.w3.org/TR/css3-color/#svg-color> - var names = tinycolor.names = { - aliceblue: "f0f8ff", - antiquewhite: "faebd7", - aqua: "0ff", - aquamarine: "7fffd4", - azure: "f0ffff", - beige: "f5f5dc", - bisque: "ffe4c4", - black: "000", - blanchedalmond: "ffebcd", - blue: "00f", - blueviolet: "8a2be2", - brown: "a52a2a", - burlywood: "deb887", - burntsienna: "ea7e5d", - cadetblue: "5f9ea0", - chartreuse: "7fff00", - chocolate: "d2691e", - coral: "ff7f50", - cornflowerblue: "6495ed", - cornsilk: "fff8dc", - crimson: "dc143c", - cyan: "0ff", - darkblue: "00008b", - darkcyan: "008b8b", - darkgoldenrod: "b8860b", - darkgray: "a9a9a9", - darkgreen: "006400", - darkgrey: "a9a9a9", - darkkhaki: "bdb76b", - darkmagenta: "8b008b", - darkolivegreen: "556b2f", - darkorange: "ff8c00", - darkorchid: "9932cc", - darkred: "8b0000", - darksalmon: "e9967a", - darkseagreen: "8fbc8f", - darkslateblue: "483d8b", - darkslategray: "2f4f4f", - darkslategrey: "2f4f4f", - darkturquoise: "00ced1", - darkviolet: "9400d3", - deeppink: "ff1493", - deepskyblue: "00bfff", - dimgray: "696969", - dimgrey: "696969", - dodgerblue: "1e90ff", - firebrick: "b22222", - floralwhite: "fffaf0", - forestgreen: "228b22", - fuchsia: "f0f", - gainsboro: "dcdcdc", - ghostwhite: "f8f8ff", - gold: "ffd700", - goldenrod: "daa520", - gray: "808080", - green: "008000", - greenyellow: "adff2f", - grey: "808080", - honeydew: "f0fff0", - hotpink: "ff69b4", - indianred: "cd5c5c", - indigo: "4b0082", - ivory: "fffff0", - khaki: "f0e68c", - lavender: "e6e6fa", - lavenderblush: "fff0f5", - lawngreen: "7cfc00", - lemonchiffon: "fffacd", - lightblue: "add8e6", - lightcoral: "f08080", - lightcyan: "e0ffff", - lightgoldenrodyellow: "fafad2", - lightgray: "d3d3d3", - lightgreen: "90ee90", - lightgrey: "d3d3d3", - lightpink: "ffb6c1", - lightsalmon: "ffa07a", - lightseagreen: "20b2aa", - lightskyblue: "87cefa", - lightslategray: "789", - lightslategrey: "789", - lightsteelblue: "b0c4de", - lightyellow: "ffffe0", - lime: "0f0", - limegreen: "32cd32", - linen: "faf0e6", - magenta: "f0f", - maroon: "800000", - mediumaquamarine: "66cdaa", - mediumblue: "0000cd", - mediumorchid: "ba55d3", - mediumpurple: "9370db", - mediumseagreen: "3cb371", - mediumslateblue: "7b68ee", - mediumspringgreen: "00fa9a", - mediumturquoise: "48d1cc", - mediumvioletred: "c71585", - midnightblue: "191970", - mintcream: "f5fffa", - mistyrose: "ffe4e1", - moccasin: "ffe4b5", - navajowhite: "ffdead", - navy: "000080", - oldlace: "fdf5e6", - olive: "808000", - olivedrab: "6b8e23", - orange: "ffa500", - orangered: "ff4500", - orchid: "da70d6", - palegoldenrod: "eee8aa", - palegreen: "98fb98", - paleturquoise: "afeeee", - palevioletred: "db7093", - papayawhip: "ffefd5", - peachpuff: "ffdab9", - peru: "cd853f", - pink: "ffc0cb", - plum: "dda0dd", - powderblue: "b0e0e6", - purple: "800080", - red: "f00", - rosybrown: "bc8f8f", - royalblue: "4169e1", - saddlebrown: "8b4513", - salmon: "fa8072", - sandybrown: "f4a460", - seagreen: "2e8b57", - seashell: "fff5ee", - sienna: "a0522d", - silver: "c0c0c0", - skyblue: "87ceeb", - slateblue: "6a5acd", - slategray: "708090", - slategrey: "708090", - snow: "fffafa", - springgreen: "00ff7f", - steelblue: "4682b4", - tan: "d2b48c", - teal: "008080", - thistle: "d8bfd8", - tomato: "ff6347", - turquoise: "40e0d0", - violet: "ee82ee", - wheat: "f5deb3", - white: "fff", - whitesmoke: "f5f5f5", - yellow: "ff0", - yellowgreen: "9acd32" - }; - - // Make it easy to access colors via `hexNames[hex]` - var hexNames = tinycolor.hexNames = flip(names); - - - // Utilities - // --------- - - // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }` - function flip(o) { - var flipped = { }; - for (var i in o) { - if (o.hasOwnProperty(i)) { - flipped[o[i]] = i; - } - } - return flipped; - } - - // Return a valid alpha value [0,1] with all invalid values being set to 1 - function boundAlpha(a) { - a = parseFloat(a); - - if (isNaN(a) || a < 0 || a > 1) { - a = 1; - } - - return a; - } - - // Take input from [0, n] and return it as [0, 1] - function bound01(n, max) { - if (isOnePointZero(n)) { n = "100%"; } - - var processPercent = isPercentage(n); - n = mathMin(max, mathMax(0, parseFloat(n))); - - // Automatically convert percentage into number - if (processPercent) { - n = parseInt(n * max, 10) / 100; - } - - // Handle floating point rounding errors - if ((math.abs(n - max) < 0.000001)) { - return 1; - } - - // Convert into [0, 1] range if it isn't already - return (n % max) / parseFloat(max); - } - - // Force a number between 0 and 1 - function clamp01(val) { - return mathMin(1, mathMax(0, val)); - } - - // Parse an integer into hex - function parseHex(val) { - return parseInt(val, 16); - } - - // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 - // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0> - function isOnePointZero(n) { - return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1; - } - - // Check to see if string passed in is a percentage - function isPercentage(n) { - return typeof n === "string" && n.indexOf('%') != -1; - } - - // Force a hex value to have 2 characters - function pad2(c) { - return c.length == 1 ? '0' + c : '' + c; - } - - // Replace a decimal with it's percentage value - function convertToPercentage(n) { - if (n <= 1) { - n = (n * 100) + "%"; - } - - return n; - } - - var matchers = (function() { - - // <http://www.w3.org/TR/css3-values/#integers> - var CSS_INTEGER = "[-\\+]?\\d+%?"; - - // <http://www.w3.org/TR/css3-values/#number-value> - var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; - - // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome. - var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; - - // Actual matching. - // Parentheses and commas are optional, but not required. - // Whitespace can take the place of commas or opening paren - var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - - return { - rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), - rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), - hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), - hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), - hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), - hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, - hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ - }; - })(); - - // `stringInputToObject` - // Permissive string parsing. Take in a number of formats, and output an object - // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}` - function stringInputToObject(color) { - - color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase(); - var named = false; - if (names[color]) { - color = names[color]; - named = true; - } - else if (color == 'transparent') { - return { r: 0, g: 0, b: 0, a: 0, format: "name" }; - } - - // Try to match string input using regular expressions. - // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] - // Just return an object and let the conversion functions handle that. - // This way the result will be the same whether the tinycolor is initialized with string or object. - var match; - if ((match = matchers.rgb.exec(color))) { - return { r: match[1], g: match[2], b: match[3] }; - } - if ((match = matchers.rgba.exec(color))) { - return { r: match[1], g: match[2], b: match[3], a: match[4] }; - } - if ((match = matchers.hsl.exec(color))) { - return { h: match[1], s: match[2], l: match[3] }; - } - if ((match = matchers.hsla.exec(color))) { - return { h: match[1], s: match[2], l: match[3], a: match[4] }; - } - if ((match = matchers.hsv.exec(color))) { - return { h: match[1], s: match[2], v: match[3] }; - } - if ((match = matchers.hex6.exec(color))) { - return { - r: parseHex(match[1]), - g: parseHex(match[2]), - b: parseHex(match[3]), - format: named ? "name" : "hex" - }; - } - if ((match = matchers.hex3.exec(color))) { - return { - r: parseHex(match[1] + '' + match[1]), - g: parseHex(match[2] + '' + match[2]), - b: parseHex(match[3] + '' + match[3]), - format: named ? "name" : "hex" - }; - } - - return false; - } - - // Expose tinycolor to window, does not need to run in non-browser context. - window.tinycolor = tinycolor; - - })(); - - - $(function () { - if ($.fn.spectrum.load) { - $.fn.spectrum.processNativeColorInputs(); - } - }); - -})(window, jQuery); |