{"version":3,"file":"../clndr.js","sources":["clndr.js"],"sourcesContent":["/**\n * ~ CLNDR v1.4.7 ~\n * ==============================================\n * https://github.com/kylestetz/CLNDR\n * ==============================================\n * Created by kyle stetz (github.com/kylestetz)\n * & available under the MIT license\n * http://opensource.org/licenses/mit-license.php\n * ==============================================\n *\n * This is the fully-commented development version of CLNDR.\n * For the production version, check out clndr.min.js\n * at https://github.com/kylestetz/CLNDR\n *\n * This work is based on the\n * jQuery lightweight plugin boilerplate\n * Original author: @ajpiano\n * Further changes, comments: @addyosmani\n * Licensed under the MIT license\n */\n(function (factory) {\n // Multiple loading methods are supported depending on\n // what is available globally. While moment is loaded\n // here, the instance can be passed in at config time.\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define(['jquery', 'moment'], factory);\n }\n else if (typeof exports === 'object') {\n // Node/CommonJS\n factory(require('jquery'), require('moment'));\n }\n else {\n // Browser globals\n factory(jQuery, moment);\n }\n}(function ($, moment) {\n // Namespace\n var pluginName = 'clndr';\n\n // This is the default calendar template. This can be overridden.\n var clndrTemplate =\n \"
\" +\n \"
\" +\n \"previous\" +\n \"
\" +\n \"
<%= month %> <%= year %>
\" +\n \"
\" +\n \"next\" +\n \"
\" +\n \"
\" +\n \"\" +\n \"\" +\n \"\" +\n \"<% for(var i = 0; i < daysOfTheWeek.length; i++) { %>\" +\n \"\" +\n \"<% } %>\" +\n \"\" +\n \"\" +\n \"\" +\n \"<% for(var i = 0; i < numberOfRows; i++){ %>\" +\n \"\" +\n \"<% for(var j = 0; j < 7; j++){ %>\" +\n \"<% var d = j + i * 7; %>\" +\n \"\" +\n \"<% } %>\" +\n \"\" +\n \"<% } %>\" +\n \"\" +\n \"
<%= daysOfTheWeek[i] %>
\" +\n \"
<%= days[d].day %>
\" +\n \"
\";\n\n // Defaults used throughout the application, see docs.\n var defaults = {\n events: [],\n ready: null,\n extras: null,\n render: null,\n moment: null,\n weekOffset: 0,\n constraints: null,\n forceSixRows: null,\n selectedDate: null,\n doneRendering: null,\n daysOfTheWeek: null,\n multiDayEvents: null,\n startWithMonth: null,\n dateParameter: 'date',\n template: clndrTemplate,\n showAdjacentMonths: true,\n trackSelectedDate: false,\n adjacentDaysChangeMonth: false,\n ignoreInactiveDaysInSelection: null,\n lengthOfTime: {\n days: null,\n interval: 1,\n months: null\n },\n clickEvents: {\n click: null,\n today: null,\n nextYear: null,\n nextMonth: null,\n nextInterval: null,\n previousYear: null,\n onYearChange: null,\n previousMonth: null,\n onMonthChange: null,\n previousInterval: null,\n onIntervalChange: null\n },\n targets: {\n day: 'day',\n empty: 'empty',\n nextButton: 'clndr-next-button',\n todayButton: 'clndr-today-button',\n previousButton: 'clndr-previous-button',\n nextYearButton: 'clndr-next-year-button',\n previousYearButton: 'clndr-previous-year-button'\n },\n classes: {\n past: \"past\",\n today: \"today\",\n event: \"event\",\n inactive: \"inactive\",\n selected: \"selected\",\n lastMonth: \"last-month\",\n nextMonth: \"next-month\",\n adjacentMonth: \"adjacent-month\"\n },\n };\n\n /**\n * The actual plugin constructor.\n * Parses the events and lengthOfTime options to build a calendar of day\n * objects containing event information from the events array.\n */\n function Clndr(element, options) {\n var dayDiff;\n var constraintEnd;\n var constraintStart;\n\n this.element = element;\n\n // Merge the default options with user-provided options\n this.options = $.extend(true, {}, defaults, options);\n\n // Check if moment was passed in as a dependency\n if (this.options.moment) {\n moment = this.options.moment;\n }\n\n // Boolean values used to log if any contraints are met\n this.constraints = {\n next: true,\n today: true,\n previous: true,\n nextYear: true,\n previousYear: true\n };\n\n // If there are events, we should run them through our\n // addMomentObjectToEvents function which will add a date object that\n // we can use to make life easier. This is only necessarywhen events\n // are provided on instantiation, since our setEvents function uses\n // addMomentObjectToEvents.\n if (this.options.events.length) {\n if (this.options.multiDayEvents) {\n this.options.events =\n this.addMultiDayMomentObjectsToEvents(this.options.events);\n } else {\n this.options.events =\n this.addMomentObjectToEvents(this.options.events);\n }\n }\n\n // This used to be a place where we'd figure out the current month,\n // but since we want to open up support for arbitrary lengths of time\n // we're going to store the current range in addition to the current\n // month.\n if (this.options.lengthOfTime.months || this.options.lengthOfTime.days) {\n // We want to establish intervalStart and intervalEnd, which will\n // keep track of our boundaries. Let's look at the possibilities...\n if (this.options.lengthOfTime.months) {\n // Gonna go right ahead and annihilate any chance for bugs here\n this.options.lengthOfTime.days = null;\n\n // The length is specified in months. Is there a start date?\n if (this.options.lengthOfTime.startDate) {\n this.intervalStart =\n moment(this.options.lengthOfTime.startDate)\n .startOf('month');\n } else if (this.options.startWithMonth) {\n this.intervalStart =\n moment(this.options.startWithMonth)\n .startOf('month');\n } else {\n this.intervalStart = moment().startOf('month');\n }\n\n // Subtract a day so that we are at the end of the interval. We\n // always want intervalEnd to be inclusive.\n this.intervalEnd = moment(this.intervalStart)\n .add(this.options.lengthOfTime.months, 'months')\n .subtract(1, 'days');\n this.month = this.intervalStart.clone();\n }\n else if (this.options.lengthOfTime.days) {\n // The length is specified in days. Start date?\n if (this.options.lengthOfTime.startDate) {\n this.intervalStart =\n moment(this.options.lengthOfTime.startDate)\n .startOf('day');\n } else {\n this.intervalStart = moment().weekday(0).startOf('day');\n }\n\n this.intervalEnd = moment(this.intervalStart)\n .add(this.options.lengthOfTime.days - 1, 'days')\n .endOf('day');\n this.month = this.intervalStart.clone();\n }\n // No length of time specified so we're going to default into using the\n // current month as the time period.\n } else {\n this.month = moment().startOf('month');\n this.intervalStart = moment(this.month);\n this.intervalEnd = moment(this.month).endOf('month');\n }\n\n if (this.options.startWithMonth) {\n this.month = moment(this.options.startWithMonth).startOf('month');\n this.intervalStart = moment(this.month);\n this.intervalEnd = (this.options.lengthOfTime.days)\n ? moment(this.month)\n .add(this.options.lengthOfTime.days - 1, 'days')\n .endOf('day')\n : moment(this.month).endOf('month');\n }\n\n // If we've got constraints set, make sure the interval is within them.\n if (this.options.constraints) {\n // First check if the startDate exists & is later than now.\n if (this.options.constraints.startDate) {\n constraintStart = moment(this.options.constraints.startDate);\n\n // We need to handle the constraints differently for weekly\n // calendars vs. monthly calendars.\n if (this.options.lengthOfTime.days) {\n if (this.intervalStart.isBefore(constraintStart, 'week')) {\n this.intervalStart = constraintStart.startOf('week');\n }\n\n // If the new interval period is less than the desired length\n // of time, or before the starting interval, then correct it.\n dayDiff = this.intervalStart.diff(this.intervalEnd, 'days');\n\n if (dayDiff < this.options.lengthOfTime.days\n || this.intervalEnd.isBefore(this.intervalStart))\n {\n this.intervalEnd = moment(this.intervalStart)\n .add(this.options.lengthOfTime.days - 1, 'days')\n .endOf('day');\n this.month = this.intervalStart.clone();\n }\n }\n else {\n if (this.intervalStart.isBefore(constraintStart, 'month')) {\n // Try to preserve the date by moving only the month.\n this.intervalStart\n .set('month', constraintStart.month())\n .set('year', constraintStart.year());\n this.month\n .set('month', constraintStart.month())\n .set('year', constraintStart.year());\n }\n\n // Check if the ending interval is earlier than now.\n if (this.intervalEnd.isBefore(constraintStart, 'month')) {\n this.intervalEnd\n .set('month', constraintStart.month())\n .set('year', constraintStart.year());\n }\n }\n }\n\n // Make sure the intervalEnd is before the endDate.\n if (this.options.constraints.endDate) {\n constraintEnd = moment(this.options.constraints.endDate);\n\n // We need to handle the constraints differently for weekly\n // calendars vs. monthly calendars.\n if (this.options.lengthOfTime.days) {\n // The starting interval is after our ending constraint.\n if (this.intervalStart.isAfter(constraintEnd, 'week')) {\n this.intervalStart = moment(constraintEnd)\n .endOf('week')\n .subtract(this.options.lengthOfTime.days - 1, 'days')\n .startOf('day');\n this.intervalEnd = moment(constraintEnd)\n .endOf('week');\n this.month = this.intervalStart.clone();\n }\n }\n else {\n if (this.intervalEnd.isAfter(constraintEnd, 'month')) {\n this.intervalEnd\n .set('month', constraintEnd.month())\n .set('year', constraintEnd.year());\n this.month\n .set('month', constraintEnd.month())\n .set('year', constraintEnd.year());\n }\n\n // Check if the starting interval is later than the ending.\n if (this.intervalStart.isAfter(constraintEnd, 'month')) {\n this.intervalStart\n .set('month', constraintEnd.month())\n .set('year', constraintEnd.year());\n }\n }\n }\n }\n\n this._defaults = defaults;\n this._name = pluginName;\n\n // Some first-time initialization -> day of the week offset, template\n // compiling, making and storing some elements we'll need later, and\n // event handling for the controller.\n this.init();\n }\n\n /**\n * Calendar initialization.\n * Sets up the days of the week, the rendering function, binds all of the\n * events to the rendered calendar, and then stores the node locally.\n */\n Clndr.prototype.init = function () {\n // Create the days of the week using moment's current language setting\n this.daysOfTheWeek = this.options.daysOfTheWeek || [];\n\n if (!this.options.daysOfTheWeek) {\n this.daysOfTheWeek = [];\n\n for (var i = 0; i < 7; i++) {\n this.daysOfTheWeek.push(\n moment().weekday(i).format('dd').charAt(0));\n }\n }\n\n // Shuffle the week if there's an offset\n if (this.options.weekOffset) {\n this.daysOfTheWeek = this.shiftWeekdayLabels(this.options.weekOffset);\n }\n\n // Quick and dirty test to make sure rendering is possible.\n if (!$.isFunction(this.options.render)) {\n this.options.render = null;\n\n if (typeof _ === 'undefined') {\n throw new Error(\n \"Underscore was not found. Please include underscore.js \" +\n \"OR provide a custom render function.\");\n } else {\n // We're just going ahead and using underscore here if no\n // render method has been supplied.\n this.compiledClndrTemplate = _.template(this.options.template);\n }\n }\n\n // Create the parent element that will hold the plugin and save it\n // for later\n $(this.element).html(\"
\");\n this.calendarContainer = $('.clndr', this.element);\n\n // Attach event handlers for clicks on buttons/cells\n this.bindEvents();\n\n // Do a normal render of the calendar template\n this.render();\n\n // If a ready callback has been provided, call it.\n if (this.options.ready) {\n this.options.ready.apply(this, []);\n }\n };\n\n Clndr.prototype.shiftWeekdayLabels = function (offset) {\n var days = this.daysOfTheWeek;\n\n for (var i = 0; i < offset; i++) {\n days.push(days.shift());\n }\n\n return days;\n };\n\n /**\n * This is where the magic happens. Given a starting date and ending date,\n * an array of calendarDay objects is constructed that contains appropriate\n * events and classes depending on the circumstance.\n */\n Clndr.prototype.createDaysObject = function (startDate, endDate) {\n // This array will hold numbers for the entire grid (even the blank\n // spaces).\n var daysArray = [],\n date = startDate.clone(),\n lengthOfInterval = endDate.diff(startDate, 'days'),\n startOfLastMonth, endOfLastMonth, startOfNextMonth,\n endOfNextMonth, diff, dateIterator;\n\n // This is a helper object so that days can resolve their classes\n // correctly. Don't use it for anything please.\n this._currentIntervalStart = startDate.clone();\n\n // Filter the events list (if it exists) to events that are happening\n // last month, this month and next month (within the current grid view).\n this.eventsLastMonth = [];\n this.eventsNextMonth = [];\n this.eventsThisInterval = [];\n\n // Event parsing\n if (this.options.events.length) {\n // Here are the only two cases where we don't get an event in our\n // interval:\n // startDate | endDate | e.start | e.end\n // e.start | e.end | startDate | endDate\n this.eventsThisInterval = $(this.options.events).filter(\n function () {\n var afterEnd = this._clndrStartDateObject.isAfter(endDate),\n beforeStart = this._clndrEndDateObject.isBefore(startDate);\n\n if (beforeStart || afterEnd) {\n return false;\n } else {\n return true;\n }\n }).toArray();\n\n if (this.options.showAdjacentMonths) {\n startOfLastMonth = startDate.clone()\n .subtract(1, 'months')\n .startOf('month');\n endOfLastMonth = startOfLastMonth.clone().endOf('month');\n startOfNextMonth = endDate.clone()\n .add(1, 'months')\n .startOf('month');\n endOfNextMonth = startOfNextMonth.clone().endOf('month');\n\n this.eventsLastMonth = $(this.options.events).filter(\n function () {\n var beforeStart = this._clndrEndDateObject\n .isBefore(startOfLastMonth);\n var afterEnd = this._clndrStartDateObject\n .isAfter(endOfLastMonth);\n\n if (beforeStart || afterEnd) {\n return false;\n } else {\n return true;\n }\n }).toArray();\n\n this.eventsNextMonth = $(this.options.events).filter(\n function () {\n var beforeStart = this._clndrEndDateObject\n .isBefore(startOfNextMonth);\n var afterEnd = this._clndrStartDateObject\n .isAfter(endOfNextMonth);\n\n if (beforeStart || afterEnd) {\n return false;\n } else {\n return true;\n }\n }).toArray();\n }\n }\n\n // If diff is greater than 0, we'll have to fill in last days of the\n // previous month to account for the empty boxes in the grid. We also\n // need to take into account the weekOffset parameter. None of this\n // needs to happen if the interval is being specified in days rather\n // than months.\n if (!this.options.lengthOfTime.days) {\n diff = date.weekday() - this.options.weekOffset;\n\n if (diff < 0) {\n diff += 7;\n }\n\n if (this.options.showAdjacentMonths) {\n for (var i = 1; i <= diff; i++) {\n var day = moment([\n startDate.year(),\n startDate.month(),\n i\n ]).subtract(diff, 'days');\n daysArray.push(\n this.createDayObject(\n day,\n this.eventsLastMonth\n ));\n }\n } else {\n for (var i = 0; i < diff; i++) {\n daysArray.push(\n this.calendarDay({\n classes: this.options.targets.empty +\n \" \" + this.options.classes.lastMonth\n }));\n }\n }\n }\n\n // Now we push all of the days in the interval\n dateIterator = startDate.clone();\n\n while (dateIterator.isBefore(endDate) || dateIterator.isSame(endDate, 'day')) {\n daysArray.push(\n this.createDayObject(\n dateIterator.clone(),\n this.eventsThisInterval\n ));\n dateIterator.add(1, 'days');\n }\n\n // ...and if there are any trailing blank boxes, fill those in with the\n // next month first days. Again, we can ignore this if the interval is\n // specified in days.\n if (!this.options.lengthOfTime.days) {\n while (daysArray.length % 7 !== 0) {\n if (this.options.showAdjacentMonths) {\n daysArray.push(\n this.createDayObject(\n dateIterator.clone(),\n this.eventsNextMonth\n ));\n } else {\n daysArray.push(\n this.calendarDay({\n classes: this.options.targets.empty + \" \" +\n this.options.classes.nextMonth\n }));\n }\n dateIterator.add(1, 'days');\n }\n }\n\n // If we want to force six rows of calendar, now's our Last Chance to\n // add another row. If the 42 seems explicit it's because we're\n // creating a 7-row grid and 6 rows of 7 is always 42!\n if (this.options.forceSixRows && daysArray.length !== 42) {\n while (daysArray.length < 42) {\n if (this.options.showAdjacentMonths) {\n daysArray.push(\n this.createDayObject(\n dateIterator.clone(),\n this.eventsNextMonth\n ));\n dateIterator.add(1, 'days');\n } else {\n daysArray.push(\n this.calendarDay({\n classes: this.options.targets.empty + \" \" +\n this.options.classes.nextMonth\n }));\n }\n }\n }\n\n return daysArray;\n };\n\n Clndr.prototype.createDayObject = function (day, monthEvents) {\n var j = 0,\n self = this,\n now = moment(),\n eventsToday = [],\n extraClasses = \"\",\n properties = {\n isToday: false,\n isInactive: false,\n isAdjacentMonth: false\n },\n startMoment, endMoment, selectedMoment;\n\n // Validate moment date\n if (!day.isValid() && day.hasOwnProperty('_d') && day._d != undefined) {\n day = moment(day._d);\n }\n\n for (j; j < monthEvents.length; j++) {\n // Keep in mind that the events here already passed the month/year\n // test. Now all we have to compare is the moment.date(), which\n // returns the day of the month.\n var start = monthEvents[j]._clndrStartDateObject,\n end = monthEvents[j]._clndrEndDateObject;\n // If today is the same day as start or is after the start, and\n // if today is the same day as the end or before the end ...\n // woohoo semantics!\n if ( (day.isSame(start, 'day') || day.isAfter(start, 'day'))\n && (day.isSame(end, 'day') || day.isBefore(end, 'day')) )\n {\n eventsToday.push( monthEvents[j] );\n }\n }\n\n if (now.format(\"YYYY-MM-DD\") == day.format(\"YYYY-MM-DD\")) {\n extraClasses += (\" \" + this.options.classes.today);\n properties.isToday = true;\n }\n\n if (day.isBefore(now, 'day')) {\n extraClasses += (\" \" + this.options.classes.past);\n }\n\n if (eventsToday.length) {\n extraClasses += (\" \" + this.options.classes.event);\n }\n\n if (!this.options.lengthOfTime.days) {\n if (this._currentIntervalStart.month() > day.month()) {\n extraClasses += (\" \" + this.options.classes.adjacentMonth);\n properties.isAdjacentMonth = true;\n\n this._currentIntervalStart.year() === day.year()\n ? extraClasses += (\" \" + this.options.classes.lastMonth)\n : extraClasses += (\" \" + this.options.classes.nextMonth);\n }\n else if (this._currentIntervalStart.month() < day.month()) {\n extraClasses += (\" \" + this.options.classes.adjacentMonth);\n properties.isAdjacentMonth = true;\n\n this._currentIntervalStart.year() === day.year()\n ? extraClasses += (\" \" + this.options.classes.nextMonth)\n : extraClasses += (\" \" + this.options.classes.lastMonth);\n }\n }\n\n // If there are constraints, we need to add the inactive class to the\n // days outside of them\n if (this.options.constraints) {\n endMoment = moment(this.options.constraints.endDate);\n startMoment = moment(this.options.constraints.startDate);\n\n if (this.options.constraints.startDate && day.isBefore(startMoment)) {\n extraClasses += (\" \" + this.options.classes.inactive);\n properties.isInactive = true;\n }\n\n if (this.options.constraints.endDate && day.isAfter(endMoment)) {\n extraClasses += (\" \" + this.options.classes.inactive);\n properties.isInactive = true;\n }\n }\n\n // Validate moment date\n if (!day.isValid() && day.hasOwnProperty('_d') && day._d != undefined) {\n day = moment(day._d);\n }\n\n // Check whether the day is \"selected\"\n selectedMoment = moment(this.options.selectedDate);\n\n if (this.options.selectedDate && day.isSame(selectedMoment, 'day')) {\n extraClasses += (\" \" + this.options.classes.selected);\n }\n\n // We're moving away from using IDs in favor of classes, since when\n // using multiple calendars on a page we are technically violating the\n // uniqueness of IDs.\n extraClasses += \" calendar-day-\" + day.format(\"YYYY-MM-DD\");\n // Day of week\n extraClasses += \" calendar-dow-\" + day.weekday();\n\n return this.calendarDay({\n date: day,\n day: day.date(),\n events: eventsToday,\n properties: properties,\n classes: this.options.targets.day + extraClasses\n });\n };\n\n Clndr.prototype.render = function () {\n // Get rid of the previous set of calendar parts. This should handle garbage\n // collection according to jQuery's docs:\n // http://api.jquery.com/empty/\n // To avoid memory leaks, jQuery removes other constructs such as\n // data and event handlers from the child elements before removing\n // the elements themselves.\n var data = {},\n end = null,\n start = null,\n oneYearFromEnd = this.intervalEnd.clone().add(1, 'years'),\n oneYearAgo = this.intervalStart.clone().subtract(1, 'years'),\n days, months, currentMonth, eventsThisInterval,\n numberOfRows;\n this.calendarContainer.empty();\n\n if (this.options.lengthOfTime.days) {\n days = this.createDaysObject(\n this.intervalStart.clone(),\n this.intervalEnd.clone());\n data = {\n days: days,\n months: [],\n year: null,\n month: null,\n eventsLastMonth: [],\n eventsNextMonth: [],\n eventsThisMonth: [],\n extras: this.options.extras,\n daysOfTheWeek: this.daysOfTheWeek,\n intervalEnd: this.intervalEnd.clone(),\n numberOfRows: Math.ceil(days.length / 7),\n intervalStart: this.intervalStart.clone(),\n eventsThisInterval: this.eventsThisInterval\n };\n }\n else if (this.options.lengthOfTime.months) {\n months = [];\n numberOfRows = 0;\n eventsThisInterval = [];\n\n for (i = 0; i < this.options.lengthOfTime.months; i++) {\n var currentIntervalStart = this.intervalStart\n .clone()\n .add(i, 'months');\n var currentIntervalEnd = currentIntervalStart\n .clone()\n .endOf('month');\n var days = this.createDaysObject(\n currentIntervalStart,\n currentIntervalEnd);\n // Save events processed for each month into a master array of\n // events for this interval\n eventsThisInterval.push(this.eventsThisInterval);\n months.push({\n days: days,\n month: currentIntervalStart\n });\n }\n\n // Get the total number of rows across all months\n for (i = 0; i < months.length; i++) {\n numberOfRows += Math.ceil(months[i].days.length / 7);\n }\n\n data = {\n days: [],\n year: null,\n month: null,\n months: months,\n eventsThisMonth: [],\n numberOfRows: numberOfRows,\n extras: this.options.extras,\n intervalEnd: this.intervalEnd,\n intervalStart: this.intervalStart,\n daysOfTheWeek: this.daysOfTheWeek,\n eventsLastMonth: this.eventsLastMonth,\n eventsNextMonth: this.eventsNextMonth,\n eventsThisInterval: eventsThisInterval,\n };\n }\n else {\n // Get an array of days and blank spaces\n days = this.createDaysObject(\n this.month.clone().startOf('month'),\n this.month.clone().endOf('month'));\n // This is to prevent a scope/naming issue between this.month and\n // data.month\n currentMonth = this.month;\n\n data = {\n days: days,\n months: [],\n intervalEnd: null,\n intervalStart: null,\n year: this.month.year(),\n eventsThisInterval: null,\n extras: this.options.extras,\n month: this.month.format('MMMM'),\n daysOfTheWeek: this.daysOfTheWeek,\n eventsLastMonth: this.eventsLastMonth,\n eventsNextMonth: this.eventsNextMonth,\n numberOfRows: Math.ceil(days.length / 7),\n eventsThisMonth: this.eventsThisInterval\n };\n }\n\n // Render the calendar with the data above & bind events to its\n // elements\n if ( !this.options.render) {\n this.calendarContainer.html(\n this.compiledClndrTemplate(data));\n } else {\n this.calendarContainer.html(\n this.options.render.apply(this, [data]));\n }\n\n // If there are constraints, we need to add the 'inactive' class to\n // the controls.\n if (this.options.constraints) {\n // In the interest of clarity we're just going to remove all\n // inactive classes and re-apply them each render.\n for (var target in this.options.targets) {\n if (target != this.options.targets.day) {\n this.element.find('.' + this.options.targets[target])\n .toggleClass(\n this.options.classes.inactive,\n false);\n }\n }\n\n // Just like the classes we'll set this internal state to true and\n // handle the disabling below.\n for (var i in this.constraints) {\n this.constraints[i] = true;\n }\n\n if (this.options.constraints.startDate) {\n start = moment(this.options.constraints.startDate);\n }\n\n if (this.options.constraints.endDate) {\n end = moment(this.options.constraints.endDate);\n }\n\n // Deal with the month controls first. Do we have room to go back?\n if (start\n && (start.isAfter(this.intervalStart)\n || start.isSame(this.intervalStart, 'day')))\n {\n this.element.find('.' + this.options.targets.previousButton)\n .toggleClass(this.options.classes.inactive, true);\n this.constraints.previous = !this.constraints.previous;\n }\n\n // Do we have room to go forward?\n if (end\n && (end.isBefore(this.intervalEnd)\n || end.isSame(this.intervalEnd, 'day')))\n {\n this.element.find('.' + this.options.targets.nextButton)\n .toggleClass(this.options.classes.inactive, true);\n this.constraints.next = !this.constraints.next;\n }\n\n // What's last year looking like?\n if (start && start.isAfter(oneYearAgo)) {\n this.element.find('.' + this.options.targets.previousYearButton)\n .toggleClass(this.options.classes.inactive, true);\n this.constraints.previousYear = !this.constraints.previousYear;\n }\n\n // How about next year?\n if (end && end.isBefore(oneYearFromEnd)) {\n this.element.find('.' + this.options.targets.nextYearButton)\n .toggleClass(this.options.classes.inactive, true);\n this.constraints.nextYear = !this.constraints.nextYear;\n }\n\n // Today? We could put this in init(), but we want to support the\n // user changing the constraints on a living instance.\n if ( (start && start.isAfter( moment(), 'month' ))\n || (end && end.isBefore( moment(), 'month' )) )\n {\n this.element.find('.' + this.options.targets.today)\n .toggleClass(this.options.classes.inactive, true);\n this.constraints.today = !this.constraints.today;\n }\n }\n\n if (this.options.doneRendering) {\n this.options.doneRendering.apply(this, []);\n }\n };\n\n Clndr.prototype.bindEvents = function () {\n var data = {},\n self = this,\n $container = $(this.element),\n targets = this.options.targets,\n classes = self.options.classes,\n eventType = (this.options.useTouchEvents === true)\n ? 'touchstart'\n : 'click',\n eventName = eventType + '.clndr';\n\n // Make sure we don't already have events\n $container\n .off(eventName, '.' + targets.day)\n .off(eventName, '.' + targets.empty)\n .off(eventName, '.' + targets.nextButton)\n .off(eventName, '.' + targets.todayButton)\n .off(eventName, '.' + targets.previousButton)\n .off(eventName, '.' + targets.nextYearButton)\n .off(eventName, '.' + targets.previousYearButton);\n\n // Target the day elements and give them click events\n $container.on(eventName, '.' + targets.day, function (event) {\n var target,\n $currentTarget = $(event.currentTarget);\n\n if (self.options.clickEvents.click) {\n target = self.buildTargetObject(event.currentTarget, true);\n self.options.clickEvents.click.apply(self, [target]);\n }\n\n // If adjacentDaysChangeMonth is on, we need to change the\n // month here.\n if (self.options.adjacentDaysChangeMonth) {\n if ($currentTarget.is('.' + classes.lastMonth)) {\n self.backActionWithContext(self);\n }\n else if ($currentTarget.is('.' + classes.nextMonth)) {\n self.forwardActionWithContext(self);\n }\n }\n\n // if trackSelectedDate is on, we need to handle click on a new day\n if (self.options.trackSelectedDate) {\n if (self.options.ignoreInactiveDaysInSelection\n && $currentTarget.hasClass(classes.inactive))\n {\n return;\n }\n\n // Remember new selected date\n self.options.selectedDate =\n self.getTargetDateString(event.currentTarget);\n // Handle \"selected\" class. This handles more complex templates\n // that may have the selected elements nested.\n $container.find('.' + classes.selected)\n .removeClass(classes.selected);\n $currentTarget.addClass(classes.selected);\n }\n });\n\n // Target the empty calendar boxes as well\n $container.on(eventName, '.' + targets.empty, function (event) {\n var target,\n $eventTarget = $(event.currentTarget);\n\n if (self.options.clickEvents.click) {\n target = self.buildTargetObject(event.currentTarget, false);\n self.options.clickEvents.click.apply(self, [target]);\n }\n\n if (self.options.adjacentDaysChangeMonth) {\n if ($eventTarget.is('.' + classes.lastMonth)) {\n self.backActionWithContext(self);\n }\n else if ($eventTarget.is('.' + classes.nextMonth)) {\n self.forwardActionWithContext(self);\n }\n }\n });\n\n // Bind the previous, next and today buttons. We pass the current\n // context along with the event so that it can update this instance.\n data = {\n context: this\n };\n\n $container\n .on(eventName, '.' + targets.todayButton, data, this.todayAction)\n .on(eventName, '.' + targets.nextButton, data, this.forwardAction)\n .on(eventName, '.' + targets.previousButton, data, this.backAction)\n .on(eventName, '.' + targets.nextYearButton, data, this.nextYearAction)\n .on(eventName, '.' + targets.previousYearButton, data, this.previousYearAction);\n };\n\n /**\n * If the user provided a click callback we'd like to give them something\n * nice to work with. buildTargetObject takes the DOM element that was\n * clicked and returns an object with the DOM element, events, and the date\n * (if the latter two exist). Currently it is based on the id, however it'd\n * be nice to use a data- attribute in the future.\n */\n Clndr.prototype.buildTargetObject = function (currentTarget, targetWasDay) {\n // This is our default target object, assuming we hit an empty day\n // with no events.\n var target = {\n date: null,\n events: [],\n element: currentTarget\n };\n var dateString, filterFn;\n\n // Did we click on a day or just an empty box?\n if (targetWasDay) {\n dateString = this.getTargetDateString(currentTarget);\n target.date = (dateString)\n ? moment(dateString)\n : null;\n\n // Do we have events?\n if (this.options.events) {\n // Are any of the events happening today?\n if (this.options.multiDayEvents) {\n filterFn = function () {\n var isSameStart = target.date.isSame(\n this._clndrStartDateObject,\n 'day');\n var isAfterStart = target.date.isAfter(\n this._clndrStartDateObject,\n 'day');\n var isSameEnd = target.date.isSame(\n this._clndrEndDateObject,\n 'day');\n var isBeforeEnd = target.date.isBefore(\n this._clndrEndDateObject,\n 'day');\n return (isSameStart || isAfterStart)\n && (isSameEnd || isBeforeEnd);\n };\n }\n else {\n filterFn = function () {\n var startString = this._clndrStartDateObject\n .format('YYYY-MM-DD');\n return startString == dateString;\n };\n }\n\n // Filter the dates down to the ones that match.\n target.events = $.makeArray(\n $(this.options.events).filter(filterFn));\n }\n }\n\n return target;\n };\n\n /**\n * Get moment date object of the date associated with the given target.\n * This method is meant to be called on \".day\" elements.\n */\n Clndr.prototype.getTargetDateString = function (target) {\n // Our identifier is in the list of classNames. Find it!\n var classNameIndex = target.className.indexOf('calendar-day-');\n\n if (classNameIndex !== -1) {\n // Our unique identifier is always 23 characters long.\n // If this feels a little wonky, that's probably because it is.\n // Open to suggestions on how to improve this guy.\n return target.className.substring(\n classNameIndex + 13,\n classNameIndex + 23);\n }\n\n return null;\n };\n\n /**\n * Triggers any applicable events given a change in the calendar's start\n * and end dates. ctx contains the current (changed) start and end date,\n * orig contains the original start and end dates.\n */\n Clndr.prototype.triggerEvents = function (ctx, orig) {\n var timeOpt = ctx.options.lengthOfTime,\n eventsOpt = ctx.options.clickEvents,\n newInt = {\n end: ctx.intervalEnd,\n start: ctx.intervalStart\n },\n intervalArg = [\n moment(ctx.intervalStart),\n moment(ctx.intervalEnd)\n ],\n monthArg = [moment(ctx.month)],\n nextYear, prevYear, yearChanged,\n nextMonth, prevMonth, monthChanged,\n nextInterval, prevInterval, intervalChanged;\n\n // We want to determine if any of the change conditions have been\n // hit and then trigger our events based off that.\n nextMonth = newInt.start.isAfter( orig.start )\n && (Math.abs(newInt.start.month() - orig.start.month()) == 1\n || orig.start.month() === 11 && newInt.start.month() === 0);\n prevMonth = newInt.start.isBefore( orig.start )\n && (Math.abs(orig.start.month() - newInt.start.month()) == 1\n || orig.start.month() === 0 && newInt.start.month() === 11);\n monthChanged = newInt.start.month() !== orig.start.month()\n || newInt.start.year() !== orig.start.year();\n nextYear = newInt.start.year() - orig.start.year() === 1\n || newInt.end.year() - orig.end.year() === 1;\n prevYear = orig.start.year() - newInt.start.year() === 1\n || orig.end.year() - newInt.end.year() === 1;\n yearChanged = newInt.start.year() !== orig.start.year();\n\n // Only configs with a time period will get the interval change event\n if (timeOpt.days || timeOpt.months) {\n nextInterval = newInt.start.isAfter(orig.start);\n prevInterval = newInt.start.isBefore(orig.start);\n intervalChanged = nextInterval || prevInterval;\n\n if (nextInterval && eventsOpt.nextInterval) {\n eventsOpt.nextInterval.apply(ctx, intervalArg);\n }\n\n if (prevInterval && eventsOpt.previousInterval) {\n eventsOpt.previousInterval.apply(ctx, intervalArg);\n }\n\n if (intervalChanged && eventsOpt.onIntervalChange) {\n eventsOpt.onIntervalChange.apply(ctx, intervalArg);\n }\n }\n // @V2-todo see https://github.com/kylestetz/CLNDR/issues/225\n else {\n if (nextMonth && eventsOpt.nextMonth) {\n eventsOpt.nextMonth.apply(ctx, monthArg);\n }\n\n if (prevMonth && eventsOpt.previousMonth) {\n eventsOpt.previousMonth.apply(ctx, monthArg);\n }\n\n if (monthChanged && eventsOpt.onMonthChange) {\n eventsOpt.onMonthChange.apply(ctx, monthArg);\n }\n\n if (nextYear && eventsOpt.nextYear) {\n eventsOpt.nextYear.apply(ctx, monthArg);\n }\n\n if (prevYear && eventsOpt.previousYear) {\n eventsOpt.previousYear.apply(ctx, monthArg);\n }\n\n if (yearChanged && eventsOpt.onYearChange) {\n eventsOpt.onYearChange.apply(ctx, monthArg);\n }\n }\n };\n\n /**\n * Main action to go backward one period. Other methods call these, like\n * backAction which proxies jQuery events, and backActionWithContext which\n * is an internal method that this library uses.\n */\n Clndr.prototype.back = function (options /*, ctx */) {\n var yearChanged = null,\n ctx = (arguments.length > 1)\n ? arguments[ 1 ]\n : this,\n timeOpt = ctx.options.lengthOfTime,\n defaults = {\n withCallbacks: false\n },\n orig = {\n end: ctx.intervalEnd.clone(),\n start: ctx.intervalStart.clone()\n };\n\n // Extend any options\n options = $.extend(true, {}, defaults, options);\n\n // Before we do anything, check if any constraints are limiting this\n if (!ctx.constraints.previous) {\n return ctx;\n }\n\n if (!timeOpt.days) {\n // Shift the interval by a month (or several months)\n ctx.intervalStart\n .subtract(timeOpt.interval, 'months')\n .startOf('month');\n ctx.intervalEnd = ctx.intervalStart.clone()\n .add(timeOpt.months || timeOpt.interval, 'months')\n .subtract(1, 'days')\n .endOf('month');\n ctx.month = ctx.intervalStart.clone();\n }\n else {\n // Shift the interval in days\n ctx.intervalStart\n .subtract(timeOpt.interval, 'days')\n .startOf('day');\n ctx.intervalEnd = ctx.intervalStart.clone()\n .add(timeOpt.days - 1, 'days')\n .endOf('day');\n // @V2-todo Useless, but consistent with API\n ctx.month = ctx.intervalStart.clone();\n }\n\n ctx.render();\n\n if (options.withCallbacks) {\n ctx.triggerEvents(ctx, orig);\n }\n\n return ctx;\n };\n\n Clndr.prototype.backAction = function (event) {\n var ctx = event.data.context;\n ctx.backActionWithContext(ctx);\n };\n\n Clndr.prototype.backActionWithContext = function (ctx) {\n ctx.back({\n withCallbacks: true\n }, ctx);\n };\n\n Clndr.prototype.previous = function (options) {\n // Alias\n return this.back(options);\n };\n\n /**\n * Main action to go forward one period. Other methods call these, like\n * forwardAction which proxies jQuery events, and backActionWithContext\n * which is an internal method that this library uses.\n */\n Clndr.prototype.forward = function (options /*, ctx */) {\n var ctx = (arguments.length > 1)\n ? arguments[1]\n : this,\n timeOpt = ctx.options.lengthOfTime,\n defaults = {\n withCallbacks: false\n },\n orig = {\n end: ctx.intervalEnd.clone(),\n start: ctx.intervalStart.clone()\n };\n\n // Extend any options\n options = $.extend(true, {}, defaults, options);\n\n // Before we do anything, check if any constraints are limiting this\n if (!ctx.constraints.next) {\n return ctx;\n }\n\n if (ctx.options.lengthOfTime.days) {\n // Shift the interval in days\n ctx.intervalStart\n .add(timeOpt.interval, 'days')\n .startOf('day');\n ctx.intervalEnd = ctx.intervalStart.clone()\n .add(timeOpt.days - 1, 'days')\n .endOf('day');\n // @V2-todo Useless, but consistent with API\n ctx.month = ctx.intervalStart.clone();\n }\n else {\n // Shift the interval by a month (or several months)\n ctx.intervalStart\n .add(timeOpt.interval, 'months')\n .startOf('month');\n ctx.intervalEnd = ctx.intervalStart.clone()\n .add(timeOpt.months || timeOpt.interval, 'months')\n .subtract(1, 'days')\n .endOf('month');\n ctx.month = ctx.intervalStart.clone();\n }\n\n ctx.render();\n\n if (options.withCallbacks) {\n ctx.triggerEvents(ctx, orig);\n }\n\n return ctx;\n };\n\n Clndr.prototype.forwardAction = function (event) {\n var ctx = event.data.context;\n ctx.forwardActionWithContext(ctx);\n };\n\n Clndr.prototype.forwardActionWithContext = function (ctx) {\n ctx.forward({\n withCallbacks: true\n }, ctx);\n };\n\n Clndr.prototype.next = function (options) {\n // Alias\n return this.forward(options);\n };\n\n /**\n * Main action to go back one year.\n */\n Clndr.prototype.previousYear = function (options /*, ctx */) {\n var ctx = (arguments.length > 1)\n ? arguments[1]\n : this,\n defaults = {\n withCallbacks: false\n },\n orig = {\n end: ctx.intervalEnd.clone(),\n start: ctx.intervalStart.clone()\n };\n\n // Extend any options\n options = $.extend(true, {}, defaults, options);\n\n // Before we do anything, check if any constraints are limiting this\n if (!ctx.constraints.previousYear) {\n return ctx;\n }\n\n ctx.month.subtract(1, 'year');\n ctx.intervalStart.subtract(1, 'year');\n ctx.intervalEnd.subtract(1, 'year');\n ctx.render();\n\n if (options.withCallbacks) {\n ctx.triggerEvents(ctx, orig);\n }\n\n return ctx;\n };\n\n Clndr.prototype.previousYearAction = function (event) {\n var ctx = event.data.context;\n ctx.previousYear({\n withCallbacks: true\n }, ctx);\n };\n\n /**\n * Main action to go forward one year.\n */\n Clndr.prototype.nextYear = function (options /*, ctx */) {\n var ctx = (arguments.length > 1)\n ? arguments[1]\n : this,\n defaults = {\n withCallbacks: false\n },\n orig = {\n end: ctx.intervalEnd.clone(),\n start: ctx.intervalStart.clone()\n };\n\n // Extend any options\n options = $.extend(true, {}, defaults, options);\n\n // Before we do anything, check if any constraints are limiting this\n if (!ctx.constraints.nextYear) {\n return ctx;\n }\n\n ctx.month.add(1, 'year');\n ctx.intervalStart.add(1, 'year');\n ctx.intervalEnd.add(1, 'year');\n ctx.render();\n\n if (options.withCallbacks) {\n ctx.triggerEvents(ctx, orig);\n }\n\n return ctx;\n };\n\n Clndr.prototype.nextYearAction = function (event) {\n var ctx = event.data.context;\n ctx.nextYear({\n withCallbacks: true\n }, ctx);\n };\n\n Clndr.prototype.today = function (options /*, ctx */) {\n var ctx = (arguments.length > 1)\n ? arguments[1]\n : this,\n timeOpt = ctx.options.lengthOfTime,\n defaults = {\n withCallbacks: false\n },\n orig = {\n end: ctx.intervalEnd.clone(),\n start: ctx.intervalStart.clone()\n };\n\n // Extend any options\n options = $.extend(true, {}, defaults, options);\n // @V2-todo Only used for legacy month view\n ctx.month = moment().startOf('month');\n\n if (timeOpt.days) {\n // If there was a startDate specified, we should figure out what\n // the weekday is and use that as the starting point of our\n // interval. If not, go to today.weekday(0).\n if (timeOpt.startDate) {\n ctx.intervalStart = moment()\n .weekday(timeOpt.startDate.weekday())\n .startOf('day');\n } else {\n ctx.intervalStart = moment().weekday(0).startOf('day');\n }\n\n ctx.intervalEnd = ctx.intervalStart.clone()\n .add(timeOpt.days - 1, 'days')\n .endOf('day');\n }\n else {\n // Set the intervalStart to this month.\n ctx.intervalStart = moment().startOf('month');\n ctx.intervalEnd = ctx.intervalStart.clone()\n .add(timeOpt.months || timeOpt.interval, 'months')\n .subtract(1, 'days')\n .endOf('month');\n }\n\n // No need to re-render if we didn't change months.\n if (!ctx.intervalStart.isSame(orig.start)\n || !ctx.intervalEnd.isSame(orig.end))\n {\n ctx.render();\n }\n\n // Fire the today event handler regardless of any change\n if (options.withCallbacks) {\n if (ctx.options.clickEvents.today) {\n ctx.options.clickEvents.today.apply(ctx, [moment(ctx.month)]);\n }\n\n ctx.triggerEvents(ctx, orig);\n }\n };\n\n Clndr.prototype.todayAction = function (event) {\n var ctx = event.data.context;\n ctx.today({\n withCallbacks: true\n }, ctx);\n };\n\n /**\n * Changes the month. Accepts 0-11 or a full/partial month name e.g. \"Jan\",\n * \"February\", \"Mar\", etc.\n */\n Clndr.prototype.setMonth = function (newMonth, options) {\n var timeOpt = this.options.lengthOfTime,\n orig = {\n end: this.intervalEnd.clone(),\n start: this.intervalStart.clone()\n };\n\n if (timeOpt.days || timeOpt.months) {\n console.log(\n 'You are using a custom date interval. Use ' +\n 'Clndr.setIntervalStart(startDate) instead.');\n return this;\n }\n\n this.month.month(newMonth);\n this.intervalStart = this.month.clone().startOf('month');\n this.intervalEnd = this.intervalStart.clone().endOf('month');\n this.render();\n\n if (options && options.withCallbacks) {\n this.triggerEvents(this, orig);\n }\n\n return this;\n };\n\n Clndr.prototype.setYear = function (newYear, options) {\n var orig = {\n end: this.intervalEnd.clone(),\n start: this.intervalStart.clone()\n };\n\n this.month.year(newYear);\n this.intervalEnd.year(newYear);\n this.intervalStart.year(newYear);\n this.render();\n\n if (options && options.withCallbacks) {\n this.triggerEvents(this, orig);\n }\n\n return this;\n };\n\n /**\n * Sets the start of the time period according to newDate. newDate can be\n * a string or a moment object.\n */\n Clndr.prototype.setIntervalStart = function (newDate, options) {\n var timeOpt = this.options.lengthOfTime,\n orig = {\n end: this.intervalEnd.clone(),\n start: this.intervalStart.clone()\n };\n\n if (!timeOpt.days && !timeOpt.months) {\n console.log(\n 'You are using a custom date interval. Use ' +\n 'Clndr.setIntervalStart(startDate) instead.');\n return this;\n }\n\n if (timeOpt.days) {\n this.intervalStart = moment(newDate).startOf('day');\n this.intervalEnd = this.intervalStart.clone()\n .add(timeOpt - 1, 'days')\n .endOf('day');\n } else {\n this.intervalStart = moment(newDate).startOf('month');\n this.intervalEnd = this.intervalStart.clone()\n .add(timeOpt.months || timeOpt.interval, 'months')\n .subtract(1, 'days')\n .endOf('month');\n }\n\n this.month = this.intervalStart.clone();\n this.render();\n\n if (options && options.withCallbacks) {\n this.triggerEvents(this, orig);\n }\n\n return this;\n };\n\n /**\n * Overwrites extras in the calendar and triggers a render.\n */\n Clndr.prototype.setExtras = function (extras) {\n this.options.extras = extras;\n this.render();\n return this;\n };\n\n /**\n * Overwrites events in the calendar and triggers a render.\n */\n Clndr.prototype.setEvents = function (events) {\n // Go through each event and add a moment object\n if (this.options.multiDayEvents) {\n this.options.events = this.addMultiDayMomentObjectsToEvents(events);\n } else {\n this.options.events = this.addMomentObjectToEvents(events);\n }\n\n this.render();\n return this;\n };\n\n /**\n * Adds additional events to the calendar and triggers a render.\n */\n Clndr.prototype.addEvents = function (events /*, reRender*/) {\n var reRender = (arguments.length > 1)\n ? arguments[1]\n : true;\n\n // Go through each event and add a moment object\n if (this.options.multiDayEvents) {\n this.options.events = $.merge(\n this.options.events,\n this.addMultiDayMomentObjectsToEvents(events));\n } else {\n this.options.events = $.merge(\n this.options.events,\n this.addMomentObjectToEvents(events));\n }\n\n if (reRender) {\n this.render();\n }\n\n return this;\n };\n\n /**\n * Passes all events through a matching function. Any that pass a truth\n * test will be removed from the calendar's events. This triggers a render.\n */\n Clndr.prototype.removeEvents = function (matchingFn) {\n for (var i = this.options.events.length - 1; i >= 0; i--) {\n if (matchingFn(this.options.events[i]) == true) {\n this.options.events.splice(i, 1);\n }\n }\n\n this.render();\n return this;\n };\n\n Clndr.prototype.addMomentObjectToEvents = function (events) {\n var i = 0,\n self = this;\n\n for (i; i < events.length; i++) {\n // Add the date as both start and end, since it's a single-day\n // event by default\n events[i]._clndrStartDateObject =\n moment(events[i][self.options.dateParameter]);\n events[i]._clndrEndDateObject =\n moment(events[i][self.options.dateParameter]);\n }\n\n return events;\n };\n\n Clndr.prototype.addMultiDayMomentObjectsToEvents = function (events) {\n var i = 0,\n self = this,\n multiEvents = self.options.multiDayEvents;\n\n for (i; i < events.length; i++) {\n var end = events[i][multiEvents.endDate],\n start = events[i][multiEvents.startDate];\n // If we don't find the startDate OR endDate fields, look for\n // singleDay\n if (!end && !start) {\n events[i]._clndrEndDateObject =\n moment(events[i][multiEvents.singleDay]);\n events[i]._clndrStartDateObject =\n moment(events[i][multiEvents.singleDay]);\n }\n // Otherwise use startDate and endDate, or whichever one is present\n else {\n events[i]._clndrEndDateObject = moment(end || start);\n events[i]._clndrStartDateObject = moment(start || end);\n }\n }\n\n return events;\n };\n\n Clndr.prototype.calendarDay = function (options) {\n var defaults = {\n day: \"\",\n date: null,\n events: [],\n classes: this.options.targets.empty\n };\n\n return $.extend({}, defaults, options);\n };\n\n Clndr.prototype.destroy = function () {\n var $container = $(this.calendarContainer);\n $container.parent().data('plugin_clndr', null);\n this.options = defaults;\n $container.empty().remove();\n this.element = null;\n };\n\n $.fn.clndr = function (options) {\n var clndrInstance;\n\n if (this.length > 1) {\n throw new Error(\n \"CLNDR does not support multiple elements yet. Make sure \" +\n \"your clndr selector returns only one element.\");\n }\n\n if (!this.length) {\n throw new Error(\n \"CLNDR cannot be instantiated on an empty selector.\");\n }\n\n if (!this.data('plugin_clndr')) {\n clndrInstance = new Clndr(this, options);\n this.data('plugin_clndr', clndrInstance);\n return clndrInstance;\n }\n\n return this.data('plugin_clndr');\n };\n}));\n"],"names":["factory","define","amd","exports","require","jQuery","moment","$","defaults","events","ready","extras","render","weekOffset","constraints","forceSixRows","selectedDate","doneRendering","daysOfTheWeek","multiDayEvents","startWithMonth","dateParameter","template","showAdjacentMonths","trackSelectedDate","adjacentDaysChangeMonth","ignoreInactiveDaysInSelection","lengthOfTime","days","interval","months","clickEvents","click","today","nextYear","nextMonth","nextInterval","previousYear","onYearChange","previousMonth","onMonthChange","previousInterval","onIntervalChange","targets","day","empty","nextButton","todayButton","previousButton","nextYearButton","previousYearButton","classes","past","event","inactive","selected","lastMonth","adjacentMonth","Clndr","element","options","constraintStart","this","extend","next","previous","length","addMultiDayMomentObjectsToEvents","addMomentObjectToEvents","startDate","intervalStart","startOf","intervalEnd","add","subtract","month","clone","weekday","endOf","isBefore","diff","set","year","endDate","constraintEnd","isAfter","_defaults","_name","init","prototype","i","push","format","charAt","shiftWeekdayLabels","isFunction","_","Error","compiledClndrTemplate","html","calendarContainer","bindEvents","apply","offset","shift","createDaysObject","startOfLastMonth","endOfLastMonth","startOfNextMonth","endOfNextMonth","dateIterator","daysArray","date","_currentIntervalStart","eventsLastMonth","eventsNextMonth","eventsThisInterval","filter","afterEnd","_clndrStartDateObject","_clndrEndDateObject","toArray","beforeStart","createDayObject","calendarDay","isSame","monthEvents","selectedMoment","j","now","eventsToday","extraClasses","properties","isToday","isInactive","isAdjacentMonth","isValid","hasOwnProperty","undefined","_d","start","end","endMoment","startMoment","numberOfRows","data","oneYearFromEnd","oneYearAgo","eventsThisMonth","Math","ceil","currentIntervalStart","currentIntervalEnd","target","find","toggleClass","self","$container","eventName","useTouchEvents","off","on","$currentTarget","currentTarget","buildTargetObject","is","backActionWithContext","forwardActionWithContext","hasClass","getTargetDateString","removeClass","addClass","$eventTarget","context","todayAction","forwardAction","backAction","nextYearAction","previousYearAction","targetWasDay","dateString","filterFn","isSameStart","isAfterStart","isSameEnd","isBeforeEnd","makeArray","classNameIndex","className","indexOf","substring","triggerEvents","ctx","orig","timeOpt","eventsOpt","newInt","intervalArg","monthArg","abs","prevMonth","monthChanged","prevYear","yearChanged","prevInterval","intervalChanged","back","arguments","withCallbacks","forward","setMonth","newMonth","console","log","setYear","newYear","setIntervalStart","newDate","setExtras","setEvents","addEvents","reRender","merge","removeEvents","matchingFn","splice","multiEvents","singleDay","destroy","parent","remove","fn","clndr","clndrInstance"],"mappings":"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"}