function Clndr (element, options) {
    var dayDiff;
    var constraintEnd;
    var constraintStart;

    this.element = element;

    // Merge the default options with user-provided options
    this.options = $.extend(true, {}, defaults, options);

    // Check if moment was passed in as a dependency
    if (this.options.moment) {
      moment = this.options.moment;
    }

    // Validate any correct options
    this.validateOptions();

    // Boolean values used to log if any contraints are met
    this.constraints = {
      next: true,
      today: true,
      previous: true,
      nextYear: true,
      previousYear: true
    };

    // If there are events, we should run them through our
    // addMomentObjectToEvents function which will add a date object that
    // we can use to make life easier. This is only necessarywhen events
    // are provided on instantiation, since our setEvents function uses
    // addMomentObjectToEvents.
    if (this.options.events.length) {
      if (this.options.multiDayEvents) {
        this.options.events =
          this.addMultiDayMomentObjectsToEvents(this.options.events);
      } else {
        this.options.events =
          this.addMomentObjectToEvents(this.options.events);
      }
    }

    // This used to be a place where we'd figure out the current month,
    // but since we want to open up support for arbitrary lengths of time
    // we're going to store the current range in addition to the current
    // month.
    if (this.options.lengthOfTime.months || this.options.lengthOfTime.days) {
      // We want to establish intervalStart and intervalEnd, which will
      // keep track of our boundaries. Let's look at the possibilities...
      if (this.options.lengthOfTime.months) {
        // Gonna go right ahead and annihilate any chance for bugs here
        this.options.lengthOfTime.days = null;

        // The length is specified in months. Is there a start date?
        if (this.options.lengthOfTime.startDate) {
          this.intervalStart =
            moment(this.options.lengthOfTime.startDate).startOf('month');
        } else if (this.options.startWithMonth) {
          this.intervalStart =
            moment(this.options.startWithMonth).startOf('month');
        } else {
          this.intervalStart = moment().startOf('month');
        }

        // Subtract a day so that we are at the end of the interval. We
        // always want intervalEnd to be inclusive.
        this.intervalEnd = moment(this.intervalStart)
          .add(this.options.lengthOfTime.months, 'months')
          .subtract(1, 'days');
        this.month = this.intervalStart.clone();
      } else if (this.options.lengthOfTime.days) {
        // The length is specified in days. Start date?
        if (this.options.lengthOfTime.startDate) {
          this.intervalStart =
            moment(this.options.lengthOfTime.startDate).startOf('day');
        } else {
          this.intervalStart = moment()
            .weekday(this.options.weekOffset)
            .startOf('day');
        }

        this.intervalEnd = moment(this.intervalStart)
          .add(this.options.lengthOfTime.days - 1, 'days')
          .endOf('day');
        this.month = this.intervalStart.clone();
      }
    // No length of time specified so we're going to default into using the
    // current month as the time period.
    } else {
      this.month = moment().startOf('month');
      this.intervalStart = moment(this.month);
      this.intervalEnd = moment(this.month).endOf('month');
    }

    if (this.options.startWithMonth) {
      this.month = moment(this.options.startWithMonth).startOf('month');
      this.intervalStart = moment(this.month);
      this.intervalEnd = this.options.lengthOfTime.days
        ? moment(this.month)
          .add(this.options.lengthOfTime.days - 1, 'days')
          .endOf('day')
        : moment(this.month).endOf('month');
    }

    // If we've got constraints set, make sure the interval is within them.
    if (this.options.constraints) {
      // First check if the startDate exists & is later than now.
      if (this.options.constraints.startDate) {
        constraintStart = moment(this.options.constraints.startDate);

        // We need to handle the constraints differently for weekly
        // calendars vs. monthly calendars.
        if (this.options.lengthOfTime.days) {
          if (this.intervalStart.isBefore(constraintStart, 'week')) {
            this.intervalStart = constraintStart.startOf('week');
          }

          // If the new interval period is less than the desired length
          // of time, or before the starting interval, then correct it.
          dayDiff = this.intervalStart.diff(this.intervalEnd, 'days');

          if (dayDiff < this.options.lengthOfTime.days ||
              this.intervalEnd.isBefore(this.intervalStart)
          ) {
            this.intervalEnd = moment(this.intervalStart)
              .add(this.options.lengthOfTime.days - 1, 'days')
              .endOf('day');
            this.month = this.intervalStart.clone();
          }
        } else {
          if (this.intervalStart.isBefore(constraintStart, 'month')) {
            // Try to preserve the date by moving only the month.
            this.intervalStart
              .set('month', constraintStart.month())
              .set('year', constraintStart.year());
            this.month
              .set('month', constraintStart.month())
              .set('year', constraintStart.year());
          }

          // Check if the ending interval is earlier than now.
          if (this.intervalEnd.isBefore(constraintStart, 'month')) {
            this.intervalEnd
              .set('month', constraintStart.month())
              .set('year', constraintStart.year());
          }
        }
      }

      // Make sure the intervalEnd is before the endDate.
      if (this.options.constraints.endDate) {
        constraintEnd = moment(this.options.constraints.endDate);

        // We need to handle the constraints differently for weekly
        // calendars vs. monthly calendars.
        if (this.options.lengthOfTime.days) {
          // The starting interval is after our ending constraint.
          if (this.intervalStart.isAfter(constraintEnd, 'week')) {
            this.intervalStart = moment(constraintEnd)
              .endOf('week')
              .subtract(this.options.lengthOfTime.days - 1, 'days')
              .startOf('day');
            this.intervalEnd = moment(constraintEnd)
              .endOf('week');
            this.month = this.intervalStart.clone();
          }
        } else {
          if (this.intervalEnd.isAfter(constraintEnd, 'month')) {
            this.intervalEnd
              .set('month', constraintEnd.month())
              .set('year', constraintEnd.year());
            this.month
              .set('month', constraintEnd.month())
              .set('year', constraintEnd.year());
          }

          // Check if the starting interval is later than the ending.
          if (this.intervalStart.isAfter(constraintEnd, 'month')) {
            this.intervalStart
              .set('month', constraintEnd.month())
              .set('year', constraintEnd.year());
          }
        }
      }
    }

    this._defaults = defaults;
    this._name = pluginName;

    // Some first-time initialization -> day of the week offset, template
    // compiling, making and storing some elements we'll need later, and
    // event handling for the controller.
    this.init();
  }
The actual plugin constructor.
Parses the events and lengthOfTime options to build a calendar of day
objects containing event information from the events array.