diff --git a/AKModel/templates/AKModel/load_fullcalendar_availabilities.html b/AKModel/templates/AKModel/load_fullcalendar_availabilities.html
new file mode 100644
index 0000000000000000000000000000000000000000..56b1fbf3c4d0fba0018db22037ec080fdf8fe0bb
--- /dev/null
+++ b/AKModel/templates/AKModel/load_fullcalendar_availabilities.html
@@ -0,0 +1,15 @@
+{% load static %}
+{% load i18n %}
+{% get_current_language as LANGUAGE_CODE %}
+
+<link href='{% static 'common/vendor/fullcalendar/main.css' %}' rel='stylesheet'/>
+<script src='{% static 'common/vendor/fullcalendar/main.js' %}'></script>
+<script src="{% static "common/vendor/moment/moment-with-locales.js" %}"></script>
+<script src="{% static "common/js/availabilities.js" %}"></script>
+
+{% with 'common/vendor/fullcalendar/locales/'|add:LANGUAGE_CODE|add:'.js' as locale_file %}
+    {% if LANGUAGE_CODE != "en" %}
+        {# Locale 'en' is included in main.js and does not exist separately #}
+        <script src="{% static locale_file %}"></script>
+    {% endif %}
+{% endwith %}
diff --git a/AKModel/templates/admin/AKModel/room_change_form.html b/AKModel/templates/admin/AKModel/room_change_form.html
index f2db1fbcaf09bb2d28c771f93f46f6e70d166bf2..aac03532656c41b442bfae811350c08719df10f0 100644
--- a/AKModel/templates/admin/AKModel/room_change_form.html
+++ b/AKModel/templates/admin/AKModel/room_change_form.html
@@ -7,8 +7,8 @@
 {% block extrahead %}
     {{ block.super }}
     {% bootstrap_javascript jquery='slim' %}
-    {% include "AKPlan/load_fullcalendar.html" %}
-    <script src="{% static "common/js/availabilities.js" %}"></script>
+    {% include "AKModel/load_fullcalendar_availabilities.html" %}
+
     <script>
         {% get_current_language as LANGUAGE_CODE %}
 
diff --git a/AKSubmission/templates/AKSubmission/submit_new.html b/AKSubmission/templates/AKSubmission/submit_new.html
index 60e387f7b410e3d9e0e6d1456cb9f39678b49ba2..b3699b3c90c500f8479ee8166dbf01deb1c300c9 100644
--- a/AKSubmission/templates/AKSubmission/submit_new.html
+++ b/AKSubmission/templates/AKSubmission/submit_new.html
@@ -12,9 +12,7 @@
     <link rel="stylesheet" href="{% static 'common/vendor/chosen-js/chosen.css' %}">
     <link rel="stylesheet" href="{% static 'common/css/bootstrap-chosen.css' %}">
 
-    {% include "AKPlan/load_fullcalendar.html" %}
-    <script src="{% static "AKSubmission/vendor/moment/moment-with-locales.js" %}"></script>
-    <script src="{% static "common/js/availabilities.js" %}"></script>
+    {% include "AKModel/load_fullcalendar_availabilities.html" %}
 
     <script>
     {% get_current_language as LANGUAGE_CODE %}
diff --git a/static_common/common/vendor/fullcalendar/locales/de.js b/static_common/common/vendor/fullcalendar/locales/de.js
new file mode 100644
index 0000000000000000000000000000000000000000..f7bb6f179a34dae00cc1f2481486864bb673cf4e
--- /dev/null
+++ b/static_common/common/vendor/fullcalendar/locales/de.js
@@ -0,0 +1,59 @@
+FullCalendar.globalLocales.push(function () {
+  'use strict';
+
+  function affix(buttonText) {
+    return buttonText === "Tag" || buttonText === "Monat" ? "r" : buttonText === "Jahr" ? "s" : "";
+  }
+  var de = {
+    code: "de",
+    week: {
+      dow: 1,
+      doy: 4
+    },
+    buttonText: {
+      prev: "Zur\xFCck",
+      next: "Vor",
+      today: "Heute",
+      year: "Jahr",
+      month: "Monat",
+      week: "Woche",
+      day: "Tag",
+      list: "Termin\xFCbersicht"
+    },
+    weekText: "KW",
+    weekTextLong: "Woche",
+    allDayText: "Ganzt\xE4gig",
+    moreLinkText: function(n) {
+      return "+ weitere " + n;
+    },
+    noEventsText: "Keine Ereignisse anzuzeigen",
+    buttonHints: {
+      prev: function(buttonText) {
+        return "Vorherige".concat(affix(buttonText), " ").concat(buttonText);
+      },
+      next: function(buttonText) {
+        return "N\xE4chste".concat(affix(buttonText), " ").concat(buttonText);
+      },
+      today: function(buttonText) {
+        if (buttonText === "Tag") {
+          return "Heute";
+        }
+        return "Diese".concat(affix(buttonText), " ").concat(buttonText);
+      }
+    },
+    viewHint: function(buttonText) {
+      var glue = buttonText === "Woche" ? "n" : buttonText === "Monat" ? "s" : "es";
+      return buttonText + glue + "ansicht";
+    },
+    navLinkHint: "Gehe zu $0",
+    moreLinkHint: function(eventCnt) {
+      return "Zeige " + (eventCnt === 1 ? "ein weiteres Ereignis" : eventCnt + " weitere Ereignisse");
+    },
+    closeHint: "Schlie\xDFen",
+    timeHint: "Uhrzeit",
+    eventHint: "Ereignis"
+  };
+
+  return de;
+
+}());
diff --git a/static_common/common/vendor/fullcalendar/main.css b/static_common/common/vendor/fullcalendar/main.css
new file mode 100644
index 0000000000000000000000000000000000000000..288a618849445804a726c1d6943dad81a0f0eeab
--- /dev/null
+++ b/static_common/common/vendor/fullcalendar/main.css
@@ -0,0 +1,1495 @@
+
+/* classes attached to <body> */
+/* TODO: make fc-event selector work when calender in shadow DOM */
+.fc-not-allowed,
+.fc-not-allowed .fc-event { /* override events' custom cursors */
+  cursor: not-allowed;
+}
+
+/* TODO: not attached to body. attached to specific els. move */
+.fc-unselectable {
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  -webkit-touch-callout: none;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+.fc {
+  /* layout of immediate children */
+  display: flex;
+  flex-direction: column;
+
+  font-size: 1em
+}
+.fc,
+  .fc *,
+  .fc *:before,
+  .fc *:after {
+    box-sizing: border-box;
+  }
+.fc table {
+    border-collapse: collapse;
+    border-spacing: 0;
+    font-size: 1em; /* normalize cross-browser */
+  }
+.fc th {
+    text-align: center;
+  }
+.fc th,
+  .fc td {
+    vertical-align: top;
+    padding: 0;
+  }
+.fc a[data-navlink] {
+    cursor: pointer;
+  }
+.fc a[data-navlink]:hover {
+    text-decoration: underline;
+  }
+.fc-direction-ltr {
+  direction: ltr;
+  text-align: left;
+}
+.fc-direction-rtl {
+  direction: rtl;
+  text-align: right;
+}
+.fc-theme-standard td,
+  .fc-theme-standard th {
+    border: 1px solid #ddd;
+    border: 1px solid var(--fc-border-color, #ddd);
+  }
+/* for FF, which doesn't expand a 100% div within a table cell. use absolute positioning */
+/* inner-wrappers are responsible for being absolute */
+/* TODO: best place for this? */
+.fc-liquid-hack td,
+  .fc-liquid-hack th {
+    position: relative;
+  }
+
+@font-face {
+  font-family: 'fcicons';
+  src: url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyYiDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format('truetype');
+  font-weight: normal;
+  font-style: normal;
+}
+
+.fc-icon {
+  /* added for fc */
+  display: inline-block;
+  width: 1em;
+  height: 1em;
+  text-align: center;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+
+  /* use !important to prevent issues with browser extensions that change fonts */
+  font-family: 'fcicons' !important;
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+
+  /* Better Font Rendering =========== */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.fc-icon-chevron-left:before {
+  content: "\e900";
+}
+
+.fc-icon-chevron-right:before {
+  content: "\e901";
+}
+
+.fc-icon-chevrons-left:before {
+  content: "\e902";
+}
+
+.fc-icon-chevrons-right:before {
+  content: "\e903";
+}
+
+.fc-icon-minus-square:before {
+  content: "\e904";
+}
+
+.fc-icon-plus-square:before {
+  content: "\e905";
+}
+
+.fc-icon-x:before {
+  content: "\e906";
+}
+/*
+Lots taken from Flatly (MIT): https://bootswatch.com/4/flatly/bootstrap.css
+
+These styles only apply when the standard-theme is activated.
+When it's NOT activated, the fc-button classes won't even be in the DOM.
+*/
+.fc {
+
+  /* reset */
+
+}
+.fc .fc-button {
+    border-radius: 0;
+    overflow: visible;
+    text-transform: none;
+    margin: 0;
+    font-family: inherit;
+    font-size: inherit;
+    line-height: inherit;
+  }
+.fc .fc-button:focus {
+    outline: 1px dotted;
+    outline: 5px auto -webkit-focus-ring-color;
+  }
+.fc .fc-button {
+    -webkit-appearance: button;
+  }
+.fc .fc-button:not(:disabled) {
+    cursor: pointer;
+  }
+.fc .fc-button::-moz-focus-inner {
+    padding: 0;
+    border-style: none;
+  }
+.fc {
+
+  /* theme */
+
+}
+.fc .fc-button {
+    display: inline-block;
+    font-weight: 400;
+    text-align: center;
+    vertical-align: middle;
+    -webkit-user-select: none;
+       -moz-user-select: none;
+        -ms-user-select: none;
+            user-select: none;
+    background-color: transparent;
+    border: 1px solid transparent;
+    padding: 0.4em 0.65em;
+    font-size: 1em;
+    line-height: 1.5;
+    border-radius: 0.25em;
+  }
+.fc .fc-button:hover {
+    text-decoration: none;
+  }
+.fc .fc-button:focus {
+    outline: 0;
+    box-shadow: 0 0 0 0.2rem rgba(44, 62, 80, 0.25);
+  }
+.fc .fc-button:disabled {
+    opacity: 0.65;
+  }
+.fc {
+
+  /* "primary" coloring */
+
+}
+.fc .fc-button-primary {
+    color: #fff;
+    color: var(--fc-button-text-color, #fff);
+    background-color: #2C3E50;
+    background-color: var(--fc-button-bg-color, #2C3E50);
+    border-color: #2C3E50;
+    border-color: var(--fc-button-border-color, #2C3E50);
+  }
+.fc .fc-button-primary:hover {
+    color: #fff;
+    color: var(--fc-button-text-color, #fff);
+    background-color: #1e2b37;
+    background-color: var(--fc-button-hover-bg-color, #1e2b37);
+    border-color: #1a252f;
+    border-color: var(--fc-button-hover-border-color, #1a252f);
+  }
+.fc .fc-button-primary:disabled { /* not DRY */
+    color: #fff;
+    color: var(--fc-button-text-color, #fff);
+    background-color: #2C3E50;
+    background-color: var(--fc-button-bg-color, #2C3E50);
+    border-color: #2C3E50;
+    border-color: var(--fc-button-border-color, #2C3E50); /* overrides :hover */
+  }
+.fc .fc-button-primary:focus {
+    box-shadow: 0 0 0 0.2rem rgba(76, 91, 106, 0.5);
+  }
+.fc .fc-button-primary:not(:disabled):active,
+  .fc .fc-button-primary:not(:disabled).fc-button-active {
+    color: #fff;
+    color: var(--fc-button-text-color, #fff);
+    background-color: #1a252f;
+    background-color: var(--fc-button-active-bg-color, #1a252f);
+    border-color: #151e27;
+    border-color: var(--fc-button-active-border-color, #151e27);
+  }
+.fc .fc-button-primary:not(:disabled):active:focus,
+  .fc .fc-button-primary:not(:disabled).fc-button-active:focus {
+    box-shadow: 0 0 0 0.2rem rgba(76, 91, 106, 0.5);
+  }
+.fc {
+
+  /* icons within buttons */
+
+}
+.fc .fc-button .fc-icon {
+    vertical-align: middle;
+    font-size: 1.5em; /* bump up the size (but don't make it bigger than line-height of button, which is 1.5em also) */
+  }
+.fc .fc-button-group {
+    position: relative;
+    display: inline-flex;
+    vertical-align: middle;
+  }
+.fc .fc-button-group > .fc-button {
+    position: relative;
+    flex: 1 1 auto;
+  }
+.fc .fc-button-group > .fc-button:hover {
+    z-index: 1;
+  }
+.fc .fc-button-group > .fc-button:focus,
+  .fc .fc-button-group > .fc-button:active,
+  .fc .fc-button-group > .fc-button.fc-button-active {
+    z-index: 1;
+  }
+.fc-direction-ltr .fc-button-group > .fc-button:not(:first-child) {
+    margin-left: -1px;
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+  }
+.fc-direction-ltr .fc-button-group > .fc-button:not(:last-child) {
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+  }
+.fc-direction-rtl .fc-button-group > .fc-button:not(:first-child) {
+    margin-right: -1px;
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+  }
+.fc-direction-rtl .fc-button-group > .fc-button:not(:last-child) {
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+  }
+.fc .fc-toolbar {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+.fc .fc-toolbar.fc-header-toolbar {
+    margin-bottom: 1.5em;
+  }
+.fc .fc-toolbar.fc-footer-toolbar {
+    margin-top: 1.5em;
+  }
+.fc .fc-toolbar-title {
+    font-size: 1.75em;
+    margin: 0;
+  }
+.fc-direction-ltr .fc-toolbar > * > :not(:first-child) {
+    margin-left: .75em; /* space between */
+  }
+.fc-direction-rtl .fc-toolbar > * > :not(:first-child) {
+    margin-right: .75em; /* space between */
+  }
+.fc-direction-rtl .fc-toolbar-ltr { /* when the toolbar-chunk positioning system is explicitly left-to-right */
+    flex-direction: row-reverse;
+  }
+.fc .fc-scroller {
+    -webkit-overflow-scrolling: touch;
+    position: relative; /* for abs-positioned elements within */
+  }
+.fc .fc-scroller-liquid {
+    height: 100%;
+  }
+.fc .fc-scroller-liquid-absolute {
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+    bottom: 0;
+  }
+.fc .fc-scroller-harness {
+    position: relative;
+    overflow: hidden;
+    direction: ltr;
+      /* hack for chrome computing the scroller's right/left wrong for rtl. undone below... */
+      /* TODO: demonstrate in codepen */
+  }
+.fc .fc-scroller-harness-liquid {
+    height: 100%;
+  }
+.fc-direction-rtl .fc-scroller-harness > .fc-scroller { /* undo above hack */
+    direction: rtl;
+  }
+.fc-theme-standard .fc-scrollgrid {
+    border: 1px solid #ddd;
+    border: 1px solid var(--fc-border-color, #ddd); /* bootstrap does this. match */
+  }
+.fc .fc-scrollgrid,
+    .fc .fc-scrollgrid table { /* all tables (self included) */
+      width: 100%; /* because tables don't normally do this */
+      table-layout: fixed;
+    }
+.fc .fc-scrollgrid table { /* inner tables */
+      border-top-style: hidden;
+      border-left-style: hidden;
+      border-right-style: hidden;
+    }
+.fc .fc-scrollgrid {
+
+    border-collapse: separate;
+    border-right-width: 0;
+    border-bottom-width: 0;
+
+  }
+.fc .fc-scrollgrid-liquid {
+    height: 100%;
+  }
+.fc .fc-scrollgrid-section { /* a <tr> */
+    height: 1px /* better than 0, for firefox */
+
+  }
+.fc .fc-scrollgrid-section > td {
+      height: 1px; /* needs a height so inner div within grow. better than 0, for firefox */
+    }
+.fc .fc-scrollgrid-section table {
+      height: 1px;
+        /* for most browsers, if a height isn't set on the table, can't do liquid-height within cells */
+        /* serves as a min-height. harmless */
+    }
+.fc .fc-scrollgrid-section-liquid > td {
+      height: 100%; /* better than `auto`, for firefox */
+    }
+.fc .fc-scrollgrid-section > * {
+    border-top-width: 0;
+    border-left-width: 0;
+  }
+.fc .fc-scrollgrid-section-header > *,
+  .fc .fc-scrollgrid-section-footer > * {
+    border-bottom-width: 0;
+  }
+.fc .fc-scrollgrid-section-body table,
+  .fc .fc-scrollgrid-section-footer table {
+    border-bottom-style: hidden; /* head keeps its bottom border tho */
+  }
+.fc {
+
+  /* stickiness */
+
+}
+.fc .fc-scrollgrid-section-sticky > * {
+    background: #fff;
+    background: var(--fc-page-bg-color, #fff);
+    position: sticky;
+    z-index: 3; /* TODO: var */
+    /* TODO: box-shadow when sticking */
+  }
+.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky > * {
+    top: 0; /* because border-sharing causes a gap at the top */
+      /* TODO: give safari -1. has bug */
+  }
+.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky > * {
+    bottom: 0; /* known bug: bottom-stickiness doesn't work in safari */
+  }
+.fc .fc-scrollgrid-sticky-shim { /* for horizontal scrollbar */
+    height: 1px; /* needs height to create scrollbars */
+    margin-bottom: -1px;
+  }
+.fc-sticky { /* no .fc wrap because used as child of body */
+  position: sticky;
+}
+.fc .fc-view-harness {
+    flex-grow: 1; /* because this harness is WITHIN the .fc's flexbox */
+    position: relative;
+  }
+.fc {
+
+  /* when the harness controls the height, make the view liquid */
+
+}
+.fc .fc-view-harness-active > .fc-view {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+  }
+.fc .fc-col-header-cell-cushion {
+    display: inline-block; /* x-browser for when sticky (when multi-tier header) */
+    padding: 2px 4px;
+  }
+.fc .fc-bg-event,
+  .fc .fc-non-business,
+  .fc .fc-highlight {
+    /* will always have a harness with position:relative/absolute, so absolutely expand */
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+  }
+.fc .fc-non-business {
+    background: rgba(215, 215, 215, 0.3);
+    background: var(--fc-non-business-color, rgba(215, 215, 215, 0.3));
+  }
+.fc .fc-bg-event {
+    background: rgb(143, 223, 130);
+    background: var(--fc-bg-event-color, rgb(143, 223, 130));
+    opacity: 0.3;
+    opacity: var(--fc-bg-event-opacity, 0.3)
+  }
+.fc .fc-bg-event .fc-event-title {
+      margin: .5em;
+      font-size: .85em;
+      font-size: var(--fc-small-font-size, .85em);
+      font-style: italic;
+    }
+.fc .fc-highlight {
+    background: rgba(188, 232, 241, 0.3);
+    background: var(--fc-highlight-color, rgba(188, 232, 241, 0.3));
+  }
+.fc .fc-cell-shaded,
+  .fc .fc-day-disabled {
+    background: rgba(208, 208, 208, 0.3);
+    background: var(--fc-neutral-bg-color, rgba(208, 208, 208, 0.3));
+  }
+/* link resets */
+/* ---------------------------------------------------------------------------------------------------- */
+a.fc-event,
+a.fc-event:hover {
+  text-decoration: none;
+}
+/* cursor */
+.fc-event[href],
+.fc-event.fc-event-draggable {
+  cursor: pointer;
+}
+/* event text content */
+/* ---------------------------------------------------------------------------------------------------- */
+.fc-event .fc-event-main {
+    position: relative;
+    z-index: 2;
+  }
+/* dragging */
+/* ---------------------------------------------------------------------------------------------------- */
+.fc-event-dragging:not(.fc-event-selected) { /* MOUSE */
+    opacity: 0.75;
+  }
+.fc-event-dragging.fc-event-selected { /* TOUCH */
+    box-shadow: 0 2px 7px rgba(0, 0, 0, 0.3);
+  }
+/* resizing */
+/* ---------------------------------------------------------------------------------------------------- */
+/* (subclasses should hone positioning for touch and non-touch) */
+.fc-event .fc-event-resizer {
+    display: none;
+    position: absolute;
+    z-index: 4;
+  }
+.fc-event:hover, /* MOUSE */
+.fc-event-selected { /* TOUCH */
+
+}
+.fc-event:hover .fc-event-resizer, .fc-event-selected .fc-event-resizer {
+    display: block;
+  }
+.fc-event-selected .fc-event-resizer {
+    border-radius: 4px;
+    border-radius: calc(var(--fc-event-resizer-dot-total-width, 8px) / 2);
+    border-width: 1px;
+    border-width: var(--fc-event-resizer-dot-border-width, 1px);
+    width: 8px;
+    width: var(--fc-event-resizer-dot-total-width, 8px);
+    height: 8px;
+    height: var(--fc-event-resizer-dot-total-width, 8px);
+    border-style: solid;
+    border-color: inherit;
+    background: #fff;
+    background: var(--fc-page-bg-color, #fff)
+
+    /* expand hit area */
+
+  }
+.fc-event-selected .fc-event-resizer:before {
+      content: '';
+      position: absolute;
+      top: -20px;
+      left: -20px;
+      right: -20px;
+      bottom: -20px;
+    }
+/* selecting (always TOUCH) */
+/* OR, focused by tab-index */
+/* (TODO: maybe not the best focus-styling for .fc-daygrid-dot-event) */
+/* ---------------------------------------------------------------------------------------------------- */
+.fc-event-selected,
+.fc-event:focus {
+  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2)
+
+  /* expand hit area (subclasses should expand) */
+
+}
+.fc-event-selected:before, .fc-event:focus:before {
+    content: "";
+    position: absolute;
+    z-index: 3;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+  }
+.fc-event-selected,
+.fc-event:focus {
+
+  /* dimmer effect */
+
+}
+.fc-event-selected:after, .fc-event:focus:after {
+    content: "";
+    background: rgba(0, 0, 0, 0.25);
+    background: var(--fc-event-selected-overlay-color, rgba(0, 0, 0, 0.25));
+    position: absolute;
+    z-index: 1;
+
+    /* assume there's a border on all sides. overcome it. */
+    /* sometimes there's NOT a border, in which case the dimmer will go over */
+    /* an adjacent border, which looks fine. */
+    top: -1px;
+    left: -1px;
+    right: -1px;
+    bottom: -1px;
+  }
+/*
+A HORIZONTAL event
+*/
+.fc-h-event { /* allowed to be top-level */
+  display: block;
+  border: 1px solid #3788d8;
+  border: 1px solid var(--fc-event-border-color, #3788d8);
+  background-color: #3788d8;
+  background-color: var(--fc-event-bg-color, #3788d8)
+
+}
+.fc-h-event .fc-event-main {
+    color: #fff;
+    color: var(--fc-event-text-color, #fff);
+  }
+.fc-h-event .fc-event-main-frame {
+    display: flex; /* for make fc-event-title-container expand */
+  }
+.fc-h-event .fc-event-time {
+    max-width: 100%; /* clip overflow on this element */
+    overflow: hidden;
+  }
+.fc-h-event .fc-event-title-container { /* serves as a container for the sticky cushion */
+    flex-grow: 1;
+    flex-shrink: 1;
+    min-width: 0; /* important for allowing to shrink all the way */
+  }
+.fc-h-event .fc-event-title {
+    display: inline-block; /* need this to be sticky cross-browser */
+    vertical-align: top; /* for not messing up line-height */
+    left: 0;  /* for sticky */
+    right: 0; /* for sticky */
+    max-width: 100%; /* clip overflow on this element */
+    overflow: hidden;
+  }
+.fc-h-event.fc-event-selected:before {
+    /* expand hit area */
+    top: -10px;
+    bottom: -10px;
+  }
+/* adjust border and border-radius (if there is any) for non-start/end */
+.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),
+.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end) {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+  border-left-width: 0;
+}
+.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),
+.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start) {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+  border-right-width: 0;
+}
+/* resizers */
+.fc-h-event:not(.fc-event-selected) .fc-event-resizer {
+  top: 0;
+  bottom: 0;
+  width: 8px;
+  width: var(--fc-event-resizer-thickness, 8px);
+}
+.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,
+.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end {
+  cursor: w-resize;
+  left: -4px;
+  left: calc(-0.5 * var(--fc-event-resizer-thickness, 8px));
+}
+.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,
+.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start {
+  cursor: e-resize;
+  right: -4px;
+  right: calc(-0.5 * var(--fc-event-resizer-thickness, 8px));
+}
+/* resizers for TOUCH */
+.fc-h-event.fc-event-selected .fc-event-resizer {
+  top: 50%;
+  margin-top: -4px;
+  margin-top: calc(-0.5 * var(--fc-event-resizer-dot-total-width, 8px));
+}
+.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,
+.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end {
+  left: -4px;
+  left: calc(-0.5 * var(--fc-event-resizer-dot-total-width, 8px));
+}
+.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,
+.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start {
+  right: -4px;
+  right: calc(-0.5 * var(--fc-event-resizer-dot-total-width, 8px));
+}
+.fc .fc-popover {
+    position: absolute;
+    z-index: 9999;
+    box-shadow: 0 2px 6px rgba(0,0,0,.15);
+  }
+.fc .fc-popover-header {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    padding: 3px 4px;
+  }
+.fc .fc-popover-title {
+    margin: 0 2px;
+  }
+.fc .fc-popover-close {
+    cursor: pointer;
+    opacity: 0.65;
+    font-size: 1.1em;
+  }
+.fc-theme-standard .fc-popover {
+    border: 1px solid #ddd;
+    border: 1px solid var(--fc-border-color, #ddd);
+    background: #fff;
+    background: var(--fc-page-bg-color, #fff);
+  }
+.fc-theme-standard .fc-popover-header {
+    background: rgba(208, 208, 208, 0.3);
+    background: var(--fc-neutral-bg-color, rgba(208, 208, 208, 0.3));
+  }
+
+
+:root {
+  --fc-daygrid-event-dot-width: 8px;
+}
+/* help things clear margins of inner content */
+.fc-daygrid-day-frame,
+.fc-daygrid-day-events,
+.fc-daygrid-event-harness { /* for event top/bottom margins */
+}
+.fc-daygrid-day-frame:before, .fc-daygrid-day-events:before, .fc-daygrid-event-harness:before {
+  content: "";
+  clear: both;
+  display: table; }
+.fc-daygrid-day-frame:after, .fc-daygrid-day-events:after, .fc-daygrid-event-harness:after {
+  content: "";
+  clear: both;
+  display: table; }
+.fc .fc-daygrid-body { /* a <div> that wraps the table */
+    position: relative;
+    z-index: 1; /* container inner z-index's because <tr>s can't do it */
+  }
+.fc .fc-daygrid-day.fc-day-today {
+      background-color: rgba(255, 220, 40, 0.15);
+      background-color: var(--fc-today-bg-color, rgba(255, 220, 40, 0.15));
+    }
+.fc .fc-daygrid-day-frame {
+    position: relative;
+    min-height: 100%; /* seems to work better than `height` because sets height after rows/cells naturally do it */
+  }
+.fc {
+
+  /* cell top */
+
+}
+.fc .fc-daygrid-day-top {
+    display: flex;
+    flex-direction: row-reverse;
+  }
+.fc .fc-day-other .fc-daygrid-day-top {
+    opacity: 0.3;
+  }
+.fc {
+
+  /* day number (within cell top) */
+
+}
+.fc .fc-daygrid-day-number {
+    position: relative;
+    z-index: 4;
+    padding: 4px;
+  }
+.fc {
+
+  /* event container */
+
+}
+.fc .fc-daygrid-day-events {
+    margin-top: 1px; /* needs to be margin, not padding, so that available cell height can be computed */
+  }
+.fc {
+
+  /* positioning for balanced vs natural */
+
+}
+.fc .fc-daygrid-body-balanced .fc-daygrid-day-events {
+      position: absolute;
+      left: 0;
+      right: 0;
+    }
+.fc .fc-daygrid-body-unbalanced .fc-daygrid-day-events {
+      position: relative; /* for containing abs positioned event harnesses */
+      min-height: 2em; /* in addition to being a min-height during natural height, equalizes the heights a little bit */
+    }
+.fc .fc-daygrid-body-natural { /* can coexist with -unbalanced */
+  }
+.fc .fc-daygrid-body-natural .fc-daygrid-day-events {
+      margin-bottom: 1em;
+    }
+.fc {
+
+  /* event harness */
+
+}
+.fc .fc-daygrid-event-harness {
+    position: relative;
+  }
+.fc .fc-daygrid-event-harness-abs {
+    position: absolute;
+    top: 0; /* fallback coords for when cannot yet be computed */
+    left: 0; /* */
+    right: 0; /* */
+  }
+.fc .fc-daygrid-bg-harness {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+  }
+.fc {
+
+  /* bg content */
+
+}
+.fc .fc-daygrid-day-bg .fc-non-business { z-index: 1 }
+.fc .fc-daygrid-day-bg .fc-bg-event { z-index: 2 }
+.fc .fc-daygrid-day-bg .fc-highlight { z-index: 3 }
+.fc {
+
+  /* events */
+
+}
+.fc .fc-daygrid-event {
+    z-index: 6;
+    margin-top: 1px;
+  }
+.fc .fc-daygrid-event.fc-event-mirror {
+    z-index: 7;
+  }
+.fc {
+
+  /* cell bottom (within day-events) */
+
+}
+.fc .fc-daygrid-day-bottom {
+    font-size: .85em;
+    padding: 2px 3px 0
+  }
+.fc .fc-daygrid-day-bottom:before {
+  content: "";
+  clear: both;
+  display: table; }
+.fc .fc-daygrid-more-link {
+    position: relative;
+    z-index: 4;
+    cursor: pointer;
+  }
+.fc {
+
+  /* week number (within frame) */
+
+}
+.fc .fc-daygrid-week-number {
+    position: absolute;
+    z-index: 5;
+    top: 0;
+    padding: 2px;
+    min-width: 1.5em;
+    text-align: center;
+    background-color: rgba(208, 208, 208, 0.3);
+    background-color: var(--fc-neutral-bg-color, rgba(208, 208, 208, 0.3));
+    color: #808080;
+    color: var(--fc-neutral-text-color, #808080);
+  }
+.fc {
+
+  /* popover */
+
+}
+.fc .fc-more-popover .fc-popover-body {
+    min-width: 220px;
+    padding: 10px;
+  }
+.fc-direction-ltr .fc-daygrid-event.fc-event-start,
+.fc-direction-rtl .fc-daygrid-event.fc-event-end {
+  margin-left: 2px;
+}
+.fc-direction-ltr .fc-daygrid-event.fc-event-end,
+.fc-direction-rtl .fc-daygrid-event.fc-event-start {
+  margin-right: 2px;
+}
+.fc-direction-ltr .fc-daygrid-week-number {
+    left: 0;
+    border-radius: 0 0 3px 0;
+  }
+.fc-direction-rtl .fc-daygrid-week-number {
+    right: 0;
+    border-radius: 0 0 0 3px;
+  }
+.fc-liquid-hack .fc-daygrid-day-frame {
+    position: static; /* will cause inner absolute stuff to expand to <td> */
+  }
+.fc-daygrid-event { /* make root-level, because will be dragged-and-dropped outside of a component root */
+  position: relative; /* for z-indexes assigned later */
+  white-space: nowrap;
+  border-radius: 3px; /* dot event needs this to when selected */
+  font-size: .85em;
+  font-size: var(--fc-small-font-size, .85em);
+}
+/* --- the rectangle ("block") style of event --- */
+.fc-daygrid-block-event .fc-event-time {
+    font-weight: bold;
+  }
+.fc-daygrid-block-event .fc-event-time,
+  .fc-daygrid-block-event .fc-event-title {
+    padding: 1px;
+  }
+/* --- the dot style of event --- */
+.fc-daygrid-dot-event {
+  display: flex;
+  align-items: center;
+  padding: 2px 0
+
+}
+.fc-daygrid-dot-event .fc-event-title {
+    flex-grow: 1;
+    flex-shrink: 1;
+    min-width: 0; /* important for allowing to shrink all the way */
+    overflow: hidden;
+    font-weight: bold;
+  }
+.fc-daygrid-dot-event:hover,
+  .fc-daygrid-dot-event.fc-event-mirror {
+    background: rgba(0, 0, 0, 0.1);
+  }
+.fc-daygrid-dot-event.fc-event-selected:before {
+    /* expand hit area */
+    top: -10px;
+    bottom: -10px;
+  }
+.fc-daygrid-event-dot { /* the actual dot */
+  margin: 0 4px;
+  box-sizing: content-box;
+  width: 0;
+  height: 0;
+  border: 4px solid #3788d8;
+  border: calc(var(--fc-daygrid-event-dot-width, 8px) / 2) solid var(--fc-event-border-color, #3788d8);
+  border-radius: 4px;
+  border-radius: calc(var(--fc-daygrid-event-dot-width, 8px) / 2);
+}
+/* --- spacing between time and title --- */
+.fc-direction-ltr .fc-daygrid-event .fc-event-time {
+    margin-right: 3px;
+  }
+.fc-direction-rtl .fc-daygrid-event .fc-event-time {
+    margin-left: 3px;
+  }
+
+
+/*
+A VERTICAL event
+*/
+
+.fc-v-event { /* allowed to be top-level */
+  display: block;
+  border: 1px solid #3788d8;
+  border: 1px solid var(--fc-event-border-color, #3788d8);
+  background-color: #3788d8;
+  background-color: var(--fc-event-bg-color, #3788d8)
+
+}
+
+.fc-v-event .fc-event-main {
+    color: #fff;
+    color: var(--fc-event-text-color, #fff);
+    height: 100%;
+  }
+
+.fc-v-event .fc-event-main-frame {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+  }
+
+.fc-v-event .fc-event-time {
+    flex-grow: 0;
+    flex-shrink: 0;
+    max-height: 100%;
+    overflow: hidden;
+  }
+
+.fc-v-event .fc-event-title-container { /* a container for the sticky cushion */
+    flex-grow: 1;
+    flex-shrink: 1;
+    min-height: 0; /* important for allowing to shrink all the way */
+  }
+
+.fc-v-event .fc-event-title { /* will have fc-sticky on it */
+    top: 0;
+    bottom: 0;
+    max-height: 100%; /* clip overflow */
+    overflow: hidden;
+  }
+
+.fc-v-event:not(.fc-event-start) {
+    border-top-width: 0;
+    border-top-left-radius: 0;
+    border-top-right-radius: 0;
+  }
+
+.fc-v-event:not(.fc-event-end) {
+    border-bottom-width: 0;
+    border-bottom-left-radius: 0;
+    border-bottom-right-radius: 0;
+  }
+
+.fc-v-event.fc-event-selected:before {
+    /* expand hit area */
+    left: -10px;
+    right: -10px;
+  }
+
+.fc-v-event {
+
+  /* resizer (mouse AND touch) */
+
+}
+
+.fc-v-event .fc-event-resizer-start {
+    cursor: n-resize;
+  }
+
+.fc-v-event .fc-event-resizer-end {
+    cursor: s-resize;
+  }
+
+.fc-v-event {
+
+  /* resizer for MOUSE */
+
+}
+
+.fc-v-event:not(.fc-event-selected) .fc-event-resizer {
+      height: 8px;
+      height: var(--fc-event-resizer-thickness, 8px);
+      left: 0;
+      right: 0;
+    }
+
+.fc-v-event:not(.fc-event-selected) .fc-event-resizer-start {
+      top: -4px;
+      top: calc(var(--fc-event-resizer-thickness, 8px) / -2);
+    }
+
+.fc-v-event:not(.fc-event-selected) .fc-event-resizer-end {
+      bottom: -4px;
+      bottom: calc(var(--fc-event-resizer-thickness, 8px) / -2);
+    }
+
+.fc-v-event {
+
+  /* resizer for TOUCH (when event is "selected") */
+
+}
+
+.fc-v-event.fc-event-selected .fc-event-resizer {
+      left: 50%;
+      margin-left: -4px;
+      margin-left: calc(var(--fc-event-resizer-dot-total-width, 8px) / -2);
+    }
+
+.fc-v-event.fc-event-selected .fc-event-resizer-start {
+      top: -4px;
+      top: calc(var(--fc-event-resizer-dot-total-width, 8px) / -2);
+    }
+
+.fc-v-event.fc-event-selected .fc-event-resizer-end {
+      bottom: -4px;
+      bottom: calc(var(--fc-event-resizer-dot-total-width, 8px) / -2);
+    }
+.fc .fc-timegrid .fc-daygrid-body { /* the all-day daygrid within the timegrid view */
+    z-index: 2; /* put above the timegrid-body so that more-popover is above everything. TODO: better solution */
+  }
+.fc .fc-timegrid-divider {
+    padding: 0 0 2px; /* browsers get confused when you set height. use padding instead */
+  }
+.fc .fc-timegrid-body {
+    position: relative;
+    z-index: 1; /* scope the z-indexes of slots and cols */
+    min-height: 100%; /* fill height always, even when slat table doesn't grow */
+  }
+.fc .fc-timegrid-axis-chunk { /* for advanced ScrollGrid */
+    position: relative /* offset parent for now-indicator-container */
+
+  }
+.fc .fc-timegrid-axis-chunk > table {
+      position: relative;
+      z-index: 1; /* above the now-indicator-container */
+    }
+.fc .fc-timegrid-slots {
+    position: relative;
+    z-index: 1;
+  }
+.fc .fc-timegrid-slot { /* a <td> */
+    height: 1.5em;
+    border-bottom: 0 /* each cell owns its top border */
+  }
+.fc .fc-timegrid-slot:empty:before {
+      content: '\00a0'; /* make sure there's at least an empty space to create height for height syncing */
+    }
+.fc .fc-timegrid-slot-minor {
+    border-top-style: dotted;
+  }
+.fc .fc-timegrid-slot-label-cushion {
+    display: inline-block;
+    white-space: nowrap;
+  }
+.fc .fc-timegrid-slot-label {
+    vertical-align: middle; /* vertical align the slots */
+  }
+.fc {
+
+
+  /* slots AND axis cells (top-left corner of view including the "all-day" text) */
+
+}
+.fc .fc-timegrid-axis-cushion,
+  .fc .fc-timegrid-slot-label-cushion {
+    padding: 0 4px;
+  }
+.fc {
+
+
+  /* axis cells (top-left corner of view including the "all-day" text) */
+  /* vertical align is more complicated, uses flexbox */
+
+}
+.fc .fc-timegrid-axis-frame-liquid {
+    height: 100%; /* will need liquid-hack in FF */
+  }
+.fc .fc-timegrid-axis-frame {
+    overflow: hidden;
+    display: flex;
+    align-items: center; /* vertical align */
+    justify-content: flex-end; /* horizontal align. matches text-align below */
+  }
+.fc .fc-timegrid-axis-cushion {
+    max-width: 60px; /* limits the width of the "all-day" text */
+    flex-shrink: 0; /* allows text to expand how it normally would, regardless of constrained width */
+  }
+.fc-direction-ltr .fc-timegrid-slot-label-frame {
+    text-align: right;
+  }
+.fc-direction-rtl .fc-timegrid-slot-label-frame {
+    text-align: left;
+  }
+.fc-liquid-hack .fc-timegrid-axis-frame-liquid {
+  height: auto;
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  }
+.fc .fc-timegrid-col.fc-day-today {
+      background-color: rgba(255, 220, 40, 0.15);
+      background-color: var(--fc-today-bg-color, rgba(255, 220, 40, 0.15));
+    }
+.fc .fc-timegrid-col-frame {
+    min-height: 100%; /* liquid-hack is below */
+    position: relative;
+  }
+.fc-media-screen.fc-liquid-hack .fc-timegrid-col-frame {
+  height: auto;
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+    }
+.fc-media-screen .fc-timegrid-cols {
+    position: absolute; /* no z-index. children will decide and go above slots */
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0
+  }
+.fc-media-screen .fc-timegrid-cols > table {
+      height: 100%;
+    }
+.fc-media-screen .fc-timegrid-col-bg,
+  .fc-media-screen .fc-timegrid-col-events,
+  .fc-media-screen .fc-timegrid-now-indicator-container {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+  }
+.fc {
+
+  /* bg */
+
+}
+.fc .fc-timegrid-col-bg {
+    z-index: 2; /* TODO: kill */
+  }
+.fc .fc-timegrid-col-bg .fc-non-business { z-index: 1 }
+.fc .fc-timegrid-col-bg .fc-bg-event { z-index: 2 }
+.fc .fc-timegrid-col-bg .fc-highlight { z-index: 3 }
+.fc .fc-timegrid-bg-harness {
+    position: absolute; /* top/bottom will be set by JS */
+    left: 0;
+    right: 0;
+  }
+.fc {
+
+  /* fg events */
+  /* (the mirror segs are put into a separate container with same classname, */
+  /* and they must be after the normal seg container to appear at a higher z-index) */
+
+}
+.fc .fc-timegrid-col-events {
+    z-index: 3;
+    /* child event segs have z-indexes that are scoped within this div */
+  }
+.fc {
+
+  /* now indicator */
+
+}
+.fc .fc-timegrid-now-indicator-container {
+    bottom: 0;
+    overflow: hidden; /* don't let overflow of lines/arrows cause unnecessary scrolling */
+    /* z-index is set on the individual elements */
+  }
+.fc-direction-ltr .fc-timegrid-col-events {
+    margin: 0 2.5% 0 2px;
+  }
+.fc-direction-rtl .fc-timegrid-col-events {
+    margin: 0 2px 0 2.5%;
+  }
+.fc-timegrid-event-harness {
+  position: absolute /* top/left/right/bottom will all be set by JS */
+}
+.fc-timegrid-event-harness > .fc-timegrid-event {
+    position: absolute; /* absolute WITHIN the harness */
+    top: 0; /* for when not yet positioned */
+    bottom: 0; /* " */
+    left: 0;
+    right: 0;
+  }
+.fc-timegrid-event-harness-inset .fc-timegrid-event,
+.fc-timegrid-event.fc-event-mirror,
+.fc-timegrid-more-link {
+  box-shadow: 0px 0px 0px 1px #fff;
+  box-shadow: 0px 0px 0px 1px var(--fc-page-bg-color, #fff);
+}
+.fc-timegrid-event,
+.fc-timegrid-more-link { /* events need to be root */
+  font-size: .85em;
+  font-size: var(--fc-small-font-size, .85em);
+  border-radius: 3px;
+}
+.fc-timegrid-event { /* events need to be root */
+  margin-bottom: 1px /* give some space from bottom */
+}
+.fc-timegrid-event .fc-event-main {
+    padding: 1px 1px 0;
+  }
+.fc-timegrid-event .fc-event-time {
+    white-space: nowrap;
+    font-size: .85em;
+    font-size: var(--fc-small-font-size, .85em);
+    margin-bottom: 1px;
+  }
+.fc-timegrid-event-short .fc-event-main-frame {
+    flex-direction: row;
+    overflow: hidden;
+  }
+.fc-timegrid-event-short .fc-event-time:after {
+    content: '\00a0-\00a0'; /* dash surrounded by non-breaking spaces */
+  }
+.fc-timegrid-event-short .fc-event-title {
+    font-size: .85em;
+    font-size: var(--fc-small-font-size, .85em)
+  }
+.fc-timegrid-more-link { /* does NOT inherit from fc-timegrid-event */
+  position: absolute;
+  z-index: 9999; /* hack */
+  color: inherit;
+  color: var(--fc-more-link-text-color, inherit);
+  background: #d0d0d0;
+  background: var(--fc-more-link-bg-color, #d0d0d0);
+  cursor: pointer;
+  margin-bottom: 1px; /* match space below fc-timegrid-event */
+}
+.fc-timegrid-more-link-inner { /* has fc-sticky */
+  padding: 3px 2px;
+  top: 0;
+}
+.fc-direction-ltr .fc-timegrid-more-link {
+    right: 0;
+  }
+.fc-direction-rtl .fc-timegrid-more-link {
+    left: 0;
+  }
+.fc {
+
+  /* line */
+
+}
+.fc .fc-timegrid-now-indicator-line {
+    position: absolute;
+    z-index: 4;
+    left: 0;
+    right: 0;
+    border-style: solid;
+    border-color: red;
+    border-color: var(--fc-now-indicator-color, red);
+    border-width: 1px 0 0;
+  }
+.fc {
+
+  /* arrow */
+
+}
+.fc .fc-timegrid-now-indicator-arrow {
+    position: absolute;
+    z-index: 4;
+    margin-top: -5px; /* vertically center on top coordinate */
+    border-style: solid;
+    border-color: red;
+    border-color: var(--fc-now-indicator-color, red);
+  }
+.fc-direction-ltr .fc-timegrid-now-indicator-arrow {
+    left: 0;
+
+    /* triangle pointing right. TODO: mixin */
+    border-width: 5px 0 5px 6px;
+    border-top-color: transparent;
+    border-bottom-color: transparent;
+  }
+.fc-direction-rtl .fc-timegrid-now-indicator-arrow {
+    right: 0;
+
+    /* triangle pointing left. TODO: mixin */
+    border-width: 5px 6px 5px 0;
+    border-top-color: transparent;
+    border-bottom-color: transparent;
+  }
+
+
+:root {
+  --fc-list-event-dot-width: 10px;
+  --fc-list-event-hover-bg-color: #f5f5f5;
+}
+.fc-theme-standard .fc-list {
+    border: 1px solid #ddd;
+    border: 1px solid var(--fc-border-color, #ddd);
+  }
+.fc {
+
+  /* message when no events */
+
+}
+.fc .fc-list-empty {
+    background-color: rgba(208, 208, 208, 0.3);
+    background-color: var(--fc-neutral-bg-color, rgba(208, 208, 208, 0.3));
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center; /* vertically aligns fc-list-empty-inner */
+  }
+.fc .fc-list-empty-cushion {
+    margin: 5em 0;
+  }
+.fc {
+
+  /* table within the scroller */
+  /* ---------------------------------------------------------------------------------------------------- */
+
+}
+.fc .fc-list-table {
+    width: 100%;
+    border-style: hidden; /* kill outer border on theme */
+  }
+.fc .fc-list-table tr > * {
+    border-left: 0;
+    border-right: 0;
+  }
+.fc .fc-list-sticky .fc-list-day > * { /* the cells */
+      position: sticky;
+      top: 0;
+      background: #fff;
+      background: var(--fc-page-bg-color, #fff); /* for when headers are styled to be transparent and sticky */
+    }
+.fc {
+
+  /* only exists for aria reasons, hide for non-screen-readers */
+
+}
+.fc .fc-list-table thead {
+    position: absolute;
+    left: -10000px;
+  }
+.fc {
+
+  /* the table's border-style:hidden gets confused by hidden thead. force-hide top border of first cell */
+
+}
+.fc .fc-list-table tbody > tr:first-child th {
+    border-top: 0;
+  }
+.fc .fc-list-table th {
+    padding: 0; /* uses an inner-wrapper instead... */
+  }
+.fc .fc-list-table td,
+  .fc .fc-list-day-cushion {
+    padding: 8px 14px;
+  }
+.fc {
+
+
+  /* date heading rows */
+  /* ---------------------------------------------------------------------------------------------------- */
+
+}
+.fc .fc-list-day-cushion:after {
+  content: "";
+  clear: both;
+  display: table; /* clear floating */
+    }
+.fc-theme-standard .fc-list-day-cushion {
+    background-color: rgba(208, 208, 208, 0.3);
+    background-color: var(--fc-neutral-bg-color, rgba(208, 208, 208, 0.3));
+  }
+.fc-direction-ltr .fc-list-day-text,
+.fc-direction-rtl .fc-list-day-side-text {
+  float: left;
+}
+.fc-direction-ltr .fc-list-day-side-text,
+.fc-direction-rtl .fc-list-day-text {
+  float: right;
+}
+/* make the dot closer to the event title */
+.fc-direction-ltr .fc-list-table .fc-list-event-graphic { padding-right: 0 }
+.fc-direction-rtl .fc-list-table .fc-list-event-graphic { padding-left: 0 }
+.fc .fc-list-event.fc-event-forced-url {
+    cursor: pointer; /* whole row will seem clickable */
+  }
+.fc .fc-list-event:hover td {
+    background-color: #f5f5f5;
+    background-color: var(--fc-list-event-hover-bg-color, #f5f5f5);
+  }
+.fc {
+
+  /* shrink certain cols */
+
+}
+.fc .fc-list-event-graphic,
+  .fc .fc-list-event-time {
+    white-space: nowrap;
+    width: 1px;
+  }
+.fc .fc-list-event-dot {
+    display: inline-block;
+    box-sizing: content-box;
+    width: 0;
+    height: 0;
+    border: 5px solid #3788d8;
+    border: calc(var(--fc-list-event-dot-width, 10px) / 2) solid var(--fc-event-border-color, #3788d8);
+    border-radius: 5px;
+    border-radius: calc(var(--fc-list-event-dot-width, 10px) / 2);
+  }
+.fc {
+
+  /* reset <a> styling */
+
+}
+.fc .fc-list-event-title a {
+    color: inherit;
+    text-decoration: none;
+  }
+.fc {
+
+  /* underline link when hovering over any part of row */
+
+}
+.fc .fc-list-event.fc-event-forced-url:hover a {
+    text-decoration: underline;
+  }
+
+
+
+  .fc-theme-bootstrap a:not([href]) {
+    color: inherit; /* natural color for navlinks */
+  }
+
+
+
+  .fc-theme-bootstrap5 a:not([href]) {
+    color: inherit;
+    text-decoration: inherit;
+  }
+
+.fc-theme-bootstrap5 .fc-list,
+  .fc-theme-bootstrap5 .fc-scrollgrid,
+  .fc-theme-bootstrap5 td,
+  .fc-theme-bootstrap5 th {
+    border: 1px solid var(--bs-gray-400);
+  }
+
+.fc-theme-bootstrap5 {
+
+  /* HACK: reapply core styles after highe-precedence border statement above */
+}
+
+.fc-theme-bootstrap5 .fc-scrollgrid {
+    border-right-width: 0;
+    border-bottom-width: 0;
+  }
+
+.fc-theme-bootstrap5-shaded {
+  background-color: var(--bs-gray-200);
+}
+
diff --git a/static_common/common/vendor/fullcalendar/main.js b/static_common/common/vendor/fullcalendar/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..c0b937b01bbf25db05c4fd05417e3e0ecca3e264
--- /dev/null
+++ b/static_common/common/vendor/fullcalendar/main.js
@@ -0,0 +1,15018 @@
+/*!
+FullCalendar v5.11.3
+Docs & License: https://fullcalendar.io/
+(c) 2022 Adam Shaw
+*/
+var FullCalendar = (function (exports) {
+    'use strict';
+
+    /*! *****************************************************************************
+    Copyright (c) Microsoft Corporation.
+
+    Permission to use, copy, modify, and/or distribute this software for any
+    purpose with or without fee is hereby granted.
+
+    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+    PERFORMANCE OF THIS SOFTWARE.
+    ***************************************************************************** */
+    /* global Reflect, Promise */
+
+    var extendStatics = function(d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+
+    function __extends(d, b) {
+        if (typeof b !== "function" && b !== null)
+            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    }
+
+    var __assign = function() {
+        __assign = Object.assign || function __assign(t) {
+            for (var s, i = 1, n = arguments.length; i < n; i++) {
+                s = arguments[i];
+                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
+            }
+            return t;
+        };
+        return __assign.apply(this, arguments);
+    };
+
+    function __spreadArray(to, from, pack) {
+        if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+            if (ar || !(i in from)) {
+                if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+                ar[i] = from[i];
+            }
+        }
+        return to.concat(ar || from);
+    }
+
+    var n,u,i$1,t,o,r$1={},f$1=[],e$1=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function c$1(n,l){for(var u in l)n[u]=l[u];return n}function s(n){var l=n.parentNode;l&&l.removeChild(n);}function a$1(n,l,u){var i,t,o,r=arguments,f={};for(o in l)"key"==o?i=l[o]:"ref"==o?t=l[o]:f[o]=l[o];if(arguments.length>3)for(u=[u],o=3;o<arguments.length;o++)u.push(r[o]);if(null!=u&&(f.children=u),"function"==typeof n&&null!=n.defaultProps)for(o in n.defaultProps)void 0===f[o]&&(f[o]=n.defaultProps[o]);return v$1(n,f,i,t,null)}function v$1(l,u,i,t,o){var r={type:l,props:u,key:i,ref:t,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++n.__v:o};return null!=n.vnode&&n.vnode(r),r}function h(){return {current:null}}function y(n){return n.children}function p(n,l){this.props=n,this.context=l;}function d(n,l){if(null==l)return n.__?d(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?d(n):null}function _(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return _(n)}}function k(l){(!l.__d&&(l.__d=!0)&&u.push(l)&&!b$1.__r++||t!==n.debounceRendering)&&((t=n.debounceRendering)||i$1)(b$1);}function b$1(){for(var n;b$1.__r=u.length;)n=u.sort(function(n,l){return n.__v.__b-l.__v.__b}),u=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=c$1({},t)).__v=t.__v+1,I$1(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?d(t):o,t.__h),T$1(u,t),t.__e!=o&&_(t)));});}function m(n,l,u,i,t,o,e,c,s,a){var h,p,_,k,b,m,w,A=i&&i.__k||f$1,P=A.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(k=u.__k[h]=null==(k=l[h])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k||"bigint"==typeof k?v$1(null,k,null,null,k):Array.isArray(k)?v$1(y,{children:k},null,null,null):k.__b>0?v$1(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(_=A[h])||_&&k.key==_.key&&k.type===_.type)A[h]=void 0;else for(p=0;p<P;p++){if((_=A[p])&&k.key==_.key&&k.type===_.type){A[p]=void 0;break}_=null;}I$1(n,k,_=_||r$1,t,o,e,c,s,a),b=k.__e,(p=k.ref)&&_.ref!=p&&(w||(w=[]),_.ref&&w.push(_.ref,null,k),w.push(p,k.__c||b,k)),null!=b?(null==m&&(m=b),"function"==typeof k.type&&null!=k.__k&&k.__k===_.__k?k.__d=s=g$1(k,s,n):s=x$1(n,k,_,A,b,s),a||"option"!==u.type?"function"==typeof u.type&&(u.__d=s):n.value=""):s&&_.__e==s&&s.parentNode!=n&&(s=d(_));}for(u.__e=m,h=P;h--;)null!=A[h]&&("function"==typeof u.type&&null!=A[h].__e&&A[h].__e==u.__d&&(u.__d=d(i,h+1)),L$1(A[h],A[h]));if(w)for(h=0;h<w.length;h++)z(w[h],w[++h],w[++h]);}function g$1(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,l="function"==typeof t.type?g$1(t,l,u):x$1(u,t,t,n.__k,t.__e,l));return l}function w$1(n,l){return l=l||[],null==n||"boolean"==typeof n||(Array.isArray(n)?n.some(function(n){w$1(n,l);}):l.push(n)),l}function x$1(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else {for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o;}return void 0!==r?r:t.nextSibling}function A$1(n,l,u,i,t){var o;for(o in u)"children"===o||"key"===o||o in l||C$1(n,o,null,u[o],i);for(o in l)t&&"function"!=typeof l[o]||"children"===o||"key"===o||"value"===o||"checked"===o||u[o]===l[o]||C$1(n,o,l[o],u[o],i);}function P$1(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||e$1.test(l)?u:u+"px";}function C$1(n,l,u,i,t){var o;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||P$1(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||P$1(n.style,l,u[l]);}else if("o"===l[0]&&"n"===l[1])o=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?H$1:$$1,o):n.removeEventListener(l,o?H$1:$$1,o);else if("dangerouslySetInnerHTML"!==l){if(t)l=l.replace(/xlink[H:h]/,"h").replace(/sName$/,"s");else if("href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null!=u&&(!1!==u||"a"===l[0]&&"r"===l[1])?n.setAttribute(l,u):n.removeAttribute(l));}}function $$1(l){this.l[l.type+!1](n.event?n.event(l):l);}function H$1(l){this.l[l.type+!0](n.event?n.event(l):l);}function I$1(l,u,i,t,o,r,f,e,s){var a,v,h,d,_,k,b,g,w,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(s=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=n.__b)&&a(u);try{n:if("function"==typeof P){if(g=u.props,w=(a=P.contextType)&&t[a.__c],x=a?w?w.props.value:a.__:t,i.__c?b=(v=u.__c=i.__c).__=v.__E:("prototype"in P&&P.prototype.render?u.__c=v=new P(g,x):(u.__c=v=new p(g,x),v.constructor=P,v.render=M$1),w&&w.sub(v),v.props=g,v.state||(v.state={}),v.context=x,v.__n=t,h=v.__d=!0,v.__h=[]),null==v.__s&&(v.__s=v.state),null!=P.getDerivedStateFromProps&&(v.__s==v.state&&(v.__s=c$1({},v.__s)),c$1(v.__s,P.getDerivedStateFromProps(g,v.__s))),d=v.props,_=v.state,h)null==P.getDerivedStateFromProps&&null!=v.componentWillMount&&v.componentWillMount(),null!=v.componentDidMount&&v.__h.push(v.componentDidMount);else {if(null==P.getDerivedStateFromProps&&g!==d&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(g,x),!v.__e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(g,v.__s,x)||u.__v===i.__v){v.props=g,v.state=v.__s,u.__v!==i.__v&&(v.__d=!1),v.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u);}),v.__h.length&&f.push(v);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(g,v.__s,x),null!=v.componentDidUpdate&&v.__h.push(function(){v.componentDidUpdate(d,_,k);});}v.context=x,v.props=g,v.state=v.__s,(a=n.__r)&&a(u),v.__d=!1,v.__v=u,v.__P=l,a=v.render(v.props,v.state,v.context),v.state=v.__s,null!=v.getChildContext&&(t=c$1(c$1({},t),v.getChildContext())),h||null==v.getSnapshotBeforeUpdate||(k=v.getSnapshotBeforeUpdate(d,_)),A=null!=a&&a.type===y&&null==a.key?a.props.children:a,m(l,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,s),v.base=u.__e,u.__h=null,v.__h.length&&f.push(v),b&&(v.__E=v.__=null),v.__e=!1;}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=j$2(i.__e,u,i,t,o,r,f,s);(a=n.diffed)&&a(u);}catch(l){u.__v=null,(s||null!=r)&&(u.__e=e,u.__h=!!s,r[r.indexOf(e)]=null),n.__e(l,u,i);}}function T$1(l,u){n.__c&&n.__c(u,l),l.some(function(u){try{l=u.__h,u.__h=[],l.some(function(n){n.call(u);});}catch(l){n.__e(l,u.__v);}});}function j$2(n,l,u,i,t,o,e,c){var a,v,h,y,p=u.props,d=l.props,_=l.type,k=0;if("svg"===_&&(t=!0),null!=o)for(;k<o.length;k++)if((a=o[k])&&(a===n||(_?a.localName==_:3==a.nodeType))){n=a,o[k]=null;break}if(null==n){if(null===_)return document.createTextNode(d);n=t?document.createElementNS("http://www.w3.org/2000/svg",_):document.createElement(_,d.is&&d),o=null,c=!1;}if(null===_)p===d||c&&n.data===d||(n.data=d);else {if(o=o&&f$1.slice.call(n.childNodes),v=(p=u.props||r$1).dangerouslySetInnerHTML,h=d.dangerouslySetInnerHTML,!c){if(null!=o)for(p={},y=0;y<n.attributes.length;y++)p[n.attributes[y].name]=n.attributes[y].value;(h||v)&&(h&&(v&&h.__html==v.__html||h.__html===n.innerHTML)||(n.innerHTML=h&&h.__html||""));}if(A$1(n,d,p,t,c),h)l.__k=[];else if(k=l.props.children,m(n,Array.isArray(k)?k:[k],l,u,i,t&&"foreignObject"!==_,o,e,n.firstChild,c),null!=o)for(k=o.length;k--;)null!=o[k]&&s(o[k]);c||("value"in d&&void 0!==(k=d.value)&&(k!==n.value||"progress"===_&&!k)&&C$1(n,"value",k,p.value,!1),"checked"in d&&void 0!==(k=d.checked)&&k!==n.checked&&C$1(n,"checked",k,p.checked,!1));}return n}function z(l,u,i){try{"function"==typeof l?l(u):l.current=u;}catch(l){n.__e(l,i);}}function L$1(l,u,i){var t,o,r;if(n.unmount&&n.unmount(l),(t=l.ref)&&(t.current&&t.current!==l.__e||z(t,null,u)),i||"function"==typeof l.type||(i=null!=(o=l.__e)),l.__e=l.__d=void 0,null!=(t=l.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(l){n.__e(l,u);}t.base=t.__P=null;}if(t=l.__k)for(r=0;r<t.length;r++)t[r]&&L$1(t[r],u,i);null!=o&&s(o);}function M$1(n,l,u){return this.constructor(n,u)}function N(l,u,i){var t,o,e;n.__&&n.__(l,u),o=(t="function"==typeof i)?null:i&&i.__k||u.__k,e=[],I$1(u,l=(!t&&i||u).__k=a$1(y,null,[l]),o||r$1,r$1,void 0!==u.ownerSVGElement,!t&&i?[i]:o?null:u.firstChild?f$1.slice.call(u.childNodes):null,e,!t&&i?i:o?o.__e:u.firstChild,t),T$1(e,l);}function q(n,l){var u={__c:l="__cC"+o++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(k);},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l;}throw n},__v:0},p.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=c$1({},this.state),"function"==typeof n&&(n=n(c$1({},u),this.props)),n&&c$1(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),k(this));},p.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),k(this));},p.prototype.render=y,u=[],i$1="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,b$1.__r=0,o=0;
+
+    var r,i=[],c=n.__b,f=n.__r,e=n.diffed,a=n.__c,v=n.unmount;function x(){i.forEach(function(t){if(t.__P)try{t.__H.__h.forEach(g),t.__H.__h.forEach(j$1),t.__H.__h=[];}catch(u){t.__H.__h=[],n.__e(u,t.__v);}}),i=[];}n.__b=function(n){c&&c(n);},n.__r=function(n){f&&f(n);var r=(n.__c).__H;r&&(r.__h.forEach(g),r.__h.forEach(j$1),r.__h=[]);},n.diffed=function(t){e&&e(t);var o=t.__c;o&&o.__H&&o.__H.__h.length&&(1!==i.push(o)&&r===n.requestAnimationFrame||((r=n.requestAnimationFrame)||function(n){var t,u=function(){clearTimeout(r),b&&cancelAnimationFrame(t),setTimeout(n);},r=setTimeout(u,100);b&&(t=requestAnimationFrame(u));})(x));},n.__c=function(t,u){u.some(function(t){try{t.__h.forEach(g),t.__h=t.__h.filter(function(n){return !n.__||j$1(n)});}catch(r){u.some(function(n){n.__h&&(n.__h=[]);}),u=[],n.__e(r,t.__v);}}),a&&a(t,u);},n.unmount=function(t){v&&v(t);var u=t.__c;if(u&&u.__H)try{u.__H.__.forEach(g);}catch(t){n.__e(t,u.__v);}};var b="function"==typeof requestAnimationFrame;function g(n){"function"==typeof n.__c&&n.__c();}function j$1(n){n.__c=n.__();}
+
+    function C(n,t){for(var e in t)n[e]=t[e];return n}function S(n,t){for(var e in n)if("__source"!==e&&!(e in t))return !0;for(var r in t)if("__source"!==r&&n[r]!==t[r])return !0;return !1}function E(n){this.props=n;}(E.prototype=new p).isPureReactComponent=!0,E.prototype.shouldComponentUpdate=function(n,t){return S(this.props,n)||S(this.state,t)};var w=n.__b;n.__b=function(n){n.type&&n.type.__f&&n.ref&&(n.props.ref=n.ref,n.ref=null),w&&w(n);};var A=n.__e;n.__e=function(n,t,e){if(n.then)for(var r,u=t;u=u.__;)if((r=u.__c)&&r.__c)return null==t.__e&&(t.__e=e.__e,t.__k=e.__k),r.__c(n,t);A(n,t,e);};var O=n.unmount;function L(){this.__u=0,this.t=null,this.__b=null;}function U(n){var t=n.__.__c;return t&&t.__e&&t.__e(n)}function F(){this.u=null,this.o=null;}n.unmount=function(n){var t=n.__c;t&&t.__R&&t.__R(),t&&!0===n.__h&&(n.type=null),O&&O(n);},(L.prototype=new p).__c=function(n,t){var e=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(e);var u=U(r.__v),o=!1,i=function(){o||(o=!0,e.__R=null,u?u(l):l());};e.__R=i;var l=function(){if(!--r.__u){if(r.state.__e){var n=r.state.__e;r.__v.__k[0]=function n(t,e,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)}),t.__c&&t.__c.__P===e&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(n,n.__c.__P,n.__c.__O);}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate();}},f=!0===t.__h;r.__u++||f||r.setState({__e:r.__b=r.__v.__k[0]}),n.then(i,i);},L.prototype.componentWillUnmount=function(){this.t=[];},L.prototype.render=function(n,t){if(this.__b){if(this.__v.__k){var e=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function n(t,e,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach(function(n){"function"==typeof n.__c&&n.__c();}),t.__c.__H=null),null!=(t=C({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=e),t.__c=null),t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)})),t}(this.__b,e,r.__O=r.__P);}this.__b=null;}var u=t.__e&&a$1(y,null,n.fallback);return u&&(u.__h=null),[a$1(y,null,t.__e?null:n.children),u]};var M=function(n,t,e){if(++e[1]===e[0]&&n.o.delete(t),n.props.revealOrder&&("t"!==n.props.revealOrder[0]||!n.o.size))for(e=n.u;e;){for(;e.length>3;)e.pop()();if(e[1]<e[0])break;n.u=e=e[2];}};function T(n){return this.getChildContext=function(){return n.context},n.children}function j(n){var t=this,e=n.i;t.componentWillUnmount=function(){N(null,t.l),t.l=null,t.i=null;},t.i&&t.i!==e&&t.componentWillUnmount(),n.__v?(t.l||(t.i=e,t.l={nodeType:1,parentNode:e,childNodes:[],appendChild:function(n){this.childNodes.push(n),t.i.appendChild(n);},insertBefore:function(n,e){this.childNodes.push(n),t.i.appendChild(n);},removeChild:function(n){this.childNodes.splice(this.childNodes.indexOf(n)>>>1,1),t.i.removeChild(n);}}),N(a$1(T,{context:t.context},n.__v),t.l)):t.l&&t.componentWillUnmount();}function I(n,t){return a$1(j,{__v:n,i:t})}(F.prototype=new p).__e=function(n){var t=this,e=U(t.__v),r=t.o.get(n);return r[0]++,function(u){var o=function(){t.props.revealOrder?(r.push(u),M(t,n,r)):u();};e?e(o):o();}},F.prototype.render=function(n){this.u=null,this.o=new Map;var t=w$1(n.children);n.revealOrder&&"b"===n.revealOrder[0]&&t.reverse();for(var e=t.length;e--;)this.o.set(t[e],this.u=[1,0,this.u]);return n.children},F.prototype.componentDidUpdate=F.prototype.componentDidMount=function(){var n=this;this.o.forEach(function(t,e){M(n,e,t);});};var W="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,P=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,V=function(n){return ("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(n)};p.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(n){Object.defineProperty(p.prototype,n,{configurable:!0,get:function(){return this["UNSAFE_"+n]},set:function(t){Object.defineProperty(this,n,{configurable:!0,writable:!0,value:t});}});});var H=n.event;function Z(){}function Y(){return this.cancelBubble}function $(){return this.defaultPrevented}n.event=function(n){return H&&(n=H(n)),n.persist=Z,n.isPropagationStopped=Y,n.isDefaultPrevented=$,n.nativeEvent=n};var G={configurable:!0,get:function(){return this.class}},J=n.vnode;n.vnode=function(n){var t=n.type,e=n.props,r=e;if("string"==typeof t){for(var u in r={},e){var o=e[u];"value"===u&&"defaultValue"in e&&null==o||("defaultValue"===u&&"value"in e&&null==e.value?u="value":"download"===u&&!0===o?o="":/ondoubleclick/i.test(u)?u="ondblclick":/^onchange(textarea|input)/i.test(u+t)&&!V(e.type)?u="oninput":/^on(Ani|Tra|Tou|BeforeInp)/.test(u)?u=u.toLowerCase():P.test(u)?u=u.replace(/[A-Z0-9]/,"-$&").toLowerCase():null===o&&(o=void 0),r[u]=o);}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=w$1(e.children).forEach(function(n){n.props.selected=-1!=r.value.indexOf(n.props.value);})),"select"==t&&null!=r.defaultValue&&(r.value=w$1(e.children).forEach(function(n){n.props.selected=r.multiple?-1!=r.defaultValue.indexOf(n.props.value):r.defaultValue==n.props.value;})),n.props=r;}t&&e.class!=e.className&&(G.enumerable="className"in e,null!=e.className&&(r.class=e.className),Object.defineProperty(r,"className",G)),n.$$typeof=W,J&&J(n);};var K=n.__r;n.__r=function(n){K&&K(n);};"object"==typeof performance&&"function"==typeof performance.now?performance.now.bind(performance):function(){return Date.now()};
+
+    var globalObj = typeof globalThis !== 'undefined' ? globalThis : window; // // TODO: streamline when killing IE11 support
+    if (globalObj.FullCalendarVDom) {
+        console.warn('FullCalendar VDOM already loaded');
+    }
+    else {
+        globalObj.FullCalendarVDom = {
+            Component: p,
+            createElement: a$1,
+            render: N,
+            createRef: h,
+            Fragment: y,
+            createContext: createContext$1,
+            createPortal: I,
+            flushSync: flushSync$1,
+            unmountComponentAtNode: unmountComponentAtNode$1,
+        };
+    }
+    // HACKS...
+    // TODO: lock version
+    // TODO: link gh issues
+    function flushSync$1(runBeforeFlush) {
+        runBeforeFlush();
+        var oldDebounceRendering = n.debounceRendering; // orig
+        var callbackQ = [];
+        function execCallbackSync(callback) {
+            callbackQ.push(callback);
+        }
+        n.debounceRendering = execCallbackSync;
+        N(a$1(FakeComponent, {}), document.createElement('div'));
+        while (callbackQ.length) {
+            callbackQ.shift()();
+        }
+        n.debounceRendering = oldDebounceRendering;
+    }
+    var FakeComponent = /** @class */ (function (_super) {
+        __extends(FakeComponent, _super);
+        function FakeComponent() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        FakeComponent.prototype.render = function () { return a$1('div', {}); };
+        FakeComponent.prototype.componentDidMount = function () { this.setState({}); };
+        return FakeComponent;
+    }(p));
+    function createContext$1(defaultValue) {
+        var ContextType = q(defaultValue);
+        var origProvider = ContextType.Provider;
+        ContextType.Provider = function () {
+            var _this = this;
+            var isNew = !this.getChildContext;
+            var children = origProvider.apply(this, arguments); // eslint-disable-line prefer-rest-params
+            if (isNew) {
+                var subs_1 = [];
+                this.shouldComponentUpdate = function (_props) {
+                    if (_this.props.value !== _props.value) {
+                        subs_1.forEach(function (c) {
+                            c.context = _props.value;
+                            c.forceUpdate();
+                        });
+                    }
+                };
+                this.sub = function (c) {
+                    subs_1.push(c);
+                    var old = c.componentWillUnmount;
+                    c.componentWillUnmount = function () {
+                        subs_1.splice(subs_1.indexOf(c), 1);
+                        old && old.call(c);
+                    };
+                };
+            }
+            return children;
+        };
+        return ContextType;
+    }
+    function unmountComponentAtNode$1(node) {
+        N(null, node);
+    }
+
+    // no public types yet. when there are, export from:
+    // import {} from './api-type-deps'
+    var EventSourceApi = /** @class */ (function () {
+        function EventSourceApi(context, internalEventSource) {
+            this.context = context;
+            this.internalEventSource = internalEventSource;
+        }
+        EventSourceApi.prototype.remove = function () {
+            this.context.dispatch({
+                type: 'REMOVE_EVENT_SOURCE',
+                sourceId: this.internalEventSource.sourceId,
+            });
+        };
+        EventSourceApi.prototype.refetch = function () {
+            this.context.dispatch({
+                type: 'FETCH_EVENT_SOURCES',
+                sourceIds: [this.internalEventSource.sourceId],
+                isRefetch: true,
+            });
+        };
+        Object.defineProperty(EventSourceApi.prototype, "id", {
+            get: function () {
+                return this.internalEventSource.publicId;
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventSourceApi.prototype, "url", {
+            get: function () {
+                return this.internalEventSource.meta.url;
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventSourceApi.prototype, "format", {
+            get: function () {
+                return this.internalEventSource.meta.format; // TODO: bad. not guaranteed
+            },
+            enumerable: false,
+            configurable: true
+        });
+        return EventSourceApi;
+    }());
+
+    function removeElement(el) {
+        if (el.parentNode) {
+            el.parentNode.removeChild(el);
+        }
+    }
+    // Querying
+    // ----------------------------------------------------------------------------------------------------------------
+    function elementClosest(el, selector) {
+        if (el.closest) {
+            return el.closest(selector);
+            // really bad fallback for IE
+            // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
+        }
+        if (!document.documentElement.contains(el)) {
+            return null;
+        }
+        do {
+            if (elementMatches(el, selector)) {
+                return el;
+            }
+            el = (el.parentElement || el.parentNode);
+        } while (el !== null && el.nodeType === 1);
+        return null;
+    }
+    function elementMatches(el, selector) {
+        var method = el.matches || el.matchesSelector || el.msMatchesSelector;
+        return method.call(el, selector);
+    }
+    // accepts multiple subject els
+    // returns a real array. good for methods like forEach
+    // TODO: accept the document
+    function findElements(container, selector) {
+        var containers = container instanceof HTMLElement ? [container] : container;
+        var allMatches = [];
+        for (var i = 0; i < containers.length; i += 1) {
+            var matches = containers[i].querySelectorAll(selector);
+            for (var j = 0; j < matches.length; j += 1) {
+                allMatches.push(matches[j]);
+            }
+        }
+        return allMatches;
+    }
+    // accepts multiple subject els
+    // only queries direct child elements // TODO: rename to findDirectChildren!
+    function findDirectChildren(parent, selector) {
+        var parents = parent instanceof HTMLElement ? [parent] : parent;
+        var allMatches = [];
+        for (var i = 0; i < parents.length; i += 1) {
+            var childNodes = parents[i].children; // only ever elements
+            for (var j = 0; j < childNodes.length; j += 1) {
+                var childNode = childNodes[j];
+                if (!selector || elementMatches(childNode, selector)) {
+                    allMatches.push(childNode);
+                }
+            }
+        }
+        return allMatches;
+    }
+    // Style
+    // ----------------------------------------------------------------------------------------------------------------
+    var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;
+    function applyStyle(el, props) {
+        for (var propName in props) {
+            applyStyleProp(el, propName, props[propName]);
+        }
+    }
+    function applyStyleProp(el, name, val) {
+        if (val == null) {
+            el.style[name] = '';
+        }
+        else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
+            el.style[name] = val + "px";
+        }
+        else {
+            el.style[name] = val;
+        }
+    }
+    // Event Handling
+    // ----------------------------------------------------------------------------------------------------------------
+    // if intercepting bubbled events at the document/window/body level,
+    // and want to see originating element (the 'target'), use this util instead
+    // of `ev.target` because it goes within web-component boundaries.
+    function getEventTargetViaRoot(ev) {
+        var _a, _b;
+        return (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)[0]) !== null && _b !== void 0 ? _b : ev.target;
+    }
+    // Shadow DOM consuderations
+    // ----------------------------------------------------------------------------------------------------------------
+    function getElRoot(el) {
+        return el.getRootNode ? el.getRootNode() : document;
+    }
+    // Unique ID for DOM attribute
+    var guid$1 = 0;
+    function getUniqueDomId() {
+        guid$1 += 1;
+        return 'fc-dom-' + guid$1;
+    }
+
+    // Stops a mouse/touch event from doing it's native browser action
+    function preventDefault(ev) {
+        ev.preventDefault();
+    }
+    // Event Delegation
+    // ----------------------------------------------------------------------------------------------------------------
+    function buildDelegationHandler(selector, handler) {
+        return function (ev) {
+            var matchedChild = elementClosest(ev.target, selector);
+            if (matchedChild) {
+                handler.call(matchedChild, ev, matchedChild);
+            }
+        };
+    }
+    function listenBySelector(container, eventType, selector, handler) {
+        var attachedHandler = buildDelegationHandler(selector, handler);
+        container.addEventListener(eventType, attachedHandler);
+        return function () {
+            container.removeEventListener(eventType, attachedHandler);
+        };
+    }
+    function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
+        var currentMatchedChild;
+        return listenBySelector(container, 'mouseover', selector, function (mouseOverEv, matchedChild) {
+            if (matchedChild !== currentMatchedChild) {
+                currentMatchedChild = matchedChild;
+                onMouseEnter(mouseOverEv, matchedChild);
+                var realOnMouseLeave_1 = function (mouseLeaveEv) {
+                    currentMatchedChild = null;
+                    onMouseLeave(mouseLeaveEv, matchedChild);
+                    matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1);
+                };
+                // listen to the next mouseleave, and then unattach
+                matchedChild.addEventListener('mouseleave', realOnMouseLeave_1);
+            }
+        });
+    }
+    // Animation
+    // ----------------------------------------------------------------------------------------------------------------
+    var transitionEventNames = [
+        'webkitTransitionEnd',
+        'otransitionend',
+        'oTransitionEnd',
+        'msTransitionEnd',
+        'transitionend',
+    ];
+    // triggered only when the next single subsequent transition finishes
+    function whenTransitionDone(el, callback) {
+        var realCallback = function (ev) {
+            callback(ev);
+            transitionEventNames.forEach(function (eventName) {
+                el.removeEventListener(eventName, realCallback);
+            });
+        };
+        transitionEventNames.forEach(function (eventName) {
+            el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes
+        });
+    }
+    // ARIA workarounds
+    // ----------------------------------------------------------------------------------------------------------------
+    function createAriaClickAttrs(handler) {
+        return __assign({ onClick: handler }, createAriaKeyboardAttrs(handler));
+    }
+    function createAriaKeyboardAttrs(handler) {
+        return {
+            tabIndex: 0,
+            onKeyDown: function (ev) {
+                if (ev.key === 'Enter' || ev.key === ' ') {
+                    handler(ev);
+                    ev.preventDefault(); // if space, don't scroll down page
+                }
+            },
+        };
+    }
+
+    var guidNumber = 0;
+    function guid() {
+        guidNumber += 1;
+        return String(guidNumber);
+    }
+    /* FullCalendar-specific DOM Utilities
+    ----------------------------------------------------------------------------------------------------------------------*/
+    // Make the mouse cursor express that an event is not allowed in the current area
+    function disableCursor() {
+        document.body.classList.add('fc-not-allowed');
+    }
+    // Returns the mouse cursor to its original look
+    function enableCursor() {
+        document.body.classList.remove('fc-not-allowed');
+    }
+    /* Selection
+    ----------------------------------------------------------------------------------------------------------------------*/
+    function preventSelection(el) {
+        el.classList.add('fc-unselectable');
+        el.addEventListener('selectstart', preventDefault);
+    }
+    function allowSelection(el) {
+        el.classList.remove('fc-unselectable');
+        el.removeEventListener('selectstart', preventDefault);
+    }
+    /* Context Menu
+    ----------------------------------------------------------------------------------------------------------------------*/
+    function preventContextMenu(el) {
+        el.addEventListener('contextmenu', preventDefault);
+    }
+    function allowContextMenu(el) {
+        el.removeEventListener('contextmenu', preventDefault);
+    }
+    function parseFieldSpecs(input) {
+        var specs = [];
+        var tokens = [];
+        var i;
+        var token;
+        if (typeof input === 'string') {
+            tokens = input.split(/\s*,\s*/);
+        }
+        else if (typeof input === 'function') {
+            tokens = [input];
+        }
+        else if (Array.isArray(input)) {
+            tokens = input;
+        }
+        for (i = 0; i < tokens.length; i += 1) {
+            token = tokens[i];
+            if (typeof token === 'string') {
+                specs.push(token.charAt(0) === '-' ?
+                    { field: token.substring(1), order: -1 } :
+                    { field: token, order: 1 });
+            }
+            else if (typeof token === 'function') {
+                specs.push({ func: token });
+            }
+        }
+        return specs;
+    }
+    function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
+        var i;
+        var cmp;
+        for (i = 0; i < fieldSpecs.length; i += 1) {
+            cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
+            if (cmp) {
+                return cmp;
+            }
+        }
+        return 0;
+    }
+    function compareByFieldSpec(obj0, obj1, fieldSpec) {
+        if (fieldSpec.func) {
+            return fieldSpec.func(obj0, obj1);
+        }
+        return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])
+            * (fieldSpec.order || 1);
+    }
+    function flexibleCompare(a, b) {
+        if (!a && !b) {
+            return 0;
+        }
+        if (b == null) {
+            return -1;
+        }
+        if (a == null) {
+            return 1;
+        }
+        if (typeof a === 'string' || typeof b === 'string') {
+            return String(a).localeCompare(String(b));
+        }
+        return a - b;
+    }
+    /* String Utilities
+    ----------------------------------------------------------------------------------------------------------------------*/
+    function padStart(val, len) {
+        var s = String(val);
+        return '000'.substr(0, len - s.length) + s;
+    }
+    function formatWithOrdinals(formatter, args, fallbackText) {
+        if (typeof formatter === 'function') {
+            return formatter.apply(void 0, args);
+        }
+        if (typeof formatter === 'string') { // non-blank string
+            return args.reduce(function (str, arg, index) { return (str.replace('$' + index, arg || '')); }, formatter);
+        }
+        return fallbackText;
+    }
+    /* Number Utilities
+    ----------------------------------------------------------------------------------------------------------------------*/
+    function compareNumbers(a, b) {
+        return a - b;
+    }
+    function isInt(n) {
+        return n % 1 === 0;
+    }
+    /* FC-specific DOM dimension stuff
+    ----------------------------------------------------------------------------------------------------------------------*/
+    function computeSmallestCellWidth(cellEl) {
+        var allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame');
+        var contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion');
+        if (!allWidthEl) {
+            throw new Error('needs fc-scrollgrid-shrink-frame className'); // TODO: use const
+        }
+        if (!contentWidthEl) {
+            throw new Error('needs fc-scrollgrid-shrink-cushion className');
+        }
+        return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width + // the cell padding+border
+            contentWidthEl.getBoundingClientRect().width;
+    }
+
+    var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
+    // Adding
+    function addWeeks(m, n) {
+        var a = dateToUtcArray(m);
+        a[2] += n * 7;
+        return arrayToUtcDate(a);
+    }
+    function addDays(m, n) {
+        var a = dateToUtcArray(m);
+        a[2] += n;
+        return arrayToUtcDate(a);
+    }
+    function addMs(m, n) {
+        var a = dateToUtcArray(m);
+        a[6] += n;
+        return arrayToUtcDate(a);
+    }
+    // Diffing (all return floats)
+    // TODO: why not use ranges?
+    function diffWeeks(m0, m1) {
+        return diffDays(m0, m1) / 7;
+    }
+    function diffDays(m0, m1) {
+        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
+    }
+    function diffHours(m0, m1) {
+        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
+    }
+    function diffMinutes(m0, m1) {
+        return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
+    }
+    function diffSeconds(m0, m1) {
+        return (m1.valueOf() - m0.valueOf()) / 1000;
+    }
+    function diffDayAndTime(m0, m1) {
+        var m0day = startOfDay(m0);
+        var m1day = startOfDay(m1);
+        return {
+            years: 0,
+            months: 0,
+            days: Math.round(diffDays(m0day, m1day)),
+            milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()),
+        };
+    }
+    // Diffing Whole Units
+    function diffWholeWeeks(m0, m1) {
+        var d = diffWholeDays(m0, m1);
+        if (d !== null && d % 7 === 0) {
+            return d / 7;
+        }
+        return null;
+    }
+    function diffWholeDays(m0, m1) {
+        if (timeAsMs(m0) === timeAsMs(m1)) {
+            return Math.round(diffDays(m0, m1));
+        }
+        return null;
+    }
+    // Start-Of
+    function startOfDay(m) {
+        return arrayToUtcDate([
+            m.getUTCFullYear(),
+            m.getUTCMonth(),
+            m.getUTCDate(),
+        ]);
+    }
+    function startOfHour(m) {
+        return arrayToUtcDate([
+            m.getUTCFullYear(),
+            m.getUTCMonth(),
+            m.getUTCDate(),
+            m.getUTCHours(),
+        ]);
+    }
+    function startOfMinute(m) {
+        return arrayToUtcDate([
+            m.getUTCFullYear(),
+            m.getUTCMonth(),
+            m.getUTCDate(),
+            m.getUTCHours(),
+            m.getUTCMinutes(),
+        ]);
+    }
+    function startOfSecond(m) {
+        return arrayToUtcDate([
+            m.getUTCFullYear(),
+            m.getUTCMonth(),
+            m.getUTCDate(),
+            m.getUTCHours(),
+            m.getUTCMinutes(),
+            m.getUTCSeconds(),
+        ]);
+    }
+    // Week Computation
+    function weekOfYear(marker, dow, doy) {
+        var y = marker.getUTCFullYear();
+        var w = weekOfGivenYear(marker, y, dow, doy);
+        if (w < 1) {
+            return weekOfGivenYear(marker, y - 1, dow, doy);
+        }
+        var nextW = weekOfGivenYear(marker, y + 1, dow, doy);
+        if (nextW >= 1) {
+            return Math.min(w, nextW);
+        }
+        return w;
+    }
+    function weekOfGivenYear(marker, year, dow, doy) {
+        var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
+        var dayStart = startOfDay(marker);
+        var days = Math.round(diffDays(firstWeekStart, dayStart));
+        return Math.floor(days / 7) + 1; // zero-indexed
+    }
+    // start-of-first-week - start-of-year
+    function firstWeekOffset(year, dow, doy) {
+        // first-week day -- which january is always in the first week (4 for iso, 1 for other)
+        var fwd = 7 + dow - doy;
+        // first-week day local weekday -- which local weekday is fwd
+        var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
+        return -fwdlw + fwd - 1;
+    }
+    // Array Conversion
+    function dateToLocalArray(date) {
+        return [
+            date.getFullYear(),
+            date.getMonth(),
+            date.getDate(),
+            date.getHours(),
+            date.getMinutes(),
+            date.getSeconds(),
+            date.getMilliseconds(),
+        ];
+    }
+    function arrayToLocalDate(a) {
+        return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month
+        a[3] || 0, a[4] || 0, a[5] || 0);
+    }
+    function dateToUtcArray(date) {
+        return [
+            date.getUTCFullYear(),
+            date.getUTCMonth(),
+            date.getUTCDate(),
+            date.getUTCHours(),
+            date.getUTCMinutes(),
+            date.getUTCSeconds(),
+            date.getUTCMilliseconds(),
+        ];
+    }
+    function arrayToUtcDate(a) {
+        // according to web standards (and Safari), a month index is required.
+        // massage if only given a year.
+        if (a.length === 1) {
+            a = a.concat([0]);
+        }
+        return new Date(Date.UTC.apply(Date, a));
+    }
+    // Other Utils
+    function isValidDate(m) {
+        return !isNaN(m.valueOf());
+    }
+    function timeAsMs(m) {
+        return m.getUTCHours() * 1000 * 60 * 60 +
+            m.getUTCMinutes() * 1000 * 60 +
+            m.getUTCSeconds() * 1000 +
+            m.getUTCMilliseconds();
+    }
+
+    function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
+        return {
+            instanceId: guid(),
+            defId: defId,
+            range: range,
+            forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
+            forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo,
+        };
+    }
+
+    var hasOwnProperty = Object.prototype.hasOwnProperty;
+    // Merges an array of objects into a single object.
+    // The second argument allows for an array of property names who's object values will be merged together.
+    function mergeProps(propObjs, complexPropsMap) {
+        var dest = {};
+        if (complexPropsMap) {
+            for (var name_1 in complexPropsMap) {
+                var complexObjs = [];
+                // collect the trailing object values, stopping when a non-object is discovered
+                for (var i = propObjs.length - 1; i >= 0; i -= 1) {
+                    var val = propObjs[i][name_1];
+                    if (typeof val === 'object' && val) { // non-null object
+                        complexObjs.unshift(val);
+                    }
+                    else if (val !== undefined) {
+                        dest[name_1] = val; // if there were no objects, this value will be used
+                        break;
+                    }
+                }
+                // if the trailing values were objects, use the merged value
+                if (complexObjs.length) {
+                    dest[name_1] = mergeProps(complexObjs);
+                }
+            }
+        }
+        // copy values into the destination, going from last to first
+        for (var i = propObjs.length - 1; i >= 0; i -= 1) {
+            var props = propObjs[i];
+            for (var name_2 in props) {
+                if (!(name_2 in dest)) { // if already assigned by previous props or complex props, don't reassign
+                    dest[name_2] = props[name_2];
+                }
+            }
+        }
+        return dest;
+    }
+    function filterHash(hash, func) {
+        var filtered = {};
+        for (var key in hash) {
+            if (func(hash[key], key)) {
+                filtered[key] = hash[key];
+            }
+        }
+        return filtered;
+    }
+    function mapHash(hash, func) {
+        var newHash = {};
+        for (var key in hash) {
+            newHash[key] = func(hash[key], key);
+        }
+        return newHash;
+    }
+    function arrayToHash(a) {
+        var hash = {};
+        for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
+            var item = a_1[_i];
+            hash[item] = true;
+        }
+        return hash;
+    }
+    function buildHashFromArray(a, func) {
+        var hash = {};
+        for (var i = 0; i < a.length; i += 1) {
+            var tuple = func(a[i], i);
+            hash[tuple[0]] = tuple[1];
+        }
+        return hash;
+    }
+    function hashValuesToArray(obj) {
+        var a = [];
+        for (var key in obj) {
+            a.push(obj[key]);
+        }
+        return a;
+    }
+    function isPropsEqual(obj0, obj1) {
+        if (obj0 === obj1) {
+            return true;
+        }
+        for (var key in obj0) {
+            if (hasOwnProperty.call(obj0, key)) {
+                if (!(key in obj1)) {
+                    return false;
+                }
+            }
+        }
+        for (var key in obj1) {
+            if (hasOwnProperty.call(obj1, key)) {
+                if (obj0[key] !== obj1[key]) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    function getUnequalProps(obj0, obj1) {
+        var keys = [];
+        for (var key in obj0) {
+            if (hasOwnProperty.call(obj0, key)) {
+                if (!(key in obj1)) {
+                    keys.push(key);
+                }
+            }
+        }
+        for (var key in obj1) {
+            if (hasOwnProperty.call(obj1, key)) {
+                if (obj0[key] !== obj1[key]) {
+                    keys.push(key);
+                }
+            }
+        }
+        return keys;
+    }
+    function compareObjs(oldProps, newProps, equalityFuncs) {
+        if (equalityFuncs === void 0) { equalityFuncs = {}; }
+        if (oldProps === newProps) {
+            return true;
+        }
+        for (var key in newProps) {
+            if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ;
+            else {
+                return false;
+            }
+        }
+        // check for props that were omitted in the new
+        for (var key in oldProps) {
+            if (!(key in newProps)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    /*
+    assumed "true" equality for handler names like "onReceiveSomething"
+    */
+    function isObjValsEqual(val0, val1, comparator) {
+        if (val0 === val1 || comparator === true) {
+            return true;
+        }
+        if (comparator) {
+            return comparator(val0, val1);
+        }
+        return false;
+    }
+    function collectFromHash(hash, startIndex, endIndex, step) {
+        if (startIndex === void 0) { startIndex = 0; }
+        if (step === void 0) { step = 1; }
+        var res = [];
+        if (endIndex == null) {
+            endIndex = Object.keys(hash).length;
+        }
+        for (var i = startIndex; i < endIndex; i += step) {
+            var val = hash[i];
+            if (val !== undefined) { // will disregard undefined for sparse arrays
+                res.push(val);
+            }
+        }
+        return res;
+    }
+
+    function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) {
+        for (var i = 0; i < recurringTypes.length; i += 1) {
+            var parsed = recurringTypes[i].parse(refined, dateEnv);
+            if (parsed) {
+                var allDay = refined.allDay;
+                if (allDay == null) {
+                    allDay = defaultAllDay;
+                    if (allDay == null) {
+                        allDay = parsed.allDayGuess;
+                        if (allDay == null) {
+                            allDay = false;
+                        }
+                    }
+                }
+                return {
+                    allDay: allDay,
+                    duration: parsed.duration,
+                    typeData: parsed.typeData,
+                    typeId: i,
+                };
+            }
+        }
+        return null;
+    }
+    function expandRecurring(eventStore, framingRange, context) {
+        var dateEnv = context.dateEnv, pluginHooks = context.pluginHooks, options = context.options;
+        var defs = eventStore.defs, instances = eventStore.instances;
+        // remove existing recurring instances
+        // TODO: bad. always expand events as a second step
+        instances = filterHash(instances, function (instance) { return !defs[instance.defId].recurringDef; });
+        for (var defId in defs) {
+            var def = defs[defId];
+            if (def.recurringDef) {
+                var duration = def.recurringDef.duration;
+                if (!duration) {
+                    duration = def.allDay ?
+                        options.defaultAllDayEventDuration :
+                        options.defaultTimedEventDuration;
+                }
+                var starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes);
+                for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) {
+                    var start = starts_1[_i];
+                    var instance = createEventInstance(defId, {
+                        start: start,
+                        end: dateEnv.add(start, duration),
+                    });
+                    instances[instance.instanceId] = instance;
+                }
+            }
+        }
+        return { defs: defs, instances: instances };
+    }
+    /*
+    Event MUST have a recurringDef
+    */
+    function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) {
+        var typeDef = recurringTypes[eventDef.recurringDef.typeId];
+        var markers = typeDef.expand(eventDef.recurringDef.typeData, {
+            start: dateEnv.subtract(framingRange.start, duration),
+            end: framingRange.end,
+        }, dateEnv);
+        // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to
+        if (eventDef.allDay) {
+            markers = markers.map(startOfDay);
+        }
+        return markers;
+    }
+
+    var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
+    var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
+    // Parsing and Creation
+    function createDuration(input, unit) {
+        var _a;
+        if (typeof input === 'string') {
+            return parseString(input);
+        }
+        if (typeof input === 'object' && input) { // non-null object
+            return parseObject(input);
+        }
+        if (typeof input === 'number') {
+            return parseObject((_a = {}, _a[unit || 'milliseconds'] = input, _a));
+        }
+        return null;
+    }
+    function parseString(s) {
+        var m = PARSE_RE.exec(s);
+        if (m) {
+            var sign = m[1] ? -1 : 1;
+            return {
+                years: 0,
+                months: 0,
+                days: sign * (m[2] ? parseInt(m[2], 10) : 0),
+                milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours
+                    (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes
+                    (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds
+                    (m[6] ? parseInt(m[6], 10) : 0) // ms
+                ),
+            };
+        }
+        return null;
+    }
+    function parseObject(obj) {
+        var duration = {
+            years: obj.years || obj.year || 0,
+            months: obj.months || obj.month || 0,
+            days: obj.days || obj.day || 0,
+            milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours
+                (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes
+                (obj.seconds || obj.second || 0) * 1000 + // seconds
+                (obj.milliseconds || obj.millisecond || obj.ms || 0), // ms
+        };
+        var weeks = obj.weeks || obj.week;
+        if (weeks) {
+            duration.days += weeks * 7;
+            duration.specifiedWeeks = true;
+        }
+        return duration;
+    }
+    // Equality
+    function durationsEqual(d0, d1) {
+        return d0.years === d1.years &&
+            d0.months === d1.months &&
+            d0.days === d1.days &&
+            d0.milliseconds === d1.milliseconds;
+    }
+    function asCleanDays(dur) {
+        if (!dur.years && !dur.months && !dur.milliseconds) {
+            return dur.days;
+        }
+        return 0;
+    }
+    // Simple Math
+    function addDurations(d0, d1) {
+        return {
+            years: d0.years + d1.years,
+            months: d0.months + d1.months,
+            days: d0.days + d1.days,
+            milliseconds: d0.milliseconds + d1.milliseconds,
+        };
+    }
+    function subtractDurations(d1, d0) {
+        return {
+            years: d1.years - d0.years,
+            months: d1.months - d0.months,
+            days: d1.days - d0.days,
+            milliseconds: d1.milliseconds - d0.milliseconds,
+        };
+    }
+    function multiplyDuration(d, n) {
+        return {
+            years: d.years * n,
+            months: d.months * n,
+            days: d.days * n,
+            milliseconds: d.milliseconds * n,
+        };
+    }
+    // Conversions
+    // "Rough" because they are based on average-case Gregorian months/years
+    function asRoughYears(dur) {
+        return asRoughDays(dur) / 365;
+    }
+    function asRoughMonths(dur) {
+        return asRoughDays(dur) / 30;
+    }
+    function asRoughDays(dur) {
+        return asRoughMs(dur) / 864e5;
+    }
+    function asRoughMinutes(dur) {
+        return asRoughMs(dur) / (1000 * 60);
+    }
+    function asRoughSeconds(dur) {
+        return asRoughMs(dur) / 1000;
+    }
+    function asRoughMs(dur) {
+        return dur.years * (365 * 864e5) +
+            dur.months * (30 * 864e5) +
+            dur.days * 864e5 +
+            dur.milliseconds;
+    }
+    // Advanced Math
+    function wholeDivideDurations(numerator, denominator) {
+        var res = null;
+        for (var i = 0; i < INTERNAL_UNITS.length; i += 1) {
+            var unit = INTERNAL_UNITS[i];
+            if (denominator[unit]) {
+                var localRes = numerator[unit] / denominator[unit];
+                if (!isInt(localRes) || (res !== null && res !== localRes)) {
+                    return null;
+                }
+                res = localRes;
+            }
+            else if (numerator[unit]) {
+                // needs to divide by something but can't!
+                return null;
+            }
+        }
+        return res;
+    }
+    function greatestDurationDenominator(dur) {
+        var ms = dur.milliseconds;
+        if (ms) {
+            if (ms % 1000 !== 0) {
+                return { unit: 'millisecond', value: ms };
+            }
+            if (ms % (1000 * 60) !== 0) {
+                return { unit: 'second', value: ms / 1000 };
+            }
+            if (ms % (1000 * 60 * 60) !== 0) {
+                return { unit: 'minute', value: ms / (1000 * 60) };
+            }
+            if (ms) {
+                return { unit: 'hour', value: ms / (1000 * 60 * 60) };
+            }
+        }
+        if (dur.days) {
+            if (dur.specifiedWeeks && dur.days % 7 === 0) {
+                return { unit: 'week', value: dur.days / 7 };
+            }
+            return { unit: 'day', value: dur.days };
+        }
+        if (dur.months) {
+            return { unit: 'month', value: dur.months };
+        }
+        if (dur.years) {
+            return { unit: 'year', value: dur.years };
+        }
+        return { unit: 'millisecond', value: 0 };
+    }
+
+    // timeZoneOffset is in minutes
+    function buildIsoString(marker, timeZoneOffset, stripZeroTime) {
+        if (stripZeroTime === void 0) { stripZeroTime = false; }
+        var s = marker.toISOString();
+        s = s.replace('.000', '');
+        if (stripZeroTime) {
+            s = s.replace('T00:00:00Z', '');
+        }
+        if (s.length > 10) { // time part wasn't stripped, can add timezone info
+            if (timeZoneOffset == null) {
+                s = s.replace('Z', '');
+            }
+            else if (timeZoneOffset !== 0) {
+                s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
+            }
+            // otherwise, its UTC-0 and we want to keep the Z
+        }
+        return s;
+    }
+    // formats the date, but with no time part
+    // TODO: somehow merge with buildIsoString and stripZeroTime
+    // TODO: rename. omit "string"
+    function formatDayString(marker) {
+        return marker.toISOString().replace(/T.*$/, '');
+    }
+    // TODO: use Date::toISOString and use everything after the T?
+    function formatIsoTimeString(marker) {
+        return padStart(marker.getUTCHours(), 2) + ':' +
+            padStart(marker.getUTCMinutes(), 2) + ':' +
+            padStart(marker.getUTCSeconds(), 2);
+    }
+    function formatTimeZoneOffset(minutes, doIso) {
+        if (doIso === void 0) { doIso = false; }
+        var sign = minutes < 0 ? '-' : '+';
+        var abs = Math.abs(minutes);
+        var hours = Math.floor(abs / 60);
+        var mins = Math.round(abs % 60);
+        if (doIso) {
+            return sign + padStart(hours, 2) + ":" + padStart(mins, 2);
+        }
+        return "GMT" + sign + hours + (mins ? ":" + padStart(mins, 2) : '');
+    }
+
+    // TODO: new util arrayify?
+    function removeExact(array, exactVal) {
+        var removeCnt = 0;
+        var i = 0;
+        while (i < array.length) {
+            if (array[i] === exactVal) {
+                array.splice(i, 1);
+                removeCnt += 1;
+            }
+            else {
+                i += 1;
+            }
+        }
+        return removeCnt;
+    }
+    function isArraysEqual(a0, a1, equalityFunc) {
+        if (a0 === a1) {
+            return true;
+        }
+        var len = a0.length;
+        var i;
+        if (len !== a1.length) { // not array? or not same length?
+            return false;
+        }
+        for (i = 0; i < len; i += 1) {
+            if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    function memoize(workerFunc, resEquality, teardownFunc) {
+        var currentArgs;
+        var currentRes;
+        return function () {
+            var newArgs = [];
+            for (var _i = 0; _i < arguments.length; _i++) {
+                newArgs[_i] = arguments[_i];
+            }
+            if (!currentArgs) {
+                currentRes = workerFunc.apply(this, newArgs);
+            }
+            else if (!isArraysEqual(currentArgs, newArgs)) {
+                if (teardownFunc) {
+                    teardownFunc(currentRes);
+                }
+                var res = workerFunc.apply(this, newArgs);
+                if (!resEquality || !resEquality(res, currentRes)) {
+                    currentRes = res;
+                }
+            }
+            currentArgs = newArgs;
+            return currentRes;
+        };
+    }
+    function memoizeObjArg(workerFunc, resEquality, teardownFunc) {
+        var _this = this;
+        var currentArg;
+        var currentRes;
+        return function (newArg) {
+            if (!currentArg) {
+                currentRes = workerFunc.call(_this, newArg);
+            }
+            else if (!isPropsEqual(currentArg, newArg)) {
+                if (teardownFunc) {
+                    teardownFunc(currentRes);
+                }
+                var res = workerFunc.call(_this, newArg);
+                if (!resEquality || !resEquality(res, currentRes)) {
+                    currentRes = res;
+                }
+            }
+            currentArg = newArg;
+            return currentRes;
+        };
+    }
+    function memoizeArraylike(// used at all?
+    workerFunc, resEquality, teardownFunc) {
+        var _this = this;
+        var currentArgSets = [];
+        var currentResults = [];
+        return function (newArgSets) {
+            var currentLen = currentArgSets.length;
+            var newLen = newArgSets.length;
+            var i = 0;
+            for (; i < currentLen; i += 1) {
+                if (!newArgSets[i]) { // one of the old sets no longer exists
+                    if (teardownFunc) {
+                        teardownFunc(currentResults[i]);
+                    }
+                }
+                else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) {
+                    if (teardownFunc) {
+                        teardownFunc(currentResults[i]);
+                    }
+                    var res = workerFunc.apply(_this, newArgSets[i]);
+                    if (!resEquality || !resEquality(res, currentResults[i])) {
+                        currentResults[i] = res;
+                    }
+                }
+            }
+            for (; i < newLen; i += 1) {
+                currentResults[i] = workerFunc.apply(_this, newArgSets[i]);
+            }
+            currentArgSets = newArgSets;
+            currentResults.splice(newLen); // remove excess
+            return currentResults;
+        };
+    }
+    function memoizeHashlike(workerFunc, resEquality, teardownFunc) {
+        var _this = this;
+        var currentArgHash = {};
+        var currentResHash = {};
+        return function (newArgHash) {
+            var newResHash = {};
+            for (var key in newArgHash) {
+                if (!currentResHash[key]) {
+                    newResHash[key] = workerFunc.apply(_this, newArgHash[key]);
+                }
+                else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) {
+                    if (teardownFunc) {
+                        teardownFunc(currentResHash[key]);
+                    }
+                    var res = workerFunc.apply(_this, newArgHash[key]);
+                    newResHash[key] = (resEquality && resEquality(res, currentResHash[key]))
+                        ? currentResHash[key]
+                        : res;
+                }
+                else {
+                    newResHash[key] = currentResHash[key];
+                }
+            }
+            currentArgHash = newArgHash;
+            currentResHash = newResHash;
+            return newResHash;
+        };
+    }
+
+    var EXTENDED_SETTINGS_AND_SEVERITIES = {
+        week: 3,
+        separator: 0,
+        omitZeroMinute: 0,
+        meridiem: 0,
+        omitCommas: 0,
+    };
+    var STANDARD_DATE_PROP_SEVERITIES = {
+        timeZoneName: 7,
+        era: 6,
+        year: 5,
+        month: 4,
+        day: 2,
+        weekday: 2,
+        hour: 1,
+        minute: 1,
+        second: 1,
+    };
+    var MERIDIEM_RE = /\s*([ap])\.?m\.?/i; // eats up leading spaces too
+    var COMMA_RE = /,/g; // we need re for globalness
+    var MULTI_SPACE_RE = /\s+/g;
+    var LTR_RE = /\u200e/g; // control character
+    var UTC_RE = /UTC|GMT/;
+    var NativeFormatter = /** @class */ (function () {
+        function NativeFormatter(formatSettings) {
+            var standardDateProps = {};
+            var extendedSettings = {};
+            var severity = 0;
+            for (var name_1 in formatSettings) {
+                if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) {
+                    extendedSettings[name_1] = formatSettings[name_1];
+                    severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity);
+                }
+                else {
+                    standardDateProps[name_1] = formatSettings[name_1];
+                    if (name_1 in STANDARD_DATE_PROP_SEVERITIES) { // TODO: what about hour12? no severity
+                        severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity);
+                    }
+                }
+            }
+            this.standardDateProps = standardDateProps;
+            this.extendedSettings = extendedSettings;
+            this.severity = severity;
+            this.buildFormattingFunc = memoize(buildFormattingFunc);
+        }
+        NativeFormatter.prototype.format = function (date, context) {
+            return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
+        };
+        NativeFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
+            var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings;
+            var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
+            if (!diffSeverity) {
+                return this.format(start, context);
+            }
+            var biggestUnitForPartial = diffSeverity;
+            if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time
+                (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&
+                (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&
+                (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
+                biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time
+            }
+            var full0 = this.format(start, context);
+            var full1 = this.format(end, context);
+            if (full0 === full1) {
+                return full0;
+            }
+            var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial);
+            var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
+            var partial0 = partialFormattingFunc(start);
+            var partial1 = partialFormattingFunc(end);
+            var insertion = findCommonInsertion(full0, partial0, full1, partial1);
+            var separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || '';
+            if (insertion) {
+                return insertion.before + partial0 + separator + partial1 + insertion.after;
+            }
+            return full0 + separator + full1;
+        };
+        NativeFormatter.prototype.getLargestUnit = function () {
+            switch (this.severity) {
+                case 7:
+                case 6:
+                case 5:
+                    return 'year';
+                case 4:
+                    return 'month';
+                case 3:
+                    return 'week';
+                case 2:
+                    return 'day';
+                default:
+                    return 'time'; // really?
+            }
+        };
+        return NativeFormatter;
+    }());
+    function buildFormattingFunc(standardDateProps, extendedSettings, context) {
+        var standardDatePropCnt = Object.keys(standardDateProps).length;
+        if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
+            return function (date) { return (formatTimeZoneOffset(date.timeZoneOffset)); };
+        }
+        if (standardDatePropCnt === 0 && extendedSettings.week) {
+            return function (date) { return (formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.weekTextLong, context.locale, extendedSettings.week)); };
+        }
+        return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
+    }
+    function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
+        standardDateProps = __assign({}, standardDateProps); // copy
+        extendedSettings = __assign({}, extendedSettings); // copy
+        sanitizeSettings(standardDateProps, extendedSettings);
+        standardDateProps.timeZone = 'UTC'; // we leverage the only guaranteed timeZone for our UTC markers
+        var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
+        var zeroFormat; // needed?
+        if (extendedSettings.omitZeroMinute) {
+            var zeroProps = __assign({}, standardDateProps);
+            delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings
+            zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
+        }
+        return function (date) {
+            var marker = date.marker;
+            var format;
+            if (zeroFormat && !marker.getUTCMinutes()) {
+                format = zeroFormat;
+            }
+            else {
+                format = normalFormat;
+            }
+            var s = format.format(marker);
+            return postProcess(s, date, standardDateProps, extendedSettings, context);
+        };
+    }
+    function sanitizeSettings(standardDateProps, extendedSettings) {
+        // deal with a browser inconsistency where formatting the timezone
+        // requires that the hour/minute be present.
+        if (standardDateProps.timeZoneName) {
+            if (!standardDateProps.hour) {
+                standardDateProps.hour = '2-digit';
+            }
+            if (!standardDateProps.minute) {
+                standardDateProps.minute = '2-digit';
+            }
+        }
+        // only support short timezone names
+        if (standardDateProps.timeZoneName === 'long') {
+            standardDateProps.timeZoneName = 'short';
+        }
+        // if requesting to display seconds, MUST display minutes
+        if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
+            delete extendedSettings.omitZeroMinute;
+        }
+    }
+    function postProcess(s, date, standardDateProps, extendedSettings, context) {
+        s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes
+        if (standardDateProps.timeZoneName === 'short') {
+            s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?
+                'UTC' : // important to normalize for IE, which does "GMT"
+                formatTimeZoneOffset(date.timeZoneOffset));
+        }
+        if (extendedSettings.omitCommas) {
+            s = s.replace(COMMA_RE, '').trim();
+        }
+        if (extendedSettings.omitZeroMinute) {
+            s = s.replace(':00', ''); // zeroFormat doesn't always achieve this
+        }
+        // ^ do anything that might create adjacent spaces before this point,
+        // because MERIDIEM_RE likes to eat up loading spaces
+        if (extendedSettings.meridiem === false) {
+            s = s.replace(MERIDIEM_RE, '').trim();
+        }
+        else if (extendedSettings.meridiem === 'narrow') { // a/p
+            s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase(); });
+        }
+        else if (extendedSettings.meridiem === 'short') { // am/pm
+            s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase() + "m"; });
+        }
+        else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase
+            s = s.replace(MERIDIEM_RE, function (m0) { return m0.toLocaleLowerCase(); });
+        }
+        s = s.replace(MULTI_SPACE_RE, ' ');
+        s = s.trim();
+        return s;
+    }
+    function injectTzoStr(s, tzoStr) {
+        var replaced = false;
+        s = s.replace(UTC_RE, function () {
+            replaced = true;
+            return tzoStr;
+        });
+        // IE11 doesn't include UTC/GMT in the original string, so append to end
+        if (!replaced) {
+            s += " " + tzoStr;
+        }
+        return s;
+    }
+    function formatWeekNumber(num, weekText, weekTextLong, locale, display) {
+        var parts = [];
+        if (display === 'long') {
+            parts.push(weekTextLong);
+        }
+        else if (display === 'short' || display === 'narrow') {
+            parts.push(weekText);
+        }
+        if (display === 'long' || display === 'short') {
+            parts.push(' ');
+        }
+        parts.push(locale.simpleNumberFormat.format(num));
+        if (locale.options.direction === 'rtl') { // TODO: use control characters instead?
+            parts.reverse();
+        }
+        return parts.join('');
+    }
+    // Range Formatting Utils
+    // 0 = exactly the same
+    // 1 = different by time
+    // and bigger
+    function computeMarkerDiffSeverity(d0, d1, ca) {
+        if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
+            return 5;
+        }
+        if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
+            return 4;
+        }
+        if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
+            return 2;
+        }
+        if (timeAsMs(d0) !== timeAsMs(d1)) {
+            return 1;
+        }
+        return 0;
+    }
+    function computePartialFormattingOptions(options, biggestUnit) {
+        var partialOptions = {};
+        for (var name_2 in options) {
+            if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)
+                STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) {
+                partialOptions[name_2] = options[name_2];
+            }
+        }
+        return partialOptions;
+    }
+    function findCommonInsertion(full0, partial0, full1, partial1) {
+        var i0 = 0;
+        while (i0 < full0.length) {
+            var found0 = full0.indexOf(partial0, i0);
+            if (found0 === -1) {
+                break;
+            }
+            var before0 = full0.substr(0, found0);
+            i0 = found0 + partial0.length;
+            var after0 = full0.substr(i0);
+            var i1 = 0;
+            while (i1 < full1.length) {
+                var found1 = full1.indexOf(partial1, i1);
+                if (found1 === -1) {
+                    break;
+                }
+                var before1 = full1.substr(0, found1);
+                i1 = found1 + partial1.length;
+                var after1 = full1.substr(i1);
+                if (before0 === before1 && after0 === after1) {
+                    return {
+                        before: before0,
+                        after: after0,
+                    };
+                }
+            }
+        }
+        return null;
+    }
+
+    function expandZonedMarker(dateInfo, calendarSystem) {
+        var a = calendarSystem.markerToArray(dateInfo.marker);
+        return {
+            marker: dateInfo.marker,
+            timeZoneOffset: dateInfo.timeZoneOffset,
+            array: a,
+            year: a[0],
+            month: a[1],
+            day: a[2],
+            hour: a[3],
+            minute: a[4],
+            second: a[5],
+            millisecond: a[6],
+        };
+    }
+
+    function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {
+        var startInfo = expandZonedMarker(start, context.calendarSystem);
+        var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
+        return {
+            date: startInfo,
+            start: startInfo,
+            end: endInfo,
+            timeZone: context.timeZone,
+            localeCodes: context.locale.codes,
+            defaultSeparator: betterDefaultSeparator || context.defaultSeparator,
+        };
+    }
+
+    /*
+    TODO: fix the terminology of "formatter" vs "formatting func"
+    */
+    /*
+    At the time of instantiation, this object does not know which cmd-formatting system it will use.
+    It receives this at the time of formatting, as a setting.
+    */
+    var CmdFormatter = /** @class */ (function () {
+        function CmdFormatter(cmdStr) {
+            this.cmdStr = cmdStr;
+        }
+        CmdFormatter.prototype.format = function (date, context, betterDefaultSeparator) {
+            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
+        };
+        CmdFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
+            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
+        };
+        return CmdFormatter;
+    }());
+
+    var FuncFormatter = /** @class */ (function () {
+        function FuncFormatter(func) {
+            this.func = func;
+        }
+        FuncFormatter.prototype.format = function (date, context, betterDefaultSeparator) {
+            return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
+        };
+        FuncFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
+            return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
+        };
+        return FuncFormatter;
+    }());
+
+    function createFormatter(input) {
+        if (typeof input === 'object' && input) { // non-null object
+            return new NativeFormatter(input);
+        }
+        if (typeof input === 'string') {
+            return new CmdFormatter(input);
+        }
+        if (typeof input === 'function') {
+            return new FuncFormatter(input);
+        }
+        return null;
+    }
+
+    // base options
+    // ------------
+    var BASE_OPTION_REFINERS = {
+        navLinkDayClick: identity,
+        navLinkWeekClick: identity,
+        duration: createDuration,
+        bootstrapFontAwesome: identity,
+        buttonIcons: identity,
+        customButtons: identity,
+        defaultAllDayEventDuration: createDuration,
+        defaultTimedEventDuration: createDuration,
+        nextDayThreshold: createDuration,
+        scrollTime: createDuration,
+        scrollTimeReset: Boolean,
+        slotMinTime: createDuration,
+        slotMaxTime: createDuration,
+        dayPopoverFormat: createFormatter,
+        slotDuration: createDuration,
+        snapDuration: createDuration,
+        headerToolbar: identity,
+        footerToolbar: identity,
+        defaultRangeSeparator: String,
+        titleRangeSeparator: String,
+        forceEventDuration: Boolean,
+        dayHeaders: Boolean,
+        dayHeaderFormat: createFormatter,
+        dayHeaderClassNames: identity,
+        dayHeaderContent: identity,
+        dayHeaderDidMount: identity,
+        dayHeaderWillUnmount: identity,
+        dayCellClassNames: identity,
+        dayCellContent: identity,
+        dayCellDidMount: identity,
+        dayCellWillUnmount: identity,
+        initialView: String,
+        aspectRatio: Number,
+        weekends: Boolean,
+        weekNumberCalculation: identity,
+        weekNumbers: Boolean,
+        weekNumberClassNames: identity,
+        weekNumberContent: identity,
+        weekNumberDidMount: identity,
+        weekNumberWillUnmount: identity,
+        editable: Boolean,
+        viewClassNames: identity,
+        viewDidMount: identity,
+        viewWillUnmount: identity,
+        nowIndicator: Boolean,
+        nowIndicatorClassNames: identity,
+        nowIndicatorContent: identity,
+        nowIndicatorDidMount: identity,
+        nowIndicatorWillUnmount: identity,
+        showNonCurrentDates: Boolean,
+        lazyFetching: Boolean,
+        startParam: String,
+        endParam: String,
+        timeZoneParam: String,
+        timeZone: String,
+        locales: identity,
+        locale: identity,
+        themeSystem: String,
+        dragRevertDuration: Number,
+        dragScroll: Boolean,
+        allDayMaintainDuration: Boolean,
+        unselectAuto: Boolean,
+        dropAccept: identity,
+        eventOrder: parseFieldSpecs,
+        eventOrderStrict: Boolean,
+        handleWindowResize: Boolean,
+        windowResizeDelay: Number,
+        longPressDelay: Number,
+        eventDragMinDistance: Number,
+        expandRows: Boolean,
+        height: identity,
+        contentHeight: identity,
+        direction: String,
+        weekNumberFormat: createFormatter,
+        eventResizableFromStart: Boolean,
+        displayEventTime: Boolean,
+        displayEventEnd: Boolean,
+        weekText: String,
+        weekTextLong: String,
+        progressiveEventRendering: Boolean,
+        businessHours: identity,
+        initialDate: identity,
+        now: identity,
+        eventDataTransform: identity,
+        stickyHeaderDates: identity,
+        stickyFooterScrollbar: identity,
+        viewHeight: identity,
+        defaultAllDay: Boolean,
+        eventSourceFailure: identity,
+        eventSourceSuccess: identity,
+        eventDisplay: String,
+        eventStartEditable: Boolean,
+        eventDurationEditable: Boolean,
+        eventOverlap: identity,
+        eventConstraint: identity,
+        eventAllow: identity,
+        eventBackgroundColor: String,
+        eventBorderColor: String,
+        eventTextColor: String,
+        eventColor: String,
+        eventClassNames: identity,
+        eventContent: identity,
+        eventDidMount: identity,
+        eventWillUnmount: identity,
+        selectConstraint: identity,
+        selectOverlap: identity,
+        selectAllow: identity,
+        droppable: Boolean,
+        unselectCancel: String,
+        slotLabelFormat: identity,
+        slotLaneClassNames: identity,
+        slotLaneContent: identity,
+        slotLaneDidMount: identity,
+        slotLaneWillUnmount: identity,
+        slotLabelClassNames: identity,
+        slotLabelContent: identity,
+        slotLabelDidMount: identity,
+        slotLabelWillUnmount: identity,
+        dayMaxEvents: identity,
+        dayMaxEventRows: identity,
+        dayMinWidth: Number,
+        slotLabelInterval: createDuration,
+        allDayText: String,
+        allDayClassNames: identity,
+        allDayContent: identity,
+        allDayDidMount: identity,
+        allDayWillUnmount: identity,
+        slotMinWidth: Number,
+        navLinks: Boolean,
+        eventTimeFormat: createFormatter,
+        rerenderDelay: Number,
+        moreLinkText: identity,
+        moreLinkHint: identity,
+        selectMinDistance: Number,
+        selectable: Boolean,
+        selectLongPressDelay: Number,
+        eventLongPressDelay: Number,
+        selectMirror: Boolean,
+        eventMaxStack: Number,
+        eventMinHeight: Number,
+        eventMinWidth: Number,
+        eventShortHeight: Number,
+        slotEventOverlap: Boolean,
+        plugins: identity,
+        firstDay: Number,
+        dayCount: Number,
+        dateAlignment: String,
+        dateIncrement: createDuration,
+        hiddenDays: identity,
+        monthMode: Boolean,
+        fixedWeekCount: Boolean,
+        validRange: identity,
+        visibleRange: identity,
+        titleFormat: identity,
+        eventInteractive: Boolean,
+        // only used by list-view, but languages define the value, so we need it in base options
+        noEventsText: String,
+        viewHint: identity,
+        navLinkHint: identity,
+        closeHint: String,
+        timeHint: String,
+        eventHint: String,
+        moreLinkClick: identity,
+        moreLinkClassNames: identity,
+        moreLinkContent: identity,
+        moreLinkDidMount: identity,
+        moreLinkWillUnmount: identity,
+    };
+    // do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results.
+    // raw values.
+    var BASE_OPTION_DEFAULTS = {
+        eventDisplay: 'auto',
+        defaultRangeSeparator: ' - ',
+        titleRangeSeparator: ' \u2013 ',
+        defaultTimedEventDuration: '01:00:00',
+        defaultAllDayEventDuration: { day: 1 },
+        forceEventDuration: false,
+        nextDayThreshold: '00:00:00',
+        dayHeaders: true,
+        initialView: '',
+        aspectRatio: 1.35,
+        headerToolbar: {
+            start: 'title',
+            center: '',
+            end: 'today prev,next',
+        },
+        weekends: true,
+        weekNumbers: false,
+        weekNumberCalculation: 'local',
+        editable: false,
+        nowIndicator: false,
+        scrollTime: '06:00:00',
+        scrollTimeReset: true,
+        slotMinTime: '00:00:00',
+        slotMaxTime: '24:00:00',
+        showNonCurrentDates: true,
+        lazyFetching: true,
+        startParam: 'start',
+        endParam: 'end',
+        timeZoneParam: 'timeZone',
+        timeZone: 'local',
+        locales: [],
+        locale: '',
+        themeSystem: 'standard',
+        dragRevertDuration: 500,
+        dragScroll: true,
+        allDayMaintainDuration: false,
+        unselectAuto: true,
+        dropAccept: '*',
+        eventOrder: 'start,-duration,allDay,title',
+        dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
+        handleWindowResize: true,
+        windowResizeDelay: 100,
+        longPressDelay: 1000,
+        eventDragMinDistance: 5,
+        expandRows: false,
+        navLinks: false,
+        selectable: false,
+        eventMinHeight: 15,
+        eventMinWidth: 30,
+        eventShortHeight: 30,
+    };
+    // calendar listeners
+    // ------------------
+    var CALENDAR_LISTENER_REFINERS = {
+        datesSet: identity,
+        eventsSet: identity,
+        eventAdd: identity,
+        eventChange: identity,
+        eventRemove: identity,
+        windowResize: identity,
+        eventClick: identity,
+        eventMouseEnter: identity,
+        eventMouseLeave: identity,
+        select: identity,
+        unselect: identity,
+        loading: identity,
+        // internal
+        _unmount: identity,
+        _beforeprint: identity,
+        _afterprint: identity,
+        _noEventDrop: identity,
+        _noEventResize: identity,
+        _resize: identity,
+        _scrollRequest: identity,
+    };
+    // calendar-specific options
+    // -------------------------
+    var CALENDAR_OPTION_REFINERS = {
+        buttonText: identity,
+        buttonHints: identity,
+        views: identity,
+        plugins: identity,
+        initialEvents: identity,
+        events: identity,
+        eventSources: identity,
+    };
+    var COMPLEX_OPTION_COMPARATORS = {
+        headerToolbar: isMaybeObjectsEqual,
+        footerToolbar: isMaybeObjectsEqual,
+        buttonText: isMaybeObjectsEqual,
+        buttonHints: isMaybeObjectsEqual,
+        buttonIcons: isMaybeObjectsEqual,
+        dateIncrement: isMaybeObjectsEqual,
+    };
+    function isMaybeObjectsEqual(a, b) {
+        if (typeof a === 'object' && typeof b === 'object' && a && b) { // both non-null objects
+            return isPropsEqual(a, b);
+        }
+        return a === b;
+    }
+    // view-specific options
+    // ---------------------
+    var VIEW_OPTION_REFINERS = {
+        type: String,
+        component: identity,
+        buttonText: String,
+        buttonTextKey: String,
+        dateProfileGeneratorClass: identity,
+        usesMinMaxTime: Boolean,
+        classNames: identity,
+        content: identity,
+        didMount: identity,
+        willUnmount: identity,
+    };
+    // util funcs
+    // ----------------------------------------------------------------------------------------------------
+    function mergeRawOptions(optionSets) {
+        return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS);
+    }
+    function refineProps(input, refiners) {
+        var refined = {};
+        var extra = {};
+        for (var propName in refiners) {
+            if (propName in input) {
+                refined[propName] = refiners[propName](input[propName]);
+            }
+        }
+        for (var propName in input) {
+            if (!(propName in refiners)) {
+                extra[propName] = input[propName];
+            }
+        }
+        return { refined: refined, extra: extra };
+    }
+    function identity(raw) {
+        return raw;
+    }
+
+    function parseEvents(rawEvents, eventSource, context, allowOpenRange) {
+        var eventStore = createEmptyEventStore();
+        var eventRefiners = buildEventRefiners(context);
+        for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
+            var rawEvent = rawEvents_1[_i];
+            var tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners);
+            if (tuple) {
+                eventTupleToStore(tuple, eventStore);
+            }
+        }
+        return eventStore;
+    }
+    function eventTupleToStore(tuple, eventStore) {
+        if (eventStore === void 0) { eventStore = createEmptyEventStore(); }
+        eventStore.defs[tuple.def.defId] = tuple.def;
+        if (tuple.instance) {
+            eventStore.instances[tuple.instance.instanceId] = tuple.instance;
+        }
+        return eventStore;
+    }
+    // retrieves events that have the same groupId as the instance specified by `instanceId`
+    // or they are the same as the instance.
+    // why might instanceId not be in the store? an event from another calendar?
+    function getRelevantEvents(eventStore, instanceId) {
+        var instance = eventStore.instances[instanceId];
+        if (instance) {
+            var def_1 = eventStore.defs[instance.defId];
+            // get events/instances with same group
+            var newStore = filterEventStoreDefs(eventStore, function (lookDef) { return isEventDefsGrouped(def_1, lookDef); });
+            // add the original
+            // TODO: wish we could use eventTupleToStore or something like it
+            newStore.defs[def_1.defId] = def_1;
+            newStore.instances[instance.instanceId] = instance;
+            return newStore;
+        }
+        return createEmptyEventStore();
+    }
+    function isEventDefsGrouped(def0, def1) {
+        return Boolean(def0.groupId && def0.groupId === def1.groupId);
+    }
+    function createEmptyEventStore() {
+        return { defs: {}, instances: {} };
+    }
+    function mergeEventStores(store0, store1) {
+        return {
+            defs: __assign(__assign({}, store0.defs), store1.defs),
+            instances: __assign(__assign({}, store0.instances), store1.instances),
+        };
+    }
+    function filterEventStoreDefs(eventStore, filterFunc) {
+        var defs = filterHash(eventStore.defs, filterFunc);
+        var instances = filterHash(eventStore.instances, function (instance) { return (defs[instance.defId] // still exists?
+        ); });
+        return { defs: defs, instances: instances };
+    }
+    function excludeSubEventStore(master, sub) {
+        var defs = master.defs, instances = master.instances;
+        var filteredDefs = {};
+        var filteredInstances = {};
+        for (var defId in defs) {
+            if (!sub.defs[defId]) { // not explicitly excluded
+                filteredDefs[defId] = defs[defId];
+            }
+        }
+        for (var instanceId in instances) {
+            if (!sub.instances[instanceId] && // not explicitly excluded
+                filteredDefs[instances[instanceId].defId] // def wasn't filtered away
+            ) {
+                filteredInstances[instanceId] = instances[instanceId];
+            }
+        }
+        return {
+            defs: filteredDefs,
+            instances: filteredInstances,
+        };
+    }
+
+    function normalizeConstraint(input, context) {
+        if (Array.isArray(input)) {
+            return parseEvents(input, null, context, true); // allowOpenRange=true
+        }
+        if (typeof input === 'object' && input) { // non-null object
+            return parseEvents([input], null, context, true); // allowOpenRange=true
+        }
+        if (input != null) {
+            return String(input);
+        }
+        return null;
+    }
+
+    function parseClassNames(raw) {
+        if (Array.isArray(raw)) {
+            return raw;
+        }
+        if (typeof raw === 'string') {
+            return raw.split(/\s+/);
+        }
+        return [];
+    }
+
+    // TODO: better called "EventSettings" or "EventConfig"
+    // TODO: move this file into structs
+    // TODO: separate constraint/overlap/allow, because selection uses only that, not other props
+    var EVENT_UI_REFINERS = {
+        display: String,
+        editable: Boolean,
+        startEditable: Boolean,
+        durationEditable: Boolean,
+        constraint: identity,
+        overlap: identity,
+        allow: identity,
+        className: parseClassNames,
+        classNames: parseClassNames,
+        color: String,
+        backgroundColor: String,
+        borderColor: String,
+        textColor: String,
+    };
+    var EMPTY_EVENT_UI = {
+        display: null,
+        startEditable: null,
+        durationEditable: null,
+        constraints: [],
+        overlap: null,
+        allows: [],
+        backgroundColor: '',
+        borderColor: '',
+        textColor: '',
+        classNames: [],
+    };
+    function createEventUi(refined, context) {
+        var constraint = normalizeConstraint(refined.constraint, context);
+        return {
+            display: refined.display || null,
+            startEditable: refined.startEditable != null ? refined.startEditable : refined.editable,
+            durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable,
+            constraints: constraint != null ? [constraint] : [],
+            overlap: refined.overlap != null ? refined.overlap : null,
+            allows: refined.allow != null ? [refined.allow] : [],
+            backgroundColor: refined.backgroundColor || refined.color || '',
+            borderColor: refined.borderColor || refined.color || '',
+            textColor: refined.textColor || '',
+            classNames: (refined.className || []).concat(refined.classNames || []), // join singular and plural
+        };
+    }
+    // TODO: prevent against problems with <2 args!
+    function combineEventUis(uis) {
+        return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
+    }
+    function combineTwoEventUis(item0, item1) {
+        return {
+            display: item1.display != null ? item1.display : item0.display,
+            startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
+            durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
+            constraints: item0.constraints.concat(item1.constraints),
+            overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
+            allows: item0.allows.concat(item1.allows),
+            backgroundColor: item1.backgroundColor || item0.backgroundColor,
+            borderColor: item1.borderColor || item0.borderColor,
+            textColor: item1.textColor || item0.textColor,
+            classNames: item0.classNames.concat(item1.classNames),
+        };
+    }
+
+    var EVENT_NON_DATE_REFINERS = {
+        id: String,
+        groupId: String,
+        title: String,
+        url: String,
+        interactive: Boolean,
+    };
+    var EVENT_DATE_REFINERS = {
+        start: identity,
+        end: identity,
+        date: identity,
+        allDay: Boolean,
+    };
+    var EVENT_REFINERS = __assign(__assign(__assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity });
+    function parseEvent(raw, eventSource, context, allowOpenRange, refiners) {
+        if (refiners === void 0) { refiners = buildEventRefiners(context); }
+        var _a = refineEventDef(raw, context, refiners), refined = _a.refined, extra = _a.extra;
+        var defaultAllDay = computeIsDefaultAllDay(eventSource, context);
+        var recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes);
+        if (recurringRes) {
+            var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context);
+            def.recurringDef = {
+                typeId: recurringRes.typeId,
+                typeData: recurringRes.typeData,
+                duration: recurringRes.duration,
+            };
+            return { def: def, instance: null };
+        }
+        var singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange);
+        if (singleRes) {
+            var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context);
+            var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
+            return { def: def, instance: instance };
+        }
+        return null;
+    }
+    function refineEventDef(raw, context, refiners) {
+        if (refiners === void 0) { refiners = buildEventRefiners(context); }
+        return refineProps(raw, refiners);
+    }
+    function buildEventRefiners(context) {
+        return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners);
+    }
+    /*
+    Will NOT populate extendedProps with the leftover properties.
+    Will NOT populate date-related props.
+    */
+    function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context) {
+        var def = {
+            title: refined.title || '',
+            groupId: refined.groupId || '',
+            publicId: refined.id || '',
+            url: refined.url || '',
+            recurringDef: null,
+            defId: guid(),
+            sourceId: sourceId,
+            allDay: allDay,
+            hasEnd: hasEnd,
+            interactive: refined.interactive,
+            ui: createEventUi(refined, context),
+            extendedProps: __assign(__assign({}, (refined.extendedProps || {})), extra),
+        };
+        for (var _i = 0, _a = context.pluginHooks.eventDefMemberAdders; _i < _a.length; _i++) {
+            var memberAdder = _a[_i];
+            __assign(def, memberAdder(refined));
+        }
+        // help out EventApi from having user modify props
+        Object.freeze(def.ui.classNames);
+        Object.freeze(def.extendedProps);
+        return def;
+    }
+    function parseSingle(refined, defaultAllDay, context, allowOpenRange) {
+        var allDay = refined.allDay;
+        var startMeta;
+        var startMarker = null;
+        var hasEnd = false;
+        var endMeta;
+        var endMarker = null;
+        var startInput = refined.start != null ? refined.start : refined.date;
+        startMeta = context.dateEnv.createMarkerMeta(startInput);
+        if (startMeta) {
+            startMarker = startMeta.marker;
+        }
+        else if (!allowOpenRange) {
+            return null;
+        }
+        if (refined.end != null) {
+            endMeta = context.dateEnv.createMarkerMeta(refined.end);
+        }
+        if (allDay == null) {
+            if (defaultAllDay != null) {
+                allDay = defaultAllDay;
+            }
+            else {
+                // fall back to the date props LAST
+                allDay = (!startMeta || startMeta.isTimeUnspecified) &&
+                    (!endMeta || endMeta.isTimeUnspecified);
+            }
+        }
+        if (allDay && startMarker) {
+            startMarker = startOfDay(startMarker);
+        }
+        if (endMeta) {
+            endMarker = endMeta.marker;
+            if (allDay) {
+                endMarker = startOfDay(endMarker);
+            }
+            if (startMarker && endMarker <= startMarker) {
+                endMarker = null;
+            }
+        }
+        if (endMarker) {
+            hasEnd = true;
+        }
+        else if (!allowOpenRange) {
+            hasEnd = context.options.forceEventDuration || false;
+            endMarker = context.dateEnv.add(startMarker, allDay ?
+                context.options.defaultAllDayEventDuration :
+                context.options.defaultTimedEventDuration);
+        }
+        return {
+            allDay: allDay,
+            hasEnd: hasEnd,
+            range: { start: startMarker, end: endMarker },
+            forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
+            forcedEndTzo: endMeta ? endMeta.forcedTzo : null,
+        };
+    }
+    function computeIsDefaultAllDay(eventSource, context) {
+        var res = null;
+        if (eventSource) {
+            res = eventSource.defaultAllDay;
+        }
+        if (res == null) {
+            res = context.options.defaultAllDay;
+        }
+        return res;
+    }
+
+    /* Date stuff that doesn't belong in datelib core
+    ----------------------------------------------------------------------------------------------------------------------*/
+    // given a timed range, computes an all-day range that has the same exact duration,
+    // but whose start time is aligned with the start of the day.
+    function computeAlignedDayRange(timedRange) {
+        var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
+        var start = startOfDay(timedRange.start);
+        var end = addDays(start, dayCnt);
+        return { start: start, end: end };
+    }
+    // given a timed range, computes an all-day range based on how for the end date bleeds into the next day
+    // TODO: give nextDayThreshold a default arg
+    function computeVisibleDayRange(timedRange, nextDayThreshold) {
+        if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); }
+        var startDay = null;
+        var endDay = null;
+        if (timedRange.end) {
+            endDay = startOfDay(timedRange.end);
+            var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`
+            // If the end time is actually inclusively part of the next day and is equal to or
+            // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
+            // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
+            if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
+                endDay = addDays(endDay, 1);
+            }
+        }
+        if (timedRange.start) {
+            startDay = startOfDay(timedRange.start); // the beginning of the day the range starts
+            // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
+            if (endDay && endDay <= startDay) {
+                endDay = addDays(startDay, 1);
+            }
+        }
+        return { start: startDay, end: endDay };
+    }
+    // spans from one day into another?
+    function isMultiDayRange(range) {
+        var visibleRange = computeVisibleDayRange(range);
+        return diffDays(visibleRange.start, visibleRange.end) > 1;
+    }
+    function diffDates(date0, date1, dateEnv, largeUnit) {
+        if (largeUnit === 'year') {
+            return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
+        }
+        if (largeUnit === 'month') {
+            return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
+        }
+        return diffDayAndTime(date0, date1); // returns a duration
+    }
+
+    function parseRange(input, dateEnv) {
+        var start = null;
+        var end = null;
+        if (input.start) {
+            start = dateEnv.createMarker(input.start);
+        }
+        if (input.end) {
+            end = dateEnv.createMarker(input.end);
+        }
+        if (!start && !end) {
+            return null;
+        }
+        if (start && end && end < start) {
+            return null;
+        }
+        return { start: start, end: end };
+    }
+    // SIDE-EFFECT: will mutate ranges.
+    // Will return a new array result.
+    function invertRanges(ranges, constraintRange) {
+        var invertedRanges = [];
+        var start = constraintRange.start; // the end of the previous range. the start of the new range
+        var i;
+        var dateRange;
+        // ranges need to be in order. required for our date-walking algorithm
+        ranges.sort(compareRanges);
+        for (i = 0; i < ranges.length; i += 1) {
+            dateRange = ranges[i];
+            // add the span of time before the event (if there is any)
+            if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)
+                invertedRanges.push({ start: start, end: dateRange.start });
+            }
+            if (dateRange.end > start) {
+                start = dateRange.end;
+            }
+        }
+        // add the span of time after the last event (if there is any)
+        if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)
+            invertedRanges.push({ start: start, end: constraintRange.end });
+        }
+        return invertedRanges;
+    }
+    function compareRanges(range0, range1) {
+        return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
+    }
+    function intersectRanges(range0, range1) {
+        var start = range0.start, end = range0.end;
+        var newRange = null;
+        if (range1.start !== null) {
+            if (start === null) {
+                start = range1.start;
+            }
+            else {
+                start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
+            }
+        }
+        if (range1.end != null) {
+            if (end === null) {
+                end = range1.end;
+            }
+            else {
+                end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
+            }
+        }
+        if (start === null || end === null || start < end) {
+            newRange = { start: start, end: end };
+        }
+        return newRange;
+    }
+    function rangesEqual(range0, range1) {
+        return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
+            (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
+    }
+    function rangesIntersect(range0, range1) {
+        return (range0.end === null || range1.start === null || range0.end > range1.start) &&
+            (range0.start === null || range1.end === null || range0.start < range1.end);
+    }
+    function rangeContainsRange(outerRange, innerRange) {
+        return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
+            (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
+    }
+    function rangeContainsMarker(range, date) {
+        return (range.start === null || date >= range.start) &&
+            (range.end === null || date < range.end);
+    }
+    // If the given date is not within the given range, move it inside.
+    // (If it's past the end, make it one millisecond before the end).
+    function constrainMarkerToRange(date, range) {
+        if (range.start != null && date < range.start) {
+            return range.start;
+        }
+        if (range.end != null && date >= range.end) {
+            return new Date(range.end.valueOf() - 1);
+        }
+        return date;
+    }
+
+    /*
+    Specifying nextDayThreshold signals that all-day ranges should be sliced.
+    */
+    function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
+        var inverseBgByGroupId = {};
+        var inverseBgByDefId = {};
+        var defByGroupId = {};
+        var bgRanges = [];
+        var fgRanges = [];
+        var eventUis = compileEventUis(eventStore.defs, eventUiBases);
+        for (var defId in eventStore.defs) {
+            var def = eventStore.defs[defId];
+            var ui = eventUis[def.defId];
+            if (ui.display === 'inverse-background') {
+                if (def.groupId) {
+                    inverseBgByGroupId[def.groupId] = [];
+                    if (!defByGroupId[def.groupId]) {
+                        defByGroupId[def.groupId] = def;
+                    }
+                }
+                else {
+                    inverseBgByDefId[defId] = [];
+                }
+            }
+        }
+        for (var instanceId in eventStore.instances) {
+            var instance = eventStore.instances[instanceId];
+            var def = eventStore.defs[instance.defId];
+            var ui = eventUis[def.defId];
+            var origRange = instance.range;
+            var normalRange = (!def.allDay && nextDayThreshold) ?
+                computeVisibleDayRange(origRange, nextDayThreshold) :
+                origRange;
+            var slicedRange = intersectRanges(normalRange, framingRange);
+            if (slicedRange) {
+                if (ui.display === 'inverse-background') {
+                    if (def.groupId) {
+                        inverseBgByGroupId[def.groupId].push(slicedRange);
+                    }
+                    else {
+                        inverseBgByDefId[instance.defId].push(slicedRange);
+                    }
+                }
+                else if (ui.display !== 'none') {
+                    (ui.display === 'background' ? bgRanges : fgRanges).push({
+                        def: def,
+                        ui: ui,
+                        instance: instance,
+                        range: slicedRange,
+                        isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
+                        isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf(),
+                    });
+                }
+            }
+        }
+        for (var groupId in inverseBgByGroupId) { // BY GROUP
+            var ranges = inverseBgByGroupId[groupId];
+            var invertedRanges = invertRanges(ranges, framingRange);
+            for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) {
+                var invertedRange = invertedRanges_1[_i];
+                var def = defByGroupId[groupId];
+                var ui = eventUis[def.defId];
+                bgRanges.push({
+                    def: def,
+                    ui: ui,
+                    instance: null,
+                    range: invertedRange,
+                    isStart: false,
+                    isEnd: false,
+                });
+            }
+        }
+        for (var defId in inverseBgByDefId) {
+            var ranges = inverseBgByDefId[defId];
+            var invertedRanges = invertRanges(ranges, framingRange);
+            for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) {
+                var invertedRange = invertedRanges_2[_a];
+                bgRanges.push({
+                    def: eventStore.defs[defId],
+                    ui: eventUis[defId],
+                    instance: null,
+                    range: invertedRange,
+                    isStart: false,
+                    isEnd: false,
+                });
+            }
+        }
+        return { bg: bgRanges, fg: fgRanges };
+    }
+    function hasBgRendering(def) {
+        return def.ui.display === 'background' || def.ui.display === 'inverse-background';
+    }
+    function setElSeg(el, seg) {
+        el.fcSeg = seg;
+    }
+    function getElSeg(el) {
+        return el.fcSeg ||
+            el.parentNode.fcSeg || // for the harness
+            null;
+    }
+    // event ui computation
+    function compileEventUis(eventDefs, eventUiBases) {
+        return mapHash(eventDefs, function (eventDef) { return compileEventUi(eventDef, eventUiBases); });
+    }
+    function compileEventUi(eventDef, eventUiBases) {
+        var uis = [];
+        if (eventUiBases['']) {
+            uis.push(eventUiBases['']);
+        }
+        if (eventUiBases[eventDef.defId]) {
+            uis.push(eventUiBases[eventDef.defId]);
+        }
+        uis.push(eventDef.ui);
+        return combineEventUis(uis);
+    }
+    function sortEventSegs(segs, eventOrderSpecs) {
+        var objs = segs.map(buildSegCompareObj);
+        objs.sort(function (obj0, obj1) { return compareByFieldSpecs(obj0, obj1, eventOrderSpecs); });
+        return objs.map(function (c) { return c._seg; });
+    }
+    // returns a object with all primitive props that can be compared
+    function buildSegCompareObj(seg) {
+        var eventRange = seg.eventRange;
+        var eventDef = eventRange.def;
+        var range = eventRange.instance ? eventRange.instance.range : eventRange.range;
+        var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
+        var end = range.end ? range.end.valueOf() : 0; // "
+        return __assign(__assign(__assign({}, eventDef.extendedProps), eventDef), { id: eventDef.publicId, start: start,
+            end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg });
+    }
+    function computeSegDraggable(seg, context) {
+        var pluginHooks = context.pluginHooks;
+        var transformers = pluginHooks.isDraggableTransformers;
+        var _a = seg.eventRange, def = _a.def, ui = _a.ui;
+        var val = ui.startEditable;
+        for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
+            var transformer = transformers_1[_i];
+            val = transformer(val, def, ui, context);
+        }
+        return val;
+    }
+    function computeSegStartResizable(seg, context) {
+        return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart;
+    }
+    function computeSegEndResizable(seg, context) {
+        return seg.isEnd && seg.eventRange.ui.durationEditable;
+    }
+    function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, // defaults to true
+    defaultDisplayEventEnd, // defaults to true
+    startOverride, endOverride) {
+        var dateEnv = context.dateEnv, options = context.options;
+        var displayEventTime = options.displayEventTime, displayEventEnd = options.displayEventEnd;
+        var eventDef = seg.eventRange.def;
+        var eventInstance = seg.eventRange.instance;
+        if (displayEventTime == null) {
+            displayEventTime = defaultDisplayEventTime !== false;
+        }
+        if (displayEventEnd == null) {
+            displayEventEnd = defaultDisplayEventEnd !== false;
+        }
+        var wholeEventStart = eventInstance.range.start;
+        var wholeEventEnd = eventInstance.range.end;
+        var segStart = startOverride || seg.start || seg.eventRange.range.start;
+        var segEnd = endOverride || seg.end || seg.eventRange.range.end;
+        var isStartDay = startOfDay(wholeEventStart).valueOf() === startOfDay(segStart).valueOf();
+        var isEndDay = startOfDay(addMs(wholeEventEnd, -1)).valueOf() === startOfDay(addMs(segEnd, -1)).valueOf();
+        if (displayEventTime && !eventDef.allDay && (isStartDay || isEndDay)) {
+            segStart = isStartDay ? wholeEventStart : segStart;
+            segEnd = isEndDay ? wholeEventEnd : segEnd;
+            if (displayEventEnd && eventDef.hasEnd) {
+                return dateEnv.formatRange(segStart, segEnd, timeFormat, {
+                    forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo,
+                    forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo,
+                });
+            }
+            return dateEnv.format(segStart, timeFormat, {
+                forcedTzo: startOverride ? null : eventInstance.forcedStartTzo, // nooooo, same
+            });
+        }
+        return '';
+    }
+    function getSegMeta(seg, todayRange, nowDate) {
+        var segRange = seg.eventRange.range;
+        return {
+            isPast: segRange.end < (nowDate || todayRange.start),
+            isFuture: segRange.start >= (nowDate || todayRange.end),
+            isToday: todayRange && rangeContainsMarker(todayRange, segRange.start),
+        };
+    }
+    function getEventClassNames(props) {
+        var classNames = ['fc-event'];
+        if (props.isMirror) {
+            classNames.push('fc-event-mirror');
+        }
+        if (props.isDraggable) {
+            classNames.push('fc-event-draggable');
+        }
+        if (props.isStartResizable || props.isEndResizable) {
+            classNames.push('fc-event-resizable');
+        }
+        if (props.isDragging) {
+            classNames.push('fc-event-dragging');
+        }
+        if (props.isResizing) {
+            classNames.push('fc-event-resizing');
+        }
+        if (props.isSelected) {
+            classNames.push('fc-event-selected');
+        }
+        if (props.isStart) {
+            classNames.push('fc-event-start');
+        }
+        if (props.isEnd) {
+            classNames.push('fc-event-end');
+        }
+        if (props.isPast) {
+            classNames.push('fc-event-past');
+        }
+        if (props.isToday) {
+            classNames.push('fc-event-today');
+        }
+        if (props.isFuture) {
+            classNames.push('fc-event-future');
+        }
+        return classNames;
+    }
+    function buildEventRangeKey(eventRange) {
+        return eventRange.instance
+            ? eventRange.instance.instanceId
+            : eventRange.def.defId + ":" + eventRange.range.start.toISOString();
+        // inverse-background events don't have specific instances. TODO: better solution
+    }
+    function getSegAnchorAttrs(seg, context) {
+        var _a = seg.eventRange, def = _a.def, instance = _a.instance;
+        var url = def.url;
+        if (url) {
+            return { href: url };
+        }
+        var emitter = context.emitter, options = context.options;
+        var eventInteractive = options.eventInteractive;
+        if (eventInteractive == null) {
+            eventInteractive = def.interactive;
+            if (eventInteractive == null) {
+                eventInteractive = Boolean(emitter.hasHandlers('eventClick'));
+            }
+        }
+        // mock what happens in EventClicking
+        if (eventInteractive) {
+            // only attach keyboard-related handlers because click handler is already done in EventClicking
+            return createAriaKeyboardAttrs(function (ev) {
+                emitter.trigger('eventClick', {
+                    el: ev.target,
+                    event: new EventApi(context, def, instance),
+                    jsEvent: ev,
+                    view: context.viewApi,
+                });
+            });
+        }
+        return {};
+    }
+
+    var STANDARD_PROPS = {
+        start: identity,
+        end: identity,
+        allDay: Boolean,
+    };
+    function parseDateSpan(raw, dateEnv, defaultDuration) {
+        var span = parseOpenDateSpan(raw, dateEnv);
+        var range = span.range;
+        if (!range.start) {
+            return null;
+        }
+        if (!range.end) {
+            if (defaultDuration == null) {
+                return null;
+            }
+            range.end = dateEnv.add(range.start, defaultDuration);
+        }
+        return span;
+    }
+    /*
+    TODO: somehow combine with parseRange?
+    Will return null if the start/end props were present but parsed invalidly.
+    */
+    function parseOpenDateSpan(raw, dateEnv) {
+        var _a = refineProps(raw, STANDARD_PROPS), standardProps = _a.refined, extra = _a.extra;
+        var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
+        var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
+        var allDay = standardProps.allDay;
+        if (allDay == null) {
+            allDay = (startMeta && startMeta.isTimeUnspecified) &&
+                (!endMeta || endMeta.isTimeUnspecified);
+        }
+        return __assign({ range: {
+                start: startMeta ? startMeta.marker : null,
+                end: endMeta ? endMeta.marker : null,
+            }, allDay: allDay }, extra);
+    }
+    function isDateSpansEqual(span0, span1) {
+        return rangesEqual(span0.range, span1.range) &&
+            span0.allDay === span1.allDay &&
+            isSpanPropsEqual(span0, span1);
+    }
+    // the NON-DATE-RELATED props
+    function isSpanPropsEqual(span0, span1) {
+        for (var propName in span1) {
+            if (propName !== 'range' && propName !== 'allDay') {
+                if (span0[propName] !== span1[propName]) {
+                    return false;
+                }
+            }
+        }
+        // are there any props that span0 has that span1 DOESN'T have?
+        // both have range/allDay, so no need to special-case.
+        for (var propName in span0) {
+            if (!(propName in span1)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    function buildDateSpanApi(span, dateEnv) {
+        return __assign(__assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay });
+    }
+    function buildRangeApiWithTimeZone(range, dateEnv, omitTime) {
+        return __assign(__assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone });
+    }
+    function buildRangeApi(range, dateEnv, omitTime) {
+        return {
+            start: dateEnv.toDate(range.start),
+            end: dateEnv.toDate(range.end),
+            startStr: dateEnv.formatIso(range.start, { omitTime: omitTime }),
+            endStr: dateEnv.formatIso(range.end, { omitTime: omitTime }),
+        };
+    }
+    function fabricateEventRange(dateSpan, eventUiBases, context) {
+        var res = refineEventDef({ editable: false }, context);
+        var def = parseEventDef(res.refined, res.extra, '', // sourceId
+        dateSpan.allDay, true, // hasEnd
+        context);
+        return {
+            def: def,
+            ui: compileEventUi(def, eventUiBases),
+            instance: createEventInstance(def.defId, dateSpan.range),
+            range: dateSpan.range,
+            isStart: true,
+            isEnd: true,
+        };
+    }
+
+    function triggerDateSelect(selection, pev, context) {
+        context.emitter.trigger('select', __assign(__assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view }));
+    }
+    function triggerDateUnselect(pev, context) {
+        context.emitter.trigger('unselect', {
+            jsEvent: pev ? pev.origEvent : null,
+            view: context.viewApi || context.calendarApi.view,
+        });
+    }
+    function buildDateSpanApiWithContext(dateSpan, context) {
+        var props = {};
+        for (var _i = 0, _a = context.pluginHooks.dateSpanTransforms; _i < _a.length; _i++) {
+            var transform = _a[_i];
+            __assign(props, transform(dateSpan, context));
+        }
+        __assign(props, buildDateSpanApi(dateSpan, context.dateEnv));
+        return props;
+    }
+    // Given an event's allDay status and start date, return what its fallback end date should be.
+    // TODO: rename to computeDefaultEventEnd
+    function getDefaultEventEnd(allDay, marker, context) {
+        var dateEnv = context.dateEnv, options = context.options;
+        var end = marker;
+        if (allDay) {
+            end = startOfDay(end);
+            end = dateEnv.add(end, options.defaultAllDayEventDuration);
+        }
+        else {
+            end = dateEnv.add(end, options.defaultTimedEventDuration);
+        }
+        return end;
+    }
+
+    // applies the mutation to ALL defs/instances within the event store
+    function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) {
+        var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
+        var dest = createEmptyEventStore();
+        for (var defId in eventStore.defs) {
+            var def = eventStore.defs[defId];
+            dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context);
+        }
+        for (var instanceId in eventStore.instances) {
+            var instance = eventStore.instances[instanceId];
+            var def = dest.defs[instance.defId]; // important to grab the newly modified def
+            dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context);
+        }
+        return dest;
+    }
+    function applyMutationToEventDef(eventDef, eventConfig, mutation, context) {
+        var standardProps = mutation.standardProps || {};
+        // if hasEnd has not been specified, guess a good value based on deltas.
+        // if duration will change, there's no way the default duration will persist,
+        // and thus, we need to mark the event as having a real end
+        if (standardProps.hasEnd == null &&
+            eventConfig.durationEditable &&
+            (mutation.startDelta || mutation.endDelta)) {
+            standardProps.hasEnd = true; // TODO: is this mutation okay?
+        }
+        var copy = __assign(__assign(__assign({}, eventDef), standardProps), { ui: __assign(__assign({}, eventDef.ui), standardProps.ui) });
+        if (mutation.extendedProps) {
+            copy.extendedProps = __assign(__assign({}, copy.extendedProps), mutation.extendedProps);
+        }
+        for (var _i = 0, _a = context.pluginHooks.eventDefMutationAppliers; _i < _a.length; _i++) {
+            var applier = _a[_i];
+            applier(copy, mutation, context);
+        }
+        if (!copy.hasEnd && context.options.forceEventDuration) {
+            copy.hasEnd = true;
+        }
+        return copy;
+    }
+    function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
+    eventConfig, mutation, context) {
+        var dateEnv = context.dateEnv;
+        var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
+        var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
+        var copy = __assign({}, eventInstance);
+        if (forceAllDay) {
+            copy.range = computeAlignedDayRange(copy.range);
+        }
+        if (mutation.datesDelta && eventConfig.startEditable) {
+            copy.range = {
+                start: dateEnv.add(copy.range.start, mutation.datesDelta),
+                end: dateEnv.add(copy.range.end, mutation.datesDelta),
+            };
+        }
+        if (mutation.startDelta && eventConfig.durationEditable) {
+            copy.range = {
+                start: dateEnv.add(copy.range.start, mutation.startDelta),
+                end: copy.range.end,
+            };
+        }
+        if (mutation.endDelta && eventConfig.durationEditable) {
+            copy.range = {
+                start: copy.range.start,
+                end: dateEnv.add(copy.range.end, mutation.endDelta),
+            };
+        }
+        if (clearEnd) {
+            copy.range = {
+                start: copy.range.start,
+                end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context),
+            };
+        }
+        // in case event was all-day but the supplied deltas were not
+        // better util for this?
+        if (eventDef.allDay) {
+            copy.range = {
+                start: startOfDay(copy.range.start),
+                end: startOfDay(copy.range.end),
+            };
+        }
+        // handle invalid durations
+        if (copy.range.end < copy.range.start) {
+            copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context);
+        }
+        return copy;
+    }
+
+    // no public types yet. when there are, export from:
+    // import {} from './api-type-deps'
+    var ViewApi = /** @class */ (function () {
+        function ViewApi(type, getCurrentData, dateEnv) {
+            this.type = type;
+            this.getCurrentData = getCurrentData;
+            this.dateEnv = dateEnv;
+        }
+        Object.defineProperty(ViewApi.prototype, "calendar", {
+            get: function () {
+                return this.getCurrentData().calendarApi;
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(ViewApi.prototype, "title", {
+            get: function () {
+                return this.getCurrentData().viewTitle;
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(ViewApi.prototype, "activeStart", {
+            get: function () {
+                return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start);
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(ViewApi.prototype, "activeEnd", {
+            get: function () {
+                return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end);
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(ViewApi.prototype, "currentStart", {
+            get: function () {
+                return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start);
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(ViewApi.prototype, "currentEnd", {
+            get: function () {
+                return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end);
+            },
+            enumerable: false,
+            configurable: true
+        });
+        ViewApi.prototype.getOption = function (name) {
+            return this.getCurrentData().options[name]; // are the view-specific options
+        };
+        return ViewApi;
+    }());
+
+    var EVENT_SOURCE_REFINERS$1 = {
+        id: String,
+        defaultAllDay: Boolean,
+        url: String,
+        format: String,
+        events: identity,
+        eventDataTransform: identity,
+        // for any network-related sources
+        success: identity,
+        failure: identity,
+    };
+    function parseEventSource(raw, context, refiners) {
+        if (refiners === void 0) { refiners = buildEventSourceRefiners(context); }
+        var rawObj;
+        if (typeof raw === 'string') {
+            rawObj = { url: raw };
+        }
+        else if (typeof raw === 'function' || Array.isArray(raw)) {
+            rawObj = { events: raw };
+        }
+        else if (typeof raw === 'object' && raw) { // not null
+            rawObj = raw;
+        }
+        if (rawObj) {
+            var _a = refineProps(rawObj, refiners), refined = _a.refined, extra = _a.extra;
+            var metaRes = buildEventSourceMeta(refined, context);
+            if (metaRes) {
+                return {
+                    _raw: raw,
+                    isFetching: false,
+                    latestFetchId: '',
+                    fetchRange: null,
+                    defaultAllDay: refined.defaultAllDay,
+                    eventDataTransform: refined.eventDataTransform,
+                    success: refined.success,
+                    failure: refined.failure,
+                    publicId: refined.id || '',
+                    sourceId: guid(),
+                    sourceDefId: metaRes.sourceDefId,
+                    meta: metaRes.meta,
+                    ui: createEventUi(refined, context),
+                    extendedProps: extra,
+                };
+            }
+        }
+        return null;
+    }
+    function buildEventSourceRefiners(context) {
+        return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS$1), context.pluginHooks.eventSourceRefiners);
+    }
+    function buildEventSourceMeta(raw, context) {
+        var defs = context.pluginHooks.eventSourceDefs;
+        for (var i = defs.length - 1; i >= 0; i -= 1) { // later-added plugins take precedence
+            var def = defs[i];
+            var meta = def.parseMeta(raw);
+            if (meta) {
+                return { sourceDefId: i, meta: meta };
+            }
+        }
+        return null;
+    }
+
+    function reduceCurrentDate(currentDate, action) {
+        switch (action.type) {
+            case 'CHANGE_DATE':
+                return action.dateMarker;
+            default:
+                return currentDate;
+        }
+    }
+    function getInitialDate(options, dateEnv) {
+        var initialDateInput = options.initialDate;
+        // compute the initial ambig-timezone date
+        if (initialDateInput != null) {
+            return dateEnv.createMarker(initialDateInput);
+        }
+        return getNow(options.now, dateEnv); // getNow already returns unzoned
+    }
+    function getNow(nowInput, dateEnv) {
+        if (typeof nowInput === 'function') {
+            nowInput = nowInput();
+        }
+        if (nowInput == null) {
+            return dateEnv.createNowMarker();
+        }
+        return dateEnv.createMarker(nowInput);
+    }
+
+    var CalendarApi = /** @class */ (function () {
+        function CalendarApi() {
+        }
+        CalendarApi.prototype.getCurrentData = function () {
+            return this.currentDataManager.getCurrentData();
+        };
+        CalendarApi.prototype.dispatch = function (action) {
+            return this.currentDataManager.dispatch(action);
+        };
+        Object.defineProperty(CalendarApi.prototype, "view", {
+            get: function () { return this.getCurrentData().viewApi; } // for public API
+            ,
+            enumerable: false,
+            configurable: true
+        });
+        CalendarApi.prototype.batchRendering = function (callback) {
+            callback();
+        };
+        CalendarApi.prototype.updateSize = function () {
+            this.trigger('_resize', true);
+        };
+        // Options
+        // -----------------------------------------------------------------------------------------------------------------
+        CalendarApi.prototype.setOption = function (name, val) {
+            this.dispatch({
+                type: 'SET_OPTION',
+                optionName: name,
+                rawOptionValue: val,
+            });
+        };
+        CalendarApi.prototype.getOption = function (name) {
+            return this.currentDataManager.currentCalendarOptionsInput[name];
+        };
+        CalendarApi.prototype.getAvailableLocaleCodes = function () {
+            return Object.keys(this.getCurrentData().availableRawLocales);
+        };
+        // Trigger
+        // -----------------------------------------------------------------------------------------------------------------
+        CalendarApi.prototype.on = function (handlerName, handler) {
+            var currentDataManager = this.currentDataManager;
+            if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) {
+                currentDataManager.emitter.on(handlerName, handler);
+            }
+            else {
+                console.warn("Unknown listener name '" + handlerName + "'");
+            }
+        };
+        CalendarApi.prototype.off = function (handlerName, handler) {
+            this.currentDataManager.emitter.off(handlerName, handler);
+        };
+        // not meant for public use
+        CalendarApi.prototype.trigger = function (handlerName) {
+            var _a;
+            var args = [];
+            for (var _i = 1; _i < arguments.length; _i++) {
+                args[_i - 1] = arguments[_i];
+            }
+            (_a = this.currentDataManager.emitter).trigger.apply(_a, __spreadArray([handlerName], args));
+        };
+        // View
+        // -----------------------------------------------------------------------------------------------------------------
+        CalendarApi.prototype.changeView = function (viewType, dateOrRange) {
+            var _this = this;
+            this.batchRendering(function () {
+                _this.unselect();
+                if (dateOrRange) {
+                    if (dateOrRange.start && dateOrRange.end) { // a range
+                        _this.dispatch({
+                            type: 'CHANGE_VIEW_TYPE',
+                            viewType: viewType,
+                        });
+                        _this.dispatch({
+                            type: 'SET_OPTION',
+                            optionName: 'visibleRange',
+                            rawOptionValue: dateOrRange,
+                        });
+                    }
+                    else {
+                        var dateEnv = _this.getCurrentData().dateEnv;
+                        _this.dispatch({
+                            type: 'CHANGE_VIEW_TYPE',
+                            viewType: viewType,
+                            dateMarker: dateEnv.createMarker(dateOrRange),
+                        });
+                    }
+                }
+                else {
+                    _this.dispatch({
+                        type: 'CHANGE_VIEW_TYPE',
+                        viewType: viewType,
+                    });
+                }
+            });
+        };
+        // Forces navigation to a view for the given date.
+        // `viewType` can be a specific view name or a generic one like "week" or "day".
+        // needs to change
+        CalendarApi.prototype.zoomTo = function (dateMarker, viewType) {
+            var state = this.getCurrentData();
+            var spec;
+            viewType = viewType || 'day'; // day is default zoom
+            spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType);
+            this.unselect();
+            if (spec) {
+                this.dispatch({
+                    type: 'CHANGE_VIEW_TYPE',
+                    viewType: spec.type,
+                    dateMarker: dateMarker,
+                });
+            }
+            else {
+                this.dispatch({
+                    type: 'CHANGE_DATE',
+                    dateMarker: dateMarker,
+                });
+            }
+        };
+        // Given a duration singular unit, like "week" or "day", finds a matching view spec.
+        // Preference is given to views that have corresponding buttons.
+        CalendarApi.prototype.getUnitViewSpec = function (unit) {
+            var _a = this.getCurrentData(), viewSpecs = _a.viewSpecs, toolbarConfig = _a.toolbarConfig;
+            var viewTypes = [].concat(toolbarConfig.header ? toolbarConfig.header.viewsWithButtons : [], toolbarConfig.footer ? toolbarConfig.footer.viewsWithButtons : []);
+            var i;
+            var spec;
+            for (var viewType in viewSpecs) {
+                viewTypes.push(viewType);
+            }
+            for (i = 0; i < viewTypes.length; i += 1) {
+                spec = viewSpecs[viewTypes[i]];
+                if (spec) {
+                    if (spec.singleUnit === unit) {
+                        return spec;
+                    }
+                }
+            }
+            return null;
+        };
+        // Current Date
+        // -----------------------------------------------------------------------------------------------------------------
+        CalendarApi.prototype.prev = function () {
+            this.unselect();
+            this.dispatch({ type: 'PREV' });
+        };
+        CalendarApi.prototype.next = function () {
+            this.unselect();
+            this.dispatch({ type: 'NEXT' });
+        };
+        CalendarApi.prototype.prevYear = function () {
+            var state = this.getCurrentData();
+            this.unselect();
+            this.dispatch({
+                type: 'CHANGE_DATE',
+                dateMarker: state.dateEnv.addYears(state.currentDate, -1),
+            });
+        };
+        CalendarApi.prototype.nextYear = function () {
+            var state = this.getCurrentData();
+            this.unselect();
+            this.dispatch({
+                type: 'CHANGE_DATE',
+                dateMarker: state.dateEnv.addYears(state.currentDate, 1),
+            });
+        };
+        CalendarApi.prototype.today = function () {
+            var state = this.getCurrentData();
+            this.unselect();
+            this.dispatch({
+                type: 'CHANGE_DATE',
+                dateMarker: getNow(state.calendarOptions.now, state.dateEnv),
+            });
+        };
+        CalendarApi.prototype.gotoDate = function (zonedDateInput) {
+            var state = this.getCurrentData();
+            this.unselect();
+            this.dispatch({
+                type: 'CHANGE_DATE',
+                dateMarker: state.dateEnv.createMarker(zonedDateInput),
+            });
+        };
+        CalendarApi.prototype.incrementDate = function (deltaInput) {
+            var state = this.getCurrentData();
+            var delta = createDuration(deltaInput);
+            if (delta) { // else, warn about invalid input?
+                this.unselect();
+                this.dispatch({
+                    type: 'CHANGE_DATE',
+                    dateMarker: state.dateEnv.add(state.currentDate, delta),
+                });
+            }
+        };
+        // for external API
+        CalendarApi.prototype.getDate = function () {
+            var state = this.getCurrentData();
+            return state.dateEnv.toDate(state.currentDate);
+        };
+        // Date Formatting Utils
+        // -----------------------------------------------------------------------------------------------------------------
+        CalendarApi.prototype.formatDate = function (d, formatter) {
+            var dateEnv = this.getCurrentData().dateEnv;
+            return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
+        };
+        // `settings` is for formatter AND isEndExclusive
+        CalendarApi.prototype.formatRange = function (d0, d1, settings) {
+            var dateEnv = this.getCurrentData().dateEnv;
+            return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings);
+        };
+        CalendarApi.prototype.formatIso = function (d, omitTime) {
+            var dateEnv = this.getCurrentData().dateEnv;
+            return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime });
+        };
+        // Date Selection / Event Selection / DayClick
+        // -----------------------------------------------------------------------------------------------------------------
+        // this public method receives start/end dates in any format, with any timezone
+        // NOTE: args were changed from v3
+        CalendarApi.prototype.select = function (dateOrObj, endDate) {
+            var selectionInput;
+            if (endDate == null) {
+                if (dateOrObj.start != null) {
+                    selectionInput = dateOrObj;
+                }
+                else {
+                    selectionInput = {
+                        start: dateOrObj,
+                        end: null,
+                    };
+                }
+            }
+            else {
+                selectionInput = {
+                    start: dateOrObj,
+                    end: endDate,
+                };
+            }
+            var state = this.getCurrentData();
+            var selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 }));
+            if (selection) { // throw parse error otherwise?
+                this.dispatch({ type: 'SELECT_DATES', selection: selection });
+                triggerDateSelect(selection, null, state);
+            }
+        };
+        // public method
+        CalendarApi.prototype.unselect = function (pev) {
+            var state = this.getCurrentData();
+            if (state.dateSelection) {
+                this.dispatch({ type: 'UNSELECT_DATES' });
+                triggerDateUnselect(pev, state);
+            }
+        };
+        // Public Events API
+        // -----------------------------------------------------------------------------------------------------------------
+        CalendarApi.prototype.addEvent = function (eventInput, sourceInput) {
+            if (eventInput instanceof EventApi) {
+                var def = eventInput._def;
+                var instance = eventInput._instance;
+                var currentData = this.getCurrentData();
+                // not already present? don't want to add an old snapshot
+                if (!currentData.eventStore.defs[def.defId]) {
+                    this.dispatch({
+                        type: 'ADD_EVENTS',
+                        eventStore: eventTupleToStore({ def: def, instance: instance }), // TODO: better util for two args?
+                    });
+                    this.triggerEventAdd(eventInput);
+                }
+                return eventInput;
+            }
+            var state = this.getCurrentData();
+            var eventSource;
+            if (sourceInput instanceof EventSourceApi) {
+                eventSource = sourceInput.internalEventSource;
+            }
+            else if (typeof sourceInput === 'boolean') {
+                if (sourceInput) { // true. part of the first event source
+                    eventSource = hashValuesToArray(state.eventSources)[0];
+                }
+            }
+            else if (sourceInput != null) { // an ID. accepts a number too
+                var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
+                if (!sourceApi) {
+                    console.warn("Could not find an event source with ID \"" + sourceInput + "\""); // TODO: test
+                    return null;
+                }
+                eventSource = sourceApi.internalEventSource;
+            }
+            var tuple = parseEvent(eventInput, eventSource, state, false);
+            if (tuple) {
+                var newEventApi = new EventApi(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
+                this.dispatch({
+                    type: 'ADD_EVENTS',
+                    eventStore: eventTupleToStore(tuple),
+                });
+                this.triggerEventAdd(newEventApi);
+                return newEventApi;
+            }
+            return null;
+        };
+        CalendarApi.prototype.triggerEventAdd = function (eventApi) {
+            var _this = this;
+            var emitter = this.getCurrentData().emitter;
+            emitter.trigger('eventAdd', {
+                event: eventApi,
+                relatedEvents: [],
+                revert: function () {
+                    _this.dispatch({
+                        type: 'REMOVE_EVENTS',
+                        eventStore: eventApiToStore(eventApi),
+                    });
+                },
+            });
+        };
+        // TODO: optimize
+        CalendarApi.prototype.getEventById = function (id) {
+            var state = this.getCurrentData();
+            var _a = state.eventStore, defs = _a.defs, instances = _a.instances;
+            id = String(id);
+            for (var defId in defs) {
+                var def = defs[defId];
+                if (def.publicId === id) {
+                    if (def.recurringDef) {
+                        return new EventApi(state, def, null);
+                    }
+                    for (var instanceId in instances) {
+                        var instance = instances[instanceId];
+                        if (instance.defId === def.defId) {
+                            return new EventApi(state, def, instance);
+                        }
+                    }
+                }
+            }
+            return null;
+        };
+        CalendarApi.prototype.getEvents = function () {
+            var currentData = this.getCurrentData();
+            return buildEventApis(currentData.eventStore, currentData);
+        };
+        CalendarApi.prototype.removeAllEvents = function () {
+            this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
+        };
+        // Public Event Sources API
+        // -----------------------------------------------------------------------------------------------------------------
+        CalendarApi.prototype.getEventSources = function () {
+            var state = this.getCurrentData();
+            var sourceHash = state.eventSources;
+            var sourceApis = [];
+            for (var internalId in sourceHash) {
+                sourceApis.push(new EventSourceApi(state, sourceHash[internalId]));
+            }
+            return sourceApis;
+        };
+        CalendarApi.prototype.getEventSourceById = function (id) {
+            var state = this.getCurrentData();
+            var sourceHash = state.eventSources;
+            id = String(id);
+            for (var sourceId in sourceHash) {
+                if (sourceHash[sourceId].publicId === id) {
+                    return new EventSourceApi(state, sourceHash[sourceId]);
+                }
+            }
+            return null;
+        };
+        CalendarApi.prototype.addEventSource = function (sourceInput) {
+            var state = this.getCurrentData();
+            if (sourceInput instanceof EventSourceApi) {
+                // not already present? don't want to add an old snapshot
+                if (!state.eventSources[sourceInput.internalEventSource.sourceId]) {
+                    this.dispatch({
+                        type: 'ADD_EVENT_SOURCES',
+                        sources: [sourceInput.internalEventSource],
+                    });
+                }
+                return sourceInput;
+            }
+            var eventSource = parseEventSource(sourceInput, state);
+            if (eventSource) { // TODO: error otherwise?
+                this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
+                return new EventSourceApi(state, eventSource);
+            }
+            return null;
+        };
+        CalendarApi.prototype.removeAllEventSources = function () {
+            this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
+        };
+        CalendarApi.prototype.refetchEvents = function () {
+            this.dispatch({ type: 'FETCH_EVENT_SOURCES', isRefetch: true });
+        };
+        // Scroll
+        // -----------------------------------------------------------------------------------------------------------------
+        CalendarApi.prototype.scrollToTime = function (timeInput) {
+            var time = createDuration(timeInput);
+            if (time) {
+                this.trigger('_scrollRequest', { time: time });
+            }
+        };
+        return CalendarApi;
+    }());
+
+    var EventApi = /** @class */ (function () {
+        // instance will be null if expressing a recurring event that has no current instances,
+        // OR if trying to validate an incoming external event that has no dates assigned
+        function EventApi(context, def, instance) {
+            this._context = context;
+            this._def = def;
+            this._instance = instance || null;
+        }
+        /*
+        TODO: make event struct more responsible for this
+        */
+        EventApi.prototype.setProp = function (name, val) {
+            var _a, _b;
+            if (name in EVENT_DATE_REFINERS) {
+                console.warn('Could not set date-related prop \'name\'. Use one of the date-related methods instead.');
+                // TODO: make proper aliasing system?
+            }
+            else if (name === 'id') {
+                val = EVENT_NON_DATE_REFINERS[name](val);
+                this.mutate({
+                    standardProps: { publicId: val }, // hardcoded internal name
+                });
+            }
+            else if (name in EVENT_NON_DATE_REFINERS) {
+                val = EVENT_NON_DATE_REFINERS[name](val);
+                this.mutate({
+                    standardProps: (_a = {}, _a[name] = val, _a),
+                });
+            }
+            else if (name in EVENT_UI_REFINERS) {
+                var ui = EVENT_UI_REFINERS[name](val);
+                if (name === 'color') {
+                    ui = { backgroundColor: val, borderColor: val };
+                }
+                else if (name === 'editable') {
+                    ui = { startEditable: val, durationEditable: val };
+                }
+                else {
+                    ui = (_b = {}, _b[name] = val, _b);
+                }
+                this.mutate({
+                    standardProps: { ui: ui },
+                });
+            }
+            else {
+                console.warn("Could not set prop '" + name + "'. Use setExtendedProp instead.");
+            }
+        };
+        EventApi.prototype.setExtendedProp = function (name, val) {
+            var _a;
+            this.mutate({
+                extendedProps: (_a = {}, _a[name] = val, _a),
+            });
+        };
+        EventApi.prototype.setStart = function (startInput, options) {
+            if (options === void 0) { options = {}; }
+            var dateEnv = this._context.dateEnv;
+            var start = dateEnv.createMarker(startInput);
+            if (start && this._instance) { // TODO: warning if parsed bad
+                var instanceRange = this._instance.range;
+                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?
+                if (options.maintainDuration) {
+                    this.mutate({ datesDelta: startDelta });
+                }
+                else {
+                    this.mutate({ startDelta: startDelta });
+                }
+            }
+        };
+        EventApi.prototype.setEnd = function (endInput, options) {
+            if (options === void 0) { options = {}; }
+            var dateEnv = this._context.dateEnv;
+            var end;
+            if (endInput != null) {
+                end = dateEnv.createMarker(endInput);
+                if (!end) {
+                    return; // TODO: warning if parsed bad
+                }
+            }
+            if (this._instance) {
+                if (end) {
+                    var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
+                    this.mutate({ endDelta: endDelta });
+                }
+                else {
+                    this.mutate({ standardProps: { hasEnd: false } });
+                }
+            }
+        };
+        EventApi.prototype.setDates = function (startInput, endInput, options) {
+            if (options === void 0) { options = {}; }
+            var dateEnv = this._context.dateEnv;
+            var standardProps = { allDay: options.allDay };
+            var start = dateEnv.createMarker(startInput);
+            var end;
+            if (!start) {
+                return; // TODO: warning if parsed bad
+            }
+            if (endInput != null) {
+                end = dateEnv.createMarker(endInput);
+                if (!end) { // TODO: warning if parsed bad
+                    return;
+                }
+            }
+            if (this._instance) {
+                var instanceRange = this._instance.range;
+                // when computing the diff for an event being converted to all-day,
+                // compute diff off of the all-day values the way event-mutation does.
+                if (options.allDay === true) {
+                    instanceRange = computeAlignedDayRange(instanceRange);
+                }
+                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
+                if (end) {
+                    var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
+                    if (durationsEqual(startDelta, endDelta)) {
+                        this.mutate({ datesDelta: startDelta, standardProps: standardProps });
+                    }
+                    else {
+                        this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps });
+                    }
+                }
+                else { // means "clear the end"
+                    standardProps.hasEnd = false;
+                    this.mutate({ datesDelta: startDelta, standardProps: standardProps });
+                }
+            }
+        };
+        EventApi.prototype.moveStart = function (deltaInput) {
+            var delta = createDuration(deltaInput);
+            if (delta) { // TODO: warning if parsed bad
+                this.mutate({ startDelta: delta });
+            }
+        };
+        EventApi.prototype.moveEnd = function (deltaInput) {
+            var delta = createDuration(deltaInput);
+            if (delta) { // TODO: warning if parsed bad
+                this.mutate({ endDelta: delta });
+            }
+        };
+        EventApi.prototype.moveDates = function (deltaInput) {
+            var delta = createDuration(deltaInput);
+            if (delta) { // TODO: warning if parsed bad
+                this.mutate({ datesDelta: delta });
+            }
+        };
+        EventApi.prototype.setAllDay = function (allDay, options) {
+            if (options === void 0) { options = {}; }
+            var standardProps = { allDay: allDay };
+            var maintainDuration = options.maintainDuration;
+            if (maintainDuration == null) {
+                maintainDuration = this._context.options.allDayMaintainDuration;
+            }
+            if (this._def.allDay !== allDay) {
+                standardProps.hasEnd = maintainDuration;
+            }
+            this.mutate({ standardProps: standardProps });
+        };
+        EventApi.prototype.formatRange = function (formatInput) {
+            var dateEnv = this._context.dateEnv;
+            var instance = this._instance;
+            var formatter = createFormatter(formatInput);
+            if (this._def.hasEnd) {
+                return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
+                    forcedStartTzo: instance.forcedStartTzo,
+                    forcedEndTzo: instance.forcedEndTzo,
+                });
+            }
+            return dateEnv.format(instance.range.start, formatter, {
+                forcedTzo: instance.forcedStartTzo,
+            });
+        };
+        EventApi.prototype.mutate = function (mutation) {
+            var instance = this._instance;
+            if (instance) {
+                var def = this._def;
+                var context_1 = this._context;
+                var eventStore_1 = context_1.getCurrentData().eventStore;
+                var relevantEvents = getRelevantEvents(eventStore_1, instance.instanceId);
+                var eventConfigBase = {
+                    '': {
+                        display: '',
+                        startEditable: true,
+                        durationEditable: true,
+                        constraints: [],
+                        overlap: null,
+                        allows: [],
+                        backgroundColor: '',
+                        borderColor: '',
+                        textColor: '',
+                        classNames: [],
+                    },
+                };
+                relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context_1);
+                var oldEvent = new EventApi(context_1, def, instance); // snapshot
+                this._def = relevantEvents.defs[def.defId];
+                this._instance = relevantEvents.instances[instance.instanceId];
+                context_1.dispatch({
+                    type: 'MERGE_EVENTS',
+                    eventStore: relevantEvents,
+                });
+                context_1.emitter.trigger('eventChange', {
+                    oldEvent: oldEvent,
+                    event: this,
+                    relatedEvents: buildEventApis(relevantEvents, context_1, instance),
+                    revert: function () {
+                        context_1.dispatch({
+                            type: 'RESET_EVENTS',
+                            eventStore: eventStore_1,
+                        });
+                    },
+                });
+            }
+        };
+        EventApi.prototype.remove = function () {
+            var context = this._context;
+            var asStore = eventApiToStore(this);
+            context.dispatch({
+                type: 'REMOVE_EVENTS',
+                eventStore: asStore,
+            });
+            context.emitter.trigger('eventRemove', {
+                event: this,
+                relatedEvents: [],
+                revert: function () {
+                    context.dispatch({
+                        type: 'MERGE_EVENTS',
+                        eventStore: asStore,
+                    });
+                },
+            });
+        };
+        Object.defineProperty(EventApi.prototype, "source", {
+            get: function () {
+                var sourceId = this._def.sourceId;
+                if (sourceId) {
+                    return new EventSourceApi(this._context, this._context.getCurrentData().eventSources[sourceId]);
+                }
+                return null;
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "start", {
+            get: function () {
+                return this._instance ?
+                    this._context.dateEnv.toDate(this._instance.range.start) :
+                    null;
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "end", {
+            get: function () {
+                return (this._instance && this._def.hasEnd) ?
+                    this._context.dateEnv.toDate(this._instance.range.end) :
+                    null;
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "startStr", {
+            get: function () {
+                var instance = this._instance;
+                if (instance) {
+                    return this._context.dateEnv.formatIso(instance.range.start, {
+                        omitTime: this._def.allDay,
+                        forcedTzo: instance.forcedStartTzo,
+                    });
+                }
+                return '';
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "endStr", {
+            get: function () {
+                var instance = this._instance;
+                if (instance && this._def.hasEnd) {
+                    return this._context.dateEnv.formatIso(instance.range.end, {
+                        omitTime: this._def.allDay,
+                        forcedTzo: instance.forcedEndTzo,
+                    });
+                }
+                return '';
+            },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "id", {
+            // computable props that all access the def
+            // TODO: find a TypeScript-compatible way to do this at scale
+            get: function () { return this._def.publicId; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "groupId", {
+            get: function () { return this._def.groupId; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "allDay", {
+            get: function () { return this._def.allDay; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "title", {
+            get: function () { return this._def.title; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "url", {
+            get: function () { return this._def.url; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "display", {
+            get: function () { return this._def.ui.display || 'auto'; } // bad. just normalize the type earlier
+            ,
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "startEditable", {
+            get: function () { return this._def.ui.startEditable; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "durationEditable", {
+            get: function () { return this._def.ui.durationEditable; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "constraint", {
+            get: function () { return this._def.ui.constraints[0] || null; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "overlap", {
+            get: function () { return this._def.ui.overlap; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "allow", {
+            get: function () { return this._def.ui.allows[0] || null; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "backgroundColor", {
+            get: function () { return this._def.ui.backgroundColor; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "borderColor", {
+            get: function () { return this._def.ui.borderColor; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "textColor", {
+            get: function () { return this._def.ui.textColor; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "classNames", {
+            // NOTE: user can't modify these because Object.freeze was called in event-def parsing
+            get: function () { return this._def.ui.classNames; },
+            enumerable: false,
+            configurable: true
+        });
+        Object.defineProperty(EventApi.prototype, "extendedProps", {
+            get: function () { return this._def.extendedProps; },
+            enumerable: false,
+            configurable: true
+        });
+        EventApi.prototype.toPlainObject = function (settings) {
+            if (settings === void 0) { settings = {}; }
+            var def = this._def;
+            var ui = def.ui;
+            var _a = this, startStr = _a.startStr, endStr = _a.endStr;
+            var res = {};
+            if (def.title) {
+                res.title = def.title;
+            }
+            if (startStr) {
+                res.start = startStr;
+            }
+            if (endStr) {
+                res.end = endStr;
+            }
+            if (def.publicId) {
+                res.id = def.publicId;
+            }
+            if (def.groupId) {
+                res.groupId = def.groupId;
+            }
+            if (def.url) {
+                res.url = def.url;
+            }
+            if (ui.display && ui.display !== 'auto') {
+                res.display = ui.display;
+            }
+            // TODO: what about recurring-event properties???
+            // TODO: include startEditable/durationEditable/constraint/overlap/allow
+            if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) {
+                res.color = ui.backgroundColor;
+            }
+            else {
+                if (ui.backgroundColor) {
+                    res.backgroundColor = ui.backgroundColor;
+                }
+                if (ui.borderColor) {
+                    res.borderColor = ui.borderColor;
+                }
+            }
+            if (ui.textColor) {
+                res.textColor = ui.textColor;
+            }
+            if (ui.classNames.length) {
+                res.classNames = ui.classNames;
+            }
+            if (Object.keys(def.extendedProps).length) {
+                if (settings.collapseExtendedProps) {
+                    __assign(res, def.extendedProps);
+                }
+                else {
+                    res.extendedProps = def.extendedProps;
+                }
+            }
+            return res;
+        };
+        EventApi.prototype.toJSON = function () {
+            return this.toPlainObject();
+        };
+        return EventApi;
+    }());
+    function eventApiToStore(eventApi) {
+        var _a, _b;
+        var def = eventApi._def;
+        var instance = eventApi._instance;
+        return {
+            defs: (_a = {}, _a[def.defId] = def, _a),
+            instances: instance
+                ? (_b = {}, _b[instance.instanceId] = instance, _b) : {},
+        };
+    }
+    function buildEventApis(eventStore, context, excludeInstance) {
+        var defs = eventStore.defs, instances = eventStore.instances;
+        var eventApis = [];
+        var excludeInstanceId = excludeInstance ? excludeInstance.instanceId : '';
+        for (var id in instances) {
+            var instance = instances[id];
+            var def = defs[instance.defId];
+            if (instance.instanceId !== excludeInstanceId) {
+                eventApis.push(new EventApi(context, def, instance));
+            }
+        }
+        return eventApis;
+    }
+
+    var calendarSystemClassMap = {};
+    function registerCalendarSystem(name, theClass) {
+        calendarSystemClassMap[name] = theClass;
+    }
+    function createCalendarSystem(name) {
+        return new calendarSystemClassMap[name]();
+    }
+    var GregorianCalendarSystem = /** @class */ (function () {
+        function GregorianCalendarSystem() {
+        }
+        GregorianCalendarSystem.prototype.getMarkerYear = function (d) {
+            return d.getUTCFullYear();
+        };
+        GregorianCalendarSystem.prototype.getMarkerMonth = function (d) {
+            return d.getUTCMonth();
+        };
+        GregorianCalendarSystem.prototype.getMarkerDay = function (d) {
+            return d.getUTCDate();
+        };
+        GregorianCalendarSystem.prototype.arrayToMarker = function (arr) {
+            return arrayToUtcDate(arr);
+        };
+        GregorianCalendarSystem.prototype.markerToArray = function (marker) {
+            return dateToUtcArray(marker);
+        };
+        return GregorianCalendarSystem;
+    }());
+    registerCalendarSystem('gregory', GregorianCalendarSystem);
+
+    var ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
+    function parse(str) {
+        var m = ISO_RE.exec(str);
+        if (m) {
+            var marker = new Date(Date.UTC(Number(m[1]), m[3] ? Number(m[3]) - 1 : 0, Number(m[5] || 1), Number(m[7] || 0), Number(m[8] || 0), Number(m[10] || 0), m[12] ? Number("0." + m[12]) * 1000 : 0));
+            if (isValidDate(marker)) {
+                var timeZoneOffset = null;
+                if (m[13]) {
+                    timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
+                        Number(m[18] || 0));
+                }
+                return {
+                    marker: marker,
+                    isTimeUnspecified: !m[6],
+                    timeZoneOffset: timeZoneOffset,
+                };
+            }
+        }
+        return null;
+    }
+
+    var DateEnv = /** @class */ (function () {
+        function DateEnv(settings) {
+            var timeZone = this.timeZone = settings.timeZone;
+            var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
+            if (settings.namedTimeZoneImpl && isNamedTimeZone) {
+                this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
+            }
+            this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
+            this.calendarSystem = createCalendarSystem(settings.calendarSystem);
+            this.locale = settings.locale;
+            this.weekDow = settings.locale.week.dow;
+            this.weekDoy = settings.locale.week.doy;
+            if (settings.weekNumberCalculation === 'ISO') {
+                this.weekDow = 1;
+                this.weekDoy = 4;
+            }
+            if (typeof settings.firstDay === 'number') {
+                this.weekDow = settings.firstDay;
+            }
+            if (typeof settings.weekNumberCalculation === 'function') {
+                this.weekNumberFunc = settings.weekNumberCalculation;
+            }
+            this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText;
+            this.weekTextLong = (settings.weekTextLong != null ? settings.weekTextLong : settings.locale.options.weekTextLong) || this.weekText;
+            this.cmdFormatter = settings.cmdFormatter;
+            this.defaultSeparator = settings.defaultSeparator;
+        }
+        // Creating / Parsing
+        DateEnv.prototype.createMarker = function (input) {
+            var meta = this.createMarkerMeta(input);
+            if (meta === null) {
+                return null;
+            }
+            return meta.marker;
+        };
+        DateEnv.prototype.createNowMarker = function () {
+            if (this.canComputeOffset) {
+                return this.timestampToMarker(new Date().valueOf());
+            }
+            // if we can't compute the current date val for a timezone,
+            // better to give the current local date vals than UTC
+            return arrayToUtcDate(dateToLocalArray(new Date()));
+        };
+        DateEnv.prototype.createMarkerMeta = function (input) {
+            if (typeof input === 'string') {
+                return this.parse(input);
+            }
+            var marker = null;
+            if (typeof input === 'number') {
+                marker = this.timestampToMarker(input);
+            }
+            else if (input instanceof Date) {
+                input = input.valueOf();
+                if (!isNaN(input)) {
+                    marker = this.timestampToMarker(input);
+                }
+            }
+            else if (Array.isArray(input)) {
+                marker = arrayToUtcDate(input);
+            }
+            if (marker === null || !isValidDate(marker)) {
+                return null;
+            }
+            return { marker: marker, isTimeUnspecified: false, forcedTzo: null };
+        };
+        DateEnv.prototype.parse = function (s) {
+            var parts = parse(s);
+            if (parts === null) {
+                return null;
+            }
+            var marker = parts.marker;
+            var forcedTzo = null;
+            if (parts.timeZoneOffset !== null) {
+                if (this.canComputeOffset) {
+                    marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
+                }
+                else {
+                    forcedTzo = parts.timeZoneOffset;
+                }
+            }
+            return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo };
+        };
+        // Accessors
+        DateEnv.prototype.getYear = function (marker) {
+            return this.calendarSystem.getMarkerYear(marker);
+        };
+        DateEnv.prototype.getMonth = function (marker) {
+            return this.calendarSystem.getMarkerMonth(marker);
+        };
+        // Adding / Subtracting
+        DateEnv.prototype.add = function (marker, dur) {
+            var a = this.calendarSystem.markerToArray(marker);
+            a[0] += dur.years;
+            a[1] += dur.months;
+            a[2] += dur.days;
+            a[6] += dur.milliseconds;
+            return this.calendarSystem.arrayToMarker(a);
+        };
+        DateEnv.prototype.subtract = function (marker, dur) {
+            var a = this.calendarSystem.markerToArray(marker);
+            a[0] -= dur.years;
+            a[1] -= dur.months;
+            a[2] -= dur.days;
+            a[6] -= dur.milliseconds;
+            return this.calendarSystem.arrayToMarker(a);
+        };
+        DateEnv.prototype.addYears = function (marker, n) {
+            var a = this.calendarSystem.markerToArray(marker);
+            a[0] += n;
+            return this.calendarSystem.arrayToMarker(a);
+        };
+        DateEnv.prototype.addMonths = function (marker, n) {
+            var a = this.calendarSystem.markerToArray(marker);
+            a[1] += n;
+            return this.calendarSystem.arrayToMarker(a);
+        };
+        // Diffing Whole Units
+        DateEnv.prototype.diffWholeYears = function (m0, m1) {
+            var calendarSystem = this.calendarSystem;
+            if (timeAsMs(m0) === timeAsMs(m1) &&
+                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
+                calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
+                return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
+            }
+            return null;
+        };
+        DateEnv.prototype.diffWholeMonths = function (m0, m1) {
+            var calendarSystem = this.calendarSystem;
+            if (timeAsMs(m0) === timeAsMs(m1) &&
+                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
+                return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
+                    (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
+            }
+            return null;
+        };
+        // Range / Duration
+        DateEnv.prototype.greatestWholeUnit = function (m0, m1) {
+            var n = this.diffWholeYears(m0, m1);
+            if (n !== null) {
+                return { unit: 'year', value: n };
+            }
+            n = this.diffWholeMonths(m0, m1);
+            if (n !== null) {
+                return { unit: 'month', value: n };
+            }
+            n = diffWholeWeeks(m0, m1);
+            if (n !== null) {
+                return { unit: 'week', value: n };
+            }
+            n = diffWholeDays(m0, m1);
+            if (n !== null) {
+                return { unit: 'day', value: n };
+            }
+            n = diffHours(m0, m1);
+            if (isInt(n)) {
+                return { unit: 'hour', value: n };
+            }
+            n = diffMinutes(m0, m1);
+            if (isInt(n)) {
+                return { unit: 'minute', value: n };
+            }
+            n = diffSeconds(m0, m1);
+            if (isInt(n)) {
+                return { unit: 'second', value: n };
+            }
+            return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
+        };
+        DateEnv.prototype.countDurationsBetween = function (m0, m1, d) {
+            // TODO: can use greatestWholeUnit
+            var diff;
+            if (d.years) {
+                diff = this.diffWholeYears(m0, m1);
+                if (diff !== null) {
+                    return diff / asRoughYears(d);
+                }
+            }
+            if (d.months) {
+                diff = this.diffWholeMonths(m0, m1);
+                if (diff !== null) {
+                    return diff / asRoughMonths(d);
+                }
+            }
+            if (d.days) {
+                diff = diffWholeDays(m0, m1);
+                if (diff !== null) {
+                    return diff / asRoughDays(d);
+                }
+            }
+            return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
+        };
+        // Start-Of
+        // these DON'T return zoned-dates. only UTC start-of dates
+        DateEnv.prototype.startOf = function (m, unit) {
+            if (unit === 'year') {
+                return this.startOfYear(m);
+            }
+            if (unit === 'month') {
+                return this.startOfMonth(m);
+            }
+            if (unit === 'week') {
+                return this.startOfWeek(m);
+            }
+            if (unit === 'day') {
+                return startOfDay(m);
+            }
+            if (unit === 'hour') {
+                return startOfHour(m);
+            }
+            if (unit === 'minute') {
+                return startOfMinute(m);
+            }
+            if (unit === 'second') {
+                return startOfSecond(m);
+            }
+            return null;
+        };
+        DateEnv.prototype.startOfYear = function (m) {
+            return this.calendarSystem.arrayToMarker([
+                this.calendarSystem.getMarkerYear(m),
+            ]);
+        };
+        DateEnv.prototype.startOfMonth = function (m) {
+            return this.calendarSystem.arrayToMarker([
+                this.calendarSystem.getMarkerYear(m),
+                this.calendarSystem.getMarkerMonth(m),
+            ]);
+        };
+        DateEnv.prototype.startOfWeek = function (m) {
+            return this.calendarSystem.arrayToMarker([
+                this.calendarSystem.getMarkerYear(m),
+                this.calendarSystem.getMarkerMonth(m),
+                m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7),
+            ]);
+        };
+        // Week Number
+        DateEnv.prototype.computeWeekNumber = function (marker) {
+            if (this.weekNumberFunc) {
+                return this.weekNumberFunc(this.toDate(marker));
+            }
+            return weekOfYear(marker, this.weekDow, this.weekDoy);
+        };
+        // TODO: choke on timeZoneName: long
+        DateEnv.prototype.format = function (marker, formatter, dateOptions) {
+            if (dateOptions === void 0) { dateOptions = {}; }
+            return formatter.format({
+                marker: marker,
+                timeZoneOffset: dateOptions.forcedTzo != null ?
+                    dateOptions.forcedTzo :
+                    this.offsetForMarker(marker),
+            }, this);
+        };
+        DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) {
+            if (dateOptions === void 0) { dateOptions = {}; }
+            if (dateOptions.isEndExclusive) {
+                end = addMs(end, -1);
+            }
+            return formatter.formatRange({
+                marker: start,
+                timeZoneOffset: dateOptions.forcedStartTzo != null ?
+                    dateOptions.forcedStartTzo :
+                    this.offsetForMarker(start),
+            }, {
+                marker: end,
+                timeZoneOffset: dateOptions.forcedEndTzo != null ?
+                    dateOptions.forcedEndTzo :
+                    this.offsetForMarker(end),
+            }, this, dateOptions.defaultSeparator);
+        };
+        /*
+        DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that,
+        might as well use buildIsoString or some other util directly
+        */
+        DateEnv.prototype.formatIso = function (marker, extraOptions) {
+            if (extraOptions === void 0) { extraOptions = {}; }
+            var timeZoneOffset = null;
+            if (!extraOptions.omitTimeZoneOffset) {
+                if (extraOptions.forcedTzo != null) {
+                    timeZoneOffset = extraOptions.forcedTzo;
+                }
+                else {
+                    timeZoneOffset = this.offsetForMarker(marker);
+                }
+            }
+            return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
+        };
+        // TimeZone
+        DateEnv.prototype.timestampToMarker = function (ms) {
+            if (this.timeZone === 'local') {
+                return arrayToUtcDate(dateToLocalArray(new Date(ms)));
+            }
+            if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
+                return new Date(ms);
+            }
+            return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
+        };
+        DateEnv.prototype.offsetForMarker = function (m) {
+            if (this.timeZone === 'local') {
+                return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
+            }
+            if (this.timeZone === 'UTC') {
+                return 0;
+            }
+            if (this.namedTimeZoneImpl) {
+                return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
+            }
+            return null;
+        };
+        // Conversion
+        DateEnv.prototype.toDate = function (m, forcedTzo) {
+            if (this.timeZone === 'local') {
+                return arrayToLocalDate(dateToUtcArray(m));
+            }
+            if (this.timeZone === 'UTC') {
+                return new Date(m.valueOf()); // make sure it's a copy
+            }
+            if (!this.namedTimeZoneImpl) {
+                return new Date(m.valueOf() - (forcedTzo || 0));
+            }
+            return new Date(m.valueOf() -
+                this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60);
+        };
+        return DateEnv;
+    }());
+
+    var globalLocales = [];
+
+    var MINIMAL_RAW_EN_LOCALE = {
+        code: 'en',
+        week: {
+            dow: 0,
+            doy: 4, // 4 days need to be within the year to be considered the first week
+        },
+        direction: 'ltr',
+        buttonText: {
+            prev: 'prev',
+            next: 'next',
+            prevYear: 'prev year',
+            nextYear: 'next year',
+            year: 'year',
+            today: 'today',
+            month: 'month',
+            week: 'week',
+            day: 'day',
+            list: 'list',
+        },
+        weekText: 'W',
+        weekTextLong: 'Week',
+        closeHint: 'Close',
+        timeHint: 'Time',
+        eventHint: 'Event',
+        allDayText: 'all-day',
+        moreLinkText: 'more',
+        noEventsText: 'No events to display',
+    };
+    var RAW_EN_LOCALE = __assign(__assign({}, MINIMAL_RAW_EN_LOCALE), { 
+        // Includes things we don't want other locales to inherit,
+        // things that derive from other translatable strings.
+        buttonHints: {
+            prev: 'Previous $0',
+            next: 'Next $0',
+            today: function (buttonText, unit) {
+                return (unit === 'day')
+                    ? 'Today'
+                    : "This " + buttonText;
+            },
+        }, viewHint: '$0 view', navLinkHint: 'Go to $0', moreLinkHint: function (eventCnt) {
+            return "Show " + eventCnt + " more event" + (eventCnt === 1 ? '' : 's');
+        } });
+    function organizeRawLocales(explicitRawLocales) {
+        var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
+        var allRawLocales = globalLocales.concat(explicitRawLocales);
+        var rawLocaleMap = {
+            en: RAW_EN_LOCALE,
+        };
+        for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) {
+            var rawLocale = allRawLocales_1[_i];
+            rawLocaleMap[rawLocale.code] = rawLocale;
+        }
+        return {
+            map: rawLocaleMap,
+            defaultCode: defaultCode,
+        };
+    }
+    function buildLocale(inputSingular, available) {
+        if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
+            return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
+        }
+        return queryLocale(inputSingular, available);
+    }
+    function queryLocale(codeArg, available) {
+        var codes = [].concat(codeArg || []); // will convert to array
+        var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
+        return parseLocale(codeArg, codes, raw);
+    }
+    function queryRawLocale(codes, available) {
+        for (var i = 0; i < codes.length; i += 1) {
+            var parts = codes[i].toLocaleLowerCase().split('-');
+            for (var j = parts.length; j > 0; j -= 1) {
+                var simpleId = parts.slice(0, j).join('-');
+                if (available[simpleId]) {
+                    return available[simpleId];
+                }
+            }
+        }
+        return null;
+    }
+    function parseLocale(codeArg, codes, raw) {
+        var merged = mergeProps([MINIMAL_RAW_EN_LOCALE, raw], ['buttonText']);
+        delete merged.code; // don't want this part of the options
+        var week = merged.week;
+        delete merged.week;
+        return {
+            codeArg: codeArg,
+            codes: codes,
+            week: week,
+            simpleNumberFormat: new Intl.NumberFormat(codeArg),
+            options: merged,
+        };
+    }
+
+    function formatDate(dateInput, options) {
+        if (options === void 0) { options = {}; }
+        var dateEnv = buildDateEnv$1(options);
+        var formatter = createFormatter(options);
+        var dateMeta = dateEnv.createMarkerMeta(dateInput);
+        if (!dateMeta) { // TODO: warning?
+            return '';
+        }
+        return dateEnv.format(dateMeta.marker, formatter, {
+            forcedTzo: dateMeta.forcedTzo,
+        });
+    }
+    function formatRange(startInput, endInput, options) {
+        var dateEnv = buildDateEnv$1(typeof options === 'object' && options ? options : {}); // pass in if non-null object
+        var formatter = createFormatter(options);
+        var startMeta = dateEnv.createMarkerMeta(startInput);
+        var endMeta = dateEnv.createMarkerMeta(endInput);
+        if (!startMeta || !endMeta) { // TODO: warning?
+            return '';
+        }
+        return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
+            forcedStartTzo: startMeta.forcedTzo,
+            forcedEndTzo: endMeta.forcedTzo,
+            isEndExclusive: options.isEndExclusive,
+            defaultSeparator: BASE_OPTION_DEFAULTS.defaultRangeSeparator,
+        });
+    }
+    // TODO: more DRY and optimized
+    function buildDateEnv$1(settings) {
+        var locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
+        return new DateEnv(__assign(__assign({ timeZone: BASE_OPTION_DEFAULTS.timeZone, calendarSystem: 'gregory' }, settings), { locale: locale }));
+    }
+
+    var DEF_DEFAULTS = {
+        startTime: '09:00',
+        endTime: '17:00',
+        daysOfWeek: [1, 2, 3, 4, 5],
+        display: 'inverse-background',
+        classNames: 'fc-non-business',
+        groupId: '_businessHours', // so multiple defs get grouped
+    };
+    /*
+    TODO: pass around as EventDefHash!!!
+    */
+    function parseBusinessHours(input, context) {
+        return parseEvents(refineInputs(input), null, context);
+    }
+    function refineInputs(input) {
+        var rawDefs;
+        if (input === true) {
+            rawDefs = [{}]; // will get DEF_DEFAULTS verbatim
+        }
+        else if (Array.isArray(input)) {
+            // if specifying an array, every sub-definition NEEDS a day-of-week
+            rawDefs = input.filter(function (rawDef) { return rawDef.daysOfWeek; });
+        }
+        else if (typeof input === 'object' && input) { // non-null object
+            rawDefs = [input];
+        }
+        else { // is probably false
+            rawDefs = [];
+        }
+        rawDefs = rawDefs.map(function (rawDef) { return (__assign(__assign({}, DEF_DEFAULTS), rawDef)); });
+        return rawDefs;
+    }
+
+    function pointInsideRect(point, rect) {
+        return point.left >= rect.left &&
+            point.left < rect.right &&
+            point.top >= rect.top &&
+            point.top < rect.bottom;
+    }
+    // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
+    function intersectRects(rect1, rect2) {
+        var res = {
+            left: Math.max(rect1.left, rect2.left),
+            right: Math.min(rect1.right, rect2.right),
+            top: Math.max(rect1.top, rect2.top),
+            bottom: Math.min(rect1.bottom, rect2.bottom),
+        };
+        if (res.left < res.right && res.top < res.bottom) {
+            return res;
+        }
+        return false;
+    }
+    function translateRect(rect, deltaX, deltaY) {
+        return {
+            left: rect.left + deltaX,
+            right: rect.right + deltaX,
+            top: rect.top + deltaY,
+            bottom: rect.bottom + deltaY,
+        };
+    }
+    // Returns a new point that will have been moved to reside within the given rectangle
+    function constrainPoint(point, rect) {
+        return {
+            left: Math.min(Math.max(point.left, rect.left), rect.right),
+            top: Math.min(Math.max(point.top, rect.top), rect.bottom),
+        };
+    }
+    // Returns a point that is the center of the given rectangle
+    function getRectCenter(rect) {
+        return {
+            left: (rect.left + rect.right) / 2,
+            top: (rect.top + rect.bottom) / 2,
+        };
+    }
+    // Subtracts point2's coordinates from point1's coordinates, returning a delta
+    function diffPoints(point1, point2) {
+        return {
+            left: point1.left - point2.left,
+            top: point1.top - point2.top,
+        };
+    }
+
+    var canVGrowWithinCell;
+    function getCanVGrowWithinCell() {
+        if (canVGrowWithinCell == null) {
+            canVGrowWithinCell = computeCanVGrowWithinCell();
+        }
+        return canVGrowWithinCell;
+    }
+    function computeCanVGrowWithinCell() {
+        // for SSR, because this function is call immediately at top-level
+        // TODO: just make this logic execute top-level, immediately, instead of doing lazily
+        if (typeof document === 'undefined') {
+            return true;
+        }
+        var el = document.createElement('div');
+        el.style.position = 'absolute';
+        el.style.top = '0px';
+        el.style.left = '0px';
+        el.innerHTML = '<table><tr><td><div></div></td></tr></table>';
+        el.querySelector('table').style.height = '100px';
+        el.querySelector('div').style.height = '100%';
+        document.body.appendChild(el);
+        var div = el.querySelector('div');
+        var possible = div.offsetHeight > 0;
+        document.body.removeChild(el);
+        return possible;
+    }
+
+    var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
+    var Splitter = /** @class */ (function () {
+        function Splitter() {
+            this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
+            this.splitDateSelection = memoize(this._splitDateSpan);
+            this.splitEventStore = memoize(this._splitEventStore);
+            this.splitIndividualUi = memoize(this._splitIndividualUi);
+            this.splitEventDrag = memoize(this._splitInteraction);
+            this.splitEventResize = memoize(this._splitInteraction);
+            this.eventUiBuilders = {}; // TODO: typescript protection
+        }
+        Splitter.prototype.splitProps = function (props) {
+            var _this = this;
+            var keyInfos = this.getKeyInfo(props);
+            var defKeys = this.getKeysForEventDefs(props.eventStore);
+            var dateSelections = this.splitDateSelection(props.dateSelection);
+            var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
+            var eventStores = this.splitEventStore(props.eventStore, defKeys);
+            var eventDrags = this.splitEventDrag(props.eventDrag);
+            var eventResizes = this.splitEventResize(props.eventResize);
+            var splitProps = {};
+            this.eventUiBuilders = mapHash(keyInfos, function (info, key) { return _this.eventUiBuilders[key] || memoize(buildEventUiForKey); });
+            for (var key in keyInfos) {
+                var keyInfo = keyInfos[key];
+                var eventStore = eventStores[key] || EMPTY_EVENT_STORE;
+                var buildEventUi = this.eventUiBuilders[key];
+                splitProps[key] = {
+                    businessHours: keyInfo.businessHours || props.businessHours,
+                    dateSelection: dateSelections[key] || null,
+                    eventStore: eventStore,
+                    eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
+                    eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
+                    eventDrag: eventDrags[key] || null,
+                    eventResize: eventResizes[key] || null,
+                };
+            }
+            return splitProps;
+        };
+        Splitter.prototype._splitDateSpan = function (dateSpan) {
+            var dateSpans = {};
+            if (dateSpan) {
+                var keys = this.getKeysForDateSpan(dateSpan);
+                for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
+                    var key = keys_1[_i];
+                    dateSpans[key] = dateSpan;
+                }
+            }
+            return dateSpans;
+        };
+        Splitter.prototype._getKeysForEventDefs = function (eventStore) {
+            var _this = this;
+            return mapHash(eventStore.defs, function (eventDef) { return _this.getKeysForEventDef(eventDef); });
+        };
+        Splitter.prototype._splitEventStore = function (eventStore, defKeys) {
+            var defs = eventStore.defs, instances = eventStore.instances;
+            var splitStores = {};
+            for (var defId in defs) {
+                for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
+                    var key = _a[_i];
+                    if (!splitStores[key]) {
+                        splitStores[key] = createEmptyEventStore();
+                    }
+                    splitStores[key].defs[defId] = defs[defId];
+                }
+            }
+            for (var instanceId in instances) {
+                var instance = instances[instanceId];
+                for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) {
+                    var key = _c[_b];
+                    if (splitStores[key]) { // must have already been created
+                        splitStores[key].instances[instanceId] = instance;
+                    }
+                }
+            }
+            return splitStores;
+        };
+        Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) {
+            var splitHashes = {};
+            for (var defId in eventUiBases) {
+                if (defId) { // not the '' key
+                    for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
+                        var key = _a[_i];
+                        if (!splitHashes[key]) {
+                            splitHashes[key] = {};
+                        }
+                        splitHashes[key][defId] = eventUiBases[defId];
+                    }
+                }
+            }
+            return splitHashes;
+        };
+        Splitter.prototype._splitInteraction = function (interaction) {
+            var splitStates = {};
+            if (interaction) {
+                var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents));
+                // can't rely on defKeys because event data is mutated
+                var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
+                var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
+                var populate = function (key) {
+                    if (!splitStates[key]) {
+                        splitStates[key] = {
+                            affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE,
+                            mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE,
+                            isEvent: interaction.isEvent,
+                        };
+                    }
+                };
+                for (var key in affectedStores_1) {
+                    populate(key);
+                }
+                for (var key in mutatedStores_1) {
+                    populate(key);
+                }
+            }
+            return splitStates;
+        };
+        return Splitter;
+    }());
+    function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
+        var baseParts = [];
+        if (allUi) {
+            baseParts.push(allUi);
+        }
+        if (eventUiForKey) {
+            baseParts.push(eventUiForKey);
+        }
+        var stuff = {
+            '': combineEventUis(baseParts),
+        };
+        if (individualUi) {
+            __assign(stuff, individualUi);
+        }
+        return stuff;
+    }
+
+    function getDateMeta(date, todayRange, nowDate, dateProfile) {
+        return {
+            dow: date.getUTCDay(),
+            isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)),
+            isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)),
+            isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)),
+            isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false),
+            isFuture: Boolean(nowDate ? (date > nowDate) : todayRange ? (date >= todayRange.end) : false),
+        };
+    }
+    function getDayClassNames(meta, theme) {
+        var classNames = [
+            'fc-day',
+            "fc-day-" + DAY_IDS[meta.dow],
+        ];
+        if (meta.isDisabled) {
+            classNames.push('fc-day-disabled');
+        }
+        else {
+            if (meta.isToday) {
+                classNames.push('fc-day-today');
+                classNames.push(theme.getClass('today'));
+            }
+            if (meta.isPast) {
+                classNames.push('fc-day-past');
+            }
+            if (meta.isFuture) {
+                classNames.push('fc-day-future');
+            }
+            if (meta.isOther) {
+                classNames.push('fc-day-other');
+            }
+        }
+        return classNames;
+    }
+    function getSlotClassNames(meta, theme) {
+        var classNames = [
+            'fc-slot',
+            "fc-slot-" + DAY_IDS[meta.dow],
+        ];
+        if (meta.isDisabled) {
+            classNames.push('fc-slot-disabled');
+        }
+        else {
+            if (meta.isToday) {
+                classNames.push('fc-slot-today');
+                classNames.push(theme.getClass('today'));
+            }
+            if (meta.isPast) {
+                classNames.push('fc-slot-past');
+            }
+            if (meta.isFuture) {
+                classNames.push('fc-slot-future');
+            }
+        }
+        return classNames;
+    }
+
+    var DAY_FORMAT = createFormatter({ year: 'numeric', month: 'long', day: 'numeric' });
+    var WEEK_FORMAT = createFormatter({ week: 'long' });
+    function buildNavLinkAttrs(context, dateMarker, viewType, isTabbable) {
+        if (viewType === void 0) { viewType = 'day'; }
+        if (isTabbable === void 0) { isTabbable = true; }
+        var dateEnv = context.dateEnv, options = context.options, calendarApi = context.calendarApi;
+        var dateStr = dateEnv.format(dateMarker, viewType === 'week' ? WEEK_FORMAT : DAY_FORMAT);
+        if (options.navLinks) {
+            var zonedDate = dateEnv.toDate(dateMarker);
+            var handleInteraction = function (ev) {
+                var customAction = viewType === 'day' ? options.navLinkDayClick :
+                    viewType === 'week' ? options.navLinkWeekClick : null;
+                if (typeof customAction === 'function') {
+                    customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev);
+                }
+                else {
+                    if (typeof customAction === 'string') {
+                        viewType = customAction;
+                    }
+                    calendarApi.zoomTo(dateMarker, viewType);
+                }
+            };
+            return __assign({ title: formatWithOrdinals(options.navLinkHint, [dateStr, zonedDate], dateStr), 'data-navlink': '' }, (isTabbable
+                ? createAriaClickAttrs(handleInteraction)
+                : { onClick: handleInteraction }));
+        }
+        return { 'aria-label': dateStr };
+    }
+
+    var _isRtlScrollbarOnLeft = null;
+    function getIsRtlScrollbarOnLeft() {
+        if (_isRtlScrollbarOnLeft === null) {
+            _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();
+        }
+        return _isRtlScrollbarOnLeft;
+    }
+    function computeIsRtlScrollbarOnLeft() {
+        var outerEl = document.createElement('div');
+        applyStyle(outerEl, {
+            position: 'absolute',
+            top: -1000,
+            left: 0,
+            border: 0,
+            padding: 0,
+            overflow: 'scroll',
+            direction: 'rtl',
+        });
+        outerEl.innerHTML = '<div></div>';
+        document.body.appendChild(outerEl);
+        var innerEl = outerEl.firstChild;
+        var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;
+        removeElement(outerEl);
+        return res;
+    }
+
+    var _scrollbarWidths;
+    function getScrollbarWidths() {
+        if (!_scrollbarWidths) {
+            _scrollbarWidths = computeScrollbarWidths();
+        }
+        return _scrollbarWidths;
+    }
+    function computeScrollbarWidths() {
+        var el = document.createElement('div');
+        el.style.overflow = 'scroll';
+        el.style.position = 'absolute';
+        el.style.top = '-9999px';
+        el.style.left = '-9999px';
+        document.body.appendChild(el);
+        var res = computeScrollbarWidthsForEl(el);
+        document.body.removeChild(el);
+        return res;
+    }
+    // WARNING: will include border
+    function computeScrollbarWidthsForEl(el) {
+        return {
+            x: el.offsetHeight - el.clientHeight,
+            y: el.offsetWidth - el.clientWidth,
+        };
+    }
+
+    function computeEdges(el, getPadding) {
+        if (getPadding === void 0) { getPadding = false; }
+        var computedStyle = window.getComputedStyle(el);
+        var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
+        var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
+        var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
+        var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
+        var badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border!
+        var scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight;
+        var scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom;
+        var res = {
+            borderLeft: borderLeft,
+            borderRight: borderRight,
+            borderTop: borderTop,
+            borderBottom: borderBottom,
+            scrollbarBottom: scrollbarBottom,
+            scrollbarLeft: 0,
+            scrollbarRight: 0,
+        };
+        if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side?
+            res.scrollbarLeft = scrollbarLeftRight;
+        }
+        else {
+            res.scrollbarRight = scrollbarLeftRight;
+        }
+        if (getPadding) {
+            res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
+            res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
+            res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
+            res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
+        }
+        return res;
+    }
+    function computeInnerRect(el, goWithinPadding, doFromWindowViewport) {
+        if (goWithinPadding === void 0) { goWithinPadding = false; }
+        var outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el);
+        var edges = computeEdges(el, goWithinPadding);
+        var res = {
+            left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
+            right: outerRect.right - edges.borderRight - edges.scrollbarRight,
+            top: outerRect.top + edges.borderTop,
+            bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom,
+        };
+        if (goWithinPadding) {
+            res.left += edges.paddingLeft;
+            res.right -= edges.paddingRight;
+            res.top += edges.paddingTop;
+            res.bottom -= edges.paddingBottom;
+        }
+        return res;
+    }
+    function computeRect(el) {
+        var rect = el.getBoundingClientRect();
+        return {
+            left: rect.left + window.pageXOffset,
+            top: rect.top + window.pageYOffset,
+            right: rect.right + window.pageXOffset,
+            bottom: rect.bottom + window.pageYOffset,
+        };
+    }
+    function computeClippedClientRect(el) {
+        var clippingParents = getClippingParents(el);
+        var rect = el.getBoundingClientRect();
+        for (var _i = 0, clippingParents_1 = clippingParents; _i < clippingParents_1.length; _i++) {
+            var clippingParent = clippingParents_1[_i];
+            var intersection = intersectRects(rect, clippingParent.getBoundingClientRect());
+            if (intersection) {
+                rect = intersection;
+            }
+            else {
+                return null;
+            }
+        }
+        return rect;
+    }
+    function computeHeightAndMargins(el) {
+        return el.getBoundingClientRect().height + computeVMargins(el);
+    }
+    function computeVMargins(el) {
+        var computed = window.getComputedStyle(el);
+        return parseInt(computed.marginTop, 10) +
+            parseInt(computed.marginBottom, 10);
+    }
+    // does not return window
+    function getClippingParents(el) {
+        var parents = [];
+        while (el instanceof HTMLElement) { // will stop when gets to document or null
+            var computedStyle = window.getComputedStyle(el);
+            if (computedStyle.position === 'fixed') {
+                break;
+            }
+            if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
+                parents.push(el);
+            }
+            el = el.parentNode;
+        }
+        return parents;
+    }
+
+    // given a function that resolves a result asynchronously.
+    // the function can either call passed-in success and failure callbacks,
+    // or it can return a promise.
+    // if you need to pass additional params to func, bind them first.
+    function unpromisify(func, success, failure) {
+        // guard against success/failure callbacks being called more than once
+        // and guard against a promise AND callback being used together.
+        var isResolved = false;
+        var wrappedSuccess = function () {
+            if (!isResolved) {
+                isResolved = true;
+                success.apply(this, arguments); // eslint-disable-line prefer-rest-params
+            }
+        };
+        var wrappedFailure = function () {
+            if (!isResolved) {
+                isResolved = true;
+                if (failure) {
+                    failure.apply(this, arguments); // eslint-disable-line prefer-rest-params
+                }
+            }
+        };
+        var res = func(wrappedSuccess, wrappedFailure);
+        if (res && typeof res.then === 'function') {
+            res.then(wrappedSuccess, wrappedFailure);
+        }
+    }
+
+    var Emitter = /** @class */ (function () {
+        function Emitter() {
+            this.handlers = {};
+            this.thisContext = null;
+        }
+        Emitter.prototype.setThisContext = function (thisContext) {
+            this.thisContext = thisContext;
+        };
+        Emitter.prototype.setOptions = function (options) {
+            this.options = options;
+        };
+        Emitter.prototype.on = function (type, handler) {
+            addToHash(this.handlers, type, handler);
+        };
+        Emitter.prototype.off = function (type, handler) {
+            removeFromHash(this.handlers, type, handler);
+        };
+        Emitter.prototype.trigger = function (type) {
+            var args = [];
+            for (var _i = 1; _i < arguments.length; _i++) {
+                args[_i - 1] = arguments[_i];
+            }
+            var attachedHandlers = this.handlers[type] || [];
+            var optionHandler = this.options && this.options[type];
+            var handlers = [].concat(optionHandler || [], attachedHandlers);
+            for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) {
+                var handler = handlers_1[_a];
+                handler.apply(this.thisContext, args);
+            }
+        };
+        Emitter.prototype.hasHandlers = function (type) {
+            return Boolean((this.handlers[type] && this.handlers[type].length) ||
+                (this.options && this.options[type]));
+        };
+        return Emitter;
+    }());
+    function addToHash(hash, type, handler) {
+        (hash[type] || (hash[type] = []))
+            .push(handler);
+    }
+    function removeFromHash(hash, type, handler) {
+        if (handler) {
+            if (hash[type]) {
+                hash[type] = hash[type].filter(function (func) { return func !== handler; });
+            }
+        }
+        else {
+            delete hash[type]; // remove all handler funcs for this type
+        }
+    }
+
+    /*
+    Records offset information for a set of elements, relative to an origin element.
+    Can record the left/right OR the top/bottom OR both.
+    Provides methods for querying the cache by position.
+    */
+    var PositionCache = /** @class */ (function () {
+        function PositionCache(originEl, els, isHorizontal, isVertical) {
+            this.els = els;
+            var originClientRect = this.originClientRect = originEl.getBoundingClientRect(); // relative to viewport top-left
+            if (isHorizontal) {
+                this.buildElHorizontals(originClientRect.left);
+            }
+            if (isVertical) {
+                this.buildElVerticals(originClientRect.top);
+            }
+        }
+        // Populates the left/right internal coordinate arrays
+        PositionCache.prototype.buildElHorizontals = function (originClientLeft) {
+            var lefts = [];
+            var rights = [];
+            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
+                var el = _a[_i];
+                var rect = el.getBoundingClientRect();
+                lefts.push(rect.left - originClientLeft);
+                rights.push(rect.right - originClientLeft);
+            }
+            this.lefts = lefts;
+            this.rights = rights;
+        };
+        // Populates the top/bottom internal coordinate arrays
+        PositionCache.prototype.buildElVerticals = function (originClientTop) {
+            var tops = [];
+            var bottoms = [];
+            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
+                var el = _a[_i];
+                var rect = el.getBoundingClientRect();
+                tops.push(rect.top - originClientTop);
+                bottoms.push(rect.bottom - originClientTop);
+            }
+            this.tops = tops;
+            this.bottoms = bottoms;
+        };
+        // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
+        // If no intersection is made, returns undefined.
+        PositionCache.prototype.leftToIndex = function (leftPosition) {
+            var _a = this, lefts = _a.lefts, rights = _a.rights;
+            var len = lefts.length;
+            var i;
+            for (i = 0; i < len; i += 1) {
+                if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
+                    return i;
+                }
+            }
+            return undefined; // TODO: better
+        };
+        // Given a top offset (from document top), returns the index of the el that it vertically intersects.
+        // If no intersection is made, returns undefined.
+        PositionCache.prototype.topToIndex = function (topPosition) {
+            var _a = this, tops = _a.tops, bottoms = _a.bottoms;
+            var len = tops.length;
+            var i;
+            for (i = 0; i < len; i += 1) {
+                if (topPosition >= tops[i] && topPosition < bottoms[i]) {
+                    return i;
+                }
+            }
+            return undefined; // TODO: better
+        };
+        // Gets the width of the element at the given index
+        PositionCache.prototype.getWidth = function (leftIndex) {
+            return this.rights[leftIndex] - this.lefts[leftIndex];
+        };
+        // Gets the height of the element at the given index
+        PositionCache.prototype.getHeight = function (topIndex) {
+            return this.bottoms[topIndex] - this.tops[topIndex];
+        };
+        return PositionCache;
+    }());
+
+    /* eslint max-classes-per-file: "off" */
+    /*
+    An object for getting/setting scroll-related information for an element.
+    Internally, this is done very differently for window versus DOM element,
+    so this object serves as a common interface.
+    */
+    var ScrollController = /** @class */ (function () {
+        function ScrollController() {
+        }
+        ScrollController.prototype.getMaxScrollTop = function () {
+            return this.getScrollHeight() - this.getClientHeight();
+        };
+        ScrollController.prototype.getMaxScrollLeft = function () {
+            return this.getScrollWidth() - this.getClientWidth();
+        };
+        ScrollController.prototype.canScrollVertically = function () {
+            return this.getMaxScrollTop() > 0;
+        };
+        ScrollController.prototype.canScrollHorizontally = function () {
+            return this.getMaxScrollLeft() > 0;
+        };
+        ScrollController.prototype.canScrollUp = function () {
+            return this.getScrollTop() > 0;
+        };
+        ScrollController.prototype.canScrollDown = function () {
+            return this.getScrollTop() < this.getMaxScrollTop();
+        };
+        ScrollController.prototype.canScrollLeft = function () {
+            return this.getScrollLeft() > 0;
+        };
+        ScrollController.prototype.canScrollRight = function () {
+            return this.getScrollLeft() < this.getMaxScrollLeft();
+        };
+        return ScrollController;
+    }());
+    var ElementScrollController = /** @class */ (function (_super) {
+        __extends(ElementScrollController, _super);
+        function ElementScrollController(el) {
+            var _this = _super.call(this) || this;
+            _this.el = el;
+            return _this;
+        }
+        ElementScrollController.prototype.getScrollTop = function () {
+            return this.el.scrollTop;
+        };
+        ElementScrollController.prototype.getScrollLeft = function () {
+            return this.el.scrollLeft;
+        };
+        ElementScrollController.prototype.setScrollTop = function (top) {
+            this.el.scrollTop = top;
+        };
+        ElementScrollController.prototype.setScrollLeft = function (left) {
+            this.el.scrollLeft = left;
+        };
+        ElementScrollController.prototype.getScrollWidth = function () {
+            return this.el.scrollWidth;
+        };
+        ElementScrollController.prototype.getScrollHeight = function () {
+            return this.el.scrollHeight;
+        };
+        ElementScrollController.prototype.getClientHeight = function () {
+            return this.el.clientHeight;
+        };
+        ElementScrollController.prototype.getClientWidth = function () {
+            return this.el.clientWidth;
+        };
+        return ElementScrollController;
+    }(ScrollController));
+    var WindowScrollController = /** @class */ (function (_super) {
+        __extends(WindowScrollController, _super);
+        function WindowScrollController() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        WindowScrollController.prototype.getScrollTop = function () {
+            return window.pageYOffset;
+        };
+        WindowScrollController.prototype.getScrollLeft = function () {
+            return window.pageXOffset;
+        };
+        WindowScrollController.prototype.setScrollTop = function (n) {
+            window.scroll(window.pageXOffset, n);
+        };
+        WindowScrollController.prototype.setScrollLeft = function (n) {
+            window.scroll(n, window.pageYOffset);
+        };
+        WindowScrollController.prototype.getScrollWidth = function () {
+            return document.documentElement.scrollWidth;
+        };
+        WindowScrollController.prototype.getScrollHeight = function () {
+            return document.documentElement.scrollHeight;
+        };
+        WindowScrollController.prototype.getClientHeight = function () {
+            return document.documentElement.clientHeight;
+        };
+        WindowScrollController.prototype.getClientWidth = function () {
+            return document.documentElement.clientWidth;
+        };
+        return WindowScrollController;
+    }(ScrollController));
+
+    var Theme = /** @class */ (function () {
+        function Theme(calendarOptions) {
+            if (this.iconOverrideOption) {
+                this.setIconOverride(calendarOptions[this.iconOverrideOption]);
+            }
+        }
+        Theme.prototype.setIconOverride = function (iconOverrideHash) {
+            var iconClassesCopy;
+            var buttonName;
+            if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object
+                iconClassesCopy = __assign({}, this.iconClasses);
+                for (buttonName in iconOverrideHash) {
+                    iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
+                }
+                this.iconClasses = iconClassesCopy;
+            }
+            else if (iconOverrideHash === false) {
+                this.iconClasses = {};
+            }
+        };
+        Theme.prototype.applyIconOverridePrefix = function (className) {
+            var prefix = this.iconOverridePrefix;
+            if (prefix && className.indexOf(prefix) !== 0) { // if not already present
+                className = prefix + className;
+            }
+            return className;
+        };
+        Theme.prototype.getClass = function (key) {
+            return this.classes[key] || '';
+        };
+        Theme.prototype.getIconClass = function (buttonName, isRtl) {
+            var className;
+            if (isRtl && this.rtlIconClasses) {
+                className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName];
+            }
+            else {
+                className = this.iconClasses[buttonName];
+            }
+            if (className) {
+                return this.baseIconClass + " " + className;
+            }
+            return '';
+        };
+        Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
+            var className;
+            if (this.iconOverrideCustomButtonOption) {
+                className = customButtonProps[this.iconOverrideCustomButtonOption];
+                if (className) {
+                    return this.baseIconClass + " " + this.applyIconOverridePrefix(className);
+                }
+            }
+            return '';
+        };
+        return Theme;
+    }());
+    Theme.prototype.classes = {};
+    Theme.prototype.iconClasses = {};
+    Theme.prototype.baseIconClass = '';
+    Theme.prototype.iconOverridePrefix = '';
+
+    /// <reference types="@fullcalendar/core-preact" />
+    if (typeof FullCalendarVDom === 'undefined') {
+        throw new Error('Please import the top-level fullcalendar lib before attempting to import a plugin.');
+    }
+    var Component = FullCalendarVDom.Component;
+    var createElement = FullCalendarVDom.createElement;
+    var render = FullCalendarVDom.render;
+    var createRef = FullCalendarVDom.createRef;
+    var Fragment = FullCalendarVDom.Fragment;
+    var createContext = FullCalendarVDom.createContext;
+    var createPortal = FullCalendarVDom.createPortal;
+    var flushSync = FullCalendarVDom.flushSync;
+    var unmountComponentAtNode = FullCalendarVDom.unmountComponentAtNode;
+    /* eslint-enable */
+
+    var ScrollResponder = /** @class */ (function () {
+        function ScrollResponder(execFunc, emitter, scrollTime, scrollTimeReset) {
+            var _this = this;
+            this.execFunc = execFunc;
+            this.emitter = emitter;
+            this.scrollTime = scrollTime;
+            this.scrollTimeReset = scrollTimeReset;
+            this.handleScrollRequest = function (request) {
+                _this.queuedRequest = __assign({}, _this.queuedRequest || {}, request);
+                _this.drain();
+            };
+            emitter.on('_scrollRequest', this.handleScrollRequest);
+            this.fireInitialScroll();
+        }
+        ScrollResponder.prototype.detach = function () {
+            this.emitter.off('_scrollRequest', this.handleScrollRequest);
+        };
+        ScrollResponder.prototype.update = function (isDatesNew) {
+            if (isDatesNew && this.scrollTimeReset) {
+                this.fireInitialScroll(); // will drain
+            }
+            else {
+                this.drain();
+            }
+        };
+        ScrollResponder.prototype.fireInitialScroll = function () {
+            this.handleScrollRequest({
+                time: this.scrollTime,
+            });
+        };
+        ScrollResponder.prototype.drain = function () {
+            if (this.queuedRequest && this.execFunc(this.queuedRequest)) {
+                this.queuedRequest = null;
+            }
+        };
+        return ScrollResponder;
+    }());
+
+    var ViewContextType = createContext({}); // for Components
+    function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) {
+        return {
+            dateEnv: dateEnv,
+            options: viewOptions,
+            pluginHooks: pluginHooks,
+            emitter: emitter,
+            dispatch: dispatch,
+            getCurrentData: getCurrentData,
+            calendarApi: calendarApi,
+            viewSpec: viewSpec,
+            viewApi: viewApi,
+            dateProfileGenerator: dateProfileGenerator,
+            theme: theme,
+            isRtl: viewOptions.direction === 'rtl',
+            addResizeHandler: function (handler) {
+                emitter.on('_resize', handler);
+            },
+            removeResizeHandler: function (handler) {
+                emitter.off('_resize', handler);
+            },
+            createScrollResponder: function (execFunc) {
+                return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime), viewOptions.scrollTimeReset);
+            },
+            registerInteractiveComponent: registerInteractiveComponent,
+            unregisterInteractiveComponent: unregisterInteractiveComponent,
+        };
+    }
+
+    /* eslint max-classes-per-file: off */
+    var PureComponent = /** @class */ (function (_super) {
+        __extends(PureComponent, _super);
+        function PureComponent() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        PureComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) {
+            if (this.debug) {
+                // eslint-disable-next-line no-console
+                console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state));
+            }
+            return !compareObjs(this.props, nextProps, this.propEquality) ||
+                !compareObjs(this.state, nextState, this.stateEquality);
+        };
+        // HACK for freakin' React StrictMode
+        PureComponent.prototype.safeSetState = function (newState) {
+            if (!compareObjs(this.state, __assign(__assign({}, this.state), newState), this.stateEquality)) {
+                this.setState(newState);
+            }
+        };
+        PureComponent.addPropsEquality = addPropsEquality;
+        PureComponent.addStateEquality = addStateEquality;
+        PureComponent.contextType = ViewContextType;
+        return PureComponent;
+    }(Component));
+    PureComponent.prototype.propEquality = {};
+    PureComponent.prototype.stateEquality = {};
+    var BaseComponent = /** @class */ (function (_super) {
+        __extends(BaseComponent, _super);
+        function BaseComponent() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        BaseComponent.contextType = ViewContextType;
+        return BaseComponent;
+    }(PureComponent));
+    function addPropsEquality(propEquality) {
+        var hash = Object.create(this.prototype.propEquality);
+        __assign(hash, propEquality);
+        this.prototype.propEquality = hash;
+    }
+    function addStateEquality(stateEquality) {
+        var hash = Object.create(this.prototype.stateEquality);
+        __assign(hash, stateEquality);
+        this.prototype.stateEquality = hash;
+    }
+    // use other one
+    function setRef(ref, current) {
+        if (typeof ref === 'function') {
+            ref(current);
+        }
+        else if (ref) {
+            // see https://github.com/facebook/react/issues/13029
+            ref.current = current;
+        }
+    }
+
+    /*
+    an INTERACTABLE date component
+
+    PURPOSES:
+    - hook up to fg, fill, and mirror renderers
+    - interface for dragging and hits
+    */
+    var DateComponent = /** @class */ (function (_super) {
+        __extends(DateComponent, _super);
+        function DateComponent() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.uid = guid();
+            return _this;
+        }
+        // Hit System
+        // -----------------------------------------------------------------------------------------------------------------
+        DateComponent.prototype.prepareHits = function () {
+        };
+        DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
+            return null; // this should be abstract
+        };
+        // Pointer Interaction Utils
+        // -----------------------------------------------------------------------------------------------------------------
+        DateComponent.prototype.isValidSegDownEl = function (el) {
+            return !this.props.eventDrag && // HACK
+                !this.props.eventResize && // HACK
+                !elementClosest(el, '.fc-event-mirror');
+        };
+        DateComponent.prototype.isValidDateDownEl = function (el) {
+            return !elementClosest(el, '.fc-event:not(.fc-bg-event)') &&
+                !elementClosest(el, '.fc-more-link') && // a "more.." link
+                !elementClosest(el, 'a[data-navlink]') && // a clickable nav link
+                !elementClosest(el, '.fc-popover'); // hack
+        };
+        return DateComponent;
+    }(BaseComponent));
+
+    // TODO: easier way to add new hooks? need to update a million things
+    function createPlugin(input) {
+        return {
+            id: guid(),
+            deps: input.deps || [],
+            reducers: input.reducers || [],
+            isLoadingFuncs: input.isLoadingFuncs || [],
+            contextInit: [].concat(input.contextInit || []),
+            eventRefiners: input.eventRefiners || {},
+            eventDefMemberAdders: input.eventDefMemberAdders || [],
+            eventSourceRefiners: input.eventSourceRefiners || {},
+            isDraggableTransformers: input.isDraggableTransformers || [],
+            eventDragMutationMassagers: input.eventDragMutationMassagers || [],
+            eventDefMutationAppliers: input.eventDefMutationAppliers || [],
+            dateSelectionTransformers: input.dateSelectionTransformers || [],
+            datePointTransforms: input.datePointTransforms || [],
+            dateSpanTransforms: input.dateSpanTransforms || [],
+            views: input.views || {},
+            viewPropsTransformers: input.viewPropsTransformers || [],
+            isPropsValid: input.isPropsValid || null,
+            externalDefTransforms: input.externalDefTransforms || [],
+            viewContainerAppends: input.viewContainerAppends || [],
+            eventDropTransformers: input.eventDropTransformers || [],
+            componentInteractions: input.componentInteractions || [],
+            calendarInteractions: input.calendarInteractions || [],
+            themeClasses: input.themeClasses || {},
+            eventSourceDefs: input.eventSourceDefs || [],
+            cmdFormatter: input.cmdFormatter,
+            recurringTypes: input.recurringTypes || [],
+            namedTimeZonedImpl: input.namedTimeZonedImpl,
+            initialView: input.initialView || '',
+            elementDraggingImpl: input.elementDraggingImpl,
+            optionChangeHandlers: input.optionChangeHandlers || {},
+            scrollGridImpl: input.scrollGridImpl || null,
+            contentTypeHandlers: input.contentTypeHandlers || {},
+            listenerRefiners: input.listenerRefiners || {},
+            optionRefiners: input.optionRefiners || {},
+            propSetHandlers: input.propSetHandlers || {},
+        };
+    }
+    function buildPluginHooks(pluginDefs, globalDefs) {
+        var isAdded = {};
+        var hooks = {
+            reducers: [],
+            isLoadingFuncs: [],
+            contextInit: [],
+            eventRefiners: {},
+            eventDefMemberAdders: [],
+            eventSourceRefiners: {},
+            isDraggableTransformers: [],
+            eventDragMutationMassagers: [],
+            eventDefMutationAppliers: [],
+            dateSelectionTransformers: [],
+            datePointTransforms: [],
+            dateSpanTransforms: [],
+            views: {},
+            viewPropsTransformers: [],
+            isPropsValid: null,
+            externalDefTransforms: [],
+            viewContainerAppends: [],
+            eventDropTransformers: [],
+            componentInteractions: [],
+            calendarInteractions: [],
+            themeClasses: {},
+            eventSourceDefs: [],
+            cmdFormatter: null,
+            recurringTypes: [],
+            namedTimeZonedImpl: null,
+            initialView: '',
+            elementDraggingImpl: null,
+            optionChangeHandlers: {},
+            scrollGridImpl: null,
+            contentTypeHandlers: {},
+            listenerRefiners: {},
+            optionRefiners: {},
+            propSetHandlers: {},
+        };
+        function addDefs(defs) {
+            for (var _i = 0, defs_1 = defs; _i < defs_1.length; _i++) {
+                var def = defs_1[_i];
+                if (!isAdded[def.id]) {
+                    isAdded[def.id] = true;
+                    addDefs(def.deps);
+                    hooks = combineHooks(hooks, def);
+                }
+            }
+        }
+        if (pluginDefs) {
+            addDefs(pluginDefs);
+        }
+        addDefs(globalDefs);
+        return hooks;
+    }
+    function buildBuildPluginHooks() {
+        var currentOverrideDefs = [];
+        var currentGlobalDefs = [];
+        var currentHooks;
+        return function (overrideDefs, globalDefs) {
+            if (!currentHooks || !isArraysEqual(overrideDefs, currentOverrideDefs) || !isArraysEqual(globalDefs, currentGlobalDefs)) {
+                currentHooks = buildPluginHooks(overrideDefs, globalDefs);
+            }
+            currentOverrideDefs = overrideDefs;
+            currentGlobalDefs = globalDefs;
+            return currentHooks;
+        };
+    }
+    function combineHooks(hooks0, hooks1) {
+        return {
+            reducers: hooks0.reducers.concat(hooks1.reducers),
+            isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs),
+            contextInit: hooks0.contextInit.concat(hooks1.contextInit),
+            eventRefiners: __assign(__assign({}, hooks0.eventRefiners), hooks1.eventRefiners),
+            eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),
+            eventSourceRefiners: __assign(__assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners),
+            isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),
+            eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
+            eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
+            dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
+            datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
+            dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
+            views: __assign(__assign({}, hooks0.views), hooks1.views),
+            viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
+            isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
+            externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
+            viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends),
+            eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
+            calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
+            componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
+            themeClasses: __assign(__assign({}, hooks0.themeClasses), hooks1.themeClasses),
+            eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
+            cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
+            recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
+            namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
+            initialView: hooks0.initialView || hooks1.initialView,
+            elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
+            optionChangeHandlers: __assign(__assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers),
+            scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl,
+            contentTypeHandlers: __assign(__assign({}, hooks0.contentTypeHandlers), hooks1.contentTypeHandlers),
+            listenerRefiners: __assign(__assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners),
+            optionRefiners: __assign(__assign({}, hooks0.optionRefiners), hooks1.optionRefiners),
+            propSetHandlers: __assign(__assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers),
+        };
+    }
+
+    var StandardTheme = /** @class */ (function (_super) {
+        __extends(StandardTheme, _super);
+        function StandardTheme() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        return StandardTheme;
+    }(Theme));
+    StandardTheme.prototype.classes = {
+        root: 'fc-theme-standard',
+        tableCellShaded: 'fc-cell-shaded',
+        buttonGroup: 'fc-button-group',
+        button: 'fc-button fc-button-primary',
+        buttonActive: 'fc-button-active',
+    };
+    StandardTheme.prototype.baseIconClass = 'fc-icon';
+    StandardTheme.prototype.iconClasses = {
+        close: 'fc-icon-x',
+        prev: 'fc-icon-chevron-left',
+        next: 'fc-icon-chevron-right',
+        prevYear: 'fc-icon-chevrons-left',
+        nextYear: 'fc-icon-chevrons-right',
+    };
+    StandardTheme.prototype.rtlIconClasses = {
+        prev: 'fc-icon-chevron-right',
+        next: 'fc-icon-chevron-left',
+        prevYear: 'fc-icon-chevrons-right',
+        nextYear: 'fc-icon-chevrons-left',
+    };
+    StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly
+    StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
+    StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
+
+    function compileViewDefs(defaultConfigs, overrideConfigs) {
+        var hash = {};
+        var viewType;
+        for (viewType in defaultConfigs) {
+            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
+        }
+        for (viewType in overrideConfigs) {
+            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
+        }
+        return hash;
+    }
+    function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
+        if (hash[viewType]) {
+            return hash[viewType];
+        }
+        var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
+        if (viewDef) {
+            hash[viewType] = viewDef;
+        }
+        return viewDef;
+    }
+    function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
+        var defaultConfig = defaultConfigs[viewType];
+        var overrideConfig = overrideConfigs[viewType];
+        var queryProp = function (name) { return ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
+            ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null)); };
+        var theComponent = queryProp('component');
+        var superType = queryProp('superType');
+        var superDef = null;
+        if (superType) {
+            if (superType === viewType) {
+                throw new Error('Can\'t have a custom view type that references itself');
+            }
+            superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);
+        }
+        if (!theComponent && superDef) {
+            theComponent = superDef.component;
+        }
+        if (!theComponent) {
+            return null; // don't throw a warning, might be settings for a single-unit view
+        }
+        return {
+            type: viewType,
+            component: theComponent,
+            defaults: __assign(__assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})),
+            overrides: __assign(__assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})),
+        };
+    }
+
+    /* eslint max-classes-per-file: off */
+    // NOTE: in JSX, you should always use this class with <HookProps> arg. otherwise, will default to any???
+    var RenderHook = /** @class */ (function (_super) {
+        __extends(RenderHook, _super);
+        function RenderHook() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.rootElRef = createRef();
+            _this.handleRootEl = function (el) {
+                setRef(_this.rootElRef, el);
+                if (_this.props.elRef) {
+                    setRef(_this.props.elRef, el);
+                }
+            };
+            return _this;
+        }
+        RenderHook.prototype.render = function () {
+            var _this = this;
+            var props = this.props;
+            var hookProps = props.hookProps;
+            return (createElement(MountHook, { hookProps: hookProps, didMount: props.didMount, willUnmount: props.willUnmount, elRef: this.handleRootEl }, function (rootElRef) { return (createElement(ContentHook, { hookProps: hookProps, content: props.content, defaultContent: props.defaultContent, backupElRef: _this.rootElRef }, function (innerElRef, innerContent) { return props.children(rootElRef, normalizeClassNames(props.classNames, hookProps), innerElRef, innerContent); })); }));
+        };
+        return RenderHook;
+    }(BaseComponent));
+    // TODO: rename to be about function, not default. use in above type
+    // for forcing rerender of components that use the ContentHook
+    var CustomContentRenderContext = createContext(0);
+    function ContentHook(props) {
+        return (createElement(CustomContentRenderContext.Consumer, null, function (renderId) { return (createElement(ContentHookInner, __assign({ renderId: renderId }, props))); }));
+    }
+    var ContentHookInner = /** @class */ (function (_super) {
+        __extends(ContentHookInner, _super);
+        function ContentHookInner() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.innerElRef = createRef();
+            return _this;
+        }
+        ContentHookInner.prototype.render = function () {
+            return this.props.children(this.innerElRef, this.renderInnerContent());
+        };
+        ContentHookInner.prototype.componentDidMount = function () {
+            this.updateCustomContent();
+        };
+        ContentHookInner.prototype.componentDidUpdate = function () {
+            this.updateCustomContent();
+        };
+        ContentHookInner.prototype.componentWillUnmount = function () {
+            if (this.customContentInfo && this.customContentInfo.destroy) {
+                this.customContentInfo.destroy();
+            }
+        };
+        ContentHookInner.prototype.renderInnerContent = function () {
+            var customContentInfo = this.customContentInfo; // only populated if using non-[p]react node(s)
+            var innerContent = this.getInnerContent();
+            var meta = this.getContentMeta(innerContent);
+            // initial run, or content-type changing? (from vue -> react for example)
+            if (!customContentInfo || customContentInfo.contentKey !== meta.contentKey) {
+                // clearing old value
+                if (customContentInfo) {
+                    if (customContentInfo.destroy) {
+                        customContentInfo.destroy();
+                    }
+                    customContentInfo = this.customContentInfo = null;
+                }
+                // assigning new value
+                if (meta.contentKey) {
+                    customContentInfo = this.customContentInfo = __assign({ contentKey: meta.contentKey, contentVal: innerContent[meta.contentKey] }, meta.buildLifecycleFuncs());
+                }
+                // updating
+            }
+            else if (customContentInfo) {
+                customContentInfo.contentVal = innerContent[meta.contentKey];
+            }
+            return customContentInfo
+                ? [] // signal that something was specified
+                : innerContent; // assume a [p]react vdom node. use it
+        };
+        ContentHookInner.prototype.getInnerContent = function () {
+            var props = this.props;
+            var innerContent = normalizeContent(props.content, props.hookProps);
+            if (innerContent === undefined) { // use the default
+                innerContent = normalizeContent(props.defaultContent, props.hookProps);
+            }
+            return innerContent == null ? null : innerContent; // convert undefined to null (better for React)
+        };
+        ContentHookInner.prototype.getContentMeta = function (innerContent) {
+            var contentTypeHandlers = this.context.pluginHooks.contentTypeHandlers;
+            var contentKey = '';
+            var buildLifecycleFuncs = null;
+            if (innerContent) { // allowed to be null, for convenience to caller
+                for (var searchKey in contentTypeHandlers) {
+                    if (innerContent[searchKey] !== undefined) {
+                        contentKey = searchKey;
+                        buildLifecycleFuncs = contentTypeHandlers[searchKey];
+                        break;
+                    }
+                }
+            }
+            return { contentKey: contentKey, buildLifecycleFuncs: buildLifecycleFuncs };
+        };
+        ContentHookInner.prototype.updateCustomContent = function () {
+            if (this.customContentInfo) { // for non-[p]react
+                this.customContentInfo.render(this.innerElRef.current || this.props.backupElRef.current, // the element to render into
+                this.customContentInfo.contentVal);
+            }
+        };
+        return ContentHookInner;
+    }(BaseComponent));
+    var MountHook = /** @class */ (function (_super) {
+        __extends(MountHook, _super);
+        function MountHook() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.handleRootEl = function (rootEl) {
+                _this.rootEl = rootEl;
+                if (_this.props.elRef) {
+                    setRef(_this.props.elRef, rootEl);
+                }
+            };
+            return _this;
+        }
+        MountHook.prototype.render = function () {
+            return this.props.children(this.handleRootEl);
+        };
+        MountHook.prototype.componentDidMount = function () {
+            var callback = this.props.didMount;
+            if (callback) {
+                callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl }));
+            }
+        };
+        MountHook.prototype.componentWillUnmount = function () {
+            var callback = this.props.willUnmount;
+            if (callback) {
+                callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl }));
+            }
+        };
+        return MountHook;
+    }(BaseComponent));
+    function buildClassNameNormalizer() {
+        var currentGenerator;
+        var currentHookProps;
+        var currentClassNames = [];
+        return function (generator, hookProps) {
+            if (!currentHookProps || !isPropsEqual(currentHookProps, hookProps) || generator !== currentGenerator) {
+                currentGenerator = generator;
+                currentHookProps = hookProps;
+                currentClassNames = normalizeClassNames(generator, hookProps);
+            }
+            return currentClassNames;
+        };
+    }
+    function normalizeClassNames(classNames, hookProps) {
+        if (typeof classNames === 'function') {
+            classNames = classNames(hookProps);
+        }
+        return parseClassNames(classNames);
+    }
+    function normalizeContent(input, hookProps) {
+        if (typeof input === 'function') {
+            return input(hookProps, createElement); // give the function the vdom-creation func
+        }
+        return input;
+    }
+
+    var ViewRoot = /** @class */ (function (_super) {
+        __extends(ViewRoot, _super);
+        function ViewRoot() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.normalizeClassNames = buildClassNameNormalizer();
+            return _this;
+        }
+        ViewRoot.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            var options = context.options;
+            var hookProps = { view: context.viewApi };
+            var customClassNames = this.normalizeClassNames(options.viewClassNames, hookProps);
+            return (createElement(MountHook, { hookProps: hookProps, didMount: options.viewDidMount, willUnmount: options.viewWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, ["fc-" + props.viewSpec.type + "-view", 'fc-view'].concat(customClassNames)); }));
+        };
+        return ViewRoot;
+    }(BaseComponent));
+
+    function parseViewConfigs(inputs) {
+        return mapHash(inputs, parseViewConfig);
+    }
+    function parseViewConfig(input) {
+        var rawOptions = typeof input === 'function' ?
+            { component: input } :
+            input;
+        var component = rawOptions.component;
+        if (rawOptions.content) {
+            component = createViewHookComponent(rawOptions);
+            // TODO: remove content/classNames/didMount/etc from options?
+        }
+        return {
+            superType: rawOptions.type,
+            component: component,
+            rawOptions: rawOptions,
+        };
+    }
+    function createViewHookComponent(options) {
+        return function (viewProps) { return (createElement(ViewContextType.Consumer, null, function (context) { return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (viewElRef, viewClassNames) {
+            var hookProps = __assign(__assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold });
+            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.classNames, content: options.content, didMount: options.didMount, willUnmount: options.willUnmount, elRef: viewElRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("div", { className: viewClassNames.concat(customClassNames).join(' '), ref: rootElRef }, innerContent)); }));
+        })); })); };
+    }
+
+    function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
+        var defaultConfigs = parseViewConfigs(defaultInputs);
+        var overrideConfigs = parseViewConfigs(optionOverrides.views);
+        var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
+        return mapHash(viewDefs, function (viewDef) { return buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults); });
+    }
+    function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
+        var durationInput = viewDef.overrides.duration ||
+            viewDef.defaults.duration ||
+            dynamicOptionOverrides.duration ||
+            optionOverrides.duration;
+        var duration = null;
+        var durationUnit = '';
+        var singleUnit = '';
+        var singleUnitOverrides = {};
+        if (durationInput) {
+            duration = createDurationCached(durationInput);
+            if (duration) { // valid?
+                var denom = greatestDurationDenominator(duration);
+                durationUnit = denom.unit;
+                if (denom.value === 1) {
+                    singleUnit = durationUnit;
+                    singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {};
+                }
+            }
+        }
+        var queryButtonText = function (optionsSubset) {
+            var buttonTextMap = optionsSubset.buttonText || {};
+            var buttonTextKey = viewDef.defaults.buttonTextKey;
+            if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
+                return buttonTextMap[buttonTextKey];
+            }
+            if (buttonTextMap[viewDef.type] != null) {
+                return buttonTextMap[viewDef.type];
+            }
+            if (buttonTextMap[singleUnit] != null) {
+                return buttonTextMap[singleUnit];
+            }
+            return null;
+        };
+        var queryButtonTitle = function (optionsSubset) {
+            var buttonHints = optionsSubset.buttonHints || {};
+            var buttonKey = viewDef.defaults.buttonTextKey; // use same key as text
+            if (buttonKey != null && buttonHints[buttonKey] != null) {
+                return buttonHints[buttonKey];
+            }
+            if (buttonHints[viewDef.type] != null) {
+                return buttonHints[viewDef.type];
+            }
+            if (buttonHints[singleUnit] != null) {
+                return buttonHints[singleUnit];
+            }
+            return null;
+        };
+        return {
+            type: viewDef.type,
+            component: viewDef.component,
+            duration: duration,
+            durationUnit: durationUnit,
+            singleUnit: singleUnit,
+            optionDefaults: viewDef.defaults,
+            optionOverrides: __assign(__assign({}, singleUnitOverrides), viewDef.overrides),
+            buttonTextOverride: queryButtonText(dynamicOptionOverrides) ||
+                queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence
+                viewDef.overrides.buttonText,
+            buttonTextDefault: queryButtonText(localeDefaults) ||
+                viewDef.defaults.buttonText ||
+                queryButtonText(BASE_OPTION_DEFAULTS) ||
+                viewDef.type,
+            // not DRY
+            buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) ||
+                queryButtonTitle(optionOverrides) ||
+                viewDef.overrides.buttonHint,
+            buttonTitleDefault: queryButtonTitle(localeDefaults) ||
+                viewDef.defaults.buttonHint ||
+                queryButtonTitle(BASE_OPTION_DEFAULTS),
+            // will eventually fall back to buttonText
+        };
+    }
+    // hack to get memoization working
+    var durationInputMap = {};
+    function createDurationCached(durationInput) {
+        var json = JSON.stringify(durationInput);
+        var res = durationInputMap[json];
+        if (res === undefined) {
+            res = createDuration(durationInput);
+            durationInputMap[json] = res;
+        }
+        return res;
+    }
+
+    var DateProfileGenerator = /** @class */ (function () {
+        function DateProfileGenerator(props) {
+            this.props = props;
+            this.nowDate = getNow(props.nowInput, props.dateEnv);
+            this.initHiddenDays();
+        }
+        /* Date Range Computation
+        ------------------------------------------------------------------------------------------------------------------*/
+        // Builds a structure with info about what the dates/ranges will be for the "prev" view.
+        DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate, forceToValid) {
+            var dateEnv = this.props.dateEnv;
+            var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
+            currentDateProfile.dateIncrement);
+            return this.build(prevDate, -1, forceToValid);
+        };
+        // Builds a structure with info about what the dates/ranges will be for the "next" view.
+        DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate, forceToValid) {
+            var dateEnv = this.props.dateEnv;
+            var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
+            currentDateProfile.dateIncrement);
+            return this.build(nextDate, 1, forceToValid);
+        };
+        // Builds a structure holding dates/ranges for rendering around the given date.
+        // Optional direction param indicates whether the date is being incremented/decremented
+        // from its previous value. decremented = -1, incremented = 1 (default).
+        DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) {
+            if (forceToValid === void 0) { forceToValid = true; }
+            var props = this.props;
+            var validRange;
+            var currentInfo;
+            var isRangeAllDay;
+            var renderRange;
+            var activeRange;
+            var isValid;
+            validRange = this.buildValidRange();
+            validRange = this.trimHiddenDays(validRange);
+            if (forceToValid) {
+                currentDate = constrainMarkerToRange(currentDate, validRange);
+            }
+            currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
+            isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
+            renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
+            renderRange = this.trimHiddenDays(renderRange);
+            activeRange = renderRange;
+            if (!props.showNonCurrentDates) {
+                activeRange = intersectRanges(activeRange, currentInfo.range);
+            }
+            activeRange = this.adjustActiveRange(activeRange);
+            activeRange = intersectRanges(activeRange, validRange); // might return null
+            // it's invalid if the originally requested date is not contained,
+            // or if the range is completely outside of the valid range.
+            isValid = rangesIntersect(currentInfo.range, validRange);
+            return {
+                // constraint for where prev/next operations can go and where events can be dragged/resized to.
+                // an object with optional start and end properties.
+                validRange: validRange,
+                // range the view is formally responsible for.
+                // for example, a month view might have 1st-31st, excluding padded dates
+                currentRange: currentInfo.range,
+                // name of largest unit being displayed, like "month" or "week"
+                currentRangeUnit: currentInfo.unit,
+                isRangeAllDay: isRangeAllDay,
+                // dates that display events and accept drag-n-drop
+                // will be `null` if no dates accept events
+                activeRange: activeRange,
+                // date range with a rendered skeleton
+                // includes not-active days that need some sort of DOM
+                renderRange: renderRange,
+                // Duration object that denotes the first visible time of any given day
+                slotMinTime: props.slotMinTime,
+                // Duration object that denotes the exclusive visible end time of any given day
+                slotMaxTime: props.slotMaxTime,
+                isValid: isValid,
+                // how far the current date will move for a prev/next operation
+                dateIncrement: this.buildDateIncrement(currentInfo.duration),
+                // pass a fallback (might be null) ^
+            };
+        };
+        // Builds an object with optional start/end properties.
+        // Indicates the minimum/maximum dates to display.
+        // not responsible for trimming hidden days.
+        DateProfileGenerator.prototype.buildValidRange = function () {
+            var input = this.props.validRangeInput;
+            var simpleInput = typeof input === 'function'
+                ? input.call(this.props.calendarApi, this.nowDate)
+                : input;
+            return this.refineRange(simpleInput) ||
+                { start: null, end: null }; // completely open-ended
+        };
+        // Builds a structure with info about the "current" range, the range that is
+        // highlighted as being the current month for example.
+        // See build() for a description of `direction`.
+        // Guaranteed to have `range` and `unit` properties. `duration` is optional.
+        DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
+            var props = this.props;
+            var duration = null;
+            var unit = null;
+            var range = null;
+            var dayCount;
+            if (props.duration) {
+                duration = props.duration;
+                unit = props.durationUnit;
+                range = this.buildRangeFromDuration(date, direction, duration, unit);
+            }
+            else if ((dayCount = this.props.dayCount)) {
+                unit = 'day';
+                range = this.buildRangeFromDayCount(date, direction, dayCount);
+            }
+            else if ((range = this.buildCustomVisibleRange(date))) {
+                unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit;
+            }
+            else {
+                duration = this.getFallbackDuration();
+                unit = greatestDurationDenominator(duration).unit;
+                range = this.buildRangeFromDuration(date, direction, duration, unit);
+            }
+            return { duration: duration, unit: unit, range: range };
+        };
+        DateProfileGenerator.prototype.getFallbackDuration = function () {
+            return createDuration({ day: 1 });
+        };
+        // Returns a new activeRange to have time values (un-ambiguate)
+        // slotMinTime or slotMaxTime causes the range to expand.
+        DateProfileGenerator.prototype.adjustActiveRange = function (range) {
+            var _a = this.props, dateEnv = _a.dateEnv, usesMinMaxTime = _a.usesMinMaxTime, slotMinTime = _a.slotMinTime, slotMaxTime = _a.slotMaxTime;
+            var start = range.start, end = range.end;
+            if (usesMinMaxTime) {
+                // expand active range if slotMinTime is negative (why not when positive?)
+                if (asRoughDays(slotMinTime) < 0) {
+                    start = startOfDay(start); // necessary?
+                    start = dateEnv.add(start, slotMinTime);
+                }
+                // expand active range if slotMaxTime is beyond one day (why not when negative?)
+                if (asRoughDays(slotMaxTime) > 1) {
+                    end = startOfDay(end); // necessary?
+                    end = addDays(end, -1);
+                    end = dateEnv.add(end, slotMaxTime);
+                }
+            }
+            return { start: start, end: end };
+        };
+        // Builds the "current" range when it is specified as an explicit duration.
+        // `unit` is the already-computed greatestDurationDenominator unit of duration.
+        DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
+            var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment;
+            var start;
+            var end;
+            var res;
+            // compute what the alignment should be
+            if (!dateAlignment) {
+                var dateIncrement = this.props.dateIncrement;
+                if (dateIncrement) {
+                    // use the smaller of the two units
+                    if (asRoughMs(dateIncrement) < asRoughMs(duration)) {
+                        dateAlignment = greatestDurationDenominator(dateIncrement).unit;
+                    }
+                    else {
+                        dateAlignment = unit;
+                    }
+                }
+                else {
+                    dateAlignment = unit;
+                }
+            }
+            // if the view displays a single day or smaller
+            if (asRoughDays(duration) <= 1) {
+                if (this.isHiddenDay(start)) {
+                    start = this.skipHiddenDays(start, direction);
+                    start = startOfDay(start);
+                }
+            }
+            function computeRes() {
+                start = dateEnv.startOf(date, dateAlignment);
+                end = dateEnv.add(start, duration);
+                res = { start: start, end: end };
+            }
+            computeRes();
+            // if range is completely enveloped by hidden days, go past the hidden days
+            if (!this.trimHiddenDays(res)) {
+                date = this.skipHiddenDays(date, direction);
+                computeRes();
+            }
+            return res;
+        };
+        // Builds the "current" range when a dayCount is specified.
+        DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
+            var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment;
+            var runningCount = 0;
+            var start = date;
+            var end;
+            if (dateAlignment) {
+                start = dateEnv.startOf(start, dateAlignment);
+            }
+            start = startOfDay(start);
+            start = this.skipHiddenDays(start, direction);
+            end = start;
+            do {
+                end = addDays(end, 1);
+                if (!this.isHiddenDay(end)) {
+                    runningCount += 1;
+                }
+            } while (runningCount < dayCount);
+            return { start: start, end: end };
+        };
+        // Builds a normalized range object for the "visible" range,
+        // which is a way to define the currentRange and activeRange at the same time.
+        DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
+            var props = this.props;
+            var input = props.visibleRangeInput;
+            var simpleInput = typeof input === 'function'
+                ? input.call(props.calendarApi, props.dateEnv.toDate(date))
+                : input;
+            var range = this.refineRange(simpleInput);
+            if (range && (range.start == null || range.end == null)) {
+                return null;
+            }
+            return range;
+        };
+        // Computes the range that will represent the element/cells for *rendering*,
+        // but which may have voided days/times.
+        // not responsible for trimming hidden days.
+        DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
+            return currentRange;
+        };
+        // Compute the duration value that should be added/substracted to the current date
+        // when a prev/next operation happens.
+        DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
+            var dateIncrement = this.props.dateIncrement;
+            var customAlignment;
+            if (dateIncrement) {
+                return dateIncrement;
+            }
+            if ((customAlignment = this.props.dateAlignment)) {
+                return createDuration(1, customAlignment);
+            }
+            if (fallback) {
+                return fallback;
+            }
+            return createDuration({ days: 1 });
+        };
+        DateProfileGenerator.prototype.refineRange = function (rangeInput) {
+            if (rangeInput) {
+                var range = parseRange(rangeInput, this.props.dateEnv);
+                if (range) {
+                    range = computeVisibleDayRange(range);
+                }
+                return range;
+            }
+            return null;
+        };
+        /* Hidden Days
+        ------------------------------------------------------------------------------------------------------------------*/
+        // Initializes internal variables related to calculating hidden days-of-week
+        DateProfileGenerator.prototype.initHiddenDays = function () {
+            var hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden
+            var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
+            var dayCnt = 0;
+            var i;
+            if (this.props.weekends === false) {
+                hiddenDays.push(0, 6); // 0=sunday, 6=saturday
+            }
+            for (i = 0; i < 7; i += 1) {
+                if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
+                    dayCnt += 1;
+                }
+            }
+            if (!dayCnt) {
+                throw new Error('invalid hiddenDays'); // all days were hidden? bad.
+            }
+            this.isHiddenDayHash = isHiddenDayHash;
+        };
+        // Remove days from the beginning and end of the range that are computed as hidden.
+        // If the whole range is trimmed off, returns null
+        DateProfileGenerator.prototype.trimHiddenDays = function (range) {
+            var start = range.start, end = range.end;
+            if (start) {
+                start = this.skipHiddenDays(start);
+            }
+            if (end) {
+                end = this.skipHiddenDays(end, -1, true);
+            }
+            if (start == null || end == null || start < end) {
+                return { start: start, end: end };
+            }
+            return null;
+        };
+        // Is the current day hidden?
+        // `day` is a day-of-week index (0-6), or a Date (used for UTC)
+        DateProfileGenerator.prototype.isHiddenDay = function (day) {
+            if (day instanceof Date) {
+                day = day.getUTCDay();
+            }
+            return this.isHiddenDayHash[day];
+        };
+        // Incrementing the current day until it is no longer a hidden day, returning a copy.
+        // DOES NOT CONSIDER validRange!
+        // If the initial value of `date` is not a hidden day, don't do anything.
+        // Pass `isExclusive` as `true` if you are dealing with an end date.
+        // `inc` defaults to `1` (increment one day forward each time)
+        DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) {
+            if (inc === void 0) { inc = 1; }
+            if (isExclusive === void 0) { isExclusive = false; }
+            while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
+                date = addDays(date, inc);
+            }
+            return date;
+        };
+        return DateProfileGenerator;
+    }());
+
+    function reduceViewType(viewType, action) {
+        switch (action.type) {
+            case 'CHANGE_VIEW_TYPE':
+                viewType = action.viewType;
+        }
+        return viewType;
+    }
+
+    function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {
+        var _a;
+        switch (action.type) {
+            case 'SET_OPTION':
+                return __assign(__assign({}, dynamicOptionOverrides), (_a = {}, _a[action.optionName] = action.rawOptionValue, _a));
+            default:
+                return dynamicOptionOverrides;
+        }
+    }
+
+    function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) {
+        var dp;
+        switch (action.type) {
+            case 'CHANGE_VIEW_TYPE':
+                return dateProfileGenerator.build(action.dateMarker || currentDate);
+            case 'CHANGE_DATE':
+                return dateProfileGenerator.build(action.dateMarker);
+            case 'PREV':
+                dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate);
+                if (dp.isValid) {
+                    return dp;
+                }
+                break;
+            case 'NEXT':
+                dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate);
+                if (dp.isValid) {
+                    return dp;
+                }
+                break;
+        }
+        return currentDateProfile;
+    }
+
+    function initEventSources(calendarOptions, dateProfile, context) {
+        var activeRange = dateProfile ? dateProfile.activeRange : null;
+        return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context);
+    }
+    function reduceEventSources(eventSources, action, dateProfile, context) {
+        var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
+        switch (action.type) {
+            case 'ADD_EVENT_SOURCES': // already parsed
+                return addSources(eventSources, action.sources, activeRange, context);
+            case 'REMOVE_EVENT_SOURCE':
+                return removeSource(eventSources, action.sourceId);
+            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
+            case 'NEXT':
+            case 'CHANGE_DATE':
+            case 'CHANGE_VIEW_TYPE':
+                if (dateProfile) {
+                    return fetchDirtySources(eventSources, activeRange, context);
+                }
+                return eventSources;
+            case 'FETCH_EVENT_SOURCES':
+                return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type?
+                    arrayToHash(action.sourceIds) :
+                    excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context);
+            case 'RECEIVE_EVENTS':
+            case 'RECEIVE_EVENT_ERROR':
+                return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
+            case 'REMOVE_ALL_EVENT_SOURCES':
+                return {};
+            default:
+                return eventSources;
+        }
+    }
+    function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) {
+        var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
+        return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context);
+    }
+    function computeEventSourcesLoading(eventSources) {
+        for (var sourceId in eventSources) {
+            if (eventSources[sourceId].isFetching) {
+                return true;
+            }
+        }
+        return false;
+    }
+    function addSources(eventSourceHash, sources, fetchRange, context) {
+        var hash = {};
+        for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
+            var source = sources_1[_i];
+            hash[source.sourceId] = source;
+        }
+        if (fetchRange) {
+            hash = fetchDirtySources(hash, fetchRange, context);
+        }
+        return __assign(__assign({}, eventSourceHash), hash);
+    }
+    function removeSource(eventSourceHash, sourceId) {
+        return filterHash(eventSourceHash, function (eventSource) { return eventSource.sourceId !== sourceId; });
+    }
+    function fetchDirtySources(sourceHash, fetchRange, context) {
+        return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) { return isSourceDirty(eventSource, fetchRange, context); }), fetchRange, false, context);
+    }
+    function isSourceDirty(eventSource, fetchRange, context) {
+        if (!doesSourceNeedRange(eventSource, context)) {
+            return !eventSource.latestFetchId;
+        }
+        return !context.options.lazyFetching ||
+            !eventSource.fetchRange ||
+            eventSource.isFetching || // always cancel outdated in-progress fetches
+            fetchRange.start < eventSource.fetchRange.start ||
+            fetchRange.end > eventSource.fetchRange.end;
+    }
+    function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) {
+        var nextSources = {};
+        for (var sourceId in prevSources) {
+            var source = prevSources[sourceId];
+            if (sourceIdHash[sourceId]) {
+                nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context);
+            }
+            else {
+                nextSources[sourceId] = source;
+            }
+        }
+        return nextSources;
+    }
+    function fetchSource(eventSource, fetchRange, isRefetch, context) {
+        var options = context.options, calendarApi = context.calendarApi;
+        var sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId];
+        var fetchId = guid();
+        sourceDef.fetch({
+            eventSource: eventSource,
+            range: fetchRange,
+            isRefetch: isRefetch,
+            context: context,
+        }, function (res) {
+            var rawEvents = res.rawEvents;
+            if (options.eventSourceSuccess) {
+                rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.xhr) || rawEvents;
+            }
+            if (eventSource.success) {
+                rawEvents = eventSource.success.call(calendarApi, rawEvents, res.xhr) || rawEvents;
+            }
+            context.dispatch({
+                type: 'RECEIVE_EVENTS',
+                sourceId: eventSource.sourceId,
+                fetchId: fetchId,
+                fetchRange: fetchRange,
+                rawEvents: rawEvents,
+            });
+        }, function (error) {
+            console.warn(error.message, error);
+            if (options.eventSourceFailure) {
+                options.eventSourceFailure.call(calendarApi, error);
+            }
+            if (eventSource.failure) {
+                eventSource.failure(error);
+            }
+            context.dispatch({
+                type: 'RECEIVE_EVENT_ERROR',
+                sourceId: eventSource.sourceId,
+                fetchId: fetchId,
+                fetchRange: fetchRange,
+                error: error,
+            });
+        });
+        return __assign(__assign({}, eventSource), { isFetching: true, latestFetchId: fetchId });
+    }
+    function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
+        var _a;
+        var eventSource = sourceHash[sourceId];
+        if (eventSource && // not already removed
+            fetchId === eventSource.latestFetchId) {
+            return __assign(__assign({}, sourceHash), (_a = {}, _a[sourceId] = __assign(__assign({}, eventSource), { isFetching: false, fetchRange: fetchRange }), _a));
+        }
+        return sourceHash;
+    }
+    function excludeStaticSources(eventSources, context) {
+        return filterHash(eventSources, function (eventSource) { return doesSourceNeedRange(eventSource, context); });
+    }
+    function parseInitialSources(rawOptions, context) {
+        var refiners = buildEventSourceRefiners(context);
+        var rawSources = [].concat(rawOptions.eventSources || []);
+        var sources = []; // parsed
+        if (rawOptions.initialEvents) {
+            rawSources.unshift(rawOptions.initialEvents);
+        }
+        if (rawOptions.events) {
+            rawSources.unshift(rawOptions.events);
+        }
+        for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) {
+            var rawSource = rawSources_1[_i];
+            var source = parseEventSource(rawSource, context, refiners);
+            if (source) {
+                sources.push(source);
+            }
+        }
+        return sources;
+    }
+    function doesSourceNeedRange(eventSource, context) {
+        var defs = context.pluginHooks.eventSourceDefs;
+        return !defs[eventSource.sourceDefId].ignoreRange;
+    }
+
+    function reduceEventStore(eventStore, action, eventSources, dateProfile, context) {
+        switch (action.type) {
+            case 'RECEIVE_EVENTS': // raw
+                return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context);
+            case 'ADD_EVENTS': // already parsed, but not expanded
+                return addEvent(eventStore, action.eventStore, // new ones
+                dateProfile ? dateProfile.activeRange : null, context);
+            case 'RESET_EVENTS':
+                return action.eventStore;
+            case 'MERGE_EVENTS': // already parsed and expanded
+                return mergeEventStores(eventStore, action.eventStore);
+            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
+            case 'NEXT':
+            case 'CHANGE_DATE':
+            case 'CHANGE_VIEW_TYPE':
+                if (dateProfile) {
+                    return expandRecurring(eventStore, dateProfile.activeRange, context);
+                }
+                return eventStore;
+            case 'REMOVE_EVENTS':
+                return excludeSubEventStore(eventStore, action.eventStore);
+            case 'REMOVE_EVENT_SOURCE':
+                return excludeEventsBySourceId(eventStore, action.sourceId);
+            case 'REMOVE_ALL_EVENT_SOURCES':
+                return filterEventStoreDefs(eventStore, function (eventDef) { return (!eventDef.sourceId // only keep events with no source id
+                ); });
+            case 'REMOVE_ALL_EVENTS':
+                return createEmptyEventStore();
+            default:
+                return eventStore;
+        }
+    }
+    function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) {
+        if (eventSource && // not already removed
+            fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
+        ) {
+            var subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context);
+            if (fetchRange) {
+                subset = expandRecurring(subset, fetchRange, context);
+            }
+            return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
+        }
+        return eventStore;
+    }
+    function transformRawEvents(rawEvents, eventSource, context) {
+        var calEachTransform = context.options.eventDataTransform;
+        var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
+        if (sourceEachTransform) {
+            rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
+        }
+        if (calEachTransform) {
+            rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
+        }
+        return rawEvents;
+    }
+    function transformEachRawEvent(rawEvents, func) {
+        var refinedEvents;
+        if (!func) {
+            refinedEvents = rawEvents;
+        }
+        else {
+            refinedEvents = [];
+            for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
+                var rawEvent = rawEvents_1[_i];
+                var refinedEvent = func(rawEvent);
+                if (refinedEvent) {
+                    refinedEvents.push(refinedEvent);
+                }
+                else if (refinedEvent == null) {
+                    refinedEvents.push(rawEvent);
+                } // if a different falsy value, do nothing
+            }
+        }
+        return refinedEvents;
+    }
+    function addEvent(eventStore, subset, expandRange, context) {
+        if (expandRange) {
+            subset = expandRecurring(subset, expandRange, context);
+        }
+        return mergeEventStores(eventStore, subset);
+    }
+    function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) {
+        var defs = eventStore.defs;
+        var instances = mapHash(eventStore.instances, function (instance) {
+            var def = defs[instance.defId];
+            if (def.allDay || def.recurringDef) {
+                return instance; // isn't dependent on timezone
+            }
+            return __assign(__assign({}, instance), { range: {
+                    start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
+                    end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)),
+                }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
+        });
+        return { defs: defs, instances: instances };
+    }
+    function excludeEventsBySourceId(eventStore, sourceId) {
+        return filterEventStoreDefs(eventStore, function (eventDef) { return eventDef.sourceId !== sourceId; });
+    }
+    // QUESTION: why not just return instances? do a general object-property-exclusion util
+    function excludeInstances(eventStore, removals) {
+        return {
+            defs: eventStore.defs,
+            instances: filterHash(eventStore.instances, function (instance) { return !removals[instance.instanceId]; }),
+        };
+    }
+
+    function reduceDateSelection(currentSelection, action) {
+        switch (action.type) {
+            case 'UNSELECT_DATES':
+                return null;
+            case 'SELECT_DATES':
+                return action.selection;
+            default:
+                return currentSelection;
+        }
+    }
+
+    function reduceSelectedEvent(currentInstanceId, action) {
+        switch (action.type) {
+            case 'UNSELECT_EVENT':
+                return '';
+            case 'SELECT_EVENT':
+                return action.eventInstanceId;
+            default:
+                return currentInstanceId;
+        }
+    }
+
+    function reduceEventDrag(currentDrag, action) {
+        var newDrag;
+        switch (action.type) {
+            case 'UNSET_EVENT_DRAG':
+                return null;
+            case 'SET_EVENT_DRAG':
+                newDrag = action.state;
+                return {
+                    affectedEvents: newDrag.affectedEvents,
+                    mutatedEvents: newDrag.mutatedEvents,
+                    isEvent: newDrag.isEvent,
+                };
+            default:
+                return currentDrag;
+        }
+    }
+
+    function reduceEventResize(currentResize, action) {
+        var newResize;
+        switch (action.type) {
+            case 'UNSET_EVENT_RESIZE':
+                return null;
+            case 'SET_EVENT_RESIZE':
+                newResize = action.state;
+                return {
+                    affectedEvents: newResize.affectedEvents,
+                    mutatedEvents: newResize.mutatedEvents,
+                    isEvent: newResize.isEvent,
+                };
+            default:
+                return currentResize;
+        }
+    }
+
+    function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {
+        var header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;
+        var footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;
+        return { header: header, footer: footer };
+    }
+    function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {
+        var sectionWidgets = {};
+        var viewsWithButtons = [];
+        var hasTitle = false;
+        for (var sectionName in sectionStrHash) {
+            var sectionStr = sectionStrHash[sectionName];
+            var sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi);
+            sectionWidgets[sectionName] = sectionRes.widgets;
+            viewsWithButtons.push.apply(viewsWithButtons, sectionRes.viewsWithButtons);
+            hasTitle = hasTitle || sectionRes.hasTitle;
+        }
+        return { sectionWidgets: sectionWidgets, viewsWithButtons: viewsWithButtons, hasTitle: hasTitle };
+    }
+    /*
+    BAD: querying icons and text here. should be done at render time
+    */
+    function parseSection(sectionStr, calendarOptions, // defaults+overrides, then refined
+    calendarOptionOverrides, // overrides only!, unrefined :(
+    theme, viewSpecs, calendarApi) {
+        var isRtl = calendarOptions.direction === 'rtl';
+        var calendarCustomButtons = calendarOptions.customButtons || {};
+        var calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {};
+        var calendarButtonText = calendarOptions.buttonText || {};
+        var calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {};
+        var calendarButtonHints = calendarOptions.buttonHints || {};
+        var sectionSubstrs = sectionStr ? sectionStr.split(' ') : [];
+        var viewsWithButtons = [];
+        var hasTitle = false;
+        var widgets = sectionSubstrs.map(function (buttonGroupStr) { return (buttonGroupStr.split(',').map(function (buttonName) {
+            if (buttonName === 'title') {
+                hasTitle = true;
+                return { buttonName: buttonName };
+            }
+            var customButtonProps;
+            var viewSpec;
+            var buttonClick;
+            var buttonIcon; // only one of these will be set
+            var buttonText; // "
+            var buttonHint;
+            // ^ for the title="" attribute, for accessibility
+            if ((customButtonProps = calendarCustomButtons[buttonName])) {
+                buttonClick = function (ev) {
+                    if (customButtonProps.click) {
+                        customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context?
+                    }
+                };
+                (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
+                    (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
+                    (buttonText = customButtonProps.text);
+                buttonHint = customButtonProps.hint || customButtonProps.text;
+            }
+            else if ((viewSpec = viewSpecs[buttonName])) {
+                viewsWithButtons.push(buttonName);
+                buttonClick = function () {
+                    calendarApi.changeView(buttonName);
+                };
+                (buttonText = viewSpec.buttonTextOverride) ||
+                    (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
+                    (buttonText = viewSpec.buttonTextDefault);
+                var textFallback = viewSpec.buttonTextOverride ||
+                    viewSpec.buttonTextDefault;
+                buttonHint = formatWithOrdinals(viewSpec.buttonTitleOverride ||
+                    viewSpec.buttonTitleDefault ||
+                    calendarOptions.viewHint, [textFallback, buttonName], // view-name = buttonName
+                textFallback);
+            }
+            else if (calendarApi[buttonName]) { // a calendarApi method
+                buttonClick = function () {
+                    calendarApi[buttonName]();
+                };
+                (buttonText = calendarButtonTextOverrides[buttonName]) ||
+                    (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
+                    (buttonText = calendarButtonText[buttonName]); // everything else is considered default
+                if (buttonName === 'prevYear' || buttonName === 'nextYear') {
+                    var prevOrNext = buttonName === 'prevYear' ? 'prev' : 'next';
+                    buttonHint = formatWithOrdinals(calendarButtonHintOverrides[prevOrNext] ||
+                        calendarButtonHints[prevOrNext], [
+                        calendarButtonText.year || 'year',
+                        'year',
+                    ], calendarButtonText[buttonName]);
+                }
+                else {
+                    buttonHint = function (navUnit) { return formatWithOrdinals(calendarButtonHintOverrides[buttonName] ||
+                        calendarButtonHints[buttonName], [
+                        calendarButtonText[navUnit] || navUnit,
+                        navUnit,
+                    ], calendarButtonText[buttonName]); };
+                }
+            }
+            return { buttonName: buttonName, buttonClick: buttonClick, buttonIcon: buttonIcon, buttonText: buttonText, buttonHint: buttonHint };
+        })); });
+        return { widgets: widgets, viewsWithButtons: viewsWithButtons, hasTitle: hasTitle };
+    }
+
+    var eventSourceDef$3 = {
+        ignoreRange: true,
+        parseMeta: function (refined) {
+            if (Array.isArray(refined.events)) {
+                return refined.events;
+            }
+            return null;
+        },
+        fetch: function (arg, success) {
+            success({
+                rawEvents: arg.eventSource.meta,
+            });
+        },
+    };
+    var arrayEventSourcePlugin = createPlugin({
+        eventSourceDefs: [eventSourceDef$3],
+    });
+
+    var eventSourceDef$2 = {
+        parseMeta: function (refined) {
+            if (typeof refined.events === 'function') {
+                return refined.events;
+            }
+            return null;
+        },
+        fetch: function (arg, success, failure) {
+            var dateEnv = arg.context.dateEnv;
+            var func = arg.eventSource.meta;
+            unpromisify(func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), function (rawEvents) {
+                success({ rawEvents: rawEvents }); // needs an object response
+            }, failure);
+        },
+    };
+    var funcEventSourcePlugin = createPlugin({
+        eventSourceDefs: [eventSourceDef$2],
+    });
+
+    function requestJson(method, url, params, successCallback, failureCallback) {
+        method = method.toUpperCase();
+        var body = null;
+        if (method === 'GET') {
+            url = injectQueryStringParams(url, params);
+        }
+        else {
+            body = encodeParams(params);
+        }
+        var xhr = new XMLHttpRequest();
+        xhr.open(method, url, true);
+        if (method !== 'GET') {
+            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+        }
+        xhr.onload = function () {
+            if (xhr.status >= 200 && xhr.status < 400) {
+                var parsed = false;
+                var res = void 0;
+                try {
+                    res = JSON.parse(xhr.responseText);
+                    parsed = true;
+                }
+                catch (err) {
+                    // will handle parsed=false
+                }
+                if (parsed) {
+                    successCallback(res, xhr);
+                }
+                else {
+                    failureCallback('Failure parsing JSON', xhr);
+                }
+            }
+            else {
+                failureCallback('Request failed', xhr);
+            }
+        };
+        xhr.onerror = function () {
+            failureCallback('Request failed', xhr);
+        };
+        xhr.send(body);
+    }
+    function injectQueryStringParams(url, params) {
+        return url +
+            (url.indexOf('?') === -1 ? '?' : '&') +
+            encodeParams(params);
+    }
+    function encodeParams(params) {
+        var parts = [];
+        for (var key in params) {
+            parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
+        }
+        return parts.join('&');
+    }
+
+    var JSON_FEED_EVENT_SOURCE_REFINERS = {
+        method: String,
+        extraParams: identity,
+        startParam: String,
+        endParam: String,
+        timeZoneParam: String,
+    };
+
+    var eventSourceDef$1 = {
+        parseMeta: function (refined) {
+            if (refined.url && (refined.format === 'json' || !refined.format)) {
+                return {
+                    url: refined.url,
+                    format: 'json',
+                    method: (refined.method || 'GET').toUpperCase(),
+                    extraParams: refined.extraParams,
+                    startParam: refined.startParam,
+                    endParam: refined.endParam,
+                    timeZoneParam: refined.timeZoneParam,
+                };
+            }
+            return null;
+        },
+        fetch: function (arg, success, failure) {
+            var meta = arg.eventSource.meta;
+            var requestParams = buildRequestParams$1(meta, arg.range, arg.context);
+            requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) {
+                success({ rawEvents: rawEvents, xhr: xhr });
+            }, function (errorMessage, xhr) {
+                failure({ message: errorMessage, xhr: xhr });
+            });
+        },
+    };
+    var jsonFeedEventSourcePlugin = createPlugin({
+        eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS,
+        eventSourceDefs: [eventSourceDef$1],
+    });
+    function buildRequestParams$1(meta, range, context) {
+        var dateEnv = context.dateEnv, options = context.options;
+        var startParam;
+        var endParam;
+        var timeZoneParam;
+        var customRequestParams;
+        var params = {};
+        startParam = meta.startParam;
+        if (startParam == null) {
+            startParam = options.startParam;
+        }
+        endParam = meta.endParam;
+        if (endParam == null) {
+            endParam = options.endParam;
+        }
+        timeZoneParam = meta.timeZoneParam;
+        if (timeZoneParam == null) {
+            timeZoneParam = options.timeZoneParam;
+        }
+        // retrieve any outbound GET/POST data from the options
+        if (typeof meta.extraParams === 'function') {
+            // supplied as a function that returns a key/value object
+            customRequestParams = meta.extraParams();
+        }
+        else {
+            // probably supplied as a straight key/value object
+            customRequestParams = meta.extraParams || {};
+        }
+        __assign(params, customRequestParams);
+        params[startParam] = dateEnv.formatIso(range.start);
+        params[endParam] = dateEnv.formatIso(range.end);
+        if (dateEnv.timeZone !== 'local') {
+            params[timeZoneParam] = dateEnv.timeZone;
+        }
+        return params;
+    }
+
+    var SIMPLE_RECURRING_REFINERS = {
+        daysOfWeek: identity,
+        startTime: createDuration,
+        endTime: createDuration,
+        duration: createDuration,
+        startRecur: identity,
+        endRecur: identity,
+    };
+
+    var recurring = {
+        parse: function (refined, dateEnv) {
+            if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) {
+                var recurringData = {
+                    daysOfWeek: refined.daysOfWeek || null,
+                    startTime: refined.startTime || null,
+                    endTime: refined.endTime || null,
+                    startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,
+                    endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null,
+                };
+                var duration = void 0;
+                if (refined.duration) {
+                    duration = refined.duration;
+                }
+                if (!duration && refined.startTime && refined.endTime) {
+                    duration = subtractDurations(refined.endTime, refined.startTime);
+                }
+                return {
+                    allDayGuess: Boolean(!refined.startTime && !refined.endTime),
+                    duration: duration,
+                    typeData: recurringData, // doesn't need endTime anymore but oh well
+                };
+            }
+            return null;
+        },
+        expand: function (typeData, framingRange, dateEnv) {
+            var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
+            if (clippedFramingRange) {
+                return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
+            }
+            return [];
+        },
+    };
+    var simpleRecurringEventsPlugin = createPlugin({
+        recurringTypes: [recurring],
+        eventRefiners: SIMPLE_RECURRING_REFINERS,
+    });
+    function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
+        var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
+        var dayMarker = startOfDay(framingRange.start);
+        var endMarker = framingRange.end;
+        var instanceStarts = [];
+        while (dayMarker < endMarker) {
+            var instanceStart 
+            // if everyday, or this particular day-of-week
+            = void 0;
+            // if everyday, or this particular day-of-week
+            if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
+                if (startTime) {
+                    instanceStart = dateEnv.add(dayMarker, startTime);
+                }
+                else {
+                    instanceStart = dayMarker;
+                }
+                instanceStarts.push(instanceStart);
+            }
+            dayMarker = addDays(dayMarker, 1);
+        }
+        return instanceStarts;
+    }
+
+    var changeHandlerPlugin = createPlugin({
+        optionChangeHandlers: {
+            events: function (events, context) {
+                handleEventSources([events], context);
+            },
+            eventSources: handleEventSources,
+        },
+    });
+    /*
+    BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out
+    */
+    function handleEventSources(inputs, context) {
+        var unfoundSources = hashValuesToArray(context.getCurrentData().eventSources);
+        var newInputs = [];
+        for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
+            var input = inputs_1[_i];
+            var inputFound = false;
+            for (var i = 0; i < unfoundSources.length; i += 1) {
+                if (unfoundSources[i]._raw === input) {
+                    unfoundSources.splice(i, 1); // delete
+                    inputFound = true;
+                    break;
+                }
+            }
+            if (!inputFound) {
+                newInputs.push(input);
+            }
+        }
+        for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) {
+            var unfoundSource = unfoundSources_1[_a];
+            context.dispatch({
+                type: 'REMOVE_EVENT_SOURCE',
+                sourceId: unfoundSource.sourceId,
+            });
+        }
+        for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) {
+            var newInput = newInputs_1[_b];
+            context.calendarApi.addEventSource(newInput);
+        }
+    }
+
+    function handleDateProfile(dateProfile, context) {
+        context.emitter.trigger('datesSet', __assign(__assign({}, buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi }));
+    }
+
+    function handleEventStore(eventStore, context) {
+        var emitter = context.emitter;
+        if (emitter.hasHandlers('eventsSet')) {
+            emitter.trigger('eventsSet', buildEventApis(eventStore, context));
+        }
+    }
+
+    /*
+    this array is exposed on the root namespace so that UMD plugins can add to it.
+    see the rollup-bundles script.
+    */
+    var globalPlugins = [
+        arrayEventSourcePlugin,
+        funcEventSourcePlugin,
+        jsonFeedEventSourcePlugin,
+        simpleRecurringEventsPlugin,
+        changeHandlerPlugin,
+        createPlugin({
+            isLoadingFuncs: [
+                function (state) { return computeEventSourcesLoading(state.eventSources); },
+            ],
+            contentTypeHandlers: {
+                html: buildHtmlRenderer,
+                domNodes: buildDomNodeRenderer,
+            },
+            propSetHandlers: {
+                dateProfile: handleDateProfile,
+                eventStore: handleEventStore,
+            },
+        }),
+    ];
+    function buildHtmlRenderer() {
+        var currentEl = null;
+        var currentHtml = '';
+        function render(el, html) {
+            if (el !== currentEl || html !== currentHtml) {
+                el.innerHTML = html;
+            }
+            currentEl = el;
+            currentHtml = html;
+        }
+        function destroy() {
+            currentEl.innerHTML = '';
+            currentEl = null;
+            currentHtml = '';
+        }
+        return { render: render, destroy: destroy };
+    }
+    function buildDomNodeRenderer() {
+        var currentEl = null;
+        var currentDomNodes = [];
+        function render(el, domNodes) {
+            var newDomNodes = Array.prototype.slice.call(domNodes);
+            if (el !== currentEl || !isArraysEqual(currentDomNodes, newDomNodes)) {
+                // append first, remove second (for scroll resetting)
+                for (var _i = 0, newDomNodes_1 = newDomNodes; _i < newDomNodes_1.length; _i++) {
+                    var newNode = newDomNodes_1[_i];
+                    el.appendChild(newNode);
+                }
+                destroy();
+            }
+            currentEl = el;
+            currentDomNodes = newDomNodes;
+        }
+        function destroy() {
+            currentDomNodes.forEach(removeElement);
+            currentDomNodes = [];
+            currentEl = null;
+        }
+        return { render: render, destroy: destroy };
+    }
+
+    var DelayedRunner = /** @class */ (function () {
+        function DelayedRunner(drainedOption) {
+            this.drainedOption = drainedOption;
+            this.isRunning = false;
+            this.isDirty = false;
+            this.pauseDepths = {};
+            this.timeoutId = 0;
+        }
+        DelayedRunner.prototype.request = function (delay) {
+            this.isDirty = true;
+            if (!this.isPaused()) {
+                this.clearTimeout();
+                if (delay == null) {
+                    this.tryDrain();
+                }
+                else {
+                    this.timeoutId = setTimeout(// NOT OPTIMAL! TODO: look at debounce
+                    this.tryDrain.bind(this), delay);
+                }
+            }
+        };
+        DelayedRunner.prototype.pause = function (scope) {
+            if (scope === void 0) { scope = ''; }
+            var pauseDepths = this.pauseDepths;
+            pauseDepths[scope] = (pauseDepths[scope] || 0) + 1;
+            this.clearTimeout();
+        };
+        DelayedRunner.prototype.resume = function (scope, force) {
+            if (scope === void 0) { scope = ''; }
+            var pauseDepths = this.pauseDepths;
+            if (scope in pauseDepths) {
+                if (force) {
+                    delete pauseDepths[scope];
+                }
+                else {
+                    pauseDepths[scope] -= 1;
+                    var depth = pauseDepths[scope];
+                    if (depth <= 0) {
+                        delete pauseDepths[scope];
+                    }
+                }
+                this.tryDrain();
+            }
+        };
+        DelayedRunner.prototype.isPaused = function () {
+            return Object.keys(this.pauseDepths).length;
+        };
+        DelayedRunner.prototype.tryDrain = function () {
+            if (!this.isRunning && !this.isPaused()) {
+                this.isRunning = true;
+                while (this.isDirty) {
+                    this.isDirty = false;
+                    this.drained(); // might set isDirty to true again
+                }
+                this.isRunning = false;
+            }
+        };
+        DelayedRunner.prototype.clear = function () {
+            this.clearTimeout();
+            this.isDirty = false;
+            this.pauseDepths = {};
+        };
+        DelayedRunner.prototype.clearTimeout = function () {
+            if (this.timeoutId) {
+                clearTimeout(this.timeoutId);
+                this.timeoutId = 0;
+            }
+        };
+        DelayedRunner.prototype.drained = function () {
+            if (this.drainedOption) {
+                this.drainedOption();
+            }
+        };
+        return DelayedRunner;
+    }());
+
+    var TaskRunner = /** @class */ (function () {
+        function TaskRunner(runTaskOption, drainedOption) {
+            this.runTaskOption = runTaskOption;
+            this.drainedOption = drainedOption;
+            this.queue = [];
+            this.delayedRunner = new DelayedRunner(this.drain.bind(this));
+        }
+        TaskRunner.prototype.request = function (task, delay) {
+            this.queue.push(task);
+            this.delayedRunner.request(delay);
+        };
+        TaskRunner.prototype.pause = function (scope) {
+            this.delayedRunner.pause(scope);
+        };
+        TaskRunner.prototype.resume = function (scope, force) {
+            this.delayedRunner.resume(scope, force);
+        };
+        TaskRunner.prototype.drain = function () {
+            var queue = this.queue;
+            while (queue.length) {
+                var completedTasks = [];
+                var task = void 0;
+                while ((task = queue.shift())) {
+                    this.runTask(task);
+                    completedTasks.push(task);
+                }
+                this.drained(completedTasks);
+            } // keep going, in case new tasks were added in the drained handler
+        };
+        TaskRunner.prototype.runTask = function (task) {
+            if (this.runTaskOption) {
+                this.runTaskOption(task);
+            }
+        };
+        TaskRunner.prototype.drained = function (completedTasks) {
+            if (this.drainedOption) {
+                this.drainedOption(completedTasks);
+            }
+        };
+        return TaskRunner;
+    }());
+
+    // Computes what the title at the top of the calendarApi should be for this view
+    function buildTitle(dateProfile, viewOptions, dateEnv) {
+        var range;
+        // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
+        if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
+            range = dateProfile.currentRange;
+        }
+        else { // for day units or smaller, use the actual day range
+            range = dateProfile.activeRange;
+        }
+        return dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), {
+            isEndExclusive: dateProfile.isRangeAllDay,
+            defaultSeparator: viewOptions.titleRangeSeparator,
+        });
+    }
+    // Generates the format string that should be used to generate the title for the current date range.
+    // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
+    function buildTitleFormat(dateProfile) {
+        var currentRangeUnit = dateProfile.currentRangeUnit;
+        if (currentRangeUnit === 'year') {
+            return { year: 'numeric' };
+        }
+        if (currentRangeUnit === 'month') {
+            return { year: 'numeric', month: 'long' }; // like "September 2014"
+        }
+        var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
+        if (days !== null && days > 1) {
+            // multi-day range. shorter, like "Sep 9 - 10 2014"
+            return { year: 'numeric', month: 'short', day: 'numeric' };
+        }
+        // one day. longer, like "September 9 2014"
+        return { year: 'numeric', month: 'long', day: 'numeric' };
+    }
+
+    // in future refactor, do the redux-style function(state=initial) for initial-state
+    // also, whatever is happening in constructor, have it happen in action queue too
+    var CalendarDataManager = /** @class */ (function () {
+        function CalendarDataManager(props) {
+            var _this = this;
+            this.computeOptionsData = memoize(this._computeOptionsData);
+            this.computeCurrentViewData = memoize(this._computeCurrentViewData);
+            this.organizeRawLocales = memoize(organizeRawLocales);
+            this.buildLocale = memoize(buildLocale);
+            this.buildPluginHooks = buildBuildPluginHooks();
+            this.buildDateEnv = memoize(buildDateEnv);
+            this.buildTheme = memoize(buildTheme);
+            this.parseToolbars = memoize(parseToolbars);
+            this.buildViewSpecs = memoize(buildViewSpecs);
+            this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator);
+            this.buildViewApi = memoize(buildViewApi);
+            this.buildViewUiProps = memoizeObjArg(buildViewUiProps);
+            this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual);
+            this.buildEventUiBases = memoize(buildEventUiBases);
+            this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours);
+            this.buildTitle = memoize(buildTitle);
+            this.emitter = new Emitter();
+            this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));
+            this.currentCalendarOptionsInput = {};
+            this.currentCalendarOptionsRefined = {};
+            this.currentViewOptionsInput = {};
+            this.currentViewOptionsRefined = {};
+            this.currentCalendarOptionsRefiners = {};
+            this.getCurrentData = function () { return _this.data; };
+            this.dispatch = function (action) {
+                _this.actionRunner.request(action); // protects against recursive calls to _handleAction
+            };
+            this.props = props;
+            this.actionRunner.pause();
+            var dynamicOptionOverrides = {};
+            var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
+            var currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;
+            var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
+            // wire things up
+            // TODO: not DRY
+            props.calendarApi.currentDataManager = this;
+            this.emitter.setThisContext(props.calendarApi);
+            this.emitter.setOptions(currentViewData.options);
+            var currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv);
+            var dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
+            if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) {
+                currentDate = dateProfile.currentRange.start;
+            }
+            var calendarContext = {
+                dateEnv: optionsData.dateEnv,
+                options: optionsData.calendarOptions,
+                pluginHooks: optionsData.pluginHooks,
+                calendarApi: props.calendarApi,
+                dispatch: this.dispatch,
+                emitter: this.emitter,
+                getCurrentData: this.getCurrentData,
+            };
+            // needs to be after setThisContext
+            for (var _i = 0, _a = optionsData.pluginHooks.contextInit; _i < _a.length; _i++) {
+                var callback = _a[_i];
+                callback(calendarContext);
+            }
+            // NOT DRY
+            var eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext);
+            var initialState = {
+                dynamicOptionOverrides: dynamicOptionOverrides,
+                currentViewType: currentViewType,
+                currentDate: currentDate,
+                dateProfile: dateProfile,
+                businessHours: this.parseContextBusinessHours(calendarContext),
+                eventSources: eventSources,
+                eventUiBases: {},
+                eventStore: createEmptyEventStore(),
+                renderableEventStore: createEmptyEventStore(),
+                dateSelection: null,
+                eventSelection: '',
+                eventDrag: null,
+                eventResize: null,
+                selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig,
+            };
+            var contextAndState = __assign(__assign({}, calendarContext), initialState);
+            for (var _b = 0, _c = optionsData.pluginHooks.reducers; _b < _c.length; _b++) {
+                var reducer = _c[_b];
+                __assign(initialState, reducer(null, null, contextAndState));
+            }
+            if (computeIsLoading(initialState, calendarContext)) {
+                this.emitter.trigger('loading', true); // NOT DRY
+            }
+            this.state = initialState;
+            this.updateData();
+            this.actionRunner.resume();
+        }
+        CalendarDataManager.prototype.resetOptions = function (optionOverrides, append) {
+            var props = this.props;
+            props.optionOverrides = append
+                ? __assign(__assign({}, props.optionOverrides), optionOverrides) : optionOverrides;
+            this.actionRunner.request({
+                type: 'NOTHING',
+            });
+        };
+        CalendarDataManager.prototype._handleAction = function (action) {
+            var _a = this, props = _a.props, state = _a.state, emitter = _a.emitter;
+            var dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action);
+            var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
+            var currentViewType = reduceViewType(state.currentViewType, action);
+            var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
+            // wire things up
+            // TODO: not DRY
+            props.calendarApi.currentDataManager = this;
+            emitter.setThisContext(props.calendarApi);
+            emitter.setOptions(currentViewData.options);
+            var calendarContext = {
+                dateEnv: optionsData.dateEnv,
+                options: optionsData.calendarOptions,
+                pluginHooks: optionsData.pluginHooks,
+                calendarApi: props.calendarApi,
+                dispatch: this.dispatch,
+                emitter: emitter,
+                getCurrentData: this.getCurrentData,
+            };
+            var currentDate = state.currentDate, dateProfile = state.dateProfile;
+            if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack
+                dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
+            }
+            currentDate = reduceCurrentDate(currentDate, action);
+            dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator);
+            if (action.type === 'PREV' || // TODO: move this logic into DateProfileGenerator
+                action.type === 'NEXT' || // "
+                !rangeContainsMarker(dateProfile.currentRange, currentDate)) {
+                currentDate = dateProfile.currentRange.start;
+            }
+            var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext);
+            var eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext);
+            var isEventsLoading = computeEventSourcesLoading(eventSources); // BAD. also called in this func in computeIsLoading
+            var renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ?
+                (state.renderableEventStore || eventStore) : // try from previous state
+                eventStore;
+            var _b = this.buildViewUiProps(calendarContext), eventUiSingleBase = _b.eventUiSingleBase, selectionConfig = _b.selectionConfig; // will memoize obj
+            var eventUiBySource = this.buildEventUiBySource(eventSources);
+            var eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
+            var newState = {
+                dynamicOptionOverrides: dynamicOptionOverrides,
+                currentViewType: currentViewType,
+                currentDate: currentDate,
+                dateProfile: dateProfile,
+                eventSources: eventSources,
+                eventStore: eventStore,
+                renderableEventStore: renderableEventStore,
+                selectionConfig: selectionConfig,
+                eventUiBases: eventUiBases,
+                businessHours: this.parseContextBusinessHours(calendarContext),
+                dateSelection: reduceDateSelection(state.dateSelection, action),
+                eventSelection: reduceSelectedEvent(state.eventSelection, action),
+                eventDrag: reduceEventDrag(state.eventDrag, action),
+                eventResize: reduceEventResize(state.eventResize, action),
+            };
+            var contextAndState = __assign(__assign({}, calendarContext), newState);
+            for (var _i = 0, _c = optionsData.pluginHooks.reducers; _i < _c.length; _i++) {
+                var reducer = _c[_i];
+                __assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value
+            }
+            var wasLoading = computeIsLoading(state, calendarContext);
+            var isLoading = computeIsLoading(newState, calendarContext);
+            // TODO: use propSetHandlers in plugin system
+            if (!wasLoading && isLoading) {
+                emitter.trigger('loading', true);
+            }
+            else if (wasLoading && !isLoading) {
+                emitter.trigger('loading', false);
+            }
+            this.state = newState;
+            if (props.onAction) {
+                props.onAction(action);
+            }
+        };
+        CalendarDataManager.prototype.updateData = function () {
+            var _a = this, props = _a.props, state = _a.state;
+            var oldData = this.data;
+            var optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);
+            var currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);
+            var data = this.data = __assign(__assign(__assign({ viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state);
+            var changeHandlers = optionsData.pluginHooks.optionChangeHandlers;
+            var oldCalendarOptions = oldData && oldData.calendarOptions;
+            var newCalendarOptions = optionsData.calendarOptions;
+            if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) {
+                if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) {
+                    // hack
+                    state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data);
+                    state.eventStore = data.eventStore = rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv);
+                }
+                for (var optionName in changeHandlers) {
+                    if (oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) {
+                        changeHandlers[optionName](newCalendarOptions[optionName], data);
+                    }
+                }
+            }
+            if (props.onData) {
+                props.onData(data);
+            }
+        };
+        CalendarDataManager.prototype._computeOptionsData = function (optionOverrides, dynamicOptionOverrides, calendarApi) {
+            // TODO: blacklist options that are handled by optionChangeHandlers
+            var _a = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, pluginHooks = _a.pluginHooks, localeDefaults = _a.localeDefaults, availableLocaleData = _a.availableLocaleData, extra = _a.extra;
+            warnUnknownOptions(extra);
+            var dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator);
+            var viewSpecs = this.buildViewSpecs(pluginHooks.views, optionOverrides, dynamicOptionOverrides, localeDefaults);
+            var theme = this.buildTheme(refinedOptions, pluginHooks);
+            var toolbarConfig = this.parseToolbars(refinedOptions, optionOverrides, theme, viewSpecs, calendarApi);
+            return {
+                calendarOptions: refinedOptions,
+                pluginHooks: pluginHooks,
+                dateEnv: dateEnv,
+                viewSpecs: viewSpecs,
+                theme: theme,
+                toolbarConfig: toolbarConfig,
+                localeDefaults: localeDefaults,
+                availableRawLocales: availableLocaleData.map,
+            };
+        };
+        // always called from behind a memoizer
+        CalendarDataManager.prototype.processRawCalendarOptions = function (optionOverrides, dynamicOptionOverrides) {
+            var _a = mergeRawOptions([
+                BASE_OPTION_DEFAULTS,
+                optionOverrides,
+                dynamicOptionOverrides,
+            ]), locales = _a.locales, locale = _a.locale;
+            var availableLocaleData = this.organizeRawLocales(locales);
+            var availableRawLocales = availableLocaleData.map;
+            var localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options;
+            var pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins);
+            var refiners = this.currentCalendarOptionsRefiners = __assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
+            var extra = {};
+            var raw = mergeRawOptions([
+                BASE_OPTION_DEFAULTS,
+                localeDefaults,
+                optionOverrides,
+                dynamicOptionOverrides,
+            ]);
+            var refined = {};
+            var currentRaw = this.currentCalendarOptionsInput;
+            var currentRefined = this.currentCalendarOptionsRefined;
+            var anyChanges = false;
+            for (var optionName in raw) {
+                if (optionName !== 'plugins') { // because plugins is special-cased
+                    if (raw[optionName] === currentRaw[optionName] ||
+                        (COMPLEX_OPTION_COMPARATORS[optionName] &&
+                            (optionName in currentRaw) &&
+                            COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName]))) {
+                        refined[optionName] = currentRefined[optionName];
+                    }
+                    else if (refiners[optionName]) {
+                        refined[optionName] = refiners[optionName](raw[optionName]);
+                        anyChanges = true;
+                    }
+                    else {
+                        extra[optionName] = currentRaw[optionName];
+                    }
+                }
+            }
+            if (anyChanges) {
+                this.currentCalendarOptionsInput = raw;
+                this.currentCalendarOptionsRefined = refined;
+            }
+            return {
+                rawOptions: this.currentCalendarOptionsInput,
+                refinedOptions: this.currentCalendarOptionsRefined,
+                pluginHooks: pluginHooks,
+                availableLocaleData: availableLocaleData,
+                localeDefaults: localeDefaults,
+                extra: extra,
+            };
+        };
+        CalendarDataManager.prototype._computeCurrentViewData = function (viewType, optionsData, optionOverrides, dynamicOptionOverrides) {
+            var viewSpec = optionsData.viewSpecs[viewType];
+            if (!viewSpec) {
+                throw new Error("viewType \"" + viewType + "\" is not available. Please make sure you've loaded all neccessary plugins");
+            }
+            var _a = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, extra = _a.extra;
+            warnUnknownOptions(extra);
+            var dateProfileGenerator = this.buildDateProfileGenerator({
+                dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,
+                duration: viewSpec.duration,
+                durationUnit: viewSpec.durationUnit,
+                usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,
+                dateEnv: optionsData.dateEnv,
+                calendarApi: this.props.calendarApi,
+                slotMinTime: refinedOptions.slotMinTime,
+                slotMaxTime: refinedOptions.slotMaxTime,
+                showNonCurrentDates: refinedOptions.showNonCurrentDates,
+                dayCount: refinedOptions.dayCount,
+                dateAlignment: refinedOptions.dateAlignment,
+                dateIncrement: refinedOptions.dateIncrement,
+                hiddenDays: refinedOptions.hiddenDays,
+                weekends: refinedOptions.weekends,
+                nowInput: refinedOptions.now,
+                validRangeInput: refinedOptions.validRange,
+                visibleRangeInput: refinedOptions.visibleRange,
+                monthMode: refinedOptions.monthMode,
+                fixedWeekCount: refinedOptions.fixedWeekCount,
+            });
+            var viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv);
+            return { viewSpec: viewSpec, options: refinedOptions, dateProfileGenerator: dateProfileGenerator, viewApi: viewApi };
+        };
+        CalendarDataManager.prototype.processRawViewOptions = function (viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) {
+            var raw = mergeRawOptions([
+                BASE_OPTION_DEFAULTS,
+                viewSpec.optionDefaults,
+                localeDefaults,
+                optionOverrides,
+                viewSpec.optionOverrides,
+                dynamicOptionOverrides,
+            ]);
+            var refiners = __assign(__assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
+            var refined = {};
+            var currentRaw = this.currentViewOptionsInput;
+            var currentRefined = this.currentViewOptionsRefined;
+            var anyChanges = false;
+            var extra = {};
+            for (var optionName in raw) {
+                if (raw[optionName] === currentRaw[optionName] ||
+                    (COMPLEX_OPTION_COMPARATORS[optionName] &&
+                        COMPLEX_OPTION_COMPARATORS[optionName](raw[optionName], currentRaw[optionName]))) {
+                    refined[optionName] = currentRefined[optionName];
+                }
+                else {
+                    if (raw[optionName] === this.currentCalendarOptionsInput[optionName] ||
+                        (COMPLEX_OPTION_COMPARATORS[optionName] &&
+                            COMPLEX_OPTION_COMPARATORS[optionName](raw[optionName], this.currentCalendarOptionsInput[optionName]))) {
+                        if (optionName in this.currentCalendarOptionsRefined) { // might be an "extra" prop
+                            refined[optionName] = this.currentCalendarOptionsRefined[optionName];
+                        }
+                    }
+                    else if (refiners[optionName]) {
+                        refined[optionName] = refiners[optionName](raw[optionName]);
+                    }
+                    else {
+                        extra[optionName] = raw[optionName];
+                    }
+                    anyChanges = true;
+                }
+            }
+            if (anyChanges) {
+                this.currentViewOptionsInput = raw;
+                this.currentViewOptionsRefined = refined;
+            }
+            return {
+                rawOptions: this.currentViewOptionsInput,
+                refinedOptions: this.currentViewOptionsRefined,
+                extra: extra,
+            };
+        };
+        return CalendarDataManager;
+    }());
+    function buildDateEnv(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) {
+        var locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map);
+        return new DateEnv({
+            calendarSystem: 'gregory',
+            timeZone: timeZone,
+            namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl,
+            locale: locale,
+            weekNumberCalculation: weekNumberCalculation,
+            firstDay: firstDay,
+            weekText: weekText,
+            cmdFormatter: pluginHooks.cmdFormatter,
+            defaultSeparator: defaultSeparator,
+        });
+    }
+    function buildTheme(options, pluginHooks) {
+        var ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme;
+        return new ThemeClass(options);
+    }
+    function buildDateProfileGenerator(props) {
+        var DateProfileGeneratorClass = props.dateProfileGeneratorClass || DateProfileGenerator;
+        return new DateProfileGeneratorClass(props);
+    }
+    function buildViewApi(type, getCurrentData, dateEnv) {
+        return new ViewApi(type, getCurrentData, dateEnv);
+    }
+    function buildEventUiBySource(eventSources) {
+        return mapHash(eventSources, function (eventSource) { return eventSource.ui; });
+    }
+    function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
+        var eventUiBases = { '': eventUiSingleBase };
+        for (var defId in eventDefs) {
+            var def = eventDefs[defId];
+            if (def.sourceId && eventUiBySource[def.sourceId]) {
+                eventUiBases[defId] = eventUiBySource[def.sourceId];
+            }
+        }
+        return eventUiBases;
+    }
+    function buildViewUiProps(calendarContext) {
+        var options = calendarContext.options;
+        return {
+            eventUiSingleBase: createEventUi({
+                display: options.eventDisplay,
+                editable: options.editable,
+                startEditable: options.eventStartEditable,
+                durationEditable: options.eventDurationEditable,
+                constraint: options.eventConstraint,
+                overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined,
+                allow: options.eventAllow,
+                backgroundColor: options.eventBackgroundColor,
+                borderColor: options.eventBorderColor,
+                textColor: options.eventTextColor,
+                color: options.eventColor,
+                // classNames: options.eventClassNames // render hook will handle this
+            }, calendarContext),
+            selectionConfig: createEventUi({
+                constraint: options.selectConstraint,
+                overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined,
+                allow: options.selectAllow,
+            }, calendarContext),
+        };
+    }
+    function computeIsLoading(state, context) {
+        for (var _i = 0, _a = context.pluginHooks.isLoadingFuncs; _i < _a.length; _i++) {
+            var isLoadingFunc = _a[_i];
+            if (isLoadingFunc(state)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    function parseContextBusinessHours(calendarContext) {
+        return parseBusinessHours(calendarContext.options.businessHours, calendarContext);
+    }
+    function warnUnknownOptions(options, viewName) {
+        for (var optionName in options) {
+            console.warn("Unknown option '" + optionName + "'" +
+                (viewName ? " for view '" + viewName + "'" : ''));
+        }
+    }
+
+    // TODO: move this to react plugin?
+    var CalendarDataProvider = /** @class */ (function (_super) {
+        __extends(CalendarDataProvider, _super);
+        function CalendarDataProvider(props) {
+            var _this = _super.call(this, props) || this;
+            _this.handleData = function (data) {
+                if (!_this.dataManager) { // still within initial run, before assignment in constructor
+                    // eslint-disable-next-line react/no-direct-mutation-state
+                    _this.state = data; // can't use setState yet
+                }
+                else {
+                    _this.setState(data);
+                }
+            };
+            _this.dataManager = new CalendarDataManager({
+                optionOverrides: props.optionOverrides,
+                calendarApi: props.calendarApi,
+                onData: _this.handleData,
+            });
+            return _this;
+        }
+        CalendarDataProvider.prototype.render = function () {
+            return this.props.children(this.state);
+        };
+        CalendarDataProvider.prototype.componentDidUpdate = function (prevProps) {
+            var newOptionOverrides = this.props.optionOverrides;
+            if (newOptionOverrides !== prevProps.optionOverrides) { // prevent recursive handleData
+                this.dataManager.resetOptions(newOptionOverrides);
+            }
+        };
+        return CalendarDataProvider;
+    }(Component));
+
+    // HELPERS
+    /*
+    if nextDayThreshold is specified, slicing is done in an all-day fashion.
+    you can get nextDayThreshold from context.nextDayThreshold
+    */
+    function sliceEvents(props, allDay) {
+        return sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;
+    }
+
+    var NamedTimeZoneImpl = /** @class */ (function () {
+        function NamedTimeZoneImpl(timeZoneName) {
+            this.timeZoneName = timeZoneName;
+        }
+        return NamedTimeZoneImpl;
+    }());
+
+    var SegHierarchy = /** @class */ (function () {
+        function SegHierarchy() {
+            // settings
+            this.strictOrder = false;
+            this.allowReslicing = false;
+            this.maxCoord = -1; // -1 means no max
+            this.maxStackCnt = -1; // -1 means no max
+            this.levelCoords = []; // ordered
+            this.entriesByLevel = []; // parallel with levelCoords
+            this.stackCnts = {}; // TODO: use better technique!?
+        }
+        SegHierarchy.prototype.addSegs = function (inputs) {
+            var hiddenEntries = [];
+            for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
+                var input = inputs_1[_i];
+                this.insertEntry(input, hiddenEntries);
+            }
+            return hiddenEntries;
+        };
+        SegHierarchy.prototype.insertEntry = function (entry, hiddenEntries) {
+            var insertion = this.findInsertion(entry);
+            if (this.isInsertionValid(insertion, entry)) {
+                this.insertEntryAt(entry, insertion);
+                return 1;
+            }
+            return this.handleInvalidInsertion(insertion, entry, hiddenEntries);
+        };
+        SegHierarchy.prototype.isInsertionValid = function (insertion, entry) {
+            return (this.maxCoord === -1 || insertion.levelCoord + entry.thickness <= this.maxCoord) &&
+                (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt);
+        };
+        // returns number of new entries inserted
+        SegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) {
+            if (this.allowReslicing && insertion.touchingEntry) {
+                return this.splitEntry(entry, insertion.touchingEntry, hiddenEntries);
+            }
+            hiddenEntries.push(entry);
+            return 0;
+        };
+        SegHierarchy.prototype.splitEntry = function (entry, barrier, hiddenEntries) {
+            var partCnt = 0;
+            var splitHiddenEntries = [];
+            var entrySpan = entry.span;
+            var barrierSpan = barrier.span;
+            if (entrySpan.start < barrierSpan.start) {
+                partCnt += this.insertEntry({
+                    index: entry.index,
+                    thickness: entry.thickness,
+                    span: { start: entrySpan.start, end: barrierSpan.start },
+                }, splitHiddenEntries);
+            }
+            if (entrySpan.end > barrierSpan.end) {
+                partCnt += this.insertEntry({
+                    index: entry.index,
+                    thickness: entry.thickness,
+                    span: { start: barrierSpan.end, end: entrySpan.end },
+                }, splitHiddenEntries);
+            }
+            if (partCnt) {
+                hiddenEntries.push.apply(hiddenEntries, __spreadArray([{
+                        index: entry.index,
+                        thickness: entry.thickness,
+                        span: intersectSpans(barrierSpan, entrySpan), // guaranteed to intersect
+                    }], splitHiddenEntries));
+                return partCnt;
+            }
+            hiddenEntries.push(entry);
+            return 0;
+        };
+        SegHierarchy.prototype.insertEntryAt = function (entry, insertion) {
+            var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords;
+            if (insertion.lateral === -1) {
+                // create a new level
+                insertAt(levelCoords, insertion.level, insertion.levelCoord);
+                insertAt(entriesByLevel, insertion.level, [entry]);
+            }
+            else {
+                // insert into existing level
+                insertAt(entriesByLevel[insertion.level], insertion.lateral, entry);
+            }
+            this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt;
+        };
+        SegHierarchy.prototype.findInsertion = function (newEntry) {
+            var _a = this, levelCoords = _a.levelCoords, entriesByLevel = _a.entriesByLevel, strictOrder = _a.strictOrder, stackCnts = _a.stackCnts;
+            var levelCnt = levelCoords.length;
+            var candidateCoord = 0;
+            var touchingLevel = -1;
+            var touchingLateral = -1;
+            var touchingEntry = null;
+            var stackCnt = 0;
+            for (var trackingLevel = 0; trackingLevel < levelCnt; trackingLevel += 1) {
+                var trackingCoord = levelCoords[trackingLevel];
+                // if the current level is past the placed entry, we have found a good empty space and can stop.
+                // if strictOrder, keep finding more lateral intersections.
+                if (!strictOrder && trackingCoord >= candidateCoord + newEntry.thickness) {
+                    break;
+                }
+                var trackingEntries = entriesByLevel[trackingLevel];
+                var trackingEntry = void 0;
+                var searchRes = binarySearch(trackingEntries, newEntry.span.start, getEntrySpanEnd); // find first entry after newEntry's end
+                var lateralIndex = searchRes[0] + searchRes[1]; // if exact match (which doesn't collide), go to next one
+                while ( // loop through entries that horizontally intersect
+                (trackingEntry = trackingEntries[lateralIndex]) && // but not past the whole entry list
+                    trackingEntry.span.start < newEntry.span.end // and not entirely past newEntry
+                ) {
+                    var trackingEntryBottom = trackingCoord + trackingEntry.thickness;
+                    // intersects into the top of the candidate?
+                    if (trackingEntryBottom > candidateCoord) {
+                        candidateCoord = trackingEntryBottom;
+                        touchingEntry = trackingEntry;
+                        touchingLevel = trackingLevel;
+                        touchingLateral = lateralIndex;
+                    }
+                    // butts up against top of candidate? (will happen if just intersected as well)
+                    if (trackingEntryBottom === candidateCoord) {
+                        // accumulate the highest possible stackCnt of the trackingEntries that butt up
+                        stackCnt = Math.max(stackCnt, stackCnts[buildEntryKey(trackingEntry)] + 1);
+                    }
+                    lateralIndex += 1;
+                }
+            }
+            // the destination level will be after touchingEntry's level. find it
+            var destLevel = 0;
+            if (touchingEntry) {
+                destLevel = touchingLevel + 1;
+                while (destLevel < levelCnt && levelCoords[destLevel] < candidateCoord) {
+                    destLevel += 1;
+                }
+            }
+            // if adding to an existing level, find where to insert
+            var destLateral = -1;
+            if (destLevel < levelCnt && levelCoords[destLevel] === candidateCoord) {
+                destLateral = binarySearch(entriesByLevel[destLevel], newEntry.span.end, getEntrySpanEnd)[0];
+            }
+            return {
+                touchingLevel: touchingLevel,
+                touchingLateral: touchingLateral,
+                touchingEntry: touchingEntry,
+                stackCnt: stackCnt,
+                levelCoord: candidateCoord,
+                level: destLevel,
+                lateral: destLateral,
+            };
+        };
+        // sorted by levelCoord (lowest to highest)
+        SegHierarchy.prototype.toRects = function () {
+            var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords;
+            var levelCnt = entriesByLevel.length;
+            var rects = [];
+            for (var level = 0; level < levelCnt; level += 1) {
+                var entries = entriesByLevel[level];
+                var levelCoord = levelCoords[level];
+                for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
+                    var entry = entries_1[_i];
+                    rects.push(__assign(__assign({}, entry), { levelCoord: levelCoord }));
+                }
+            }
+            return rects;
+        };
+        return SegHierarchy;
+    }());
+    function getEntrySpanEnd(entry) {
+        return entry.span.end;
+    }
+    function buildEntryKey(entry) {
+        return entry.index + ':' + entry.span.start;
+    }
+    // returns groups with entries sorted by input order
+    function groupIntersectingEntries(entries) {
+        var merges = [];
+        for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) {
+            var entry = entries_2[_i];
+            var filteredMerges = [];
+            var hungryMerge = {
+                span: entry.span,
+                entries: [entry],
+            };
+            for (var _a = 0, merges_1 = merges; _a < merges_1.length; _a++) {
+                var merge = merges_1[_a];
+                if (intersectSpans(merge.span, hungryMerge.span)) {
+                    hungryMerge = {
+                        entries: merge.entries.concat(hungryMerge.entries),
+                        span: joinSpans(merge.span, hungryMerge.span),
+                    };
+                }
+                else {
+                    filteredMerges.push(merge);
+                }
+            }
+            filteredMerges.push(hungryMerge);
+            merges = filteredMerges;
+        }
+        return merges;
+    }
+    function joinSpans(span0, span1) {
+        return {
+            start: Math.min(span0.start, span1.start),
+            end: Math.max(span0.end, span1.end),
+        };
+    }
+    function intersectSpans(span0, span1) {
+        var start = Math.max(span0.start, span1.start);
+        var end = Math.min(span0.end, span1.end);
+        if (start < end) {
+            return { start: start, end: end };
+        }
+        return null;
+    }
+    // general util
+    // ---------------------------------------------------------------------------------------------------------------------
+    function insertAt(arr, index, item) {
+        arr.splice(index, 0, item);
+    }
+    function binarySearch(a, searchVal, getItemVal) {
+        var startIndex = 0;
+        var endIndex = a.length; // exclusive
+        if (!endIndex || searchVal < getItemVal(a[startIndex])) { // no items OR before first item
+            return [0, 0];
+        }
+        if (searchVal > getItemVal(a[endIndex - 1])) { // after last item
+            return [endIndex, 0];
+        }
+        while (startIndex < endIndex) {
+            var middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2);
+            var middleVal = getItemVal(a[middleIndex]);
+            if (searchVal < middleVal) {
+                endIndex = middleIndex;
+            }
+            else if (searchVal > middleVal) {
+                startIndex = middleIndex + 1;
+            }
+            else { // equal!
+                return [middleIndex, 1];
+            }
+        }
+        return [startIndex, 0];
+    }
+
+    var Interaction = /** @class */ (function () {
+        function Interaction(settings) {
+            this.component = settings.component;
+            this.isHitComboAllowed = settings.isHitComboAllowed || null;
+        }
+        Interaction.prototype.destroy = function () {
+        };
+        return Interaction;
+    }());
+    function parseInteractionSettings(component, input) {
+        return {
+            component: component,
+            el: input.el,
+            useEventCenter: input.useEventCenter != null ? input.useEventCenter : true,
+            isHitComboAllowed: input.isHitComboAllowed || null,
+        };
+    }
+    function interactionSettingsToStore(settings) {
+        var _a;
+        return _a = {},
+            _a[settings.component.uid] = settings,
+            _a;
+    }
+    // global state
+    var interactionSettingsStore = {};
+
+    /*
+    An abstraction for a dragging interaction originating on an event.
+    Does higher-level things than PointerDragger, such as possibly:
+    - a "mirror" that moves with the pointer
+    - a minimum number of pixels or other criteria for a true drag to begin
+
+    subclasses must emit:
+    - pointerdown
+    - dragstart
+    - dragmove
+    - pointerup
+    - dragend
+    */
+    var ElementDragging = /** @class */ (function () {
+        function ElementDragging(el, selector) {
+            this.emitter = new Emitter();
+        }
+        ElementDragging.prototype.destroy = function () {
+        };
+        ElementDragging.prototype.setMirrorIsVisible = function (bool) {
+            // optional if subclass doesn't want to support a mirror
+        };
+        ElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
+            // optional if subclass doesn't want to support a mirror
+        };
+        ElementDragging.prototype.setAutoScrollEnabled = function (bool) {
+            // optional
+        };
+        return ElementDragging;
+    }());
+
+    // TODO: get rid of this in favor of options system,
+    // tho it's really easy to access this globally rather than pass thru options.
+    var config = {};
+
+    /*
+    Information about what will happen when an external element is dragged-and-dropped
+    onto a calendar. Contains information for creating an event.
+    */
+    var DRAG_META_REFINERS = {
+        startTime: createDuration,
+        duration: createDuration,
+        create: Boolean,
+        sourceId: String,
+    };
+    function parseDragMeta(raw) {
+        var _a = refineProps(raw, DRAG_META_REFINERS), refined = _a.refined, extra = _a.extra;
+        return {
+            startTime: refined.startTime || null,
+            duration: refined.duration || null,
+            create: refined.create != null ? refined.create : true,
+            sourceId: refined.sourceId,
+            leftoverProps: extra,
+        };
+    }
+
+    var ToolbarSection = /** @class */ (function (_super) {
+        __extends(ToolbarSection, _super);
+        function ToolbarSection() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        ToolbarSection.prototype.render = function () {
+            var _this = this;
+            var children = this.props.widgetGroups.map(function (widgetGroup) { return _this.renderWidgetGroup(widgetGroup); });
+            return createElement.apply(void 0, __spreadArray(['div', { className: 'fc-toolbar-chunk' }], children));
+        };
+        ToolbarSection.prototype.renderWidgetGroup = function (widgetGroup) {
+            var props = this.props;
+            var theme = this.context.theme;
+            var children = [];
+            var isOnlyButtons = true;
+            for (var _i = 0, widgetGroup_1 = widgetGroup; _i < widgetGroup_1.length; _i++) {
+                var widget = widgetGroup_1[_i];
+                var buttonName = widget.buttonName, buttonClick = widget.buttonClick, buttonText = widget.buttonText, buttonIcon = widget.buttonIcon, buttonHint = widget.buttonHint;
+                if (buttonName === 'title') {
+                    isOnlyButtons = false;
+                    children.push(createElement("h2", { className: "fc-toolbar-title", id: props.titleId }, props.title));
+                }
+                else {
+                    var isPressed = buttonName === props.activeButton;
+                    var isDisabled = (!props.isTodayEnabled && buttonName === 'today') ||
+                        (!props.isPrevEnabled && buttonName === 'prev') ||
+                        (!props.isNextEnabled && buttonName === 'next');
+                    var buttonClasses = ["fc-" + buttonName + "-button", theme.getClass('button')];
+                    if (isPressed) {
+                        buttonClasses.push(theme.getClass('buttonActive'));
+                    }
+                    children.push(createElement("button", { type: "button", title: typeof buttonHint === 'function' ? buttonHint(props.navUnit) : buttonHint, disabled: isDisabled, "aria-pressed": isPressed, className: buttonClasses.join(' '), onClick: buttonClick }, buttonText || (buttonIcon ? createElement("span", { className: buttonIcon }) : '')));
+                }
+            }
+            if (children.length > 1) {
+                var groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || '';
+                return createElement.apply(void 0, __spreadArray(['div', { className: groupClassName }], children));
+            }
+            return children[0];
+        };
+        return ToolbarSection;
+    }(BaseComponent));
+
+    var Toolbar = /** @class */ (function (_super) {
+        __extends(Toolbar, _super);
+        function Toolbar() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        Toolbar.prototype.render = function () {
+            var _a = this.props, model = _a.model, extraClassName = _a.extraClassName;
+            var forceLtr = false;
+            var startContent;
+            var endContent;
+            var sectionWidgets = model.sectionWidgets;
+            var centerContent = sectionWidgets.center;
+            if (sectionWidgets.left) {
+                forceLtr = true;
+                startContent = sectionWidgets.left;
+            }
+            else {
+                startContent = sectionWidgets.start;
+            }
+            if (sectionWidgets.right) {
+                forceLtr = true;
+                endContent = sectionWidgets.right;
+            }
+            else {
+                endContent = sectionWidgets.end;
+            }
+            var classNames = [
+                extraClassName || '',
+                'fc-toolbar',
+                forceLtr ? 'fc-toolbar-ltr' : '',
+            ];
+            return (createElement("div", { className: classNames.join(' ') },
+                this.renderSection('start', startContent || []),
+                this.renderSection('center', centerContent || []),
+                this.renderSection('end', endContent || [])));
+        };
+        Toolbar.prototype.renderSection = function (key, widgetGroups) {
+            var props = this.props;
+            return (createElement(ToolbarSection, { key: key, widgetGroups: widgetGroups, title: props.title, navUnit: props.navUnit, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled, titleId: props.titleId }));
+        };
+        return Toolbar;
+    }(BaseComponent));
+
+    // TODO: do function component?
+    var ViewContainer = /** @class */ (function (_super) {
+        __extends(ViewContainer, _super);
+        function ViewContainer() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.state = {
+                availableWidth: null,
+            };
+            _this.handleEl = function (el) {
+                _this.el = el;
+                setRef(_this.props.elRef, el);
+                _this.updateAvailableWidth();
+            };
+            _this.handleResize = function () {
+                _this.updateAvailableWidth();
+            };
+            return _this;
+        }
+        ViewContainer.prototype.render = function () {
+            var _a = this, props = _a.props, state = _a.state;
+            var aspectRatio = props.aspectRatio;
+            var classNames = [
+                'fc-view-harness',
+                (aspectRatio || props.liquid || props.height)
+                    ? 'fc-view-harness-active' // harness controls the height
+                    : 'fc-view-harness-passive', // let the view do the height
+            ];
+            var height = '';
+            var paddingBottom = '';
+            if (aspectRatio) {
+                if (state.availableWidth !== null) {
+                    height = state.availableWidth / aspectRatio;
+                }
+                else {
+                    // while waiting to know availableWidth, we can't set height to *zero*
+                    // because will cause lots of unnecessary scrollbars within scrollgrid.
+                    // BETTER: don't start rendering ANYTHING yet until we know container width
+                    // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606)
+                    paddingBottom = (1 / aspectRatio) * 100 + "%";
+                }
+            }
+            else {
+                height = props.height || '';
+            }
+            return (createElement("div", { "aria-labelledby": props.labeledById, ref: this.handleEl, className: classNames.join(' '), style: { height: height, paddingBottom: paddingBottom } }, props.children));
+        };
+        ViewContainer.prototype.componentDidMount = function () {
+            this.context.addResizeHandler(this.handleResize);
+        };
+        ViewContainer.prototype.componentWillUnmount = function () {
+            this.context.removeResizeHandler(this.handleResize);
+        };
+        ViewContainer.prototype.updateAvailableWidth = function () {
+            if (this.el && // needed. but why?
+                this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth
+            ) {
+                this.setState({ availableWidth: this.el.offsetWidth });
+            }
+        };
+        return ViewContainer;
+    }(BaseComponent));
+
+    /*
+    Detects when the user clicks on an event within a DateComponent
+    */
+    var EventClicking = /** @class */ (function (_super) {
+        __extends(EventClicking, _super);
+        function EventClicking(settings) {
+            var _this = _super.call(this, settings) || this;
+            _this.handleSegClick = function (ev, segEl) {
+                var component = _this.component;
+                var context = component.context;
+                var seg = getElSeg(segEl);
+                if (seg && // might be the <div> surrounding the more link
+                    component.isValidSegDownEl(ev.target)) {
+                    // our way to simulate a link click for elements that can't be <a> tags
+                    // grab before trigger fired in case trigger trashes DOM thru rerendering
+                    var hasUrlContainer = elementClosest(ev.target, '.fc-event-forced-url');
+                    var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
+                    context.emitter.trigger('eventClick', {
+                        el: segEl,
+                        event: new EventApi(component.context, seg.eventRange.def, seg.eventRange.instance),
+                        jsEvent: ev,
+                        view: context.viewApi,
+                    });
+                    if (url && !ev.defaultPrevented) {
+                        window.location.href = url;
+                    }
+                }
+            };
+            _this.destroy = listenBySelector(settings.el, 'click', '.fc-event', // on both fg and bg events
+            _this.handleSegClick);
+            return _this;
+        }
+        return EventClicking;
+    }(Interaction));
+
+    /*
+    Triggers events and adds/removes core classNames when the user's pointer
+    enters/leaves event-elements of a component.
+    */
+    var EventHovering = /** @class */ (function (_super) {
+        __extends(EventHovering, _super);
+        function EventHovering(settings) {
+            var _this = _super.call(this, settings) || this;
+            // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
+            _this.handleEventElRemove = function (el) {
+                if (el === _this.currentSegEl) {
+                    _this.handleSegLeave(null, _this.currentSegEl);
+                }
+            };
+            _this.handleSegEnter = function (ev, segEl) {
+                if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
+                    _this.currentSegEl = segEl;
+                    _this.triggerEvent('eventMouseEnter', ev, segEl);
+                }
+            };
+            _this.handleSegLeave = function (ev, segEl) {
+                if (_this.currentSegEl) {
+                    _this.currentSegEl = null;
+                    _this.triggerEvent('eventMouseLeave', ev, segEl);
+                }
+            };
+            _this.removeHoverListeners = listenToHoverBySelector(settings.el, '.fc-event', // on both fg and bg events
+            _this.handleSegEnter, _this.handleSegLeave);
+            return _this;
+        }
+        EventHovering.prototype.destroy = function () {
+            this.removeHoverListeners();
+        };
+        EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) {
+            var component = this.component;
+            var context = component.context;
+            var seg = getElSeg(segEl);
+            if (!ev || component.isValidSegDownEl(ev.target)) {
+                context.emitter.trigger(publicEvName, {
+                    el: segEl,
+                    event: new EventApi(context, seg.eventRange.def, seg.eventRange.instance),
+                    jsEvent: ev,
+                    view: context.viewApi,
+                });
+            }
+        };
+        return EventHovering;
+    }(Interaction));
+
+    var CalendarContent = /** @class */ (function (_super) {
+        __extends(CalendarContent, _super);
+        function CalendarContent() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.buildViewContext = memoize(buildViewContext);
+            _this.buildViewPropTransformers = memoize(buildViewPropTransformers);
+            _this.buildToolbarProps = memoize(buildToolbarProps);
+            _this.headerRef = createRef();
+            _this.footerRef = createRef();
+            _this.interactionsStore = {};
+            // eslint-disable-next-line
+            _this.state = {
+                viewLabelId: getUniqueDomId(),
+            };
+            // Component Registration
+            // -----------------------------------------------------------------------------------------------------------------
+            _this.registerInteractiveComponent = function (component, settingsInput) {
+                var settings = parseInteractionSettings(component, settingsInput);
+                var DEFAULT_INTERACTIONS = [
+                    EventClicking,
+                    EventHovering,
+                ];
+                var interactionClasses = DEFAULT_INTERACTIONS.concat(_this.props.pluginHooks.componentInteractions);
+                var interactions = interactionClasses.map(function (TheInteractionClass) { return new TheInteractionClass(settings); });
+                _this.interactionsStore[component.uid] = interactions;
+                interactionSettingsStore[component.uid] = settings;
+            };
+            _this.unregisterInteractiveComponent = function (component) {
+                var listeners = _this.interactionsStore[component.uid];
+                if (listeners) {
+                    for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) {
+                        var listener = listeners_1[_i];
+                        listener.destroy();
+                    }
+                    delete _this.interactionsStore[component.uid];
+                }
+                delete interactionSettingsStore[component.uid];
+            };
+            // Resizing
+            // -----------------------------------------------------------------------------------------------------------------
+            _this.resizeRunner = new DelayedRunner(function () {
+                _this.props.emitter.trigger('_resize', true); // should window resizes be considered "forced" ?
+                _this.props.emitter.trigger('windowResize', { view: _this.props.viewApi });
+            });
+            _this.handleWindowResize = function (ev) {
+                var options = _this.props.options;
+                if (options.handleWindowResize &&
+                    ev.target === window // avoid jqui events
+                ) {
+                    _this.resizeRunner.request(options.windowResizeDelay);
+                }
+            };
+            return _this;
+        }
+        /*
+        renders INSIDE of an outer div
+        */
+        CalendarContent.prototype.render = function () {
+            var props = this.props;
+            var toolbarConfig = props.toolbarConfig, options = props.options;
+            var toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, getNow(props.options.now, props.dateEnv), // TODO: use NowTimer????
+            props.viewTitle);
+            var viewVGrow = false;
+            var viewHeight = '';
+            var viewAspectRatio;
+            if (props.isHeightAuto || props.forPrint) {
+                viewHeight = '';
+            }
+            else if (options.height != null) {
+                viewVGrow = true;
+            }
+            else if (options.contentHeight != null) {
+                viewHeight = options.contentHeight;
+            }
+            else {
+                viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall
+            }
+            var viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);
+            var viewLabelId = (toolbarConfig.header && toolbarConfig.header.hasTitle)
+                ? this.state.viewLabelId
+                : '';
+            return (createElement(ViewContextType.Provider, { value: viewContext },
+                toolbarConfig.header && (createElement(Toolbar, __assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps))),
+                createElement(ViewContainer, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId },
+                    this.renderView(props),
+                    this.buildAppendContent()),
+                toolbarConfig.footer && (createElement(Toolbar, __assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footer, titleId: "" }, toolbarProps)))));
+        };
+        CalendarContent.prototype.componentDidMount = function () {
+            var props = this.props;
+            this.calendarInteractions = props.pluginHooks.calendarInteractions
+                .map(function (CalendarInteractionClass) { return new CalendarInteractionClass(props); });
+            window.addEventListener('resize', this.handleWindowResize);
+            var propSetHandlers = props.pluginHooks.propSetHandlers;
+            for (var propName in propSetHandlers) {
+                propSetHandlers[propName](props[propName], props);
+            }
+        };
+        CalendarContent.prototype.componentDidUpdate = function (prevProps) {
+            var props = this.props;
+            var propSetHandlers = props.pluginHooks.propSetHandlers;
+            for (var propName in propSetHandlers) {
+                if (props[propName] !== prevProps[propName]) {
+                    propSetHandlers[propName](props[propName], props);
+                }
+            }
+        };
+        CalendarContent.prototype.componentWillUnmount = function () {
+            window.removeEventListener('resize', this.handleWindowResize);
+            this.resizeRunner.clear();
+            for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) {
+                var interaction = _a[_i];
+                interaction.destroy();
+            }
+            this.props.emitter.trigger('_unmount');
+        };
+        CalendarContent.prototype.buildAppendContent = function () {
+            var props = this.props;
+            var children = props.pluginHooks.viewContainerAppends.map(function (buildAppendContent) { return buildAppendContent(props); });
+            return createElement.apply(void 0, __spreadArray([Fragment, {}], children));
+        };
+        CalendarContent.prototype.renderView = function (props) {
+            var pluginHooks = props.pluginHooks;
+            var viewSpec = props.viewSpec;
+            var viewProps = {
+                dateProfile: props.dateProfile,
+                businessHours: props.businessHours,
+                eventStore: props.renderableEventStore,
+                eventUiBases: props.eventUiBases,
+                dateSelection: props.dateSelection,
+                eventSelection: props.eventSelection,
+                eventDrag: props.eventDrag,
+                eventResize: props.eventResize,
+                isHeightAuto: props.isHeightAuto,
+                forPrint: props.forPrint,
+            };
+            var transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers);
+            for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
+                var transformer = transformers_1[_i];
+                __assign(viewProps, transformer.transform(viewProps, props));
+            }
+            var ViewComponent = viewSpec.component;
+            return (createElement(ViewComponent, __assign({}, viewProps)));
+        };
+        return CalendarContent;
+    }(PureComponent));
+    function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) {
+        // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid
+        var todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason
+        var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false);
+        var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false);
+        return {
+            title: title,
+            activeButton: viewSpec.type,
+            navUnit: viewSpec.singleUnit,
+            isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now),
+            isPrevEnabled: prevInfo.isValid,
+            isNextEnabled: nextInfo.isValid,
+        };
+    }
+    // Plugin
+    // -----------------------------------------------------------------------------------------------------------------
+    function buildViewPropTransformers(theClasses) {
+        return theClasses.map(function (TheClass) { return new TheClass(); });
+    }
+
+    var CalendarRoot = /** @class */ (function (_super) {
+        __extends(CalendarRoot, _super);
+        function CalendarRoot() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.state = {
+                forPrint: false,
+            };
+            _this.handleBeforePrint = function () {
+                _this.setState({ forPrint: true });
+            };
+            _this.handleAfterPrint = function () {
+                _this.setState({ forPrint: false });
+            };
+            return _this;
+        }
+        CalendarRoot.prototype.render = function () {
+            var props = this.props;
+            var options = props.options;
+            var forPrint = this.state.forPrint;
+            var isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto';
+            var height = (!isHeightAuto && options.height != null) ? options.height : '';
+            var classNames = [
+                'fc',
+                forPrint ? 'fc-media-print' : 'fc-media-screen',
+                "fc-direction-" + options.direction,
+                props.theme.getClass('root'),
+            ];
+            if (!getCanVGrowWithinCell()) {
+                classNames.push('fc-liquid-hack');
+            }
+            return props.children(classNames, height, isHeightAuto, forPrint);
+        };
+        CalendarRoot.prototype.componentDidMount = function () {
+            var emitter = this.props.emitter;
+            emitter.on('_beforeprint', this.handleBeforePrint);
+            emitter.on('_afterprint', this.handleAfterPrint);
+        };
+        CalendarRoot.prototype.componentWillUnmount = function () {
+            var emitter = this.props.emitter;
+            emitter.off('_beforeprint', this.handleBeforePrint);
+            emitter.off('_afterprint', this.handleAfterPrint);
+        };
+        return CalendarRoot;
+    }(BaseComponent));
+
+    // Computes a default column header formatting string if `colFormat` is not explicitly defined
+    function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
+        // if more than one week row, or if there are a lot of columns with not much space,
+        // put just the day numbers will be in each cell
+        if (!datesRepDistinctDays || dayCnt > 10) {
+            return createFormatter({ weekday: 'short' }); // "Sat"
+        }
+        if (dayCnt > 1) {
+            return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12"
+        }
+        return createFormatter({ weekday: 'long' }); // "Saturday"
+    }
+
+    var CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no
+    function renderInner$1(hookProps) {
+        return hookProps.text;
+    }
+
+    var TableDateCell = /** @class */ (function (_super) {
+        __extends(TableDateCell, _super);
+        function TableDateCell() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        TableDateCell.prototype.render = function () {
+            var _a = this.context, dateEnv = _a.dateEnv, options = _a.options, theme = _a.theme, viewApi = _a.viewApi;
+            var props = this.props;
+            var date = props.date, dateProfile = props.dateProfile;
+            var dayMeta = getDateMeta(date, props.todayRange, null, dateProfile);
+            var classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme));
+            var text = dateEnv.format(date, props.dayHeaderFormat);
+            // if colCnt is 1, we are already in a day-view and don't need a navlink
+            var navLinkAttrs = (!dayMeta.isDisabled && props.colCnt > 1)
+                ? buildNavLinkAttrs(this.context, date)
+                : {};
+            var hookProps = __assign(__assign(__assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraHookProps), { text: text }), dayMeta);
+            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner$1, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, role: "columnheader", className: classNames.concat(customClassNames).join(' '), "data-date": !dayMeta.isDisabled ? formatDayString(date) : undefined, colSpan: props.colSpan }, props.extraDataAttrs),
+                createElement("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && (createElement("a", __assign({ ref: innerElRef, className: [
+                        'fc-col-header-cell-cushion',
+                        props.isSticky ? 'fc-sticky' : '',
+                    ].join(' ') }, navLinkAttrs), innerContent))))); }));
+        };
+        return TableDateCell;
+    }(BaseComponent));
+
+    var WEEKDAY_FORMAT = createFormatter({ weekday: 'long' });
+    var TableDowCell = /** @class */ (function (_super) {
+        __extends(TableDowCell, _super);
+        function TableDowCell() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        TableDowCell.prototype.render = function () {
+            var props = this.props;
+            var _a = this.context, dateEnv = _a.dateEnv, theme = _a.theme, viewApi = _a.viewApi, options = _a.options;
+            var date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT
+            var dateMeta = {
+                dow: props.dow,
+                isDisabled: false,
+                isFuture: false,
+                isPast: false,
+                isToday: false,
+                isOther: false,
+            };
+            var classNames = [CLASS_NAME].concat(getDayClassNames(dateMeta, theme), props.extraClassNames || []);
+            var text = dateEnv.format(date, props.dayHeaderFormat);
+            var hookProps = __assign(__assign(__assign(__assign({ // TODO: make this public?
+                date: date }, dateMeta), { view: viewApi }), props.extraHookProps), { text: text });
+            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner$1, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, role: "columnheader", className: classNames.concat(customClassNames).join(' '), colSpan: props.colSpan }, props.extraDataAttrs),
+                createElement("div", { className: "fc-scrollgrid-sync-inner" },
+                    createElement("a", { "aria-label": dateEnv.format(date, WEEKDAY_FORMAT), className: [
+                            'fc-col-header-cell-cushion',
+                            props.isSticky ? 'fc-sticky' : '',
+                        ].join(' '), ref: innerElRef }, innerContent)))); }));
+        };
+        return TableDowCell;
+    }(BaseComponent));
+
+    var NowTimer = /** @class */ (function (_super) {
+        __extends(NowTimer, _super);
+        function NowTimer(props, context) {
+            var _this = _super.call(this, props, context) || this;
+            _this.initialNowDate = getNow(context.options.now, context.dateEnv);
+            _this.initialNowQueriedMs = new Date().valueOf();
+            _this.state = _this.computeTiming().currentState;
+            return _this;
+        }
+        NowTimer.prototype.render = function () {
+            var _a = this, props = _a.props, state = _a.state;
+            return props.children(state.nowDate, state.todayRange);
+        };
+        NowTimer.prototype.componentDidMount = function () {
+            this.setTimeout();
+        };
+        NowTimer.prototype.componentDidUpdate = function (prevProps) {
+            if (prevProps.unit !== this.props.unit) {
+                this.clearTimeout();
+                this.setTimeout();
+            }
+        };
+        NowTimer.prototype.componentWillUnmount = function () {
+            this.clearTimeout();
+        };
+        NowTimer.prototype.computeTiming = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            var unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs);
+            var currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit);
+            var nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit));
+            var waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf();
+            // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342)
+            // ensure no longer than a day
+            waitMs = Math.min(1000 * 60 * 60 * 24, waitMs);
+            return {
+                currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) },
+                nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) },
+                waitMs: waitMs,
+            };
+        };
+        NowTimer.prototype.setTimeout = function () {
+            var _this = this;
+            var _a = this.computeTiming(), nextState = _a.nextState, waitMs = _a.waitMs;
+            this.timeoutId = setTimeout(function () {
+                _this.setState(nextState, function () {
+                    _this.setTimeout();
+                });
+            }, waitMs);
+        };
+        NowTimer.prototype.clearTimeout = function () {
+            if (this.timeoutId) {
+                clearTimeout(this.timeoutId);
+            }
+        };
+        NowTimer.contextType = ViewContextType;
+        return NowTimer;
+    }(Component));
+    function buildDayRange(date) {
+        var start = startOfDay(date);
+        var end = addDays(start, 1);
+        return { start: start, end: end };
+    }
+
+    var DayHeader = /** @class */ (function (_super) {
+        __extends(DayHeader, _super);
+        function DayHeader() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.createDayHeaderFormatter = memoize(createDayHeaderFormatter);
+            return _this;
+        }
+        DayHeader.prototype.render = function () {
+            var context = this.context;
+            var _a = this.props, dates = _a.dates, dateProfile = _a.dateProfile, datesRepDistinctDays = _a.datesRepDistinctDays, renderIntro = _a.renderIntro;
+            var dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length);
+            return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement("tr", { role: "row" },
+                renderIntro && renderIntro('day'),
+                dates.map(function (date) { return (datesRepDistinctDays ? (createElement(TableDateCell, { key: date.toISOString(), date: date, dateProfile: dateProfile, todayRange: todayRange, colCnt: dates.length, dayHeaderFormat: dayHeaderFormat })) : (createElement(TableDowCell, { key: date.getUTCDay(), dow: date.getUTCDay(), dayHeaderFormat: dayHeaderFormat }))); }))); }));
+        };
+        return DayHeader;
+    }(BaseComponent));
+    function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) {
+        return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt);
+    }
+
+    var DaySeriesModel = /** @class */ (function () {
+        function DaySeriesModel(range, dateProfileGenerator) {
+            var date = range.start;
+            var end = range.end;
+            var indices = [];
+            var dates = [];
+            var dayIndex = -1;
+            while (date < end) { // loop each day from start to end
+                if (dateProfileGenerator.isHiddenDay(date)) {
+                    indices.push(dayIndex + 0.5); // mark that it's between indices
+                }
+                else {
+                    dayIndex += 1;
+                    indices.push(dayIndex);
+                    dates.push(date);
+                }
+                date = addDays(date, 1);
+            }
+            this.dates = dates;
+            this.indices = indices;
+            this.cnt = dates.length;
+        }
+        DaySeriesModel.prototype.sliceRange = function (range) {
+            var firstIndex = this.getDateDayIndex(range.start); // inclusive first index
+            var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
+            var clippedFirstIndex = Math.max(0, firstIndex);
+            var clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
+            // deal with in-between indices
+            clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
+            clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
+            if (clippedFirstIndex <= clippedLastIndex) {
+                return {
+                    firstIndex: clippedFirstIndex,
+                    lastIndex: clippedLastIndex,
+                    isStart: firstIndex === clippedFirstIndex,
+                    isEnd: lastIndex === clippedLastIndex,
+                };
+            }
+            return null;
+        };
+        // Given a date, returns its chronolocial cell-index from the first cell of the grid.
+        // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
+        // If before the first offset, returns a negative number.
+        // If after the last offset, returns an offset past the last cell offset.
+        // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
+        DaySeriesModel.prototype.getDateDayIndex = function (date) {
+            var indices = this.indices;
+            var dayOffset = Math.floor(diffDays(this.dates[0], date));
+            if (dayOffset < 0) {
+                return indices[0] - 1;
+            }
+            if (dayOffset >= indices.length) {
+                return indices[indices.length - 1] + 1;
+            }
+            return indices[dayOffset];
+        };
+        return DaySeriesModel;
+    }());
+
+    var DayTableModel = /** @class */ (function () {
+        function DayTableModel(daySeries, breakOnWeeks) {
+            var dates = daySeries.dates;
+            var daysPerRow;
+            var firstDay;
+            var rowCnt;
+            if (breakOnWeeks) {
+                // count columns until the day-of-week repeats
+                firstDay = dates[0].getUTCDay();
+                for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) {
+                    if (dates[daysPerRow].getUTCDay() === firstDay) {
+                        break;
+                    }
+                }
+                rowCnt = Math.ceil(dates.length / daysPerRow);
+            }
+            else {
+                rowCnt = 1;
+                daysPerRow = dates.length;
+            }
+            this.rowCnt = rowCnt;
+            this.colCnt = daysPerRow;
+            this.daySeries = daySeries;
+            this.cells = this.buildCells();
+            this.headerDates = this.buildHeaderDates();
+        }
+        DayTableModel.prototype.buildCells = function () {
+            var rows = [];
+            for (var row = 0; row < this.rowCnt; row += 1) {
+                var cells = [];
+                for (var col = 0; col < this.colCnt; col += 1) {
+                    cells.push(this.buildCell(row, col));
+                }
+                rows.push(cells);
+            }
+            return rows;
+        };
+        DayTableModel.prototype.buildCell = function (row, col) {
+            var date = this.daySeries.dates[row * this.colCnt + col];
+            return {
+                key: date.toISOString(),
+                date: date,
+            };
+        };
+        DayTableModel.prototype.buildHeaderDates = function () {
+            var dates = [];
+            for (var col = 0; col < this.colCnt; col += 1) {
+                dates.push(this.cells[0][col].date);
+            }
+            return dates;
+        };
+        DayTableModel.prototype.sliceRange = function (range) {
+            var colCnt = this.colCnt;
+            var seriesSeg = this.daySeries.sliceRange(range);
+            var segs = [];
+            if (seriesSeg) {
+                var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex;
+                var index = firstIndex;
+                while (index <= lastIndex) {
+                    var row = Math.floor(index / colCnt);
+                    var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
+                    segs.push({
+                        row: row,
+                        firstCol: index % colCnt,
+                        lastCol: (nextIndex - 1) % colCnt,
+                        isStart: seriesSeg.isStart && index === firstIndex,
+                        isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex,
+                    });
+                    index = nextIndex;
+                }
+            }
+            return segs;
+        };
+        return DayTableModel;
+    }());
+
+    var Slicer = /** @class */ (function () {
+        function Slicer() {
+            this.sliceBusinessHours = memoize(this._sliceBusinessHours);
+            this.sliceDateSelection = memoize(this._sliceDateSpan);
+            this.sliceEventStore = memoize(this._sliceEventStore);
+            this.sliceEventDrag = memoize(this._sliceInteraction);
+            this.sliceEventResize = memoize(this._sliceInteraction);
+            this.forceDayIfListItem = false; // hack
+        }
+        Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, context) {
+            var extraArgs = [];
+            for (var _i = 4; _i < arguments.length; _i++) {
+                extraArgs[_i - 4] = arguments[_i];
+            }
+            var eventUiBases = props.eventUiBases;
+            var eventSegs = this.sliceEventStore.apply(this, __spreadArray([props.eventStore, eventUiBases, dateProfile, nextDayThreshold], extraArgs));
+            return {
+                dateSelectionSegs: this.sliceDateSelection.apply(this, __spreadArray([props.dateSelection, eventUiBases, context], extraArgs)),
+                businessHourSegs: this.sliceBusinessHours.apply(this, __spreadArray([props.businessHours, dateProfile, nextDayThreshold, context], extraArgs)),
+                fgEventSegs: eventSegs.fg,
+                bgEventSegs: eventSegs.bg,
+                eventDrag: this.sliceEventDrag.apply(this, __spreadArray([props.eventDrag, eventUiBases, dateProfile, nextDayThreshold], extraArgs)),
+                eventResize: this.sliceEventResize.apply(this, __spreadArray([props.eventResize, eventUiBases, dateProfile, nextDayThreshold], extraArgs)),
+                eventSelection: props.eventSelection,
+            }; // TODO: give interactionSegs?
+        };
+        Slicer.prototype.sliceNowDate = function (// does not memoize
+        date, context) {
+            var extraArgs = [];
+            for (var _i = 2; _i < arguments.length; _i++) {
+                extraArgs[_i - 2] = arguments[_i];
+            }
+            return this._sliceDateSpan.apply(this, __spreadArray([{ range: { start: date, end: addMs(date, 1) }, allDay: false },
+                {},
+                context], extraArgs));
+        };
+        Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, context) {
+            var extraArgs = [];
+            for (var _i = 4; _i < arguments.length; _i++) {
+                extraArgs[_i - 4] = arguments[_i];
+            }
+            if (!businessHours) {
+                return [];
+            }
+            return this._sliceEventStore.apply(this, __spreadArray([expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context),
+                {},
+                dateProfile,
+                nextDayThreshold], extraArgs)).bg;
+        };
+        Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold) {
+            var extraArgs = [];
+            for (var _i = 4; _i < arguments.length; _i++) {
+                extraArgs[_i - 4] = arguments[_i];
+            }
+            if (eventStore) {
+                var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
+                return {
+                    bg: this.sliceEventRanges(rangeRes.bg, extraArgs),
+                    fg: this.sliceEventRanges(rangeRes.fg, extraArgs),
+                };
+            }
+            return { bg: [], fg: [] };
+        };
+        Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold) {
+            var extraArgs = [];
+            for (var _i = 4; _i < arguments.length; _i++) {
+                extraArgs[_i - 4] = arguments[_i];
+            }
+            if (!interaction) {
+                return null;
+            }
+            var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
+            return {
+                segs: this.sliceEventRanges(rangeRes.fg, extraArgs),
+                affectedInstances: interaction.affectedEvents.instances,
+                isEvent: interaction.isEvent,
+            };
+        };
+        Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, context) {
+            var extraArgs = [];
+            for (var _i = 3; _i < arguments.length; _i++) {
+                extraArgs[_i - 3] = arguments[_i];
+            }
+            if (!dateSpan) {
+                return [];
+            }
+            var eventRange = fabricateEventRange(dateSpan, eventUiBases, context);
+            var segs = this.sliceRange.apply(this, __spreadArray([dateSpan.range], extraArgs));
+            for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) {
+                var seg = segs_1[_a];
+                seg.eventRange = eventRange;
+            }
+            return segs;
+        };
+        /*
+        "complete" seg means it has component and eventRange
+        */
+        Slicer.prototype.sliceEventRanges = function (eventRanges, extraArgs) {
+            var segs = [];
+            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
+                var eventRange = eventRanges_1[_i];
+                segs.push.apply(segs, this.sliceEventRange(eventRange, extraArgs));
+            }
+            return segs;
+        };
+        /*
+        "complete" seg means it has component and eventRange
+        */
+        Slicer.prototype.sliceEventRange = function (eventRange, extraArgs) {
+            var dateRange = eventRange.range;
+            // hack to make multi-day events that are being force-displayed as list-items to take up only one day
+            if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') {
+                dateRange = {
+                    start: dateRange.start,
+                    end: addDays(dateRange.start, 1),
+                };
+            }
+            var segs = this.sliceRange.apply(this, __spreadArray([dateRange], extraArgs));
+            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
+                var seg = segs_2[_i];
+                seg.eventRange = eventRange;
+                seg.isStart = eventRange.isStart && seg.isStart;
+                seg.isEnd = eventRange.isEnd && seg.isEnd;
+            }
+            return segs;
+        };
+        return Slicer;
+    }());
+    /*
+    for incorporating slotMinTime/slotMaxTime if appropriate
+    TODO: should be part of DateProfile!
+    TimelineDateProfile already does this btw
+    */
+    function computeActiveRange(dateProfile, isComponentAllDay) {
+        var range = dateProfile.activeRange;
+        if (isComponentAllDay) {
+            return range;
+        }
+        return {
+            start: addMs(range.start, dateProfile.slotMinTime.milliseconds),
+            end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5), // 864e5 = ms in a day
+        };
+    }
+
+    // high-level segmenting-aware tester functions
+    // ------------------------------------------------------------------------------------------------------------------------
+    function isInteractionValid(interaction, dateProfile, context) {
+        var instances = interaction.mutatedEvents.instances;
+        for (var instanceId in instances) {
+            if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
+                return false;
+            }
+        }
+        return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions
+    }
+    function isDateSelectionValid(dateSelection, dateProfile, context) {
+        if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) {
+            return false;
+        }
+        return isNewPropsValid({ dateSelection: dateSelection }, context);
+    }
+    function isNewPropsValid(newProps, context) {
+        var calendarState = context.getCurrentData();
+        var props = __assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
+        return (context.pluginHooks.isPropsValid || isPropsValid)(props, context);
+    }
+    function isPropsValid(state, context, dateSpanMeta, filterConfig) {
+        if (dateSpanMeta === void 0) { dateSpanMeta = {}; }
+        if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) {
+            return false;
+        }
+        if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) {
+            return false;
+        }
+        return true;
+    }
+    // Moving Event Validation
+    // ------------------------------------------------------------------------------------------------------------------------
+    function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) {
+        var currentState = context.getCurrentData();
+        var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
+        var subjectEventStore = interaction.mutatedEvents;
+        var subjectDefs = subjectEventStore.defs;
+        var subjectInstances = subjectEventStore.instances;
+        var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
+            state.eventUiBases :
+            { '': currentState.selectionConfig });
+        if (filterConfig) {
+            subjectConfigs = mapHash(subjectConfigs, filterConfig);
+        }
+        // exclude the subject events. TODO: exclude defs too?
+        var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances);
+        var otherDefs = otherEventStore.defs;
+        var otherInstances = otherEventStore.instances;
+        var otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
+        for (var subjectInstanceId in subjectInstances) {
+            var subjectInstance = subjectInstances[subjectInstanceId];
+            var subjectRange = subjectInstance.range;
+            var subjectConfig = subjectConfigs[subjectInstance.defId];
+            var subjectDef = subjectDefs[subjectInstance.defId];
+            // constraint
+            if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) {
+                return false;
+            }
+            // overlap
+            var eventOverlap = context.options.eventOverlap;
+            var eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null;
+            for (var otherInstanceId in otherInstances) {
+                var otherInstance = otherInstances[otherInstanceId];
+                // intersect! evaluate
+                if (rangesIntersect(subjectRange, otherInstance.range)) {
+                    var otherOverlap = otherConfigs[otherInstance.defId].overlap;
+                    // consider the other event's overlap. only do this if the subject event is a "real" event
+                    if (otherOverlap === false && interaction.isEvent) {
+                        return false;
+                    }
+                    if (subjectConfig.overlap === false) {
+                        return false;
+                    }
+                    if (eventOverlapFunc && !eventOverlapFunc(new EventApi(context, otherDefs[otherInstance.defId], otherInstance), // still event
+                    new EventApi(context, subjectDef, subjectInstance))) {
+                        return false;
+                    }
+                }
+            }
+            // allow (a function)
+            var calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state
+            for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) {
+                var subjectAllow = _a[_i];
+                var subjectDateSpan = __assign(__assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay });
+                var origDef = calendarEventStore.defs[subjectDef.defId];
+                var origInstance = calendarEventStore.instances[subjectInstanceId];
+                var eventApi = void 0;
+                if (origDef) { // was previously in the calendar
+                    eventApi = new EventApi(context, origDef, origInstance);
+                }
+                else { // was an external event
+                    eventApi = new EventApi(context, subjectDef); // no instance, because had no dates
+                }
+                if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+    // Date Selection Validation
+    // ------------------------------------------------------------------------------------------------------------------------
+    function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) {
+        var relevantEventStore = state.eventStore;
+        var relevantDefs = relevantEventStore.defs;
+        var relevantInstances = relevantEventStore.instances;
+        var selection = state.dateSelection;
+        var selectionRange = selection.range;
+        var selectionConfig = context.getCurrentData().selectionConfig;
+        if (filterConfig) {
+            selectionConfig = filterConfig(selectionConfig);
+        }
+        // constraint
+        if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) {
+            return false;
+        }
+        // overlap
+        var selectOverlap = context.options.selectOverlap;
+        var selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null;
+        for (var relevantInstanceId in relevantInstances) {
+            var relevantInstance = relevantInstances[relevantInstanceId];
+            // intersect! evaluate
+            if (rangesIntersect(selectionRange, relevantInstance.range)) {
+                if (selectionConfig.overlap === false) {
+                    return false;
+                }
+                if (selectOverlapFunc && !selectOverlapFunc(new EventApi(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) {
+                    return false;
+                }
+            }
+        }
+        // allow (a function)
+        for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) {
+            var selectionAllow = _a[_i];
+            var fullDateSpan = __assign(__assign({}, dateSpanMeta), selection);
+            if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    // Constraint Utils
+    // ------------------------------------------------------------------------------------------------------------------------
+    function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) {
+        for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
+            var constraint = constraints_1[_i];
+            if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
+    otherEventStore, // for if constraint is an even group ID
+    businessHoursUnexpanded, // for if constraint is 'businessHours'
+    context) {
+        if (constraint === 'businessHours') {
+            return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context));
+        }
+        if (typeof constraint === 'string') { // an group ID
+            return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) { return eventDef.groupId === constraint; }));
+        }
+        if (typeof constraint === 'object' && constraint) { // non-null object
+            return eventStoreToRanges(expandRecurring(constraint, subjectRange, context));
+        }
+        return []; // if it's false
+    }
+    // TODO: move to event-store file?
+    function eventStoreToRanges(eventStore) {
+        var instances = eventStore.instances;
+        var ranges = [];
+        for (var instanceId in instances) {
+            ranges.push(instances[instanceId].range);
+        }
+        return ranges;
+    }
+    // TODO: move to geom file?
+    function anyRangesContainRange(outerRanges, innerRange) {
+        for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) {
+            var outerRange = outerRanges_1[_i];
+            if (rangeContainsRange(outerRange, innerRange)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    var VISIBLE_HIDDEN_RE = /^(visible|hidden)$/;
+    var Scroller = /** @class */ (function (_super) {
+        __extends(Scroller, _super);
+        function Scroller() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.handleEl = function (el) {
+                _this.el = el;
+                setRef(_this.props.elRef, el);
+            };
+            return _this;
+        }
+        Scroller.prototype.render = function () {
+            var props = this.props;
+            var liquid = props.liquid, liquidIsAbsolute = props.liquidIsAbsolute;
+            var isAbsolute = liquid && liquidIsAbsolute;
+            var className = ['fc-scroller'];
+            if (liquid) {
+                if (liquidIsAbsolute) {
+                    className.push('fc-scroller-liquid-absolute');
+                }
+                else {
+                    className.push('fc-scroller-liquid');
+                }
+            }
+            return (createElement("div", { ref: this.handleEl, className: className.join(' '), style: {
+                    overflowX: props.overflowX,
+                    overflowY: props.overflowY,
+                    left: (isAbsolute && -(props.overcomeLeft || 0)) || '',
+                    right: (isAbsolute && -(props.overcomeRight || 0)) || '',
+                    bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '',
+                    marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '',
+                    marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '',
+                    marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '',
+                    maxHeight: props.maxHeight || '',
+                } }, props.children));
+        };
+        Scroller.prototype.needsXScrolling = function () {
+            if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
+                return false;
+            }
+            // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers.
+            // much more reliable to see if children are taller than the scroller, even tho doesn't account for
+            // inner-child margins and absolute positioning
+            var el = this.el;
+            var realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth();
+            var children = el.children;
+            for (var i = 0; i < children.length; i += 1) {
+                var childEl = children[i];
+                if (childEl.getBoundingClientRect().width > realClientWidth) {
+                    return true;
+                }
+            }
+            return false;
+        };
+        Scroller.prototype.needsYScrolling = function () {
+            if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
+                return false;
+            }
+            // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers.
+            // much more reliable to see if children are taller than the scroller, even tho doesn't account for
+            // inner-child margins and absolute positioning
+            var el = this.el;
+            var realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth();
+            var children = el.children;
+            for (var i = 0; i < children.length; i += 1) {
+                var childEl = children[i];
+                if (childEl.getBoundingClientRect().height > realClientHeight) {
+                    return true;
+                }
+            }
+            return false;
+        };
+        Scroller.prototype.getXScrollbarWidth = function () {
+            if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
+                return 0;
+            }
+            return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important?
+        };
+        Scroller.prototype.getYScrollbarWidth = function () {
+            if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
+                return 0;
+            }
+            return this.el.offsetWidth - this.el.clientWidth; // only works because we guarantee no borders. TODO: add to CSS with important?
+        };
+        return Scroller;
+    }(BaseComponent));
+
+    /*
+    TODO: somehow infer OtherArgs from masterCallback?
+    TODO: infer RefType from masterCallback if provided
+    */
+    var RefMap = /** @class */ (function () {
+        function RefMap(masterCallback) {
+            var _this = this;
+            this.masterCallback = masterCallback;
+            this.currentMap = {};
+            this.depths = {};
+            this.callbackMap = {};
+            this.handleValue = function (val, key) {
+                var _a = _this, depths = _a.depths, currentMap = _a.currentMap;
+                var removed = false;
+                var added = false;
+                if (val !== null) {
+                    // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore
+                    removed = (key in currentMap);
+                    currentMap[key] = val;
+                    depths[key] = (depths[key] || 0) + 1;
+                    added = true;
+                }
+                else {
+                    depths[key] -= 1;
+                    if (!depths[key]) {
+                        delete currentMap[key];
+                        delete _this.callbackMap[key];
+                        removed = true;
+                    }
+                }
+                if (_this.masterCallback) {
+                    if (removed) {
+                        _this.masterCallback(null, String(key));
+                    }
+                    if (added) {
+                        _this.masterCallback(val, String(key));
+                    }
+                }
+            };
+        }
+        RefMap.prototype.createRef = function (key) {
+            var _this = this;
+            var refCallback = this.callbackMap[key];
+            if (!refCallback) {
+                refCallback = this.callbackMap[key] = function (val) {
+                    _this.handleValue(val, String(key));
+                };
+            }
+            return refCallback;
+        };
+        // TODO: check callers that don't care about order. should use getAll instead
+        // NOTE: this method has become less valuable now that we are encouraged to map order by some other index
+        // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect"
+        RefMap.prototype.collect = function (startIndex, endIndex, step) {
+            return collectFromHash(this.currentMap, startIndex, endIndex, step);
+        };
+        RefMap.prototype.getAll = function () {
+            return hashValuesToArray(this.currentMap);
+        };
+        return RefMap;
+    }());
+
+    function computeShrinkWidth(chunkEls) {
+        var shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink');
+        var largestWidth = 0;
+        for (var _i = 0, shrinkCells_1 = shrinkCells; _i < shrinkCells_1.length; _i++) {
+            var shrinkCell = shrinkCells_1[_i];
+            largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell));
+        }
+        return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits
+    }
+    function getSectionHasLiquidHeight(props, sectionConfig) {
+        return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well)
+    }
+    function getAllowYScrolling(props, sectionConfig) {
+        return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars
+            getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars
+    }
+    // TODO: ONLY use `arg`. force out internal function to use same API
+    function renderChunkContent(sectionConfig, chunkConfig, arg, isHeader) {
+        var expandRows = arg.expandRows;
+        var content = typeof chunkConfig.content === 'function' ?
+            chunkConfig.content(arg) :
+            createElement('table', {
+                role: 'presentation',
+                className: [
+                    chunkConfig.tableClassName,
+                    sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : '',
+                ].join(' '),
+                style: {
+                    minWidth: arg.tableMinWidth,
+                    width: arg.clientWidth,
+                    height: expandRows ? arg.clientHeight : '', // css `height` on a <table> serves as a min-height
+                },
+            }, arg.tableColGroupNode, createElement(isHeader ? 'thead' : 'tbody', {
+                role: 'presentation',
+            }, typeof chunkConfig.rowContent === 'function'
+                ? chunkConfig.rowContent(arg)
+                : chunkConfig.rowContent));
+        return content;
+    }
+    function isColPropsEqual(cols0, cols1) {
+        return isArraysEqual(cols0, cols1, isPropsEqual);
+    }
+    function renderMicroColGroup(cols, shrinkWidth) {
+        var colNodes = [];
+        /*
+        for ColProps with spans, it would have been great to make a single <col span="">
+        HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans.
+        SOLUTION: making individual <col> elements makes Chrome behave.
+        */
+        for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) {
+            var colProps = cols_1[_i];
+            var span = colProps.span || 1;
+            for (var i = 0; i < span; i += 1) {
+                colNodes.push(createElement("col", { style: {
+                        width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''),
+                        minWidth: colProps.minWidth || '',
+                    } }));
+            }
+        }
+        return createElement.apply(void 0, __spreadArray(['colgroup', {}], colNodes));
+    }
+    function sanitizeShrinkWidth(shrinkWidth) {
+        /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth
+        4 accounts for 2 2-pixel borders. TODO: better solution? */
+        return shrinkWidth == null ? 4 : shrinkWidth;
+    }
+    function hasShrinkWidth(cols) {
+        for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) {
+            var col = cols_2[_i];
+            if (col.width === 'shrink') {
+                return true;
+            }
+        }
+        return false;
+    }
+    function getScrollGridClassNames(liquid, context) {
+        var classNames = [
+            'fc-scrollgrid',
+            context.theme.getClass('table'),
+        ];
+        if (liquid) {
+            classNames.push('fc-scrollgrid-liquid');
+        }
+        return classNames;
+    }
+    function getSectionClassNames(sectionConfig, wholeTableVGrow) {
+        var classNames = [
+            'fc-scrollgrid-section',
+            "fc-scrollgrid-section-" + sectionConfig.type,
+            sectionConfig.className, // used?
+        ];
+        if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) {
+            classNames.push('fc-scrollgrid-section-liquid');
+        }
+        if (sectionConfig.isSticky) {
+            classNames.push('fc-scrollgrid-section-sticky');
+        }
+        return classNames;
+    }
+    function renderScrollShim(arg) {
+        return (createElement("div", { className: "fc-scrollgrid-sticky-shim", style: {
+                width: arg.clientWidth,
+                minWidth: arg.tableMinWidth,
+            } }));
+    }
+    function getStickyHeaderDates(options) {
+        var stickyHeaderDates = options.stickyHeaderDates;
+        if (stickyHeaderDates == null || stickyHeaderDates === 'auto') {
+            stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto';
+        }
+        return stickyHeaderDates;
+    }
+    function getStickyFooterScrollbar(options) {
+        var stickyFooterScrollbar = options.stickyFooterScrollbar;
+        if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') {
+            stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto';
+        }
+        return stickyFooterScrollbar;
+    }
+
+    var SimpleScrollGrid = /** @class */ (function (_super) {
+        __extends(SimpleScrollGrid, _super);
+        function SimpleScrollGrid() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.processCols = memoize(function (a) { return a; }, isColPropsEqual); // so we get same `cols` props every time
+            // yucky to memoize VNodes, but much more efficient for consumers
+            _this.renderMicroColGroup = memoize(renderMicroColGroup);
+            _this.scrollerRefs = new RefMap();
+            _this.scrollerElRefs = new RefMap(_this._handleScrollerEl.bind(_this));
+            _this.state = {
+                shrinkWidth: null,
+                forceYScrollbars: false,
+                scrollerClientWidths: {},
+                scrollerClientHeights: {},
+            };
+            // TODO: can do a really simple print-view. dont need to join rows
+            _this.handleSizing = function () {
+                _this.safeSetState(__assign({ shrinkWidth: _this.computeShrinkWidth() }, _this.computeScrollerDims()));
+            };
+            return _this;
+        }
+        SimpleScrollGrid.prototype.render = function () {
+            var _a = this, props = _a.props, state = _a.state, context = _a.context;
+            var sectionConfigs = props.sections || [];
+            var cols = this.processCols(props.cols);
+            var microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth);
+            var classNames = getScrollGridClassNames(props.liquid, context);
+            if (props.collapsibleWidth) {
+                classNames.push('fc-scrollgrid-collapsible');
+            }
+            // TODO: make DRY
+            var configCnt = sectionConfigs.length;
+            var configI = 0;
+            var currentConfig;
+            var headSectionNodes = [];
+            var bodySectionNodes = [];
+            var footSectionNodes = [];
+            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') {
+                headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true));
+                configI += 1;
+            }
+            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') {
+                bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode, false));
+                configI += 1;
+            }
+            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') {
+                footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true));
+                configI += 1;
+            }
+            // firefox bug: when setting height on table and there is a thead or tfoot,
+            // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524)
+            // use getCanVGrowWithinCell as a way to detect table-stupid firefox.
+            // if so, use a simpler dom structure, jam everything into a lone tbody.
+            var isBuggy = !getCanVGrowWithinCell();
+            var roleAttrs = { role: 'rowgroup' };
+            return createElement('table', {
+                role: 'grid',
+                className: classNames.join(' '),
+                style: { height: props.height },
+            }, Boolean(!isBuggy && headSectionNodes.length) && createElement.apply(void 0, __spreadArray(['thead', roleAttrs], headSectionNodes)), Boolean(!isBuggy && bodySectionNodes.length) && createElement.apply(void 0, __spreadArray(['tbody', roleAttrs], bodySectionNodes)), Boolean(!isBuggy && footSectionNodes.length) && createElement.apply(void 0, __spreadArray(['tfoot', roleAttrs], footSectionNodes)), isBuggy && createElement.apply(void 0, __spreadArray(__spreadArray(__spreadArray(['tbody', roleAttrs], headSectionNodes), bodySectionNodes), footSectionNodes)));
+        };
+        SimpleScrollGrid.prototype.renderSection = function (sectionConfig, microColGroupNode, isHeader) {
+            if ('outerContent' in sectionConfig) {
+                return (createElement(Fragment, { key: sectionConfig.key }, sectionConfig.outerContent));
+            }
+            return (createElement("tr", { key: sectionConfig.key, role: "presentation", className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk, isHeader)));
+        };
+        SimpleScrollGrid.prototype.renderChunkTd = function (sectionConfig, microColGroupNode, chunkConfig, isHeader) {
+            if ('outerContent' in chunkConfig) {
+                return chunkConfig.outerContent;
+            }
+            var props = this.props;
+            var _a = this.state, forceYScrollbars = _a.forceYScrollbars, scrollerClientWidths = _a.scrollerClientWidths, scrollerClientHeights = _a.scrollerClientHeights;
+            var needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config?
+            var isLiquid = getSectionHasLiquidHeight(props, sectionConfig);
+            // for `!props.liquid` - is WHOLE scrollgrid natural height?
+            // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars
+            var overflowY = !props.liquid ? 'visible' :
+                forceYScrollbars ? 'scroll' :
+                    !needsYScrolling ? 'hidden' :
+                        'auto';
+            var sectionKey = sectionConfig.key;
+            var content = renderChunkContent(sectionConfig, chunkConfig, {
+                tableColGroupNode: microColGroupNode,
+                tableMinWidth: '',
+                clientWidth: (!props.collapsibleWidth && scrollerClientWidths[sectionKey] !== undefined) ? scrollerClientWidths[sectionKey] : null,
+                clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null,
+                expandRows: sectionConfig.expandRows,
+                syncRowHeights: false,
+                rowSyncHeights: [],
+                reportRowHeightChange: function () { },
+            }, isHeader);
+            return createElement(isHeader ? 'th' : 'td', {
+                ref: chunkConfig.elRef,
+                role: 'presentation',
+            }, createElement("div", { className: "fc-scroller-harness" + (isLiquid ? ' fc-scroller-harness-liquid' : '') },
+                createElement(Scroller, { ref: this.scrollerRefs.createRef(sectionKey), elRef: this.scrollerElRefs.createRef(sectionKey), overflowY: overflowY, overflowX: !props.liquid ? 'visible' : 'hidden' /* natural height? */, maxHeight: sectionConfig.maxHeight, liquid: isLiquid, liquidIsAbsolute // because its within a harness
+                    : true }, content)));
+        };
+        SimpleScrollGrid.prototype._handleScrollerEl = function (scrollerEl, key) {
+            var section = getSectionByKey(this.props.sections, key);
+            if (section) {
+                setRef(section.chunk.scrollerElRef, scrollerEl);
+            }
+        };
+        SimpleScrollGrid.prototype.componentDidMount = function () {
+            this.handleSizing();
+            this.context.addResizeHandler(this.handleSizing);
+        };
+        SimpleScrollGrid.prototype.componentDidUpdate = function () {
+            // TODO: need better solution when state contains non-sizing things
+            this.handleSizing();
+        };
+        SimpleScrollGrid.prototype.componentWillUnmount = function () {
+            this.context.removeResizeHandler(this.handleSizing);
+        };
+        SimpleScrollGrid.prototype.computeShrinkWidth = function () {
+            return hasShrinkWidth(this.props.cols)
+                ? computeShrinkWidth(this.scrollerElRefs.getAll())
+                : 0;
+        };
+        SimpleScrollGrid.prototype.computeScrollerDims = function () {
+            var scrollbarWidth = getScrollbarWidths();
+            var _a = this, scrollerRefs = _a.scrollerRefs, scrollerElRefs = _a.scrollerElRefs;
+            var forceYScrollbars = false;
+            var scrollerClientWidths = {};
+            var scrollerClientHeights = {};
+            for (var sectionKey in scrollerRefs.currentMap) {
+                var scroller = scrollerRefs.currentMap[sectionKey];
+                if (scroller && scroller.needsYScrolling()) {
+                    forceYScrollbars = true;
+                    break;
+                }
+            }
+            for (var _i = 0, _b = this.props.sections; _i < _b.length; _i++) {
+                var section = _b[_i];
+                var sectionKey = section.key;
+                var scrollerEl = scrollerElRefs.currentMap[sectionKey];
+                if (scrollerEl) {
+                    var harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders
+                    scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars
+                        ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future
+                        : 0));
+                    scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height);
+                }
+            }
+            return { forceYScrollbars: forceYScrollbars, scrollerClientWidths: scrollerClientWidths, scrollerClientHeights: scrollerClientHeights };
+        };
+        return SimpleScrollGrid;
+    }(BaseComponent));
+    SimpleScrollGrid.addStateEquality({
+        scrollerClientWidths: isPropsEqual,
+        scrollerClientHeights: isPropsEqual,
+    });
+    function getSectionByKey(sections, key) {
+        for (var _i = 0, sections_1 = sections; _i < sections_1.length; _i++) {
+            var section = sections_1[_i];
+            if (section.key === key) {
+                return section;
+            }
+        }
+        return null;
+    }
+
+    var EventRoot = /** @class */ (function (_super) {
+        __extends(EventRoot, _super);
+        function EventRoot() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.elRef = createRef();
+            return _this;
+        }
+        EventRoot.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            var options = context.options;
+            var seg = props.seg;
+            var eventRange = seg.eventRange;
+            var ui = eventRange.ui;
+            var hookProps = {
+                event: new EventApi(context, eventRange.def, eventRange.instance),
+                view: context.viewApi,
+                timeText: props.timeText,
+                textColor: ui.textColor,
+                backgroundColor: ui.backgroundColor,
+                borderColor: ui.borderColor,
+                isDraggable: !props.disableDragging && computeSegDraggable(seg, context),
+                isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context),
+                isEndResizable: !props.disableResizing && computeSegEndResizable(seg),
+                isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting),
+                isStart: Boolean(seg.isStart),
+                isEnd: Boolean(seg.isEnd),
+                isPast: Boolean(props.isPast),
+                isFuture: Boolean(props.isFuture),
+                isToday: Boolean(props.isToday),
+                isSelected: Boolean(props.isSelected),
+                isDragging: Boolean(props.isDragging),
+                isResizing: Boolean(props.isResizing),
+            };
+            var standardClassNames = getEventClassNames(hookProps).concat(ui.classNames);
+            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.eventClassNames, content: options.eventContent, defaultContent: props.defaultContent, didMount: options.eventDidMount, willUnmount: options.eventWillUnmount, elRef: this.elRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return props.children(rootElRef, standardClassNames.concat(customClassNames), innerElRef, innerContent, hookProps); }));
+        };
+        EventRoot.prototype.componentDidMount = function () {
+            setElSeg(this.elRef.current, this.props.seg);
+        };
+        /*
+        need to re-assign seg to the element if seg changes, even if the element is the same
+        */
+        EventRoot.prototype.componentDidUpdate = function (prevProps) {
+            var seg = this.props.seg;
+            if (seg !== prevProps.seg) {
+                setElSeg(this.elRef.current, seg);
+            }
+        };
+        return EventRoot;
+    }(BaseComponent));
+
+    // should not be a purecomponent
+    var StandardEvent = /** @class */ (function (_super) {
+        __extends(StandardEvent, _super);
+        function StandardEvent() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        StandardEvent.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            var seg = props.seg;
+            var timeFormat = context.options.eventTimeFormat || props.defaultTimeFormat;
+            var timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd);
+            return (createElement(EventRoot, { seg: seg, timeText: timeText, disableDragging: props.disableDragging, disableResizing: props.disableResizing, defaultContent: props.defaultContent || renderInnerContent$4, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("a", __assign({ className: props.extraClassNames.concat(classNames).join(' '), style: {
+                    borderColor: hookProps.borderColor,
+                    backgroundColor: hookProps.backgroundColor,
+                }, ref: rootElRef }, getSegAnchorAttrs(seg, context)),
+                createElement("div", { className: "fc-event-main", ref: innerElRef, style: { color: hookProps.textColor } }, innerContent),
+                hookProps.isStartResizable &&
+                    createElement("div", { className: "fc-event-resizer fc-event-resizer-start" }),
+                hookProps.isEndResizable &&
+                    createElement("div", { className: "fc-event-resizer fc-event-resizer-end" }))); }));
+        };
+        return StandardEvent;
+    }(BaseComponent));
+    function renderInnerContent$4(innerProps) {
+        return (createElement("div", { className: "fc-event-main-frame" },
+            innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)),
+            createElement("div", { className: "fc-event-title-container" },
+                createElement("div", { className: "fc-event-title fc-sticky" }, innerProps.event.title || createElement(Fragment, null, "\u00A0")))));
+    }
+
+    var NowIndicatorRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) {
+        var options = context.options;
+        var hookProps = {
+            isAxis: props.isAxis,
+            date: context.dateEnv.toDate(props.date),
+            view: context.viewApi,
+        };
+        return (createElement(RenderHook, { hookProps: hookProps, classNames: options.nowIndicatorClassNames, content: options.nowIndicatorContent, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount }, props.children));
+    })); };
+
+    var DAY_NUM_FORMAT = createFormatter({ day: 'numeric' });
+    var DayCellContent = /** @class */ (function (_super) {
+        __extends(DayCellContent, _super);
+        function DayCellContent() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        DayCellContent.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            var options = context.options;
+            var hookProps = refineDayCellHookProps({
+                date: props.date,
+                dateProfile: props.dateProfile,
+                todayRange: props.todayRange,
+                showDayNumber: props.showDayNumber,
+                extraProps: props.extraHookProps,
+                viewApi: context.viewApi,
+                dateEnv: context.dateEnv,
+            });
+            return (createElement(ContentHook, { hookProps: hookProps, content: options.dayCellContent, defaultContent: props.defaultContent }, props.children));
+        };
+        return DayCellContent;
+    }(BaseComponent));
+    function refineDayCellHookProps(raw) {
+        var date = raw.date, dateEnv = raw.dateEnv;
+        var dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile);
+        return __assign(__assign(__assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { dayNumberText: raw.showDayNumber ? dateEnv.format(date, DAY_NUM_FORMAT) : '' }), raw.extraProps);
+    }
+
+    var DayCellRoot = /** @class */ (function (_super) {
+        __extends(DayCellRoot, _super);
+        function DayCellRoot() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.refineHookProps = memoizeObjArg(refineDayCellHookProps);
+            _this.normalizeClassNames = buildClassNameNormalizer();
+            return _this;
+        }
+        DayCellRoot.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            var options = context.options;
+            var hookProps = this.refineHookProps({
+                date: props.date,
+                dateProfile: props.dateProfile,
+                todayRange: props.todayRange,
+                showDayNumber: props.showDayNumber,
+                extraProps: props.extraHookProps,
+                viewApi: context.viewApi,
+                dateEnv: context.dateEnv,
+            });
+            var classNames = getDayClassNames(hookProps, context.theme).concat(hookProps.isDisabled
+                ? [] // don't use custom classNames if disabled
+                : this.normalizeClassNames(options.dayCellClassNames, hookProps));
+            var dataAttrs = hookProps.isDisabled ? {} : {
+                'data-date': formatDayString(props.date),
+            };
+            return (createElement(MountHook, { hookProps: hookProps, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, classNames, dataAttrs, hookProps.isDisabled); }));
+        };
+        return DayCellRoot;
+    }(BaseComponent));
+
+    function renderFill(fillType) {
+        return (createElement("div", { className: "fc-" + fillType }));
+    }
+    var BgEvent = function (props) { return (createElement(EventRoot, { defaultContent: renderInnerContent$3, seg: props.seg /* uselesss i think */, timeText: "", disableDragging: true, disableResizing: true, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("div", { ref: rootElRef, className: ['fc-bg-event'].concat(classNames).join(' '), style: {
+            backgroundColor: hookProps.backgroundColor,
+        } }, innerContent)); })); };
+    function renderInnerContent$3(props) {
+        var title = props.event.title;
+        return title && (createElement("div", { className: "fc-event-title" }, props.event.title));
+    }
+
+    var WeekNumberRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) {
+        var dateEnv = context.dateEnv, options = context.options;
+        var date = props.date;
+        var format = options.weekNumberFormat || props.defaultFormat;
+        var num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well?
+        var text = dateEnv.format(date, format);
+        var hookProps = { num: num, text: text, date: date };
+        return (createElement(RenderHook, { hookProps: hookProps, classNames: options.weekNumberClassNames, content: options.weekNumberContent, defaultContent: renderInner, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount }, props.children));
+    })); };
+    function renderInner(innerProps) {
+        return innerProps.text;
+    }
+
+    var PADDING_FROM_VIEWPORT = 10;
+    var Popover = /** @class */ (function (_super) {
+        __extends(Popover, _super);
+        function Popover() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.state = {
+                titleId: getUniqueDomId(),
+            };
+            _this.handleRootEl = function (el) {
+                _this.rootEl = el;
+                if (_this.props.elRef) {
+                    setRef(_this.props.elRef, el);
+                }
+            };
+            // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
+            _this.handleDocumentMouseDown = function (ev) {
+                // only hide the popover if the click happened outside the popover
+                var target = getEventTargetViaRoot(ev);
+                if (!_this.rootEl.contains(target)) {
+                    _this.handleCloseClick();
+                }
+            };
+            _this.handleDocumentKeyDown = function (ev) {
+                if (ev.key === 'Escape') {
+                    _this.handleCloseClick();
+                }
+            };
+            _this.handleCloseClick = function () {
+                var onClose = _this.props.onClose;
+                if (onClose) {
+                    onClose();
+                }
+            };
+            return _this;
+        }
+        Popover.prototype.render = function () {
+            var _a = this.context, theme = _a.theme, options = _a.options;
+            var _b = this, props = _b.props, state = _b.state;
+            var classNames = [
+                'fc-popover',
+                theme.getClass('popover'),
+            ].concat(props.extraClassNames || []);
+            return createPortal(createElement("div", __assign({ id: props.id, className: classNames.join(' '), "aria-labelledby": state.titleId }, props.extraAttrs, { ref: this.handleRootEl }),
+                createElement("div", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') },
+                    createElement("span", { className: "fc-popover-title", id: state.titleId }, props.title),
+                    createElement("span", { className: 'fc-popover-close ' + theme.getIconClass('close'), title: options.closeHint, onClick: this.handleCloseClick })),
+                createElement("div", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)), props.parentEl);
+        };
+        Popover.prototype.componentDidMount = function () {
+            document.addEventListener('mousedown', this.handleDocumentMouseDown);
+            document.addEventListener('keydown', this.handleDocumentKeyDown);
+            this.updateSize();
+        };
+        Popover.prototype.componentWillUnmount = function () {
+            document.removeEventListener('mousedown', this.handleDocumentMouseDown);
+            document.removeEventListener('keydown', this.handleDocumentKeyDown);
+        };
+        Popover.prototype.updateSize = function () {
+            var isRtl = this.context.isRtl;
+            var _a = this.props, alignmentEl = _a.alignmentEl, alignGridTop = _a.alignGridTop;
+            var rootEl = this.rootEl;
+            var alignmentRect = computeClippedClientRect(alignmentEl);
+            if (alignmentRect) {
+                var popoverDims = rootEl.getBoundingClientRect();
+                // position relative to viewport
+                var popoverTop = alignGridTop
+                    ? elementClosest(alignmentEl, '.fc-scrollgrid').getBoundingClientRect().top
+                    : alignmentRect.top;
+                var popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left;
+                // constrain
+                popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT);
+                popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width);
+                popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT);
+                var origin_1 = rootEl.offsetParent.getBoundingClientRect();
+                applyStyle(rootEl, {
+                    top: popoverTop - origin_1.top,
+                    left: popoverLeft - origin_1.left,
+                });
+            }
+        };
+        return Popover;
+    }(BaseComponent));
+
+    var MorePopover = /** @class */ (function (_super) {
+        __extends(MorePopover, _super);
+        function MorePopover() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.handleRootEl = function (rootEl) {
+                _this.rootEl = rootEl;
+                if (rootEl) {
+                    _this.context.registerInteractiveComponent(_this, {
+                        el: rootEl,
+                        useEventCenter: false,
+                    });
+                }
+                else {
+                    _this.context.unregisterInteractiveComponent(_this);
+                }
+            };
+            return _this;
+        }
+        MorePopover.prototype.render = function () {
+            var _a = this.context, options = _a.options, dateEnv = _a.dateEnv;
+            var props = this.props;
+            var startDate = props.startDate, todayRange = props.todayRange, dateProfile = props.dateProfile;
+            var title = dateEnv.format(startDate, options.dayPopoverFormat);
+            return (createElement(DayCellRoot, { date: startDate, dateProfile: dateProfile, todayRange: todayRange, elRef: this.handleRootEl }, function (rootElRef, dayClassNames, dataAttrs) { return (createElement(Popover, { elRef: rootElRef, id: props.id, title: title, extraClassNames: ['fc-more-popover'].concat(dayClassNames), extraAttrs: dataAttrs /* TODO: make these time-based when not whole-day? */, parentEl: props.parentEl, alignmentEl: props.alignmentEl, alignGridTop: props.alignGridTop, onClose: props.onClose },
+                createElement(DayCellContent, { date: startDate, dateProfile: dateProfile, todayRange: todayRange }, function (innerElRef, innerContent) { return (innerContent &&
+                    createElement("div", { className: "fc-more-popover-misc", ref: innerElRef }, innerContent)); }),
+                props.children)); }));
+        };
+        MorePopover.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
+            var _a = this, rootEl = _a.rootEl, props = _a.props;
+            if (positionLeft >= 0 && positionLeft < elWidth &&
+                positionTop >= 0 && positionTop < elHeight) {
+                return {
+                    dateProfile: props.dateProfile,
+                    dateSpan: __assign({ allDay: true, range: {
+                            start: props.startDate,
+                            end: props.endDate,
+                        } }, props.extraDateSpan),
+                    dayEl: rootEl,
+                    rect: {
+                        left: 0,
+                        top: 0,
+                        right: elWidth,
+                        bottom: elHeight,
+                    },
+                    layer: 1, // important when comparing with hits from other components
+                };
+            }
+            return null;
+        };
+        return MorePopover;
+    }(DateComponent));
+
+    var MoreLinkRoot = /** @class */ (function (_super) {
+        __extends(MoreLinkRoot, _super);
+        function MoreLinkRoot() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.linkElRef = createRef();
+            _this.state = {
+                isPopoverOpen: false,
+                popoverId: getUniqueDomId(),
+            };
+            _this.handleClick = function (ev) {
+                var _a = _this, props = _a.props, context = _a.context;
+                var moreLinkClick = context.options.moreLinkClick;
+                var date = computeRange(props).start;
+                function buildPublicSeg(seg) {
+                    var _a = seg.eventRange, def = _a.def, instance = _a.instance, range = _a.range;
+                    return {
+                        event: new EventApi(context, def, instance),
+                        start: context.dateEnv.toDate(range.start),
+                        end: context.dateEnv.toDate(range.end),
+                        isStart: seg.isStart,
+                        isEnd: seg.isEnd,
+                    };
+                }
+                if (typeof moreLinkClick === 'function') {
+                    moreLinkClick = moreLinkClick({
+                        date: date,
+                        allDay: Boolean(props.allDayDate),
+                        allSegs: props.allSegs.map(buildPublicSeg),
+                        hiddenSegs: props.hiddenSegs.map(buildPublicSeg),
+                        jsEvent: ev,
+                        view: context.viewApi,
+                    });
+                }
+                if (!moreLinkClick || moreLinkClick === 'popover') {
+                    _this.setState({ isPopoverOpen: true });
+                }
+                else if (typeof moreLinkClick === 'string') { // a view name
+                    context.calendarApi.zoomTo(date, moreLinkClick);
+                }
+            };
+            _this.handlePopoverClose = function () {
+                _this.setState({ isPopoverOpen: false });
+            };
+            return _this;
+        }
+        MoreLinkRoot.prototype.render = function () {
+            var _this = this;
+            var _a = this, props = _a.props, state = _a.state;
+            return (createElement(ViewContextType.Consumer, null, function (context) {
+                var viewApi = context.viewApi, options = context.options, calendarApi = context.calendarApi;
+                var moreLinkText = options.moreLinkText;
+                var moreCnt = props.moreCnt;
+                var range = computeRange(props);
+                var text = typeof moreLinkText === 'function' // TODO: eventually use formatWithOrdinals
+                    ? moreLinkText.call(calendarApi, moreCnt)
+                    : "+" + moreCnt + " " + moreLinkText;
+                var title = formatWithOrdinals(options.moreLinkHint, [moreCnt], text);
+                var hookProps = {
+                    num: moreCnt,
+                    shortText: "+" + moreCnt,
+                    text: text,
+                    view: viewApi,
+                };
+                return (createElement(Fragment, null,
+                    Boolean(props.moreCnt) && (createElement(RenderHook, { elRef: _this.linkElRef, hookProps: hookProps, classNames: options.moreLinkClassNames, content: options.moreLinkContent, defaultContent: props.defaultContent || renderMoreLinkInner$1, didMount: options.moreLinkDidMount, willUnmount: options.moreLinkWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return props.children(rootElRef, ['fc-more-link'].concat(customClassNames), innerElRef, innerContent, _this.handleClick, title, state.isPopoverOpen, state.isPopoverOpen ? state.popoverId : ''); })),
+                    state.isPopoverOpen && (createElement(MorePopover, { id: state.popoverId, startDate: range.start, endDate: range.end, dateProfile: props.dateProfile, todayRange: props.todayRange, extraDateSpan: props.extraDateSpan, parentEl: _this.parentEl, alignmentEl: props.alignmentElRef.current, alignGridTop: props.alignGridTop, onClose: _this.handlePopoverClose }, props.popoverContent()))));
+            }));
+        };
+        MoreLinkRoot.prototype.componentDidMount = function () {
+            this.updateParentEl();
+        };
+        MoreLinkRoot.prototype.componentDidUpdate = function () {
+            this.updateParentEl();
+        };
+        MoreLinkRoot.prototype.updateParentEl = function () {
+            if (this.linkElRef.current) {
+                this.parentEl = elementClosest(this.linkElRef.current, '.fc-view-harness');
+            }
+        };
+        return MoreLinkRoot;
+    }(BaseComponent));
+    function renderMoreLinkInner$1(props) {
+        return props.text;
+    }
+    function computeRange(props) {
+        if (props.allDayDate) {
+            return {
+                start: props.allDayDate,
+                end: addDays(props.allDayDate, 1),
+            };
+        }
+        var hiddenSegs = props.hiddenSegs;
+        return {
+            start: computeEarliestSegStart(hiddenSegs),
+            end: computeLatestSegEnd(hiddenSegs),
+        };
+    }
+    function computeEarliestSegStart(segs) {
+        return segs.reduce(pickEarliestStart).eventRange.range.start;
+    }
+    function pickEarliestStart(seg0, seg1) {
+        return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1;
+    }
+    function computeLatestSegEnd(segs) {
+        return segs.reduce(pickLatestEnd).eventRange.range.end;
+    }
+    function pickLatestEnd(seg0, seg1) {
+        return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1;
+    }
+
+    // exports
+    // --------------------------------------------------------------------------------------------------
+    var version = '5.11.3'; // important to type it, so .d.ts has generic string
+
+    var Calendar = /** @class */ (function (_super) {
+        __extends(Calendar, _super);
+        function Calendar(el, optionOverrides) {
+            if (optionOverrides === void 0) { optionOverrides = {}; }
+            var _this = _super.call(this) || this;
+            _this.isRendering = false;
+            _this.isRendered = false;
+            _this.currentClassNames = [];
+            _this.customContentRenderId = 0; // will affect custom generated classNames?
+            _this.handleAction = function (action) {
+                // actions we know we want to render immediately
+                switch (action.type) {
+                    case 'SET_EVENT_DRAG':
+                    case 'SET_EVENT_RESIZE':
+                        _this.renderRunner.tryDrain();
+                }
+            };
+            _this.handleData = function (data) {
+                _this.currentData = data;
+                _this.renderRunner.request(data.calendarOptions.rerenderDelay);
+            };
+            _this.handleRenderRequest = function () {
+                if (_this.isRendering) {
+                    _this.isRendered = true;
+                    var currentData_1 = _this.currentData;
+                    flushSync(function () {
+                        render(createElement(CalendarRoot, { options: currentData_1.calendarOptions, theme: currentData_1.theme, emitter: currentData_1.emitter }, function (classNames, height, isHeightAuto, forPrint) {
+                            _this.setClassNames(classNames);
+                            _this.setHeight(height);
+                            return (createElement(CustomContentRenderContext.Provider, { value: _this.customContentRenderId },
+                                createElement(CalendarContent, __assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData_1))));
+                        }), _this.el);
+                    });
+                }
+                else if (_this.isRendered) {
+                    _this.isRendered = false;
+                    unmountComponentAtNode(_this.el);
+                    _this.setClassNames([]);
+                    _this.setHeight('');
+                }
+            };
+            _this.el = el;
+            _this.renderRunner = new DelayedRunner(_this.handleRenderRequest);
+            new CalendarDataManager({
+                optionOverrides: optionOverrides,
+                calendarApi: _this,
+                onAction: _this.handleAction,
+                onData: _this.handleData,
+            });
+            return _this;
+        }
+        Object.defineProperty(Calendar.prototype, "view", {
+            get: function () { return this.currentData.viewApi; } // for public API
+            ,
+            enumerable: false,
+            configurable: true
+        });
+        Calendar.prototype.render = function () {
+            var wasRendering = this.isRendering;
+            if (!wasRendering) {
+                this.isRendering = true;
+            }
+            else {
+                this.customContentRenderId += 1;
+            }
+            this.renderRunner.request();
+            if (wasRendering) {
+                this.updateSize();
+            }
+        };
+        Calendar.prototype.destroy = function () {
+            if (this.isRendering) {
+                this.isRendering = false;
+                this.renderRunner.request();
+            }
+        };
+        Calendar.prototype.updateSize = function () {
+            var _this = this;
+            flushSync(function () {
+                _super.prototype.updateSize.call(_this);
+            });
+        };
+        Calendar.prototype.batchRendering = function (func) {
+            this.renderRunner.pause('batchRendering');
+            func();
+            this.renderRunner.resume('batchRendering');
+        };
+        Calendar.prototype.pauseRendering = function () {
+            this.renderRunner.pause('pauseRendering');
+        };
+        Calendar.prototype.resumeRendering = function () {
+            this.renderRunner.resume('pauseRendering', true);
+        };
+        Calendar.prototype.resetOptions = function (optionOverrides, append) {
+            this.currentDataManager.resetOptions(optionOverrides, append);
+        };
+        Calendar.prototype.setClassNames = function (classNames) {
+            if (!isArraysEqual(classNames, this.currentClassNames)) {
+                var classList = this.el.classList;
+                for (var _i = 0, _a = this.currentClassNames; _i < _a.length; _i++) {
+                    var className = _a[_i];
+                    classList.remove(className);
+                }
+                for (var _b = 0, classNames_1 = classNames; _b < classNames_1.length; _b++) {
+                    var className = classNames_1[_b];
+                    classList.add(className);
+                }
+                this.currentClassNames = classNames;
+            }
+        };
+        Calendar.prototype.setHeight = function (height) {
+            applyStyleProp(this.el, 'height', height);
+        };
+        return Calendar;
+    }(CalendarApi));
+
+    config.touchMouseIgnoreWait = 500;
+    var ignoreMouseDepth = 0;
+    var listenerCnt = 0;
+    var isWindowTouchMoveCancelled = false;
+    /*
+    Uses a "pointer" abstraction, which monitors UI events for both mouse and touch.
+    Tracks when the pointer "drags" on a certain element, meaning down+move+up.
+
+    Also, tracks if there was touch-scrolling.
+    Also, can prevent touch-scrolling from happening.
+    Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.
+
+    emits:
+    - pointerdown
+    - pointermove
+    - pointerup
+    */
+    var PointerDragging = /** @class */ (function () {
+        function PointerDragging(containerEl) {
+            var _this = this;
+            this.subjectEl = null;
+            // options that can be directly assigned by caller
+            this.selector = ''; // will cause subjectEl in all emitted events to be this element
+            this.handleSelector = '';
+            this.shouldIgnoreMove = false;
+            this.shouldWatchScroll = true; // for simulating pointermove on scroll
+            // internal states
+            this.isDragging = false;
+            this.isTouchDragging = false;
+            this.wasTouchScroll = false;
+            // Mouse
+            // ----------------------------------------------------------------------------------------------------
+            this.handleMouseDown = function (ev) {
+                if (!_this.shouldIgnoreMouse() &&
+                    isPrimaryMouseButton(ev) &&
+                    _this.tryStart(ev)) {
+                    var pev = _this.createEventFromMouse(ev, true);
+                    _this.emitter.trigger('pointerdown', pev);
+                    _this.initScrollWatch(pev);
+                    if (!_this.shouldIgnoreMove) {
+                        document.addEventListener('mousemove', _this.handleMouseMove);
+                    }
+                    document.addEventListener('mouseup', _this.handleMouseUp);
+                }
+            };
+            this.handleMouseMove = function (ev) {
+                var pev = _this.createEventFromMouse(ev);
+                _this.recordCoords(pev);
+                _this.emitter.trigger('pointermove', pev);
+            };
+            this.handleMouseUp = function (ev) {
+                document.removeEventListener('mousemove', _this.handleMouseMove);
+                document.removeEventListener('mouseup', _this.handleMouseUp);
+                _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev));
+                _this.cleanup(); // call last so that pointerup has access to props
+            };
+            // Touch
+            // ----------------------------------------------------------------------------------------------------
+            this.handleTouchStart = function (ev) {
+                if (_this.tryStart(ev)) {
+                    _this.isTouchDragging = true;
+                    var pev = _this.createEventFromTouch(ev, true);
+                    _this.emitter.trigger('pointerdown', pev);
+                    _this.initScrollWatch(pev);
+                    // unlike mouse, need to attach to target, not document
+                    // https://stackoverflow.com/a/45760014
+                    var targetEl = ev.target;
+                    if (!_this.shouldIgnoreMove) {
+                        targetEl.addEventListener('touchmove', _this.handleTouchMove);
+                    }
+                    targetEl.addEventListener('touchend', _this.handleTouchEnd);
+                    targetEl.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end
+                    // attach a handler to get called when ANY scroll action happens on the page.
+                    // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
+                    // http://stackoverflow.com/a/32954565/96342
+                    window.addEventListener('scroll', _this.handleTouchScroll, true);
+                }
+            };
+            this.handleTouchMove = function (ev) {
+                var pev = _this.createEventFromTouch(ev);
+                _this.recordCoords(pev);
+                _this.emitter.trigger('pointermove', pev);
+            };
+            this.handleTouchEnd = function (ev) {
+                if (_this.isDragging) { // done to guard against touchend followed by touchcancel
+                    var targetEl = ev.target;
+                    targetEl.removeEventListener('touchmove', _this.handleTouchMove);
+                    targetEl.removeEventListener('touchend', _this.handleTouchEnd);
+                    targetEl.removeEventListener('touchcancel', _this.handleTouchEnd);
+                    window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true
+                    _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev));
+                    _this.cleanup(); // call last so that pointerup has access to props
+                    _this.isTouchDragging = false;
+                    startIgnoringMouse();
+                }
+            };
+            this.handleTouchScroll = function () {
+                _this.wasTouchScroll = true;
+            };
+            this.handleScroll = function (ev) {
+                if (!_this.shouldIgnoreMove) {
+                    var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX;
+                    var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY;
+                    _this.emitter.trigger('pointermove', {
+                        origEvent: ev,
+                        isTouch: _this.isTouchDragging,
+                        subjectEl: _this.subjectEl,
+                        pageX: pageX,
+                        pageY: pageY,
+                        deltaX: pageX - _this.origPageX,
+                        deltaY: pageY - _this.origPageY,
+                    });
+                }
+            };
+            this.containerEl = containerEl;
+            this.emitter = new Emitter();
+            containerEl.addEventListener('mousedown', this.handleMouseDown);
+            containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true });
+            listenerCreated();
+        }
+        PointerDragging.prototype.destroy = function () {
+            this.containerEl.removeEventListener('mousedown', this.handleMouseDown);
+            this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
+            listenerDestroyed();
+        };
+        PointerDragging.prototype.tryStart = function (ev) {
+            var subjectEl = this.querySubjectEl(ev);
+            var downEl = ev.target;
+            if (subjectEl &&
+                (!this.handleSelector || elementClosest(downEl, this.handleSelector))) {
+                this.subjectEl = subjectEl;
+                this.isDragging = true; // do this first so cancelTouchScroll will work
+                this.wasTouchScroll = false;
+                return true;
+            }
+            return false;
+        };
+        PointerDragging.prototype.cleanup = function () {
+            isWindowTouchMoveCancelled = false;
+            this.isDragging = false;
+            this.subjectEl = null;
+            // keep wasTouchScroll around for later access
+            this.destroyScrollWatch();
+        };
+        PointerDragging.prototype.querySubjectEl = function (ev) {
+            if (this.selector) {
+                return elementClosest(ev.target, this.selector);
+            }
+            return this.containerEl;
+        };
+        PointerDragging.prototype.shouldIgnoreMouse = function () {
+            return ignoreMouseDepth || this.isTouchDragging;
+        };
+        // can be called by user of this class, to cancel touch-based scrolling for the current drag
+        PointerDragging.prototype.cancelTouchScroll = function () {
+            if (this.isDragging) {
+                isWindowTouchMoveCancelled = true;
+            }
+        };
+        // Scrolling that simulates pointermoves
+        // ----------------------------------------------------------------------------------------------------
+        PointerDragging.prototype.initScrollWatch = function (ev) {
+            if (this.shouldWatchScroll) {
+                this.recordCoords(ev);
+                window.addEventListener('scroll', this.handleScroll, true); // useCapture=true
+            }
+        };
+        PointerDragging.prototype.recordCoords = function (ev) {
+            if (this.shouldWatchScroll) {
+                this.prevPageX = ev.pageX;
+                this.prevPageY = ev.pageY;
+                this.prevScrollX = window.pageXOffset;
+                this.prevScrollY = window.pageYOffset;
+            }
+        };
+        PointerDragging.prototype.destroyScrollWatch = function () {
+            if (this.shouldWatchScroll) {
+                window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true
+            }
+        };
+        // Event Normalization
+        // ----------------------------------------------------------------------------------------------------
+        PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) {
+            var deltaX = 0;
+            var deltaY = 0;
+            // TODO: repeat code
+            if (isFirst) {
+                this.origPageX = ev.pageX;
+                this.origPageY = ev.pageY;
+            }
+            else {
+                deltaX = ev.pageX - this.origPageX;
+                deltaY = ev.pageY - this.origPageY;
+            }
+            return {
+                origEvent: ev,
+                isTouch: false,
+                subjectEl: this.subjectEl,
+                pageX: ev.pageX,
+                pageY: ev.pageY,
+                deltaX: deltaX,
+                deltaY: deltaY,
+            };
+        };
+        PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) {
+            var touches = ev.touches;
+            var pageX;
+            var pageY;
+            var deltaX = 0;
+            var deltaY = 0;
+            // if touch coords available, prefer,
+            // because FF would give bad ev.pageX ev.pageY
+            if (touches && touches.length) {
+                pageX = touches[0].pageX;
+                pageY = touches[0].pageY;
+            }
+            else {
+                pageX = ev.pageX;
+                pageY = ev.pageY;
+            }
+            // TODO: repeat code
+            if (isFirst) {
+                this.origPageX = pageX;
+                this.origPageY = pageY;
+            }
+            else {
+                deltaX = pageX - this.origPageX;
+                deltaY = pageY - this.origPageY;
+            }
+            return {
+                origEvent: ev,
+                isTouch: true,
+                subjectEl: this.subjectEl,
+                pageX: pageX,
+                pageY: pageY,
+                deltaX: deltaX,
+                deltaY: deltaY,
+            };
+        };
+        return PointerDragging;
+    }());
+    // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
+    function isPrimaryMouseButton(ev) {
+        return ev.button === 0 && !ev.ctrlKey;
+    }
+    // Ignoring fake mouse events generated by touch
+    // ----------------------------------------------------------------------------------------------------
+    function startIgnoringMouse() {
+        ignoreMouseDepth += 1;
+        setTimeout(function () {
+            ignoreMouseDepth -= 1;
+        }, config.touchMouseIgnoreWait);
+    }
+    // We want to attach touchmove as early as possible for Safari
+    // ----------------------------------------------------------------------------------------------------
+    function listenerCreated() {
+        listenerCnt += 1;
+        if (listenerCnt === 1) {
+            window.addEventListener('touchmove', onWindowTouchMove, { passive: false });
+        }
+    }
+    function listenerDestroyed() {
+        listenerCnt -= 1;
+        if (!listenerCnt) {
+            window.removeEventListener('touchmove', onWindowTouchMove, { passive: false });
+        }
+    }
+    function onWindowTouchMove(ev) {
+        if (isWindowTouchMoveCancelled) {
+            ev.preventDefault();
+        }
+    }
+
+    /*
+    An effect in which an element follows the movement of a pointer across the screen.
+    The moving element is a clone of some other element.
+    Must call start + handleMove + stop.
+    */
+    var ElementMirror = /** @class */ (function () {
+        function ElementMirror() {
+            this.isVisible = false; // must be explicitly enabled
+            this.sourceEl = null;
+            this.mirrorEl = null;
+            this.sourceElRect = null; // screen coords relative to viewport
+            // options that can be set directly by caller
+            this.parentNode = document.body; // HIGHLY SUGGESTED to set this to sidestep ShadowDOM issues
+            this.zIndex = 9999;
+            this.revertDuration = 0;
+        }
+        ElementMirror.prototype.start = function (sourceEl, pageX, pageY) {
+            this.sourceEl = sourceEl;
+            this.sourceElRect = this.sourceEl.getBoundingClientRect();
+            this.origScreenX = pageX - window.pageXOffset;
+            this.origScreenY = pageY - window.pageYOffset;
+            this.deltaX = 0;
+            this.deltaY = 0;
+            this.updateElPosition();
+        };
+        ElementMirror.prototype.handleMove = function (pageX, pageY) {
+            this.deltaX = (pageX - window.pageXOffset) - this.origScreenX;
+            this.deltaY = (pageY - window.pageYOffset) - this.origScreenY;
+            this.updateElPosition();
+        };
+        // can be called before start
+        ElementMirror.prototype.setIsVisible = function (bool) {
+            if (bool) {
+                if (!this.isVisible) {
+                    if (this.mirrorEl) {
+                        this.mirrorEl.style.display = '';
+                    }
+                    this.isVisible = bool; // needs to happen before updateElPosition
+                    this.updateElPosition(); // because was not updating the position while invisible
+                }
+            }
+            else if (this.isVisible) {
+                if (this.mirrorEl) {
+                    this.mirrorEl.style.display = 'none';
+                }
+                this.isVisible = bool;
+            }
+        };
+        // always async
+        ElementMirror.prototype.stop = function (needsRevertAnimation, callback) {
+            var _this = this;
+            var done = function () {
+                _this.cleanup();
+                callback();
+            };
+            if (needsRevertAnimation &&
+                this.mirrorEl &&
+                this.isVisible &&
+                this.revertDuration && // if 0, transition won't work
+                (this.deltaX || this.deltaY) // if same coords, transition won't work
+            ) {
+                this.doRevertAnimation(done, this.revertDuration);
+            }
+            else {
+                setTimeout(done, 0);
+            }
+        };
+        ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) {
+            var mirrorEl = this.mirrorEl;
+            var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened
+            mirrorEl.style.transition =
+                'top ' + revertDuration + 'ms,' +
+                    'left ' + revertDuration + 'ms';
+            applyStyle(mirrorEl, {
+                left: finalSourceElRect.left,
+                top: finalSourceElRect.top,
+            });
+            whenTransitionDone(mirrorEl, function () {
+                mirrorEl.style.transition = '';
+                callback();
+            });
+        };
+        ElementMirror.prototype.cleanup = function () {
+            if (this.mirrorEl) {
+                removeElement(this.mirrorEl);
+                this.mirrorEl = null;
+            }
+            this.sourceEl = null;
+        };
+        ElementMirror.prototype.updateElPosition = function () {
+            if (this.sourceEl && this.isVisible) {
+                applyStyle(this.getMirrorEl(), {
+                    left: this.sourceElRect.left + this.deltaX,
+                    top: this.sourceElRect.top + this.deltaY,
+                });
+            }
+        };
+        ElementMirror.prototype.getMirrorEl = function () {
+            var sourceElRect = this.sourceElRect;
+            var mirrorEl = this.mirrorEl;
+            if (!mirrorEl) {
+                mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
+                // we don't want long taps or any mouse interaction causing selection/menus.
+                // would use preventSelection(), but that prevents selectstart, causing problems.
+                mirrorEl.classList.add('fc-unselectable');
+                mirrorEl.classList.add('fc-event-dragging');
+                applyStyle(mirrorEl, {
+                    position: 'fixed',
+                    zIndex: this.zIndex,
+                    visibility: '',
+                    boxSizing: 'border-box',
+                    width: sourceElRect.right - sourceElRect.left,
+                    height: sourceElRect.bottom - sourceElRect.top,
+                    right: 'auto',
+                    bottom: 'auto',
+                    margin: 0,
+                });
+                this.parentNode.appendChild(mirrorEl);
+            }
+            return mirrorEl;
+        };
+        return ElementMirror;
+    }());
+
+    /*
+    Is a cache for a given element's scroll information (all the info that ScrollController stores)
+    in addition the "client rectangle" of the element.. the area within the scrollbars.
+
+    The cache can be in one of two modes:
+    - doesListening:false - ignores when the container is scrolled by someone else
+    - doesListening:true - watch for scrolling and update the cache
+    */
+    var ScrollGeomCache = /** @class */ (function (_super) {
+        __extends(ScrollGeomCache, _super);
+        function ScrollGeomCache(scrollController, doesListening) {
+            var _this = _super.call(this) || this;
+            _this.handleScroll = function () {
+                _this.scrollTop = _this.scrollController.getScrollTop();
+                _this.scrollLeft = _this.scrollController.getScrollLeft();
+                _this.handleScrollChange();
+            };
+            _this.scrollController = scrollController;
+            _this.doesListening = doesListening;
+            _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop();
+            _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
+            _this.scrollWidth = scrollController.getScrollWidth();
+            _this.scrollHeight = scrollController.getScrollHeight();
+            _this.clientWidth = scrollController.getClientWidth();
+            _this.clientHeight = scrollController.getClientHeight();
+            _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values
+            if (_this.doesListening) {
+                _this.getEventTarget().addEventListener('scroll', _this.handleScroll);
+            }
+            return _this;
+        }
+        ScrollGeomCache.prototype.destroy = function () {
+            if (this.doesListening) {
+                this.getEventTarget().removeEventListener('scroll', this.handleScroll);
+            }
+        };
+        ScrollGeomCache.prototype.getScrollTop = function () {
+            return this.scrollTop;
+        };
+        ScrollGeomCache.prototype.getScrollLeft = function () {
+            return this.scrollLeft;
+        };
+        ScrollGeomCache.prototype.setScrollTop = function (top) {
+            this.scrollController.setScrollTop(top);
+            if (!this.doesListening) {
+                // we are not relying on the element to normalize out-of-bounds scroll values
+                // so we need to sanitize ourselves
+                this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
+                this.handleScrollChange();
+            }
+        };
+        ScrollGeomCache.prototype.setScrollLeft = function (top) {
+            this.scrollController.setScrollLeft(top);
+            if (!this.doesListening) {
+                // we are not relying on the element to normalize out-of-bounds scroll values
+                // so we need to sanitize ourselves
+                this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
+                this.handleScrollChange();
+            }
+        };
+        ScrollGeomCache.prototype.getClientWidth = function () {
+            return this.clientWidth;
+        };
+        ScrollGeomCache.prototype.getClientHeight = function () {
+            return this.clientHeight;
+        };
+        ScrollGeomCache.prototype.getScrollWidth = function () {
+            return this.scrollWidth;
+        };
+        ScrollGeomCache.prototype.getScrollHeight = function () {
+            return this.scrollHeight;
+        };
+        ScrollGeomCache.prototype.handleScrollChange = function () {
+        };
+        return ScrollGeomCache;
+    }(ScrollController));
+
+    var ElementScrollGeomCache = /** @class */ (function (_super) {
+        __extends(ElementScrollGeomCache, _super);
+        function ElementScrollGeomCache(el, doesListening) {
+            return _super.call(this, new ElementScrollController(el), doesListening) || this;
+        }
+        ElementScrollGeomCache.prototype.getEventTarget = function () {
+            return this.scrollController.el;
+        };
+        ElementScrollGeomCache.prototype.computeClientRect = function () {
+            return computeInnerRect(this.scrollController.el);
+        };
+        return ElementScrollGeomCache;
+    }(ScrollGeomCache));
+
+    var WindowScrollGeomCache = /** @class */ (function (_super) {
+        __extends(WindowScrollGeomCache, _super);
+        function WindowScrollGeomCache(doesListening) {
+            return _super.call(this, new WindowScrollController(), doesListening) || this;
+        }
+        WindowScrollGeomCache.prototype.getEventTarget = function () {
+            return window;
+        };
+        WindowScrollGeomCache.prototype.computeClientRect = function () {
+            return {
+                left: this.scrollLeft,
+                right: this.scrollLeft + this.clientWidth,
+                top: this.scrollTop,
+                bottom: this.scrollTop + this.clientHeight,
+            };
+        };
+        // the window is the only scroll object that changes it's rectangle relative
+        // to the document's topleft as it scrolls
+        WindowScrollGeomCache.prototype.handleScrollChange = function () {
+            this.clientRect = this.computeClientRect();
+        };
+        return WindowScrollGeomCache;
+    }(ScrollGeomCache));
+
+    // If available we are using native "performance" API instead of "Date"
+    // Read more about it on MDN:
+    // https://developer.mozilla.org/en-US/docs/Web/API/Performance
+    var getTime = typeof performance === 'function' ? performance.now : Date.now;
+    /*
+    For a pointer interaction, automatically scrolls certain scroll containers when the pointer
+    approaches the edge.
+
+    The caller must call start + handleMove + stop.
+    */
+    var AutoScroller = /** @class */ (function () {
+        function AutoScroller() {
+            var _this = this;
+            // options that can be set by caller
+            this.isEnabled = true;
+            this.scrollQuery = [window, '.fc-scroller'];
+            this.edgeThreshold = 50; // pixels
+            this.maxVelocity = 300; // pixels per second
+            // internal state
+            this.pointerScreenX = null;
+            this.pointerScreenY = null;
+            this.isAnimating = false;
+            this.scrollCaches = null;
+            // protect against the initial pointerdown being too close to an edge and starting the scroll
+            this.everMovedUp = false;
+            this.everMovedDown = false;
+            this.everMovedLeft = false;
+            this.everMovedRight = false;
+            this.animate = function () {
+                if (_this.isAnimating) { // wasn't cancelled between animation calls
+                    var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset);
+                    if (edge) {
+                        var now = getTime();
+                        _this.handleSide(edge, (now - _this.msSinceRequest) / 1000);
+                        _this.requestAnimation(now);
+                    }
+                    else {
+                        _this.isAnimating = false; // will stop animation
+                    }
+                }
+            };
+        }
+        AutoScroller.prototype.start = function (pageX, pageY, scrollStartEl) {
+            if (this.isEnabled) {
+                this.scrollCaches = this.buildCaches(scrollStartEl);
+                this.pointerScreenX = null;
+                this.pointerScreenY = null;
+                this.everMovedUp = false;
+                this.everMovedDown = false;
+                this.everMovedLeft = false;
+                this.everMovedRight = false;
+                this.handleMove(pageX, pageY);
+            }
+        };
+        AutoScroller.prototype.handleMove = function (pageX, pageY) {
+            if (this.isEnabled) {
+                var pointerScreenX = pageX - window.pageXOffset;
+                var pointerScreenY = pageY - window.pageYOffset;
+                var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
+                var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
+                if (yDelta < 0) {
+                    this.everMovedUp = true;
+                }
+                else if (yDelta > 0) {
+                    this.everMovedDown = true;
+                }
+                if (xDelta < 0) {
+                    this.everMovedLeft = true;
+                }
+                else if (xDelta > 0) {
+                    this.everMovedRight = true;
+                }
+                this.pointerScreenX = pointerScreenX;
+                this.pointerScreenY = pointerScreenY;
+                if (!this.isAnimating) {
+                    this.isAnimating = true;
+                    this.requestAnimation(getTime());
+                }
+            }
+        };
+        AutoScroller.prototype.stop = function () {
+            if (this.isEnabled) {
+                this.isAnimating = false; // will stop animation
+                for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+                    var scrollCache = _a[_i];
+                    scrollCache.destroy();
+                }
+                this.scrollCaches = null;
+            }
+        };
+        AutoScroller.prototype.requestAnimation = function (now) {
+            this.msSinceRequest = now;
+            requestAnimationFrame(this.animate);
+        };
+        AutoScroller.prototype.handleSide = function (edge, seconds) {
+            var scrollCache = edge.scrollCache;
+            var edgeThreshold = this.edgeThreshold;
+            var invDistance = edgeThreshold - edge.distance;
+            var velocity = // the closer to the edge, the faster we scroll
+             ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic
+                this.maxVelocity * seconds;
+            var sign = 1;
+            switch (edge.name) {
+                case 'left':
+                    sign = -1;
+                // falls through
+                case 'right':
+                    scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
+                    break;
+                case 'top':
+                    sign = -1;
+                // falls through
+                case 'bottom':
+                    scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
+                    break;
+            }
+        };
+        // left/top are relative to document topleft
+        AutoScroller.prototype.computeBestEdge = function (left, top) {
+            var edgeThreshold = this.edgeThreshold;
+            var bestSide = null;
+            var scrollCaches = this.scrollCaches || [];
+            for (var _i = 0, scrollCaches_1 = scrollCaches; _i < scrollCaches_1.length; _i++) {
+                var scrollCache = scrollCaches_1[_i];
+                var rect = scrollCache.clientRect;
+                var leftDist = left - rect.left;
+                var rightDist = rect.right - left;
+                var topDist = top - rect.top;
+                var bottomDist = rect.bottom - top;
+                // completely within the rect?
+                if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
+                    if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&
+                        (!bestSide || bestSide.distance > topDist)) {
+                        bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist };
+                    }
+                    if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&
+                        (!bestSide || bestSide.distance > bottomDist)) {
+                        bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist };
+                    }
+                    if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&
+                        (!bestSide || bestSide.distance > leftDist)) {
+                        bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist };
+                    }
+                    if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&
+                        (!bestSide || bestSide.distance > rightDist)) {
+                        bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist };
+                    }
+                }
+            }
+            return bestSide;
+        };
+        AutoScroller.prototype.buildCaches = function (scrollStartEl) {
+            return this.queryScrollEls(scrollStartEl).map(function (el) {
+                if (el === window) {
+                    return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls
+                }
+                return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls
+            });
+        };
+        AutoScroller.prototype.queryScrollEls = function (scrollStartEl) {
+            var els = [];
+            for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) {
+                var query = _a[_i];
+                if (typeof query === 'object') {
+                    els.push(query);
+                }
+                else {
+                    els.push.apply(els, Array.prototype.slice.call(getElRoot(scrollStartEl).querySelectorAll(query)));
+                }
+            }
+            return els;
+        };
+        return AutoScroller;
+    }());
+
+    /*
+    Monitors dragging on an element. Has a number of high-level features:
+    - minimum distance required before dragging
+    - minimum wait time ("delay") before dragging
+    - a mirror element that follows the pointer
+    */
+    var FeaturefulElementDragging = /** @class */ (function (_super) {
+        __extends(FeaturefulElementDragging, _super);
+        function FeaturefulElementDragging(containerEl, selector) {
+            var _this = _super.call(this, containerEl) || this;
+            _this.containerEl = containerEl;
+            // options that can be directly set by caller
+            // the caller can also set the PointerDragging's options as well
+            _this.delay = null;
+            _this.minDistance = 0;
+            _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag
+            _this.mirrorNeedsRevert = false;
+            _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup
+            _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation
+            _this.isDelayEnded = false;
+            _this.isDistanceSurpassed = false;
+            _this.delayTimeoutId = null;
+            _this.onPointerDown = function (ev) {
+                if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going
+                    _this.isInteracting = true;
+                    _this.isDelayEnded = false;
+                    _this.isDistanceSurpassed = false;
+                    preventSelection(document.body);
+                    preventContextMenu(document.body);
+                    // prevent links from being visited if there's an eventual drag.
+                    // also prevents selection in older browsers (maybe?).
+                    // not necessary for touch, besides, browser would complain about passiveness.
+                    if (!ev.isTouch) {
+                        ev.origEvent.preventDefault();
+                    }
+                    _this.emitter.trigger('pointerdown', ev);
+                    if (_this.isInteracting && // not destroyed via pointerdown handler
+                        !_this.pointer.shouldIgnoreMove) {
+                        // actions related to initiating dragstart+dragmove+dragend...
+                        _this.mirror.setIsVisible(false); // reset. caller must set-visible
+                        _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down
+                        _this.startDelay(ev);
+                        if (!_this.minDistance) {
+                            _this.handleDistanceSurpassed(ev);
+                        }
+                    }
+                }
+            };
+            _this.onPointerMove = function (ev) {
+                if (_this.isInteracting) {
+                    _this.emitter.trigger('pointermove', ev);
+                    if (!_this.isDistanceSurpassed) {
+                        var minDistance = _this.minDistance;
+                        var distanceSq = void 0; // current distance from the origin, squared
+                        var deltaX = ev.deltaX, deltaY = ev.deltaY;
+                        distanceSq = deltaX * deltaX + deltaY * deltaY;
+                        if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
+                            _this.handleDistanceSurpassed(ev);
+                        }
+                    }
+                    if (_this.isDragging) {
+                        // a real pointer move? (not one simulated by scrolling)
+                        if (ev.origEvent.type !== 'scroll') {
+                            _this.mirror.handleMove(ev.pageX, ev.pageY);
+                            _this.autoScroller.handleMove(ev.pageX, ev.pageY);
+                        }
+                        _this.emitter.trigger('dragmove', ev);
+                    }
+                }
+            };
+            _this.onPointerUp = function (ev) {
+                if (_this.isInteracting) {
+                    _this.isInteracting = false;
+                    allowSelection(document.body);
+                    allowContextMenu(document.body);
+                    _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert
+                    if (_this.isDragging) {
+                        _this.autoScroller.stop();
+                        _this.tryStopDrag(ev); // which will stop the mirror
+                    }
+                    if (_this.delayTimeoutId) {
+                        clearTimeout(_this.delayTimeoutId);
+                        _this.delayTimeoutId = null;
+                    }
+                }
+            };
+            var pointer = _this.pointer = new PointerDragging(containerEl);
+            pointer.emitter.on('pointerdown', _this.onPointerDown);
+            pointer.emitter.on('pointermove', _this.onPointerMove);
+            pointer.emitter.on('pointerup', _this.onPointerUp);
+            if (selector) {
+                pointer.selector = selector;
+            }
+            _this.mirror = new ElementMirror();
+            _this.autoScroller = new AutoScroller();
+            return _this;
+        }
+        FeaturefulElementDragging.prototype.destroy = function () {
+            this.pointer.destroy();
+            // HACK: simulate a pointer-up to end the current drag
+            // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire)
+            this.onPointerUp({});
+        };
+        FeaturefulElementDragging.prototype.startDelay = function (ev) {
+            var _this = this;
+            if (typeof this.delay === 'number') {
+                this.delayTimeoutId = setTimeout(function () {
+                    _this.delayTimeoutId = null;
+                    _this.handleDelayEnd(ev);
+                }, this.delay); // not assignable to number!
+            }
+            else {
+                this.handleDelayEnd(ev);
+            }
+        };
+        FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) {
+            this.isDelayEnded = true;
+            this.tryStartDrag(ev);
+        };
+        FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) {
+            this.isDistanceSurpassed = true;
+            this.tryStartDrag(ev);
+        };
+        FeaturefulElementDragging.prototype.tryStartDrag = function (ev) {
+            if (this.isDelayEnded && this.isDistanceSurpassed) {
+                if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
+                    this.isDragging = true;
+                    this.mirrorNeedsRevert = false;
+                    this.autoScroller.start(ev.pageX, ev.pageY, this.containerEl);
+                    this.emitter.trigger('dragstart', ev);
+                    if (this.touchScrollAllowed === false) {
+                        this.pointer.cancelTouchScroll();
+                    }
+                }
+            }
+        };
+        FeaturefulElementDragging.prototype.tryStopDrag = function (ev) {
+            // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events
+            // that come from the document to fire beforehand. much more convenient this way.
+            this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev));
+        };
+        FeaturefulElementDragging.prototype.stopDrag = function (ev) {
+            this.isDragging = false;
+            this.emitter.trigger('dragend', ev);
+        };
+        // fill in the implementations...
+        FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) {
+            this.pointer.shouldIgnoreMove = bool;
+        };
+        FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) {
+            this.mirror.setIsVisible(bool);
+        };
+        FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
+            this.mirrorNeedsRevert = bool;
+        };
+        FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) {
+            this.autoScroller.isEnabled = bool;
+        };
+        return FeaturefulElementDragging;
+    }(ElementDragging));
+
+    /*
+    When this class is instantiated, it records the offset of an element (relative to the document topleft),
+    and continues to monitor scrolling, updating the cached coordinates if it needs to.
+    Does not access the DOM after instantiation, so highly performant.
+
+    Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element
+    and an determine if a given point is inside the combined clipping rectangle.
+    */
+    var OffsetTracker = /** @class */ (function () {
+        function OffsetTracker(el) {
+            this.origRect = computeRect(el);
+            // will work fine for divs that have overflow:hidden
+            this.scrollCaches = getClippingParents(el).map(function (scrollEl) { return new ElementScrollGeomCache(scrollEl, true); });
+        }
+        OffsetTracker.prototype.destroy = function () {
+            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+                var scrollCache = _a[_i];
+                scrollCache.destroy();
+            }
+        };
+        OffsetTracker.prototype.computeLeft = function () {
+            var left = this.origRect.left;
+            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+                var scrollCache = _a[_i];
+                left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
+            }
+            return left;
+        };
+        OffsetTracker.prototype.computeTop = function () {
+            var top = this.origRect.top;
+            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+                var scrollCache = _a[_i];
+                top += scrollCache.origScrollTop - scrollCache.getScrollTop();
+            }
+            return top;
+        };
+        OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) {
+            var point = { left: pageX, top: pageY };
+            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
+                var scrollCache = _a[_i];
+                if (!isIgnoredClipping(scrollCache.getEventTarget()) &&
+                    !pointInsideRect(point, scrollCache.clientRect)) {
+                    return false;
+                }
+            }
+            return true;
+        };
+        return OffsetTracker;
+    }());
+    // certain clipping containers should never constrain interactions, like <html> and <body>
+    // https://github.com/fullcalendar/fullcalendar/issues/3615
+    function isIgnoredClipping(node) {
+        var tagName = node.tagName;
+        return tagName === 'HTML' || tagName === 'BODY';
+    }
+
+    /*
+    Tracks movement over multiple droppable areas (aka "hits")
+    that exist in one or more DateComponents.
+    Relies on an existing draggable.
+
+    emits:
+    - pointerdown
+    - dragstart
+    - hitchange - fires initially, even if not over a hit
+    - pointerup
+    - (hitchange - again, to null, if ended over a hit)
+    - dragend
+    */
+    var HitDragging = /** @class */ (function () {
+        function HitDragging(dragging, droppableStore) {
+            var _this = this;
+            // options that can be set by caller
+            this.useSubjectCenter = false;
+            this.requireInitial = true; // if doesn't start out on a hit, won't emit any events
+            this.initialHit = null;
+            this.movingHit = null;
+            this.finalHit = null; // won't ever be populated if shouldIgnoreMove
+            this.handlePointerDown = function (ev) {
+                var dragging = _this.dragging;
+                _this.initialHit = null;
+                _this.movingHit = null;
+                _this.finalHit = null;
+                _this.prepareHits();
+                _this.processFirstCoord(ev);
+                if (_this.initialHit || !_this.requireInitial) {
+                    dragging.setIgnoreMove(false);
+                    // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
+                    _this.emitter.trigger('pointerdown', ev);
+                }
+                else {
+                    dragging.setIgnoreMove(true);
+                }
+            };
+            this.handleDragStart = function (ev) {
+                _this.emitter.trigger('dragstart', ev);
+                _this.handleMove(ev, true); // force = fire even if initially null
+            };
+            this.handleDragMove = function (ev) {
+                _this.emitter.trigger('dragmove', ev);
+                _this.handleMove(ev);
+            };
+            this.handlePointerUp = function (ev) {
+                _this.releaseHits();
+                _this.emitter.trigger('pointerup', ev);
+            };
+            this.handleDragEnd = function (ev) {
+                if (_this.movingHit) {
+                    _this.emitter.trigger('hitupdate', null, true, ev);
+                }
+                _this.finalHit = _this.movingHit;
+                _this.movingHit = null;
+                _this.emitter.trigger('dragend', ev);
+            };
+            this.droppableStore = droppableStore;
+            dragging.emitter.on('pointerdown', this.handlePointerDown);
+            dragging.emitter.on('dragstart', this.handleDragStart);
+            dragging.emitter.on('dragmove', this.handleDragMove);
+            dragging.emitter.on('pointerup', this.handlePointerUp);
+            dragging.emitter.on('dragend', this.handleDragEnd);
+            this.dragging = dragging;
+            this.emitter = new Emitter();
+        }
+        // sets initialHit
+        // sets coordAdjust
+        HitDragging.prototype.processFirstCoord = function (ev) {
+            var origPoint = { left: ev.pageX, top: ev.pageY };
+            var adjustedPoint = origPoint;
+            var subjectEl = ev.subjectEl;
+            var subjectRect;
+            if (subjectEl instanceof HTMLElement) { // i.e. not a Document/ShadowRoot
+                subjectRect = computeRect(subjectEl);
+                adjustedPoint = constrainPoint(adjustedPoint, subjectRect);
+            }
+            var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
+            if (initialHit) {
+                if (this.useSubjectCenter && subjectRect) {
+                    var slicedSubjectRect = intersectRects(subjectRect, initialHit.rect);
+                    if (slicedSubjectRect) {
+                        adjustedPoint = getRectCenter(slicedSubjectRect);
+                    }
+                }
+                this.coordAdjust = diffPoints(adjustedPoint, origPoint);
+            }
+            else {
+                this.coordAdjust = { left: 0, top: 0 };
+            }
+        };
+        HitDragging.prototype.handleMove = function (ev, forceHandle) {
+            var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
+            if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
+                this.movingHit = hit;
+                this.emitter.trigger('hitupdate', hit, false, ev);
+            }
+        };
+        HitDragging.prototype.prepareHits = function () {
+            this.offsetTrackers = mapHash(this.droppableStore, function (interactionSettings) {
+                interactionSettings.component.prepareHits();
+                return new OffsetTracker(interactionSettings.el);
+            });
+        };
+        HitDragging.prototype.releaseHits = function () {
+            var offsetTrackers = this.offsetTrackers;
+            for (var id in offsetTrackers) {
+                offsetTrackers[id].destroy();
+            }
+            this.offsetTrackers = {};
+        };
+        HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) {
+            var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers;
+            var bestHit = null;
+            for (var id in droppableStore) {
+                var component = droppableStore[id].component;
+                var offsetTracker = offsetTrackers[id];
+                if (offsetTracker && // wasn't destroyed mid-drag
+                    offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
+                    var originLeft = offsetTracker.computeLeft();
+                    var originTop = offsetTracker.computeTop();
+                    var positionLeft = offsetLeft - originLeft;
+                    var positionTop = offsetTop - originTop;
+                    var origRect = offsetTracker.origRect;
+                    var width = origRect.right - origRect.left;
+                    var height = origRect.bottom - origRect.top;
+                    if (
+                    // must be within the element's bounds
+                    positionLeft >= 0 && positionLeft < width &&
+                        positionTop >= 0 && positionTop < height) {
+                        var hit = component.queryHit(positionLeft, positionTop, width, height);
+                        if (hit && (
+                        // make sure the hit is within activeRange, meaning it's not a dead cell
+                        rangeContainsRange(hit.dateProfile.activeRange, hit.dateSpan.range)) &&
+                            (!bestHit || hit.layer > bestHit.layer)) {
+                            hit.componentId = id;
+                            hit.context = component.context;
+                            // TODO: better way to re-orient rectangle
+                            hit.rect.left += originLeft;
+                            hit.rect.right += originLeft;
+                            hit.rect.top += originTop;
+                            hit.rect.bottom += originTop;
+                            bestHit = hit;
+                        }
+                    }
+                }
+            }
+            return bestHit;
+        };
+        return HitDragging;
+    }());
+    function isHitsEqual(hit0, hit1) {
+        if (!hit0 && !hit1) {
+            return true;
+        }
+        if (Boolean(hit0) !== Boolean(hit1)) {
+            return false;
+        }
+        return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan);
+    }
+
+    function buildDatePointApiWithContext(dateSpan, context) {
+        var props = {};
+        for (var _i = 0, _a = context.pluginHooks.datePointTransforms; _i < _a.length; _i++) {
+            var transform = _a[_i];
+            __assign(props, transform(dateSpan, context));
+        }
+        __assign(props, buildDatePointApi(dateSpan, context.dateEnv));
+        return props;
+    }
+    function buildDatePointApi(span, dateEnv) {
+        return {
+            date: dateEnv.toDate(span.range.start),
+            dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
+            allDay: span.allDay,
+        };
+    }
+
+    /*
+    Monitors when the user clicks on a specific date/time of a component.
+    A pointerdown+pointerup on the same "hit" constitutes a click.
+    */
+    var DateClicking = /** @class */ (function (_super) {
+        __extends(DateClicking, _super);
+        function DateClicking(settings) {
+            var _this = _super.call(this, settings) || this;
+            _this.handlePointerDown = function (pev) {
+                var dragging = _this.dragging;
+                var downEl = pev.origEvent.target;
+                // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired
+                dragging.setIgnoreMove(!_this.component.isValidDateDownEl(downEl));
+            };
+            // won't even fire if moving was ignored
+            _this.handleDragEnd = function (ev) {
+                var component = _this.component;
+                var pointer = _this.dragging.pointer;
+                if (!pointer.wasTouchScroll) {
+                    var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit;
+                    if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
+                        var context = component.context;
+                        var arg = __assign(__assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view });
+                        context.emitter.trigger('dateClick', arg);
+                    }
+                }
+            };
+            // we DO want to watch pointer moves because otherwise finalHit won't get populated
+            _this.dragging = new FeaturefulElementDragging(settings.el);
+            _this.dragging.autoScroller.isEnabled = false;
+            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
+            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
+            hitDragging.emitter.on('dragend', _this.handleDragEnd);
+            return _this;
+        }
+        DateClicking.prototype.destroy = function () {
+            this.dragging.destroy();
+        };
+        return DateClicking;
+    }(Interaction));
+
+    /*
+    Tracks when the user selects a portion of time of a component,
+    constituted by a drag over date cells, with a possible delay at the beginning of the drag.
+    */
+    var DateSelecting = /** @class */ (function (_super) {
+        __extends(DateSelecting, _super);
+        function DateSelecting(settings) {
+            var _this = _super.call(this, settings) || this;
+            _this.dragSelection = null;
+            _this.handlePointerDown = function (ev) {
+                var _a = _this, component = _a.component, dragging = _a.dragging;
+                var options = component.context.options;
+                var canSelect = options.selectable &&
+                    component.isValidDateDownEl(ev.origEvent.target);
+                // don't bother to watch expensive moves if component won't do selection
+                dragging.setIgnoreMove(!canSelect);
+                // if touch, require user to hold down
+                dragging.delay = ev.isTouch ? getComponentTouchDelay$1(component) : null;
+            };
+            _this.handleDragStart = function (ev) {
+                _this.component.context.calendarApi.unselect(ev); // unselect previous selections
+            };
+            _this.handleHitUpdate = function (hit, isFinal) {
+                var context = _this.component.context;
+                var dragSelection = null;
+                var isInvalid = false;
+                if (hit) {
+                    var initialHit = _this.hitDragging.initialHit;
+                    var disallowed = hit.componentId === initialHit.componentId
+                        && _this.isHitComboAllowed
+                        && !_this.isHitComboAllowed(initialHit, hit);
+                    if (!disallowed) {
+                        dragSelection = joinHitsIntoSelection(initialHit, hit, context.pluginHooks.dateSelectionTransformers);
+                    }
+                    if (!dragSelection || !isDateSelectionValid(dragSelection, hit.dateProfile, context)) {
+                        isInvalid = true;
+                        dragSelection = null;
+                    }
+                }
+                if (dragSelection) {
+                    context.dispatch({ type: 'SELECT_DATES', selection: dragSelection });
+                }
+                else if (!isFinal) { // only unselect if moved away while dragging
+                    context.dispatch({ type: 'UNSELECT_DATES' });
+                }
+                if (!isInvalid) {
+                    enableCursor();
+                }
+                else {
+                    disableCursor();
+                }
+                if (!isFinal) {
+                    _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging
+                }
+            };
+            _this.handlePointerUp = function (pev) {
+                if (_this.dragSelection) {
+                    // selection is already rendered, so just need to report selection
+                    triggerDateSelect(_this.dragSelection, pev, _this.component.context);
+                    _this.dragSelection = null;
+                }
+            };
+            var component = settings.component;
+            var options = component.context.options;
+            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
+            dragging.touchScrollAllowed = false;
+            dragging.minDistance = options.selectMinDistance || 0;
+            dragging.autoScroller.isEnabled = options.dragScroll;
+            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
+            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
+            hitDragging.emitter.on('dragstart', _this.handleDragStart);
+            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
+            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
+            return _this;
+        }
+        DateSelecting.prototype.destroy = function () {
+            this.dragging.destroy();
+        };
+        return DateSelecting;
+    }(Interaction));
+    function getComponentTouchDelay$1(component) {
+        var options = component.context.options;
+        var delay = options.selectLongPressDelay;
+        if (delay == null) {
+            delay = options.longPressDelay;
+        }
+        return delay;
+    }
+    function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
+        var dateSpan0 = hit0.dateSpan;
+        var dateSpan1 = hit1.dateSpan;
+        var ms = [
+            dateSpan0.range.start,
+            dateSpan0.range.end,
+            dateSpan1.range.start,
+            dateSpan1.range.end,
+        ];
+        ms.sort(compareNumbers);
+        var props = {};
+        for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) {
+            var transformer = dateSelectionTransformers_1[_i];
+            var res = transformer(hit0, hit1);
+            if (res === false) {
+                return null;
+            }
+            if (res) {
+                __assign(props, res);
+            }
+        }
+        props.range = { start: ms[0], end: ms[3] };
+        props.allDay = dateSpan0.allDay;
+        return props;
+    }
+
+    var EventDragging = /** @class */ (function (_super) {
+        __extends(EventDragging, _super);
+        function EventDragging(settings) {
+            var _this = _super.call(this, settings) || this;
+            // internal state
+            _this.subjectEl = null;
+            _this.subjectSeg = null; // the seg being selected/dragged
+            _this.isDragging = false;
+            _this.eventRange = null;
+            _this.relevantEvents = null; // the events being dragged
+            _this.receivingContext = null;
+            _this.validMutation = null;
+            _this.mutatedRelevantEvents = null;
+            _this.handlePointerDown = function (ev) {
+                var origTarget = ev.origEvent.target;
+                var _a = _this, component = _a.component, dragging = _a.dragging;
+                var mirror = dragging.mirror;
+                var options = component.context.options;
+                var initialContext = component.context;
+                _this.subjectEl = ev.subjectEl;
+                var subjectSeg = _this.subjectSeg = getElSeg(ev.subjectEl);
+                var eventRange = _this.eventRange = subjectSeg.eventRange;
+                var eventInstanceId = eventRange.instance.instanceId;
+                _this.relevantEvents = getRelevantEvents(initialContext.getCurrentData().eventStore, eventInstanceId);
+                dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance;
+                dragging.delay =
+                    // only do a touch delay if touch and this event hasn't been selected yet
+                    (ev.isTouch && eventInstanceId !== component.props.eventSelection) ?
+                        getComponentTouchDelay(component) :
+                        null;
+                if (options.fixedMirrorParent) {
+                    mirror.parentNode = options.fixedMirrorParent;
+                }
+                else {
+                    mirror.parentNode = elementClosest(origTarget, '.fc');
+                }
+                mirror.revertDuration = options.dragRevertDuration;
+                var isValid = component.isValidSegDownEl(origTarget) &&
+                    !elementClosest(origTarget, '.fc-event-resizer'); // NOT on a resizer
+                dragging.setIgnoreMove(!isValid);
+                // disable dragging for elements that are resizable (ie, selectable)
+                // but are not draggable
+                _this.isDragging = isValid &&
+                    ev.subjectEl.classList.contains('fc-event-draggable');
+            };
+            _this.handleDragStart = function (ev) {
+                var initialContext = _this.component.context;
+                var eventRange = _this.eventRange;
+                var eventInstanceId = eventRange.instance.instanceId;
+                if (ev.isTouch) {
+                    // need to select a different event?
+                    if (eventInstanceId !== _this.component.props.eventSelection) {
+                        initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId });
+                    }
+                }
+                else {
+                    // if now using mouse, but was previous touch interaction, clear selected event
+                    initialContext.dispatch({ type: 'UNSELECT_EVENT' });
+                }
+                if (_this.isDragging) {
+                    initialContext.calendarApi.unselect(ev); // unselect *date* selection
+                    initialContext.emitter.trigger('eventDragStart', {
+                        el: _this.subjectEl,
+                        event: new EventApi(initialContext, eventRange.def, eventRange.instance),
+                        jsEvent: ev.origEvent,
+                        view: initialContext.viewApi,
+                    });
+                }
+            };
+            _this.handleHitUpdate = function (hit, isFinal) {
+                if (!_this.isDragging) {
+                    return;
+                }
+                var relevantEvents = _this.relevantEvents;
+                var initialHit = _this.hitDragging.initialHit;
+                var initialContext = _this.component.context;
+                // states based on new hit
+                var receivingContext = null;
+                var mutation = null;
+                var mutatedRelevantEvents = null;
+                var isInvalid = false;
+                var interaction = {
+                    affectedEvents: relevantEvents,
+                    mutatedEvents: createEmptyEventStore(),
+                    isEvent: true,
+                };
+                if (hit) {
+                    receivingContext = hit.context;
+                    var receivingOptions = receivingContext.options;
+                    if (initialContext === receivingContext ||
+                        (receivingOptions.editable && receivingOptions.droppable)) {
+                        mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers);
+                        if (mutation) {
+                            mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext);
+                            interaction.mutatedEvents = mutatedRelevantEvents;
+                            if (!isInteractionValid(interaction, hit.dateProfile, receivingContext)) {
+                                isInvalid = true;
+                                mutation = null;
+                                mutatedRelevantEvents = null;
+                                interaction.mutatedEvents = createEmptyEventStore();
+                            }
+                        }
+                    }
+                    else {
+                        receivingContext = null;
+                    }
+                }
+                _this.displayDrag(receivingContext, interaction);
+                if (!isInvalid) {
+                    enableCursor();
+                }
+                else {
+                    disableCursor();
+                }
+                if (!isFinal) {
+                    if (initialContext === receivingContext && // TODO: write test for this
+                        isHitsEqual(initialHit, hit)) {
+                        mutation = null;
+                    }
+                    _this.dragging.setMirrorNeedsRevert(!mutation);
+                    // render the mirror if no already-rendered mirror
+                    // TODO: wish we could somehow wait for dispatch to guarantee render
+                    _this.dragging.setMirrorIsVisible(!hit || !getElRoot(_this.subjectEl).querySelector('.fc-event-mirror'));
+                    // assign states based on new hit
+                    _this.receivingContext = receivingContext;
+                    _this.validMutation = mutation;
+                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
+                }
+            };
+            _this.handlePointerUp = function () {
+                if (!_this.isDragging) {
+                    _this.cleanup(); // because handleDragEnd won't fire
+                }
+            };
+            _this.handleDragEnd = function (ev) {
+                if (_this.isDragging) {
+                    var initialContext_1 = _this.component.context;
+                    var initialView = initialContext_1.viewApi;
+                    var _a = _this, receivingContext_1 = _a.receivingContext, validMutation = _a.validMutation;
+                    var eventDef = _this.eventRange.def;
+                    var eventInstance = _this.eventRange.instance;
+                    var eventApi = new EventApi(initialContext_1, eventDef, eventInstance);
+                    var relevantEvents_1 = _this.relevantEvents;
+                    var mutatedRelevantEvents_1 = _this.mutatedRelevantEvents;
+                    var finalHit = _this.hitDragging.finalHit;
+                    _this.clearDrag(); // must happen after revert animation
+                    initialContext_1.emitter.trigger('eventDragStop', {
+                        el: _this.subjectEl,
+                        event: eventApi,
+                        jsEvent: ev.origEvent,
+                        view: initialView,
+                    });
+                    if (validMutation) {
+                        // dropped within same calendar
+                        if (receivingContext_1 === initialContext_1) {
+                            var updatedEventApi = new EventApi(initialContext_1, mutatedRelevantEvents_1.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents_1.instances[eventInstance.instanceId] : null);
+                            initialContext_1.dispatch({
+                                type: 'MERGE_EVENTS',
+                                eventStore: mutatedRelevantEvents_1,
+                            });
+                            var eventChangeArg = {
+                                oldEvent: eventApi,
+                                event: updatedEventApi,
+                                relatedEvents: buildEventApis(mutatedRelevantEvents_1, initialContext_1, eventInstance),
+                                revert: function () {
+                                    initialContext_1.dispatch({
+                                        type: 'MERGE_EVENTS',
+                                        eventStore: relevantEvents_1, // the pre-change data
+                                    });
+                                },
+                            };
+                            var transformed = {};
+                            for (var _i = 0, _b = initialContext_1.getCurrentData().pluginHooks.eventDropTransformers; _i < _b.length; _i++) {
+                                var transformer = _b[_i];
+                                __assign(transformed, transformer(validMutation, initialContext_1));
+                            }
+                            initialContext_1.emitter.trigger('eventDrop', __assign(__assign(__assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView }));
+                            initialContext_1.emitter.trigger('eventChange', eventChangeArg);
+                            // dropped in different calendar
+                        }
+                        else if (receivingContext_1) {
+                            var eventRemoveArg = {
+                                event: eventApi,
+                                relatedEvents: buildEventApis(relevantEvents_1, initialContext_1, eventInstance),
+                                revert: function () {
+                                    initialContext_1.dispatch({
+                                        type: 'MERGE_EVENTS',
+                                        eventStore: relevantEvents_1,
+                                    });
+                                },
+                            };
+                            initialContext_1.emitter.trigger('eventLeave', __assign(__assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView }));
+                            initialContext_1.dispatch({
+                                type: 'REMOVE_EVENTS',
+                                eventStore: relevantEvents_1,
+                            });
+                            initialContext_1.emitter.trigger('eventRemove', eventRemoveArg);
+                            var addedEventDef = mutatedRelevantEvents_1.defs[eventDef.defId];
+                            var addedEventInstance = mutatedRelevantEvents_1.instances[eventInstance.instanceId];
+                            var addedEventApi = new EventApi(receivingContext_1, addedEventDef, addedEventInstance);
+                            receivingContext_1.dispatch({
+                                type: 'MERGE_EVENTS',
+                                eventStore: mutatedRelevantEvents_1,
+                            });
+                            var eventAddArg = {
+                                event: addedEventApi,
+                                relatedEvents: buildEventApis(mutatedRelevantEvents_1, receivingContext_1, addedEventInstance),
+                                revert: function () {
+                                    receivingContext_1.dispatch({
+                                        type: 'REMOVE_EVENTS',
+                                        eventStore: mutatedRelevantEvents_1,
+                                    });
+                                },
+                            };
+                            receivingContext_1.emitter.trigger('eventAdd', eventAddArg);
+                            if (ev.isTouch) {
+                                receivingContext_1.dispatch({
+                                    type: 'SELECT_EVENT',
+                                    eventInstanceId: eventInstance.instanceId,
+                                });
+                            }
+                            receivingContext_1.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext_1)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.context.viewApi }));
+                            receivingContext_1.emitter.trigger('eventReceive', __assign(__assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.context.viewApi }));
+                        }
+                    }
+                    else {
+                        initialContext_1.emitter.trigger('_noEventDrop');
+                    }
+                }
+                _this.cleanup();
+            };
+            var component = _this.component;
+            var options = component.context.options;
+            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
+            dragging.pointer.selector = EventDragging.SELECTOR;
+            dragging.touchScrollAllowed = false;
+            dragging.autoScroller.isEnabled = options.dragScroll;
+            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsStore);
+            hitDragging.useSubjectCenter = settings.useEventCenter;
+            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
+            hitDragging.emitter.on('dragstart', _this.handleDragStart);
+            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
+            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
+            hitDragging.emitter.on('dragend', _this.handleDragEnd);
+            return _this;
+        }
+        EventDragging.prototype.destroy = function () {
+            this.dragging.destroy();
+        };
+        // render a drag state on the next receivingCalendar
+        EventDragging.prototype.displayDrag = function (nextContext, state) {
+            var initialContext = this.component.context;
+            var prevContext = this.receivingContext;
+            // does the previous calendar need to be cleared?
+            if (prevContext && prevContext !== nextContext) {
+                // does the initial calendar need to be cleared?
+                // if so, don't clear all the way. we still need to to hide the affectedEvents
+                if (prevContext === initialContext) {
+                    prevContext.dispatch({
+                        type: 'SET_EVENT_DRAG',
+                        state: {
+                            affectedEvents: state.affectedEvents,
+                            mutatedEvents: createEmptyEventStore(),
+                            isEvent: true,
+                        },
+                    });
+                    // completely clear the old calendar if it wasn't the initial
+                }
+                else {
+                    prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
+                }
+            }
+            if (nextContext) {
+                nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state });
+            }
+        };
+        EventDragging.prototype.clearDrag = function () {
+            var initialCalendar = this.component.context;
+            var receivingContext = this.receivingContext;
+            if (receivingContext) {
+                receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
+            }
+            // the initial calendar might have an dummy drag state from displayDrag
+            if (initialCalendar !== receivingContext) {
+                initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
+            }
+        };
+        EventDragging.prototype.cleanup = function () {
+            this.subjectSeg = null;
+            this.isDragging = false;
+            this.eventRange = null;
+            this.relevantEvents = null;
+            this.receivingContext = null;
+            this.validMutation = null;
+            this.mutatedRelevantEvents = null;
+        };
+        // TODO: test this in IE11
+        // QUESTION: why do we need it on the resizable???
+        EventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable';
+        return EventDragging;
+    }(Interaction));
+    function computeEventMutation(hit0, hit1, massagers) {
+        var dateSpan0 = hit0.dateSpan;
+        var dateSpan1 = hit1.dateSpan;
+        var date0 = dateSpan0.range.start;
+        var date1 = dateSpan1.range.start;
+        var standardProps = {};
+        if (dateSpan0.allDay !== dateSpan1.allDay) {
+            standardProps.allDay = dateSpan1.allDay;
+            standardProps.hasEnd = hit1.context.options.allDayMaintainDuration;
+            if (dateSpan1.allDay) {
+                // means date1 is already start-of-day,
+                // but date0 needs to be converted
+                date0 = startOfDay(date0);
+            }
+        }
+        var delta = diffDates(date0, date1, hit0.context.dateEnv, hit0.componentId === hit1.componentId ?
+            hit0.largeUnit :
+            null);
+        if (delta.milliseconds) { // has hours/minutes/seconds
+            standardProps.allDay = false;
+        }
+        var mutation = {
+            datesDelta: delta,
+            standardProps: standardProps,
+        };
+        for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) {
+            var massager = massagers_1[_i];
+            massager(mutation, hit0, hit1);
+        }
+        return mutation;
+    }
+    function getComponentTouchDelay(component) {
+        var options = component.context.options;
+        var delay = options.eventLongPressDelay;
+        if (delay == null) {
+            delay = options.longPressDelay;
+        }
+        return delay;
+    }
+
+    var EventResizing = /** @class */ (function (_super) {
+        __extends(EventResizing, _super);
+        function EventResizing(settings) {
+            var _this = _super.call(this, settings) || this;
+            // internal state
+            _this.draggingSegEl = null;
+            _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?
+            _this.eventRange = null;
+            _this.relevantEvents = null;
+            _this.validMutation = null;
+            _this.mutatedRelevantEvents = null;
+            _this.handlePointerDown = function (ev) {
+                var component = _this.component;
+                var segEl = _this.querySegEl(ev);
+                var seg = getElSeg(segEl);
+                var eventRange = _this.eventRange = seg.eventRange;
+                _this.dragging.minDistance = component.context.options.eventDragMinDistance;
+                // if touch, need to be working with a selected event
+                _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) ||
+                    (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId));
+            };
+            _this.handleDragStart = function (ev) {
+                var context = _this.component.context;
+                var eventRange = _this.eventRange;
+                _this.relevantEvents = getRelevantEvents(context.getCurrentData().eventStore, _this.eventRange.instance.instanceId);
+                var segEl = _this.querySegEl(ev);
+                _this.draggingSegEl = segEl;
+                _this.draggingSeg = getElSeg(segEl);
+                context.calendarApi.unselect();
+                context.emitter.trigger('eventResizeStart', {
+                    el: segEl,
+                    event: new EventApi(context, eventRange.def, eventRange.instance),
+                    jsEvent: ev.origEvent,
+                    view: context.viewApi,
+                });
+            };
+            _this.handleHitUpdate = function (hit, isFinal, ev) {
+                var context = _this.component.context;
+                var relevantEvents = _this.relevantEvents;
+                var initialHit = _this.hitDragging.initialHit;
+                var eventInstance = _this.eventRange.instance;
+                var mutation = null;
+                var mutatedRelevantEvents = null;
+                var isInvalid = false;
+                var interaction = {
+                    affectedEvents: relevantEvents,
+                    mutatedEvents: createEmptyEventStore(),
+                    isEvent: true,
+                };
+                if (hit) {
+                    var disallowed = hit.componentId === initialHit.componentId
+                        && _this.isHitComboAllowed
+                        && !_this.isHitComboAllowed(initialHit, hit);
+                    if (!disallowed) {
+                        mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range);
+                    }
+                }
+                if (mutation) {
+                    mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context);
+                    interaction.mutatedEvents = mutatedRelevantEvents;
+                    if (!isInteractionValid(interaction, hit.dateProfile, context)) {
+                        isInvalid = true;
+                        mutation = null;
+                        mutatedRelevantEvents = null;
+                        interaction.mutatedEvents = null;
+                    }
+                }
+                if (mutatedRelevantEvents) {
+                    context.dispatch({
+                        type: 'SET_EVENT_RESIZE',
+                        state: interaction,
+                    });
+                }
+                else {
+                    context.dispatch({ type: 'UNSET_EVENT_RESIZE' });
+                }
+                if (!isInvalid) {
+                    enableCursor();
+                }
+                else {
+                    disableCursor();
+                }
+                if (!isFinal) {
+                    if (mutation && isHitsEqual(initialHit, hit)) {
+                        mutation = null;
+                    }
+                    _this.validMutation = mutation;
+                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
+                }
+            };
+            _this.handleDragEnd = function (ev) {
+                var context = _this.component.context;
+                var eventDef = _this.eventRange.def;
+                var eventInstance = _this.eventRange.instance;
+                var eventApi = new EventApi(context, eventDef, eventInstance);
+                var relevantEvents = _this.relevantEvents;
+                var mutatedRelevantEvents = _this.mutatedRelevantEvents;
+                context.emitter.trigger('eventResizeStop', {
+                    el: _this.draggingSegEl,
+                    event: eventApi,
+                    jsEvent: ev.origEvent,
+                    view: context.viewApi,
+                });
+                if (_this.validMutation) {
+                    var updatedEventApi = new EventApi(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);
+                    context.dispatch({
+                        type: 'MERGE_EVENTS',
+                        eventStore: mutatedRelevantEvents,
+                    });
+                    var eventChangeArg = {
+                        oldEvent: eventApi,
+                        event: updatedEventApi,
+                        relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance),
+                        revert: function () {
+                            context.dispatch({
+                                type: 'MERGE_EVENTS',
+                                eventStore: relevantEvents, // the pre-change events
+                            });
+                        },
+                    };
+                    context.emitter.trigger('eventResize', __assign(__assign({}, eventChangeArg), { el: _this.draggingSegEl, startDelta: _this.validMutation.startDelta || createDuration(0), endDelta: _this.validMutation.endDelta || createDuration(0), jsEvent: ev.origEvent, view: context.viewApi }));
+                    context.emitter.trigger('eventChange', eventChangeArg);
+                }
+                else {
+                    context.emitter.trigger('_noEventResize');
+                }
+                // reset all internal state
+                _this.draggingSeg = null;
+                _this.relevantEvents = null;
+                _this.validMutation = null;
+                // okay to keep eventInstance around. useful to set it in handlePointerDown
+            };
+            var component = settings.component;
+            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
+            dragging.pointer.selector = '.fc-event-resizer';
+            dragging.touchScrollAllowed = false;
+            dragging.autoScroller.isEnabled = component.context.options.dragScroll;
+            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
+            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
+            hitDragging.emitter.on('dragstart', _this.handleDragStart);
+            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
+            hitDragging.emitter.on('dragend', _this.handleDragEnd);
+            return _this;
+        }
+        EventResizing.prototype.destroy = function () {
+            this.dragging.destroy();
+        };
+        EventResizing.prototype.querySegEl = function (ev) {
+            return elementClosest(ev.subjectEl, '.fc-event');
+        };
+        return EventResizing;
+    }(Interaction));
+    function computeMutation(hit0, hit1, isFromStart, instanceRange) {
+        var dateEnv = hit0.context.dateEnv;
+        var date0 = hit0.dateSpan.range.start;
+        var date1 = hit1.dateSpan.range.start;
+        var delta = diffDates(date0, date1, dateEnv, hit0.largeUnit);
+        if (isFromStart) {
+            if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
+                return { startDelta: delta };
+            }
+        }
+        else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
+            return { endDelta: delta };
+        }
+        return null;
+    }
+
+    var UnselectAuto = /** @class */ (function () {
+        function UnselectAuto(context) {
+            var _this = this;
+            this.context = context;
+            this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system
+            this.matchesCancel = false;
+            this.matchesEvent = false;
+            this.onSelect = function (selectInfo) {
+                if (selectInfo.jsEvent) {
+                    _this.isRecentPointerDateSelect = true;
+                }
+            };
+            this.onDocumentPointerDown = function (pev) {
+                var unselectCancel = _this.context.options.unselectCancel;
+                var downEl = getEventTargetViaRoot(pev.origEvent);
+                _this.matchesCancel = !!elementClosest(downEl, unselectCancel);
+                _this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR); // interaction started on an event?
+            };
+            this.onDocumentPointerUp = function (pev) {
+                var context = _this.context;
+                var documentPointer = _this.documentPointer;
+                var calendarState = context.getCurrentData();
+                // touch-scrolling should never unfocus any type of selection
+                if (!documentPointer.wasTouchScroll) {
+                    if (calendarState.dateSelection && // an existing date selection?
+                        !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?
+                    ) {
+                        var unselectAuto = context.options.unselectAuto;
+                        if (unselectAuto && (!unselectAuto || !_this.matchesCancel)) {
+                            context.calendarApi.unselect(pev);
+                        }
+                    }
+                    if (calendarState.eventSelection && // an existing event selected?
+                        !_this.matchesEvent // interaction DIDN'T start on an event
+                    ) {
+                        context.dispatch({ type: 'UNSELECT_EVENT' });
+                    }
+                }
+                _this.isRecentPointerDateSelect = false;
+            };
+            var documentPointer = this.documentPointer = new PointerDragging(document);
+            documentPointer.shouldIgnoreMove = true;
+            documentPointer.shouldWatchScroll = false;
+            documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown);
+            documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);
+            /*
+            TODO: better way to know about whether there was a selection with the pointer
+            */
+            context.emitter.on('select', this.onSelect);
+        }
+        UnselectAuto.prototype.destroy = function () {
+            this.context.emitter.off('select', this.onSelect);
+            this.documentPointer.destroy();
+        };
+        return UnselectAuto;
+    }());
+
+    var OPTION_REFINERS$3 = {
+        fixedMirrorParent: identity,
+    };
+    var LISTENER_REFINERS = {
+        dateClick: identity,
+        eventDragStart: identity,
+        eventDragStop: identity,
+        eventDrop: identity,
+        eventResizeStart: identity,
+        eventResizeStop: identity,
+        eventResize: identity,
+        drop: identity,
+        eventReceive: identity,
+        eventLeave: identity,
+    };
+
+    /*
+    Given an already instantiated draggable object for one-or-more elements,
+    Interprets any dragging as an attempt to drag an events that lives outside
+    of a calendar onto a calendar.
+    */
+    var ExternalElementDragging = /** @class */ (function () {
+        function ExternalElementDragging(dragging, suppliedDragMeta) {
+            var _this = this;
+            this.receivingContext = null;
+            this.droppableEvent = null; // will exist for all drags, even if create:false
+            this.suppliedDragMeta = null;
+            this.dragMeta = null;
+            this.handleDragStart = function (ev) {
+                _this.dragMeta = _this.buildDragMeta(ev.subjectEl);
+            };
+            this.handleHitUpdate = function (hit, isFinal, ev) {
+                var dragging = _this.hitDragging.dragging;
+                var receivingContext = null;
+                var droppableEvent = null;
+                var isInvalid = false;
+                var interaction = {
+                    affectedEvents: createEmptyEventStore(),
+                    mutatedEvents: createEmptyEventStore(),
+                    isEvent: _this.dragMeta.create,
+                };
+                if (hit) {
+                    receivingContext = hit.context;
+                    if (_this.canDropElOnCalendar(ev.subjectEl, receivingContext)) {
+                        droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingContext);
+                        interaction.mutatedEvents = eventTupleToStore(droppableEvent);
+                        isInvalid = !isInteractionValid(interaction, hit.dateProfile, receivingContext);
+                        if (isInvalid) {
+                            interaction.mutatedEvents = createEmptyEventStore();
+                            droppableEvent = null;
+                        }
+                    }
+                }
+                _this.displayDrag(receivingContext, interaction);
+                // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)
+                // TODO: wish we could somehow wait for dispatch to guarantee render
+                dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror'));
+                if (!isInvalid) {
+                    enableCursor();
+                }
+                else {
+                    disableCursor();
+                }
+                if (!isFinal) {
+                    dragging.setMirrorNeedsRevert(!droppableEvent);
+                    _this.receivingContext = receivingContext;
+                    _this.droppableEvent = droppableEvent;
+                }
+            };
+            this.handleDragEnd = function (pev) {
+                var _a = _this, receivingContext = _a.receivingContext, droppableEvent = _a.droppableEvent;
+                _this.clearDrag();
+                if (receivingContext && droppableEvent) {
+                    var finalHit = _this.hitDragging.finalHit;
+                    var finalView = finalHit.context.viewApi;
+                    var dragMeta = _this.dragMeta;
+                    receivingContext.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView }));
+                    if (dragMeta.create) {
+                        var addingEvents_1 = eventTupleToStore(droppableEvent);
+                        receivingContext.dispatch({
+                            type: 'MERGE_EVENTS',
+                            eventStore: addingEvents_1,
+                        });
+                        if (pev.isTouch) {
+                            receivingContext.dispatch({
+                                type: 'SELECT_EVENT',
+                                eventInstanceId: droppableEvent.instance.instanceId,
+                            });
+                        }
+                        // signal that an external event landed
+                        receivingContext.emitter.trigger('eventReceive', {
+                            event: new EventApi(receivingContext, droppableEvent.def, droppableEvent.instance),
+                            relatedEvents: [],
+                            revert: function () {
+                                receivingContext.dispatch({
+                                    type: 'REMOVE_EVENTS',
+                                    eventStore: addingEvents_1,
+                                });
+                            },
+                            draggedEl: pev.subjectEl,
+                            view: finalView,
+                        });
+                    }
+                }
+                _this.receivingContext = null;
+                _this.droppableEvent = null;
+            };
+            var hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore);
+            hitDragging.requireInitial = false; // will start outside of a component
+            hitDragging.emitter.on('dragstart', this.handleDragStart);
+            hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
+            hitDragging.emitter.on('dragend', this.handleDragEnd);
+            this.suppliedDragMeta = suppliedDragMeta;
+        }
+        ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) {
+            if (typeof this.suppliedDragMeta === 'object') {
+                return parseDragMeta(this.suppliedDragMeta);
+            }
+            if (typeof this.suppliedDragMeta === 'function') {
+                return parseDragMeta(this.suppliedDragMeta(subjectEl));
+            }
+            return getDragMetaFromEl(subjectEl);
+        };
+        ExternalElementDragging.prototype.displayDrag = function (nextContext, state) {
+            var prevContext = this.receivingContext;
+            if (prevContext && prevContext !== nextContext) {
+                prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
+            }
+            if (nextContext) {
+                nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state });
+            }
+        };
+        ExternalElementDragging.prototype.clearDrag = function () {
+            if (this.receivingContext) {
+                this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
+            }
+        };
+        ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingContext) {
+            var dropAccept = receivingContext.options.dropAccept;
+            if (typeof dropAccept === 'function') {
+                return dropAccept.call(receivingContext.calendarApi, el);
+            }
+            if (typeof dropAccept === 'string' && dropAccept) {
+                return Boolean(elementMatches(el, dropAccept));
+            }
+            return true;
+        };
+        return ExternalElementDragging;
+    }());
+    // Utils for computing event store from the DragMeta
+    // ----------------------------------------------------------------------------------------------------
+    function computeEventForDateSpan(dateSpan, dragMeta, context) {
+        var defProps = __assign({}, dragMeta.leftoverProps);
+        for (var _i = 0, _a = context.pluginHooks.externalDefTransforms; _i < _a.length; _i++) {
+            var transform = _a[_i];
+            __assign(defProps, transform(dateSpan, dragMeta));
+        }
+        var _b = refineEventDef(defProps, context), refined = _b.refined, extra = _b.extra;
+        var def = parseEventDef(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd
+        context);
+        var start = dateSpan.range.start;
+        // only rely on time info if drop zone is all-day,
+        // otherwise, we already know the time
+        if (dateSpan.allDay && dragMeta.startTime) {
+            start = context.dateEnv.add(start, dragMeta.startTime);
+        }
+        var end = dragMeta.duration ?
+            context.dateEnv.add(start, dragMeta.duration) :
+            getDefaultEventEnd(dateSpan.allDay, start, context);
+        var instance = createEventInstance(def.defId, { start: start, end: end });
+        return { def: def, instance: instance };
+    }
+    // Utils for extracting data from element
+    // ----------------------------------------------------------------------------------------------------
+    function getDragMetaFromEl(el) {
+        var str = getEmbeddedElData(el, 'event');
+        var obj = str ?
+            JSON.parse(str) :
+            { create: false }; // if no embedded data, assume no event creation
+        return parseDragMeta(obj);
+    }
+    config.dataAttrPrefix = '';
+    function getEmbeddedElData(el, name) {
+        var prefix = config.dataAttrPrefix;
+        var prefixedName = (prefix ? prefix + '-' : '') + name;
+        return el.getAttribute('data-' + prefixedName) || '';
+    }
+
+    /*
+    Makes an element (that is *external* to any calendar) draggable.
+    Can pass in data that determines how an event will be created when dropped onto a calendar.
+    Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.
+    */
+    var ExternalDraggable = /** @class */ (function () {
+        function ExternalDraggable(el, settings) {
+            var _this = this;
+            if (settings === void 0) { settings = {}; }
+            this.handlePointerDown = function (ev) {
+                var dragging = _this.dragging;
+                var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay;
+                dragging.minDistance =
+                    minDistance != null ?
+                        minDistance :
+                        (ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance);
+                dragging.delay =
+                    ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv
+                        (longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay) :
+                        0;
+            };
+            this.handleDragStart = function (ev) {
+                if (ev.isTouch &&
+                    _this.dragging.delay &&
+                    ev.subjectEl.classList.contains('fc-event')) {
+                    _this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected');
+                }
+            };
+            this.settings = settings;
+            var dragging = this.dragging = new FeaturefulElementDragging(el);
+            dragging.touchScrollAllowed = false;
+            if (settings.itemSelector != null) {
+                dragging.pointer.selector = settings.itemSelector;
+            }
+            if (settings.appendTo != null) {
+                dragging.mirror.parentNode = settings.appendTo; // TODO: write tests
+            }
+            dragging.emitter.on('pointerdown', this.handlePointerDown);
+            dragging.emitter.on('dragstart', this.handleDragStart);
+            new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new
+        }
+        ExternalDraggable.prototype.destroy = function () {
+            this.dragging.destroy();
+        };
+        return ExternalDraggable;
+    }());
+
+    /*
+    Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements.
+    The third-party system is responsible for drawing the visuals effects of the drag.
+    This class simply monitors for pointer movements and fires events.
+    It also has the ability to hide the moving element (the "mirror") during the drag.
+    */
+    var InferredElementDragging = /** @class */ (function (_super) {
+        __extends(InferredElementDragging, _super);
+        function InferredElementDragging(containerEl) {
+            var _this = _super.call(this, containerEl) || this;
+            _this.shouldIgnoreMove = false;
+            _this.mirrorSelector = '';
+            _this.currentMirrorEl = null;
+            _this.handlePointerDown = function (ev) {
+                _this.emitter.trigger('pointerdown', ev);
+                if (!_this.shouldIgnoreMove) {
+                    // fire dragstart right away. does not support delay or min-distance
+                    _this.emitter.trigger('dragstart', ev);
+                }
+            };
+            _this.handlePointerMove = function (ev) {
+                if (!_this.shouldIgnoreMove) {
+                    _this.emitter.trigger('dragmove', ev);
+                }
+            };
+            _this.handlePointerUp = function (ev) {
+                _this.emitter.trigger('pointerup', ev);
+                if (!_this.shouldIgnoreMove) {
+                    // fire dragend right away. does not support a revert animation
+                    _this.emitter.trigger('dragend', ev);
+                }
+            };
+            var pointer = _this.pointer = new PointerDragging(containerEl);
+            pointer.emitter.on('pointerdown', _this.handlePointerDown);
+            pointer.emitter.on('pointermove', _this.handlePointerMove);
+            pointer.emitter.on('pointerup', _this.handlePointerUp);
+            return _this;
+        }
+        InferredElementDragging.prototype.destroy = function () {
+            this.pointer.destroy();
+        };
+        InferredElementDragging.prototype.setIgnoreMove = function (bool) {
+            this.shouldIgnoreMove = bool;
+        };
+        InferredElementDragging.prototype.setMirrorIsVisible = function (bool) {
+            if (bool) {
+                // restore a previously hidden element.
+                // use the reference in case the selector class has already been removed.
+                if (this.currentMirrorEl) {
+                    this.currentMirrorEl.style.visibility = '';
+                    this.currentMirrorEl = null;
+                }
+            }
+            else {
+                var mirrorEl = this.mirrorSelector
+                    // TODO: somehow query FullCalendars WITHIN shadow-roots
+                    ? document.querySelector(this.mirrorSelector)
+                    : null;
+                if (mirrorEl) {
+                    this.currentMirrorEl = mirrorEl;
+                    mirrorEl.style.visibility = 'hidden';
+                }
+            }
+        };
+        return InferredElementDragging;
+    }(ElementDragging));
+
+    /*
+    Bridges third-party drag-n-drop systems with FullCalendar.
+    Must be instantiated and destroyed by caller.
+    */
+    var ThirdPartyDraggable = /** @class */ (function () {
+        function ThirdPartyDraggable(containerOrSettings, settings) {
+            var containerEl = document;
+            if (
+            // wish we could just test instanceof EventTarget, but doesn't work in IE11
+            containerOrSettings === document ||
+                containerOrSettings instanceof Element) {
+                containerEl = containerOrSettings;
+                settings = settings || {};
+            }
+            else {
+                settings = (containerOrSettings || {});
+            }
+            var dragging = this.dragging = new InferredElementDragging(containerEl);
+            if (typeof settings.itemSelector === 'string') {
+                dragging.pointer.selector = settings.itemSelector;
+            }
+            else if (containerEl === document) {
+                dragging.pointer.selector = '[data-event]';
+            }
+            if (typeof settings.mirrorSelector === 'string') {
+                dragging.mirrorSelector = settings.mirrorSelector;
+            }
+            new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new
+        }
+        ThirdPartyDraggable.prototype.destroy = function () {
+            this.dragging.destroy();
+        };
+        return ThirdPartyDraggable;
+    }());
+
+    var interactionPlugin = createPlugin({
+        componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing],
+        calendarInteractions: [UnselectAuto],
+        elementDraggingImpl: FeaturefulElementDragging,
+        optionRefiners: OPTION_REFINERS$3,
+        listenerRefiners: LISTENER_REFINERS,
+    });
+
+    /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
+    ----------------------------------------------------------------------------------------------------------------------*/
+    // It is a manager for a Table subcomponent, which does most of the heavy lifting.
+    // It is responsible for managing width/height.
+    var TableView = /** @class */ (function (_super) {
+        __extends(TableView, _super);
+        function TableView() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.headerElRef = createRef();
+            return _this;
+        }
+        TableView.prototype.renderSimpleLayout = function (headerRowContent, bodyContent) {
+            var _a = this, props = _a.props, context = _a.context;
+            var sections = [];
+            var stickyHeaderDates = getStickyHeaderDates(context.options);
+            if (headerRowContent) {
+                sections.push({
+                    type: 'header',
+                    key: 'header',
+                    isSticky: stickyHeaderDates,
+                    chunk: {
+                        elRef: this.headerElRef,
+                        tableClassName: 'fc-col-header',
+                        rowContent: headerRowContent,
+                    },
+                });
+            }
+            sections.push({
+                type: 'body',
+                key: 'body',
+                liquid: true,
+                chunk: { content: bodyContent },
+            });
+            return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') },
+                createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [] /* TODO: make optional? */, sections: sections }))); }));
+        };
+        TableView.prototype.renderHScrollLayout = function (headerRowContent, bodyContent, colCnt, dayMinWidth) {
+            var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
+            if (!ScrollGrid) {
+                throw new Error('No ScrollGrid implementation');
+            }
+            var _a = this, props = _a.props, context = _a.context;
+            var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options);
+            var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options);
+            var sections = [];
+            if (headerRowContent) {
+                sections.push({
+                    type: 'header',
+                    key: 'header',
+                    isSticky: stickyHeaderDates,
+                    chunks: [{
+                            key: 'main',
+                            elRef: this.headerElRef,
+                            tableClassName: 'fc-col-header',
+                            rowContent: headerRowContent,
+                        }],
+                });
+            }
+            sections.push({
+                type: 'body',
+                key: 'body',
+                liquid: true,
+                chunks: [{
+                        key: 'main',
+                        content: bodyContent,
+                    }],
+            });
+            if (stickyFooterScrollbar) {
+                sections.push({
+                    type: 'footer',
+                    key: 'footer',
+                    isSticky: true,
+                    chunks: [{
+                            key: 'main',
+                            content: renderScrollShim,
+                        }],
+                });
+            }
+            return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') },
+                createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections }))); }));
+        };
+        return TableView;
+    }(DateComponent));
+
+    function splitSegsByRow(segs, rowCnt) {
+        var byRow = [];
+        for (var i = 0; i < rowCnt; i += 1) {
+            byRow[i] = [];
+        }
+        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
+            var seg = segs_1[_i];
+            byRow[seg.row].push(seg);
+        }
+        return byRow;
+    }
+    function splitSegsByFirstCol(segs, colCnt) {
+        var byCol = [];
+        for (var i = 0; i < colCnt; i += 1) {
+            byCol[i] = [];
+        }
+        for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
+            var seg = segs_2[_i];
+            byCol[seg.firstCol].push(seg);
+        }
+        return byCol;
+    }
+    function splitInteractionByRow(ui, rowCnt) {
+        var byRow = [];
+        if (!ui) {
+            for (var i = 0; i < rowCnt; i += 1) {
+                byRow[i] = null;
+            }
+        }
+        else {
+            for (var i = 0; i < rowCnt; i += 1) {
+                byRow[i] = {
+                    affectedInstances: ui.affectedInstances,
+                    isEvent: ui.isEvent,
+                    segs: [],
+                };
+            }
+            for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
+                var seg = _a[_i];
+                byRow[seg.row].segs.push(seg);
+            }
+        }
+        return byRow;
+    }
+
+    var TableCellTop = /** @class */ (function (_super) {
+        __extends(TableCellTop, _super);
+        function TableCellTop() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        TableCellTop.prototype.render = function () {
+            var props = this.props;
+            var navLinkAttrs = buildNavLinkAttrs(this.context, props.date);
+            return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, defaultContent: renderTopInner }, function (innerElRef, innerContent) { return ((innerContent || props.forceDayTop) && (createElement("div", { className: "fc-daygrid-day-top", ref: innerElRef },
+                createElement("a", __assign({ id: props.dayNumberId, className: "fc-daygrid-day-number" }, navLinkAttrs), innerContent || createElement(Fragment, null, "\u00A0"))))); }));
+        };
+        return TableCellTop;
+    }(BaseComponent));
+    function renderTopInner(props) {
+        return props.dayNumberText;
+    }
+
+    var DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({
+        hour: 'numeric',
+        minute: '2-digit',
+        omitZeroMinute: true,
+        meridiem: 'narrow',
+    });
+    function hasListItemDisplay(seg) {
+        var display = seg.eventRange.ui.display;
+        return display === 'list-item' || (display === 'auto' &&
+            !seg.eventRange.def.allDay &&
+            seg.firstCol === seg.lastCol && // can't be multi-day
+            seg.isStart && // "
+            seg.isEnd // "
+        );
+    }
+
+    var TableBlockEvent = /** @class */ (function (_super) {
+        __extends(TableBlockEvent, _super);
+        function TableBlockEvent() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        TableBlockEvent.prototype.render = function () {
+            var props = this.props;
+            return (createElement(StandardEvent, __assign({}, props, { extraClassNames: ['fc-daygrid-event', 'fc-daygrid-block-event', 'fc-h-event'], defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, defaultDisplayEventEnd: props.defaultDisplayEventEnd, disableResizing: !props.seg.eventRange.def.allDay })));
+        };
+        return TableBlockEvent;
+    }(BaseComponent));
+
+    var TableListItemEvent = /** @class */ (function (_super) {
+        __extends(TableListItemEvent, _super);
+        function TableListItemEvent() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        TableListItemEvent.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            var timeFormat = context.options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT;
+            var timeText = buildSegTimeText(props.seg, timeFormat, context, true, props.defaultDisplayEventEnd);
+            return (createElement(EventRoot, { seg: props.seg, timeText: timeText, defaultContent: renderInnerContent$2, isDragging: props.isDragging, isResizing: false, isDateSelecting: false, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent) { return ( // we don't use styles!
+            createElement("a", __assign({ className: ['fc-daygrid-event', 'fc-daygrid-dot-event'].concat(classNames).join(' '), ref: rootElRef }, getSegAnchorAttrs(props.seg, context)), innerContent)); }));
+        };
+        return TableListItemEvent;
+    }(BaseComponent));
+    function renderInnerContent$2(innerProps) {
+        return (createElement(Fragment, null,
+            createElement("div", { className: "fc-daygrid-event-dot", style: { borderColor: innerProps.borderColor || innerProps.backgroundColor } }),
+            innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)),
+            createElement("div", { className: "fc-event-title" }, innerProps.event.title || createElement(Fragment, null, "\u00A0"))));
+    }
+
+    var TableCellMoreLink = /** @class */ (function (_super) {
+        __extends(TableCellMoreLink, _super);
+        function TableCellMoreLink() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.compileSegs = memoize(compileSegs);
+            return _this;
+        }
+        TableCellMoreLink.prototype.render = function () {
+            var props = this.props;
+            var _a = this.compileSegs(props.singlePlacements), allSegs = _a.allSegs, invisibleSegs = _a.invisibleSegs;
+            return (createElement(MoreLinkRoot, { dateProfile: props.dateProfile, todayRange: props.todayRange, allDayDate: props.allDayDate, moreCnt: props.moreCnt, allSegs: allSegs, hiddenSegs: invisibleSegs, alignmentElRef: props.alignmentElRef, alignGridTop: props.alignGridTop, extraDateSpan: props.extraDateSpan, popoverContent: function () {
+                    var isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) ||
+                        (props.eventResize ? props.eventResize.affectedInstances : null) ||
+                        {};
+                    return (createElement(Fragment, null, allSegs.map(function (seg) {
+                        var instanceId = seg.eventRange.instance.instanceId;
+                        return (createElement("div", { className: "fc-daygrid-event-harness", key: instanceId, style: {
+                                visibility: isForcedInvisible[instanceId] ? 'hidden' : '',
+                            } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange))))));
+                    })));
+                } }, function (rootElRef, classNames, innerElRef, innerContent, handleClick, title, isExpanded, popoverId) { return (createElement("a", __assign({ ref: rootElRef, className: ['fc-daygrid-more-link'].concat(classNames).join(' '), title: title, "aria-expanded": isExpanded, "aria-controls": popoverId }, createAriaClickAttrs(handleClick)), innerContent)); }));
+        };
+        return TableCellMoreLink;
+    }(BaseComponent));
+    function compileSegs(singlePlacements) {
+        var allSegs = [];
+        var invisibleSegs = [];
+        for (var _i = 0, singlePlacements_1 = singlePlacements; _i < singlePlacements_1.length; _i++) {
+            var placement = singlePlacements_1[_i];
+            allSegs.push(placement.seg);
+            if (!placement.isVisible) {
+                invisibleSegs.push(placement.seg);
+            }
+        }
+        return { allSegs: allSegs, invisibleSegs: invisibleSegs };
+    }
+
+    var DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: 'narrow' });
+    var TableCell = /** @class */ (function (_super) {
+        __extends(TableCell, _super);
+        function TableCell() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.rootElRef = createRef();
+            _this.state = {
+                dayNumberId: getUniqueDomId(),
+            };
+            _this.handleRootEl = function (el) {
+                setRef(_this.rootElRef, el);
+                setRef(_this.props.elRef, el);
+            };
+            return _this;
+        }
+        TableCell.prototype.render = function () {
+            var _a = this, context = _a.context, props = _a.props, state = _a.state, rootElRef = _a.rootElRef;
+            var date = props.date, dateProfile = props.dateProfile;
+            var navLinkAttrs = buildNavLinkAttrs(context, date, 'week');
+            return (createElement(DayCellRoot, { date: date, dateProfile: dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, elRef: this.handleRootEl }, function (dayElRef, dayClassNames, rootDataAttrs, isDisabled) { return (createElement("td", __assign({ ref: dayElRef, role: "gridcell", className: ['fc-daygrid-day'].concat(dayClassNames, props.extraClassNames || []).join(' ') }, rootDataAttrs, props.extraDataAttrs, (props.showDayNumber ? { 'aria-labelledby': state.dayNumberId } : {})),
+                createElement("div", { className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", ref: props.innerElRef /* different from hook system! RENAME */ },
+                    props.showWeekNumber && (createElement(WeekNumberRoot, { date: date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT$1 }, function (weekElRef, weekClassNames, innerElRef, innerContent) { return (createElement("a", __assign({ ref: weekElRef, className: ['fc-daygrid-week-number'].concat(weekClassNames).join(' ') }, navLinkAttrs), innerContent)); })),
+                    !isDisabled && (createElement(TableCellTop, { date: date, dateProfile: dateProfile, showDayNumber: props.showDayNumber, dayNumberId: state.dayNumberId, forceDayTop: props.forceDayTop, todayRange: props.todayRange, extraHookProps: props.extraHookProps })),
+                    createElement("div", { className: "fc-daygrid-day-events", ref: props.fgContentElRef },
+                        props.fgContent,
+                        createElement("div", { className: "fc-daygrid-day-bottom", style: { marginTop: props.moreMarginTop } },
+                            createElement(TableCellMoreLink, { allDayDate: date, singlePlacements: props.singlePlacements, moreCnt: props.moreCnt, alignmentElRef: rootElRef, alignGridTop: !props.showDayNumber, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange }))),
+                    createElement("div", { className: "fc-daygrid-day-bg" }, props.bgContent)))); }));
+        };
+        return TableCell;
+    }(DateComponent));
+
+    function computeFgSegPlacement(segs, // assumed already sorted
+    dayMaxEvents, dayMaxEventRows, strictOrder, eventInstanceHeights, maxContentHeight, cells) {
+        var hierarchy = new DayGridSegHierarchy();
+        hierarchy.allowReslicing = true;
+        hierarchy.strictOrder = strictOrder;
+        if (dayMaxEvents === true || dayMaxEventRows === true) {
+            hierarchy.maxCoord = maxContentHeight;
+            hierarchy.hiddenConsumes = true;
+        }
+        else if (typeof dayMaxEvents === 'number') {
+            hierarchy.maxStackCnt = dayMaxEvents;
+        }
+        else if (typeof dayMaxEventRows === 'number') {
+            hierarchy.maxStackCnt = dayMaxEventRows;
+            hierarchy.hiddenConsumes = true;
+        }
+        // create segInputs only for segs with known heights
+        var segInputs = [];
+        var unknownHeightSegs = [];
+        for (var i = 0; i < segs.length; i += 1) {
+            var seg = segs[i];
+            var instanceId = seg.eventRange.instance.instanceId;
+            var eventHeight = eventInstanceHeights[instanceId];
+            if (eventHeight != null) {
+                segInputs.push({
+                    index: i,
+                    thickness: eventHeight,
+                    span: {
+                        start: seg.firstCol,
+                        end: seg.lastCol + 1,
+                    },
+                });
+            }
+            else {
+                unknownHeightSegs.push(seg);
+            }
+        }
+        var hiddenEntries = hierarchy.addSegs(segInputs);
+        var segRects = hierarchy.toRects();
+        var _a = placeRects(segRects, segs, cells), singleColPlacements = _a.singleColPlacements, multiColPlacements = _a.multiColPlacements, leftoverMargins = _a.leftoverMargins;
+        var moreCnts = [];
+        var moreMarginTops = [];
+        // add segs with unknown heights
+        for (var _i = 0, unknownHeightSegs_1 = unknownHeightSegs; _i < unknownHeightSegs_1.length; _i++) {
+            var seg = unknownHeightSegs_1[_i];
+            multiColPlacements[seg.firstCol].push({
+                seg: seg,
+                isVisible: false,
+                isAbsolute: true,
+                absoluteTop: 0,
+                marginTop: 0,
+            });
+            for (var col = seg.firstCol; col <= seg.lastCol; col += 1) {
+                singleColPlacements[col].push({
+                    seg: resliceSeg(seg, col, col + 1, cells),
+                    isVisible: false,
+                    isAbsolute: false,
+                    absoluteTop: 0,
+                    marginTop: 0,
+                });
+            }
+        }
+        // add the hidden entries
+        for (var col = 0; col < cells.length; col += 1) {
+            moreCnts.push(0);
+        }
+        for (var _b = 0, hiddenEntries_1 = hiddenEntries; _b < hiddenEntries_1.length; _b++) {
+            var hiddenEntry = hiddenEntries_1[_b];
+            var seg = segs[hiddenEntry.index];
+            var hiddenSpan = hiddenEntry.span;
+            multiColPlacements[hiddenSpan.start].push({
+                seg: resliceSeg(seg, hiddenSpan.start, hiddenSpan.end, cells),
+                isVisible: false,
+                isAbsolute: true,
+                absoluteTop: 0,
+                marginTop: 0,
+            });
+            for (var col = hiddenSpan.start; col < hiddenSpan.end; col += 1) {
+                moreCnts[col] += 1;
+                singleColPlacements[col].push({
+                    seg: resliceSeg(seg, col, col + 1, cells),
+                    isVisible: false,
+                    isAbsolute: false,
+                    absoluteTop: 0,
+                    marginTop: 0,
+                });
+            }
+        }
+        // deal with leftover margins
+        for (var col = 0; col < cells.length; col += 1) {
+            moreMarginTops.push(leftoverMargins[col]);
+        }
+        return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, moreCnts: moreCnts, moreMarginTops: moreMarginTops };
+    }
+    // rects ordered by top coord, then left
+    function placeRects(allRects, segs, cells) {
+        var rectsByEachCol = groupRectsByEachCol(allRects, cells.length);
+        var singleColPlacements = [];
+        var multiColPlacements = [];
+        var leftoverMargins = [];
+        for (var col = 0; col < cells.length; col += 1) {
+            var rects = rectsByEachCol[col];
+            // compute all static segs in singlePlacements
+            var singlePlacements = [];
+            var currentHeight = 0;
+            var currentMarginTop = 0;
+            for (var _i = 0, rects_1 = rects; _i < rects_1.length; _i++) {
+                var rect = rects_1[_i];
+                var seg = segs[rect.index];
+                singlePlacements.push({
+                    seg: resliceSeg(seg, col, col + 1, cells),
+                    isVisible: true,
+                    isAbsolute: false,
+                    absoluteTop: rect.levelCoord,
+                    marginTop: rect.levelCoord - currentHeight,
+                });
+                currentHeight = rect.levelCoord + rect.thickness;
+            }
+            // compute mixed static/absolute segs in multiPlacements
+            var multiPlacements = [];
+            currentHeight = 0;
+            currentMarginTop = 0;
+            for (var _a = 0, rects_2 = rects; _a < rects_2.length; _a++) {
+                var rect = rects_2[_a];
+                var seg = segs[rect.index];
+                var isAbsolute = rect.span.end - rect.span.start > 1; // multi-column?
+                var isFirstCol = rect.span.start === col;
+                currentMarginTop += rect.levelCoord - currentHeight; // amount of space since bottom of previous seg
+                currentHeight = rect.levelCoord + rect.thickness; // height will now be bottom of current seg
+                if (isAbsolute) {
+                    currentMarginTop += rect.thickness;
+                    if (isFirstCol) {
+                        multiPlacements.push({
+                            seg: resliceSeg(seg, rect.span.start, rect.span.end, cells),
+                            isVisible: true,
+                            isAbsolute: true,
+                            absoluteTop: rect.levelCoord,
+                            marginTop: 0,
+                        });
+                    }
+                }
+                else if (isFirstCol) {
+                    multiPlacements.push({
+                        seg: resliceSeg(seg, rect.span.start, rect.span.end, cells),
+                        isVisible: true,
+                        isAbsolute: false,
+                        absoluteTop: rect.levelCoord,
+                        marginTop: currentMarginTop, // claim the margin
+                    });
+                    currentMarginTop = 0;
+                }
+            }
+            singleColPlacements.push(singlePlacements);
+            multiColPlacements.push(multiPlacements);
+            leftoverMargins.push(currentMarginTop);
+        }
+        return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, leftoverMargins: leftoverMargins };
+    }
+    function groupRectsByEachCol(rects, colCnt) {
+        var rectsByEachCol = [];
+        for (var col = 0; col < colCnt; col += 1) {
+            rectsByEachCol.push([]);
+        }
+        for (var _i = 0, rects_3 = rects; _i < rects_3.length; _i++) {
+            var rect = rects_3[_i];
+            for (var col = rect.span.start; col < rect.span.end; col += 1) {
+                rectsByEachCol[col].push(rect);
+            }
+        }
+        return rectsByEachCol;
+    }
+    function resliceSeg(seg, spanStart, spanEnd, cells) {
+        if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) {
+            return seg;
+        }
+        var eventRange = seg.eventRange;
+        var origRange = eventRange.range;
+        var slicedRange = intersectRanges(origRange, {
+            start: cells[spanStart].date,
+            end: addDays(cells[spanEnd - 1].date, 1),
+        });
+        return __assign(__assign({}, seg), { firstCol: spanStart, lastCol: spanEnd - 1, eventRange: {
+                def: eventRange.def,
+                ui: __assign(__assign({}, eventRange.ui), { durationEditable: false }),
+                instance: eventRange.instance,
+                range: slicedRange,
+            }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() });
+    }
+    var DayGridSegHierarchy = /** @class */ (function (_super) {
+        __extends(DayGridSegHierarchy, _super);
+        function DayGridSegHierarchy() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            // config
+            _this.hiddenConsumes = false;
+            // allows us to keep hidden entries in the hierarchy so they take up space
+            _this.forceHidden = {};
+            return _this;
+        }
+        DayGridSegHierarchy.prototype.addSegs = function (segInputs) {
+            var _this = this;
+            var hiddenSegs = _super.prototype.addSegs.call(this, segInputs);
+            var entriesByLevel = this.entriesByLevel;
+            var excludeHidden = function (entry) { return !_this.forceHidden[buildEntryKey(entry)]; };
+            // remove the forced-hidden segs
+            for (var level = 0; level < entriesByLevel.length; level += 1) {
+                entriesByLevel[level] = entriesByLevel[level].filter(excludeHidden);
+            }
+            return hiddenSegs;
+        };
+        DayGridSegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) {
+            var _a = this, entriesByLevel = _a.entriesByLevel, forceHidden = _a.forceHidden;
+            var touchingEntry = insertion.touchingEntry, touchingLevel = insertion.touchingLevel, touchingLateral = insertion.touchingLateral;
+            if (this.hiddenConsumes && touchingEntry) {
+                var touchingEntryId = buildEntryKey(touchingEntry);
+                // if not already hidden
+                if (!forceHidden[touchingEntryId]) {
+                    if (this.allowReslicing) {
+                        var placeholderEntry = __assign(__assign({}, touchingEntry), { span: intersectSpans(touchingEntry.span, entry.span) });
+                        var placeholderEntryId = buildEntryKey(placeholderEntry);
+                        forceHidden[placeholderEntryId] = true;
+                        entriesByLevel[touchingLevel][touchingLateral] = placeholderEntry; // replace touchingEntry with our placeholder
+                        this.splitEntry(touchingEntry, entry, hiddenEntries); // split up the touchingEntry, reinsert it
+                    }
+                    else {
+                        forceHidden[touchingEntryId] = true;
+                        hiddenEntries.push(touchingEntry);
+                    }
+                }
+            }
+            return _super.prototype.handleInvalidInsertion.call(this, insertion, entry, hiddenEntries);
+        };
+        return DayGridSegHierarchy;
+    }(SegHierarchy));
+
+    var TableRow = /** @class */ (function (_super) {
+        __extends(TableRow, _super);
+        function TableRow() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.cellElRefs = new RefMap(); // the <td>
+            _this.frameElRefs = new RefMap(); // the fc-daygrid-day-frame
+            _this.fgElRefs = new RefMap(); // the fc-daygrid-day-events
+            _this.segHarnessRefs = new RefMap(); // indexed by "instanceId:firstCol"
+            _this.rootElRef = createRef();
+            _this.state = {
+                framePositions: null,
+                maxContentHeight: null,
+                eventInstanceHeights: {},
+            };
+            return _this;
+        }
+        TableRow.prototype.render = function () {
+            var _this = this;
+            var _a = this, props = _a.props, state = _a.state, context = _a.context;
+            var options = context.options;
+            var colCnt = props.cells.length;
+            var businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt);
+            var bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt);
+            var highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt);
+            var mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt);
+            var _b = computeFgSegPlacement(sortEventSegs(props.fgEventSegs, options.eventOrder), props.dayMaxEvents, props.dayMaxEventRows, options.eventOrderStrict, state.eventInstanceHeights, state.maxContentHeight, props.cells), singleColPlacements = _b.singleColPlacements, multiColPlacements = _b.multiColPlacements, moreCnts = _b.moreCnts, moreMarginTops = _b.moreMarginTops;
+            var isForcedInvisible = // TODO: messy way to compute this
+             (props.eventDrag && props.eventDrag.affectedInstances) ||
+                (props.eventResize && props.eventResize.affectedInstances) ||
+                {};
+            return (createElement("tr", { ref: this.rootElRef, role: "row" },
+                props.renderIntro && props.renderIntro(),
+                props.cells.map(function (cell, col) {
+                    var normalFgNodes = _this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible);
+                    var mirrorFgNodes = _this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false);
+                    return (createElement(TableCell, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), innerElRef: _this.frameElRefs.createRef(cell.key) /* FF <td> problem, but okay to use for left/right. TODO: rename prop */, dateProfile: props.dateProfile, date: cell.date, showDayNumber: props.showDayNumbers, showWeekNumber: props.showWeekNumbers && col === 0, forceDayTop: props.showWeekNumbers /* even displaying weeknum for row, not necessarily day */, todayRange: props.todayRange, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, moreCnt: moreCnts[col], moreMarginTop: moreMarginTops[col], singlePlacements: singleColPlacements[col], fgContentElRef: _this.fgElRefs.createRef(cell.key), fgContent: ( // Fragment scopes the keys
+                        createElement(Fragment, null,
+                            createElement(Fragment, null, normalFgNodes),
+                            createElement(Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys
+                        createElement(Fragment, null,
+                            _this.renderFillSegs(highlightSegsByCol[col], 'highlight'),
+                            _this.renderFillSegs(businessHoursByCol[col], 'non-business'),
+                            _this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))) }));
+                })));
+        };
+        TableRow.prototype.componentDidMount = function () {
+            this.updateSizing(true);
+        };
+        TableRow.prototype.componentDidUpdate = function (prevProps, prevState) {
+            var currentProps = this.props;
+            this.updateSizing(!isPropsEqual(prevProps, currentProps));
+        };
+        TableRow.prototype.getHighlightSegs = function () {
+            var props = this.props;
+            if (props.eventDrag && props.eventDrag.segs.length) { // messy check
+                return props.eventDrag.segs;
+            }
+            if (props.eventResize && props.eventResize.segs.length) { // messy check
+                return props.eventResize.segs;
+            }
+            return props.dateSelectionSegs;
+        };
+        TableRow.prototype.getMirrorSegs = function () {
+            var props = this.props;
+            if (props.eventResize && props.eventResize.segs.length) { // messy check
+                return props.eventResize.segs;
+            }
+            return [];
+        };
+        TableRow.prototype.renderFgSegs = function (col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) {
+            var context = this.context;
+            var eventSelection = this.props.eventSelection;
+            var framePositions = this.state.framePositions;
+            var defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1
+            var isMirror = isDragging || isResizing || isDateSelecting;
+            var nodes = [];
+            if (framePositions) {
+                for (var _i = 0, segPlacements_1 = segPlacements; _i < segPlacements_1.length; _i++) {
+                    var placement = segPlacements_1[_i];
+                    var seg = placement.seg;
+                    var instanceId = seg.eventRange.instance.instanceId;
+                    var key = instanceId + ':' + col;
+                    var isVisible = placement.isVisible && !isForcedInvisible[instanceId];
+                    var isAbsolute = placement.isAbsolute;
+                    var left = '';
+                    var right = '';
+                    if (isAbsolute) {
+                        if (context.isRtl) {
+                            right = 0;
+                            left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol];
+                        }
+                        else {
+                            left = 0;
+                            right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol];
+                        }
+                    }
+                    /*
+                    known bug: events that are force to be list-item but span multiple days still take up space in later columns
+                    todo: in print view, for multi-day events, don't display title within non-start/end segs
+                    */
+                    nodes.push(createElement("div", { className: 'fc-daygrid-event-harness' + (isAbsolute ? ' fc-daygrid-event-harness-abs' : ''), key: key, ref: isMirror ? null : this.segHarnessRefs.createRef(key), style: {
+                            visibility: isVisible ? '' : 'hidden',
+                            marginTop: isAbsolute ? '' : placement.marginTop,
+                            top: isAbsolute ? placement.absoluteTop : '',
+                            left: left,
+                            right: right,
+                        } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange))))));
+                }
+            }
+            return nodes;
+        };
+        TableRow.prototype.renderFillSegs = function (segs, fillType) {
+            var isRtl = this.context.isRtl;
+            var todayRange = this.props.todayRange;
+            var framePositions = this.state.framePositions;
+            var nodes = [];
+            if (framePositions) {
+                for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
+                    var seg = segs_1[_i];
+                    var leftRightCss = isRtl ? {
+                        right: 0,
+                        left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol],
+                    } : {
+                        left: 0,
+                        right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol],
+                    };
+                    nodes.push(createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-daygrid-bg-harness", style: leftRightCss }, fillType === 'bg-event' ?
+                        createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, todayRange))) :
+                        renderFill(fillType)));
+                }
+            }
+            return createElement.apply(void 0, __spreadArray([Fragment, {}], nodes));
+        };
+        TableRow.prototype.updateSizing = function (isExternalSizingChange) {
+            var _a = this, props = _a.props, frameElRefs = _a.frameElRefs;
+            if (!props.forPrint &&
+                props.clientWidth !== null // positioning ready?
+            ) {
+                if (isExternalSizingChange) {
+                    var frameEls = props.cells.map(function (cell) { return frameElRefs.currentMap[cell.key]; });
+                    if (frameEls.length) {
+                        var originEl = this.rootElRef.current;
+                        this.setState({
+                            framePositions: new PositionCache(originEl, frameEls, true, // isHorizontal
+                            false),
+                        });
+                    }
+                }
+                var oldInstanceHeights = this.state.eventInstanceHeights;
+                var newInstanceHeights = this.queryEventInstanceHeights();
+                var limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;
+                this.safeSetState({
+                    // HACK to prevent oscillations of events being shown/hidden from max-event-rows
+                    // Essentially, once you compute an element's height, never null-out.
+                    // TODO: always display all events, as visibility:hidden?
+                    eventInstanceHeights: __assign(__assign({}, oldInstanceHeights), newInstanceHeights),
+                    maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null,
+                });
+            }
+        };
+        TableRow.prototype.queryEventInstanceHeights = function () {
+            var segElMap = this.segHarnessRefs.currentMap;
+            var eventInstanceHeights = {};
+            // get the max height amongst instance segs
+            for (var key in segElMap) {
+                var height = Math.round(segElMap[key].getBoundingClientRect().height);
+                var instanceId = key.split(':')[0]; // deconstruct how renderFgSegs makes the key
+                eventInstanceHeights[instanceId] = Math.max(eventInstanceHeights[instanceId] || 0, height);
+            }
+            return eventInstanceHeights;
+        };
+        TableRow.prototype.computeMaxContentHeight = function () {
+            var firstKey = this.props.cells[0].key;
+            var cellEl = this.cellElRefs.currentMap[firstKey];
+            var fcContainerEl = this.fgElRefs.currentMap[firstKey];
+            return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top;
+        };
+        TableRow.prototype.getCellEls = function () {
+            var elMap = this.cellElRefs.currentMap;
+            return this.props.cells.map(function (cell) { return elMap[cell.key]; });
+        };
+        return TableRow;
+    }(DateComponent));
+    TableRow.addStateEquality({
+        eventInstanceHeights: isPropsEqual,
+    });
+    function buildMirrorPlacements(mirrorSegs, colPlacements) {
+        if (!mirrorSegs.length) {
+            return [];
+        }
+        var topsByInstanceId = buildAbsoluteTopHash(colPlacements); // TODO: cache this at first render?
+        return mirrorSegs.map(function (seg) { return ({
+            seg: seg,
+            isVisible: true,
+            isAbsolute: true,
+            absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId],
+            marginTop: 0,
+        }); });
+    }
+    function buildAbsoluteTopHash(colPlacements) {
+        var topsByInstanceId = {};
+        for (var _i = 0, colPlacements_1 = colPlacements; _i < colPlacements_1.length; _i++) {
+            var placements = colPlacements_1[_i];
+            for (var _a = 0, placements_1 = placements; _a < placements_1.length; _a++) {
+                var placement = placements_1[_a];
+                topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop;
+            }
+        }
+        return topsByInstanceId;
+    }
+
+    var Table = /** @class */ (function (_super) {
+        __extends(Table, _super);
+        function Table() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.splitBusinessHourSegs = memoize(splitSegsByRow);
+            _this.splitBgEventSegs = memoize(splitSegsByRow);
+            _this.splitFgEventSegs = memoize(splitSegsByRow);
+            _this.splitDateSelectionSegs = memoize(splitSegsByRow);
+            _this.splitEventDrag = memoize(splitInteractionByRow);
+            _this.splitEventResize = memoize(splitInteractionByRow);
+            _this.rowRefs = new RefMap();
+            _this.handleRootEl = function (rootEl) {
+                _this.rootEl = rootEl;
+                if (rootEl) {
+                    _this.context.registerInteractiveComponent(_this, {
+                        el: rootEl,
+                        isHitComboAllowed: _this.props.isHitComboAllowed,
+                    });
+                }
+                else {
+                    _this.context.unregisterInteractiveComponent(_this);
+                }
+            };
+            return _this;
+        }
+        Table.prototype.render = function () {
+            var _this = this;
+            var props = this.props;
+            var dateProfile = props.dateProfile, dayMaxEventRows = props.dayMaxEventRows, dayMaxEvents = props.dayMaxEvents, expandRows = props.expandRows;
+            var rowCnt = props.cells.length;
+            var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt);
+            var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt);
+            var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt);
+            var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt);
+            var eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt);
+            var eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt);
+            var limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true;
+            // if rows can't expand to fill fixed height, can't do balanced-height event limit
+            // TODO: best place to normalize these options?
+            if (limitViaBalanced && !expandRows) {
+                limitViaBalanced = false;
+                dayMaxEventRows = null;
+                dayMaxEvents = null;
+            }
+            var classNames = [
+                'fc-daygrid-body',
+                limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced',
+                expandRows ? '' : 'fc-daygrid-body-natural', // will height of one row depend on the others?
+            ];
+            return (createElement("div", { className: classNames.join(' '), ref: this.handleRootEl, style: {
+                    // these props are important to give this wrapper correct dimensions for interactions
+                    // TODO: if we set it here, can we avoid giving to inner tables?
+                    width: props.clientWidth,
+                    minWidth: props.tableMinWidth,
+                } },
+                createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement(Fragment, null,
+                    createElement("table", { role: "presentation", className: "fc-scrollgrid-sync-table", style: {
+                            width: props.clientWidth,
+                            minWidth: props.tableMinWidth,
+                            height: expandRows ? props.clientHeight : '',
+                        } },
+                        props.colGroupNode,
+                        createElement("tbody", { role: "presentation" }, props.cells.map(function (cells, row) { return (createElement(TableRow, { ref: _this.rowRefs.createRef(row), key: cells.length
+                                ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */
+                                : row // in case there are no cells (like when resource view is loading)
+                            , showDayNumbers: rowCnt > 1, showWeekNumbers: props.showWeekNumbers, todayRange: todayRange, dateProfile: dateProfile, cells: cells, renderIntro: props.renderRowIntro, businessHourSegs: businessHourSegsByRow[row], eventSelection: props.eventSelection, bgEventSegs: bgEventSegsByRow[row].filter(isSegAllDay) /* hack */, fgEventSegs: fgEventSegsByRow[row], dateSelectionSegs: dateSelectionSegsByRow[row], eventDrag: eventDragByRow[row], eventResize: eventResizeByRow[row], dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint })); }))))); })));
+        };
+        // Hit System
+        // ----------------------------------------------------------------------------------------------------
+        Table.prototype.prepareHits = function () {
+            this.rowPositions = new PositionCache(this.rootEl, this.rowRefs.collect().map(function (rowObj) { return rowObj.getCellEls()[0]; }), // first cell el in each row. TODO: not optimal
+            false, true);
+            this.colPositions = new PositionCache(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row
+            true, // horizontal
+            false);
+        };
+        Table.prototype.queryHit = function (positionLeft, positionTop) {
+            var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions;
+            var col = colPositions.leftToIndex(positionLeft);
+            var row = rowPositions.topToIndex(positionTop);
+            if (row != null && col != null) {
+                var cell = this.props.cells[row][col];
+                return {
+                    dateProfile: this.props.dateProfile,
+                    dateSpan: __assign({ range: this.getCellRange(row, col), allDay: true }, cell.extraDateSpan),
+                    dayEl: this.getCellEl(row, col),
+                    rect: {
+                        left: colPositions.lefts[col],
+                        right: colPositions.rights[col],
+                        top: rowPositions.tops[row],
+                        bottom: rowPositions.bottoms[row],
+                    },
+                    layer: 0,
+                };
+            }
+            return null;
+        };
+        Table.prototype.getCellEl = function (row, col) {
+            return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal
+        };
+        Table.prototype.getCellRange = function (row, col) {
+            var start = this.props.cells[row][col].date;
+            var end = addDays(start, 1);
+            return { start: start, end: end };
+        };
+        return Table;
+    }(DateComponent));
+    function isSegAllDay(seg) {
+        return seg.eventRange.def.allDay;
+    }
+
+    var DayTableSlicer = /** @class */ (function (_super) {
+        __extends(DayTableSlicer, _super);
+        function DayTableSlicer() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.forceDayIfListItem = true;
+            return _this;
+        }
+        DayTableSlicer.prototype.sliceRange = function (dateRange, dayTableModel) {
+            return dayTableModel.sliceRange(dateRange);
+        };
+        return DayTableSlicer;
+    }(Slicer));
+
+    var DayTable = /** @class */ (function (_super) {
+        __extends(DayTable, _super);
+        function DayTable() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.slicer = new DayTableSlicer();
+            _this.tableRef = createRef();
+            return _this;
+        }
+        DayTable.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            return (createElement(Table, __assign({ ref: this.tableRef }, this.slicer.sliceProps(props, props.dateProfile, props.nextDayThreshold, context, props.dayTableModel), { dateProfile: props.dateProfile, cells: props.dayTableModel.cells, colGroupNode: props.colGroupNode, tableMinWidth: props.tableMinWidth, renderRowIntro: props.renderRowIntro, dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows, showWeekNumbers: props.showWeekNumbers, expandRows: props.expandRows, headerAlignElRef: props.headerAlignElRef, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint })));
+        };
+        return DayTable;
+    }(DateComponent));
+
+    var DayTableView = /** @class */ (function (_super) {
+        __extends(DayTableView, _super);
+        function DayTableView() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.buildDayTableModel = memoize(buildDayTableModel);
+            _this.headerRef = createRef();
+            _this.tableRef = createRef();
+            return _this;
+        }
+        DayTableView.prototype.render = function () {
+            var _this = this;
+            var _a = this.context, options = _a.options, dateProfileGenerator = _a.dateProfileGenerator;
+            var props = this.props;
+            var dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator);
+            var headerContent = options.dayHeaders && (createElement(DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 }));
+            var bodyContent = function (contentArg) { return (createElement(DayTable, { ref: _this.tableRef, dateProfile: props.dateProfile, dayTableModel: dayTableModel, businessHours: props.businessHours, dateSelection: props.dateSelection, eventStore: props.eventStore, eventUiBases: props.eventUiBases, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, nextDayThreshold: options.nextDayThreshold, colGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, dayMaxEvents: options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows, showWeekNumbers: options.weekNumbers, expandRows: !props.isHeightAuto, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint })); };
+            return options.dayMinWidth
+                ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth)
+                : this.renderSimpleLayout(headerContent, bodyContent);
+        };
+        return DayTableView;
+    }(TableView));
+    function buildDayTableModel(dateProfile, dateProfileGenerator) {
+        var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
+        return new DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
+    }
+
+    var TableDateProfileGenerator = /** @class */ (function (_super) {
+        __extends(TableDateProfileGenerator, _super);
+        function TableDateProfileGenerator() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        // Computes the date range that will be rendered.
+        TableDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
+            var dateEnv = this.props.dateEnv;
+            var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay);
+            var start = renderRange.start;
+            var end = renderRange.end;
+            var endOfWeek;
+            // year and month views should be aligned with weeks. this is already done for week
+            if (/^(year|month)$/.test(currentRangeUnit)) {
+                start = dateEnv.startOfWeek(start);
+                // make end-of-week if not already
+                endOfWeek = dateEnv.startOfWeek(end);
+                if (endOfWeek.valueOf() !== end.valueOf()) {
+                    end = addWeeks(endOfWeek, 1);
+                }
+            }
+            // ensure 6 weeks
+            if (this.props.monthMode &&
+                this.props.fixedWeekCount) {
+                var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
+                diffWeeks(start, end));
+                end = addWeeks(end, 6 - rowCnt);
+            }
+            return { start: start, end: end };
+        };
+        return TableDateProfileGenerator;
+    }(DateProfileGenerator));
+
+    var dayGridPlugin = createPlugin({
+        initialView: 'dayGridMonth',
+        views: {
+            dayGrid: {
+                component: DayTableView,
+                dateProfileGeneratorClass: TableDateProfileGenerator,
+            },
+            dayGridDay: {
+                type: 'dayGrid',
+                duration: { days: 1 },
+            },
+            dayGridWeek: {
+                type: 'dayGrid',
+                duration: { weeks: 1 },
+            },
+            dayGridMonth: {
+                type: 'dayGrid',
+                duration: { months: 1 },
+                monthMode: true,
+                fixedWeekCount: true,
+            },
+        },
+    });
+
+    var AllDaySplitter = /** @class */ (function (_super) {
+        __extends(AllDaySplitter, _super);
+        function AllDaySplitter() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        AllDaySplitter.prototype.getKeyInfo = function () {
+            return {
+                allDay: {},
+                timed: {},
+            };
+        };
+        AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
+            if (dateSpan.allDay) {
+                return ['allDay'];
+            }
+            return ['timed'];
+        };
+        AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
+            if (!eventDef.allDay) {
+                return ['timed'];
+            }
+            if (hasBgRendering(eventDef)) {
+                return ['timed', 'allDay'];
+            }
+            return ['allDay'];
+        };
+        return AllDaySplitter;
+    }(Splitter));
+
+    var DEFAULT_SLAT_LABEL_FORMAT = createFormatter({
+        hour: 'numeric',
+        minute: '2-digit',
+        omitZeroMinute: true,
+        meridiem: 'short',
+    });
+    function TimeColsAxisCell(props) {
+        var classNames = [
+            'fc-timegrid-slot',
+            'fc-timegrid-slot-label',
+            props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor',
+        ];
+        return (createElement(ViewContextType.Consumer, null, function (context) {
+            if (!props.isLabeled) {
+                return (createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr }));
+            }
+            var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi;
+            var labelFormat = // TODO: fully pre-parse
+             options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT :
+                Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) :
+                    createFormatter(options.slotLabelFormat);
+            var hookProps = {
+                level: 0,
+                time: props.time,
+                date: dateEnv.toDate(props.date),
+                view: viewApi,
+                text: dateEnv.format(props.date, labelFormat),
+            };
+            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLabelClassNames, content: options.slotLabelContent, defaultContent: renderInnerContent$1, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-time": props.isoTimeStr },
+                createElement("div", { className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame" },
+                    createElement("div", { className: "fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion", ref: innerElRef }, innerContent)))); }));
+        }));
+    }
+    function renderInnerContent$1(props) {
+        return props.text;
+    }
+
+    var TimeBodyAxis = /** @class */ (function (_super) {
+        __extends(TimeBodyAxis, _super);
+        function TimeBodyAxis() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        TimeBodyAxis.prototype.render = function () {
+            return this.props.slatMetas.map(function (slatMeta) { return (createElement("tr", { key: slatMeta.key },
+                createElement(TimeColsAxisCell, __assign({}, slatMeta)))); });
+        };
+        return TimeBodyAxis;
+    }(BaseComponent));
+
+    var DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: 'short' });
+    var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5;
+    var TimeColsView = /** @class */ (function (_super) {
+        __extends(TimeColsView, _super);
+        function TimeColsView() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses
+            _this.headerElRef = createRef();
+            _this.rootElRef = createRef();
+            _this.scrollerElRef = createRef();
+            _this.state = {
+                slatCoords: null,
+            };
+            _this.handleScrollTopRequest = function (scrollTop) {
+                var scrollerEl = _this.scrollerElRef.current;
+                if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer
+                    scrollerEl.scrollTop = scrollTop;
+                }
+            };
+            /* Header Render Methods
+            ------------------------------------------------------------------------------------------------------------------*/
+            _this.renderHeadAxis = function (rowKey, frameHeight) {
+                if (frameHeight === void 0) { frameHeight = ''; }
+                var options = _this.context.options;
+                var dateProfile = _this.props.dateProfile;
+                var range = dateProfile.renderRange;
+                var dayCnt = diffDays(range.start, range.end);
+                var navLinkAttrs = (dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it)
+                    ? buildNavLinkAttrs(_this.context, range.start, 'week')
+                    : {};
+                if (options.weekNumbers && rowKey === 'day') {
+                    return (createElement(WeekNumberRoot, { date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("th", { ref: rootElRef, "aria-hidden": true, className: [
+                            'fc-timegrid-axis',
+                            'fc-scrollgrid-shrink',
+                        ].concat(classNames).join(' ') },
+                        createElement("div", { className: "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid", style: { height: frameHeight } },
+                            createElement("a", __assign({ ref: innerElRef, className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner" }, navLinkAttrs), innerContent)))); }));
+                }
+                return (createElement("th", { "aria-hidden": true, className: "fc-timegrid-axis" },
+                    createElement("div", { className: "fc-timegrid-axis-frame", style: { height: frameHeight } })));
+            };
+            /* Table Component Render Methods
+            ------------------------------------------------------------------------------------------------------------------*/
+            // only a one-way height sync. we don't send the axis inner-content height to the DayGrid,
+            // but DayGrid still needs to have classNames on inner elements in order to measure.
+            _this.renderTableRowAxis = function (rowHeight) {
+                var _a = _this.context, options = _a.options, viewApi = _a.viewApi;
+                var hookProps = {
+                    text: options.allDayText,
+                    view: viewApi,
+                };
+                return (
+                // TODO: make reusable hook. used in list view too
+                createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner$1, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, "aria-hidden": true, className: [
+                        'fc-timegrid-axis',
+                        'fc-scrollgrid-shrink',
+                    ].concat(classNames).join(' ') },
+                    createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } },
+                        createElement("span", { className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", ref: innerElRef }, innerContent)))); }));
+            };
+            _this.handleSlatCoords = function (slatCoords) {
+                _this.setState({ slatCoords: slatCoords });
+            };
+            return _this;
+        }
+        // rendering
+        // ----------------------------------------------------------------------------------------------------
+        TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) {
+            var _a = this, context = _a.context, props = _a.props;
+            var sections = [];
+            var stickyHeaderDates = getStickyHeaderDates(context.options);
+            if (headerRowContent) {
+                sections.push({
+                    type: 'header',
+                    key: 'header',
+                    isSticky: stickyHeaderDates,
+                    chunk: {
+                        elRef: this.headerElRef,
+                        tableClassName: 'fc-col-header',
+                        rowContent: headerRowContent,
+                    },
+                });
+            }
+            if (allDayContent) {
+                sections.push({
+                    type: 'body',
+                    key: 'all-day',
+                    chunk: { content: allDayContent },
+                });
+                sections.push({
+                    type: 'body',
+                    key: 'all-day-divider',
+                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
+                    createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" },
+                        createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),
+                });
+            }
+            sections.push({
+                type: 'body',
+                key: 'body',
+                liquid: true,
+                expandRows: Boolean(context.options.expandRows),
+                chunk: {
+                    scrollerElRef: this.scrollerElRef,
+                    content: timeContent,
+                },
+            });
+            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef },
+                createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); }));
+        };
+        TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) {
+            var _this = this;
+            var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
+            if (!ScrollGrid) {
+                throw new Error('No ScrollGrid implementation');
+            }
+            var _a = this, context = _a.context, props = _a.props;
+            var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options);
+            var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options);
+            var sections = [];
+            if (headerRowContent) {
+                sections.push({
+                    type: 'header',
+                    key: 'header',
+                    isSticky: stickyHeaderDates,
+                    syncRowHeights: true,
+                    chunks: [
+                        {
+                            key: 'axis',
+                            rowContent: function (arg) { return (createElement("tr", { role: "presentation" }, _this.renderHeadAxis('day', arg.rowSyncHeights[0]))); },
+                        },
+                        {
+                            key: 'cols',
+                            elRef: this.headerElRef,
+                            tableClassName: 'fc-col-header',
+                            rowContent: headerRowContent,
+                        },
+                    ],
+                });
+            }
+            if (allDayContent) {
+                sections.push({
+                    type: 'body',
+                    key: 'all-day',
+                    syncRowHeights: true,
+                    chunks: [
+                        {
+                            key: 'axis',
+                            rowContent: function (contentArg) { return (createElement("tr", { role: "presentation" }, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); },
+                        },
+                        {
+                            key: 'cols',
+                            content: allDayContent,
+                        },
+                    ],
+                });
+                sections.push({
+                    key: 'all-day-divider',
+                    type: 'body',
+                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
+                    createElement("tr", { role: "presentation", className: "fc-scrollgrid-section" },
+                        createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),
+                });
+            }
+            var isNowIndicator = context.options.nowIndicator;
+            sections.push({
+                type: 'body',
+                key: 'body',
+                liquid: true,
+                expandRows: Boolean(context.options.expandRows),
+                chunks: [
+                    {
+                        key: 'axis',
+                        content: function (arg) { return (
+                        // TODO: make this now-indicator arrow more DRY with TimeColsContent
+                        createElement("div", { className: "fc-timegrid-axis-chunk" },
+                            createElement("table", { "aria-hidden": true, style: { height: arg.expandRows ? arg.clientHeight : '' } },
+                                arg.tableColGroupNode,
+                                createElement("tbody", null,
+                                    createElement(TimeBodyAxis, { slatMetas: slatMetas }))),
+                            createElement("div", { className: "fc-timegrid-now-indicator-container" },
+                                createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) {
+                                    var nowIndicatorTop = isNowIndicator &&
+                                        slatCoords &&
+                                        slatCoords.safeComputeTop(nowDate); // might return void
+                                    if (typeof nowIndicatorTop === 'number') {
+                                        return (createElement(NowIndicatorRoot, { isAxis: true, date: nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); }));
+                                    }
+                                    return null;
+                                })))); },
+                    },
+                    {
+                        key: 'cols',
+                        scrollerElRef: this.scrollerElRef,
+                        content: timeContent,
+                    },
+                ],
+            });
+            if (stickyFooterScrollbar) {
+                sections.push({
+                    key: 'footer',
+                    type: 'footer',
+                    isSticky: true,
+                    chunks: [
+                        {
+                            key: 'axis',
+                            content: renderScrollShim,
+                        },
+                        {
+                            key: 'cols',
+                            content: renderScrollShim,
+                        },
+                    ],
+                });
+            }
+            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef },
+                createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: false, colGroups: [
+                        { width: 'shrink', cols: [{ width: 'shrink' }] },
+                        { cols: [{ span: colCnt, minWidth: dayMinWidth }] },
+                    ], sections: sections }))); }));
+        };
+        /* Dimensions
+        ------------------------------------------------------------------------------------------------------------------*/
+        TimeColsView.prototype.getAllDayMaxEventProps = function () {
+            var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows;
+            if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto?
+                dayMaxEvents = undefined;
+                dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number
+            }
+            return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows };
+        };
+        return TimeColsView;
+    }(DateComponent));
+    function renderAllDayInner$1(hookProps) {
+        return hookProps.text;
+    }
+
+    var TimeColsSlatsCoords = /** @class */ (function () {
+        function TimeColsSlatsCoords(positions, dateProfile, slotDuration) {
+            this.positions = positions;
+            this.dateProfile = dateProfile;
+            this.slotDuration = slotDuration;
+        }
+        TimeColsSlatsCoords.prototype.safeComputeTop = function (date) {
+            var dateProfile = this.dateProfile;
+            if (rangeContainsMarker(dateProfile.currentRange, date)) {
+                var startOfDayDate = startOfDay(date);
+                var timeMs = date.valueOf() - startOfDayDate.valueOf();
+                if (timeMs >= asRoughMs(dateProfile.slotMinTime) &&
+                    timeMs < asRoughMs(dateProfile.slotMaxTime)) {
+                    return this.computeTimeTop(createDuration(timeMs));
+                }
+            }
+            return null;
+        };
+        // Computes the top coordinate, relative to the bounds of the grid, of the given date.
+        // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
+        TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) {
+            if (!startOfDayDate) {
+                startOfDayDate = startOfDay(when);
+            }
+            return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf()));
+        };
+        // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
+        // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform.
+        // Eventually allow computation with arbirary slat dates.
+        TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) {
+            var _a = this, positions = _a.positions, dateProfile = _a.dateProfile;
+            var len = positions.els.length;
+            // floating-point value of # of slots covered
+            var slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration);
+            var slatIndex;
+            var slatRemainder;
+            // compute a floating-point number for how many slats should be progressed through.
+            // from 0 to number of slats (inclusive)
+            // constrained because slotMinTime/slotMaxTime might be customized.
+            slatCoverage = Math.max(0, slatCoverage);
+            slatCoverage = Math.min(len, slatCoverage);
+            // an integer index of the furthest whole slat
+            // from 0 to number slats (*exclusive*, so len-1)
+            slatIndex = Math.floor(slatCoverage);
+            slatIndex = Math.min(slatIndex, len - 1);
+            // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
+            // could be 1.0 if slatCoverage is covering *all* the slots
+            slatRemainder = slatCoverage - slatIndex;
+            return positions.tops[slatIndex] +
+                positions.getHeight(slatIndex) * slatRemainder;
+        };
+        return TimeColsSlatsCoords;
+    }());
+
+    var TimeColsSlatsBody = /** @class */ (function (_super) {
+        __extends(TimeColsSlatsBody, _super);
+        function TimeColsSlatsBody() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        TimeColsSlatsBody.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            var options = context.options;
+            var slatElRefs = props.slatElRefs;
+            return (createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) {
+                var hookProps = {
+                    time: slatMeta.time,
+                    date: context.dateEnv.toDate(slatMeta.date),
+                    view: context.viewApi,
+                };
+                var classNames = [
+                    'fc-timegrid-slot',
+                    'fc-timegrid-slot-lane',
+                    slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor',
+                ];
+                return (createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) },
+                    props.axis && (createElement(TimeColsAxisCell, __assign({}, slatMeta))),
+                    createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLaneClassNames, content: options.slotLaneContent, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); })));
+            })));
+        };
+        return TimeColsSlatsBody;
+    }(BaseComponent));
+
+    /*
+    for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
+    */
+    var TimeColsSlats = /** @class */ (function (_super) {
+        __extends(TimeColsSlats, _super);
+        function TimeColsSlats() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.rootElRef = createRef();
+            _this.slatElRefs = new RefMap();
+            return _this;
+        }
+        TimeColsSlats.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            return (createElement("div", { ref: this.rootElRef, className: "fc-timegrid-slots" },
+                createElement("table", { "aria-hidden": true, className: context.theme.getClass('table'), style: {
+                        minWidth: props.tableMinWidth,
+                        width: props.clientWidth,
+                        height: props.minHeight,
+                    } },
+                    props.tableColGroupNode /* relies on there only being a single <col> for the axis */,
+                    createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas }))));
+        };
+        TimeColsSlats.prototype.componentDidMount = function () {
+            this.updateSizing();
+        };
+        TimeColsSlats.prototype.componentDidUpdate = function () {
+            this.updateSizing();
+        };
+        TimeColsSlats.prototype.componentWillUnmount = function () {
+            if (this.props.onCoords) {
+                this.props.onCoords(null);
+            }
+        };
+        TimeColsSlats.prototype.updateSizing = function () {
+            var _a = this, context = _a.context, props = _a.props;
+            if (props.onCoords &&
+                props.clientWidth !== null // means sizing has stabilized
+            ) {
+                var rootEl = this.rootElRef.current;
+                if (rootEl.offsetHeight) { // not hidden by css
+                    props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration));
+                }
+            }
+        };
+        return TimeColsSlats;
+    }(BaseComponent));
+    function collectSlatEls(elMap, slatMetas) {
+        return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; });
+    }
+
+    function splitSegsByCol(segs, colCnt) {
+        var segsByCol = [];
+        var i;
+        for (i = 0; i < colCnt; i += 1) {
+            segsByCol.push([]);
+        }
+        if (segs) {
+            for (i = 0; i < segs.length; i += 1) {
+                segsByCol[segs[i].col].push(segs[i]);
+            }
+        }
+        return segsByCol;
+    }
+    function splitInteractionByCol(ui, colCnt) {
+        var byRow = [];
+        if (!ui) {
+            for (var i = 0; i < colCnt; i += 1) {
+                byRow[i] = null;
+            }
+        }
+        else {
+            for (var i = 0; i < colCnt; i += 1) {
+                byRow[i] = {
+                    affectedInstances: ui.affectedInstances,
+                    isEvent: ui.isEvent,
+                    segs: [],
+                };
+            }
+            for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
+                var seg = _a[_i];
+                byRow[seg.col].segs.push(seg);
+            }
+        }
+        return byRow;
+    }
+
+    var TimeColMoreLink = /** @class */ (function (_super) {
+        __extends(TimeColMoreLink, _super);
+        function TimeColMoreLink() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.rootElRef = createRef();
+            return _this;
+        }
+        TimeColMoreLink.prototype.render = function () {
+            var _this = this;
+            var props = this.props;
+            return (createElement(MoreLinkRoot, { allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, alignmentElRef: this.rootElRef, defaultContent: renderMoreLinkInner, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, todayRange: props.todayRange, popoverContent: function () { return renderPlainFgSegs(props.hiddenSegs, props); } }, function (rootElRef, classNames, innerElRef, innerContent, handleClick, title, isExpanded, popoverId) { return (createElement("a", { ref: function (el) {
+                    setRef(rootElRef, el);
+                    setRef(_this.rootElRef, el);
+                }, className: ['fc-timegrid-more-link'].concat(classNames).join(' '), style: { top: props.top, bottom: props.bottom }, onClick: handleClick, title: title, "aria-expanded": isExpanded, "aria-controls": popoverId },
+                createElement("div", { ref: innerElRef, className: "fc-timegrid-more-link-inner fc-sticky" }, innerContent))); }));
+        };
+        return TimeColMoreLink;
+    }(BaseComponent));
+    function renderMoreLinkInner(props) {
+        return props.shortText;
+    }
+
+    // segInputs assumed sorted
+    function buildPositioning(segInputs, strictOrder, maxStackCnt) {
+        var hierarchy = new SegHierarchy();
+        if (strictOrder != null) {
+            hierarchy.strictOrder = strictOrder;
+        }
+        if (maxStackCnt != null) {
+            hierarchy.maxStackCnt = maxStackCnt;
+        }
+        var hiddenEntries = hierarchy.addSegs(segInputs);
+        var hiddenGroups = groupIntersectingEntries(hiddenEntries);
+        var web = buildWeb(hierarchy);
+        web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0
+        var segRects = webToRects(web);
+        return { segRects: segRects, hiddenGroups: hiddenGroups };
+    }
+    function buildWeb(hierarchy) {
+        var entriesByLevel = hierarchy.entriesByLevel;
+        var buildNode = cacheable(function (level, lateral) { return level + ':' + lateral; }, function (level, lateral) {
+            var siblingRange = findNextLevelSegs(hierarchy, level, lateral);
+            var nextLevelRes = buildNodes(siblingRange, buildNode);
+            var entry = entriesByLevel[level][lateral];
+            return [
+                __assign(__assign({}, entry), { nextLevelNodes: nextLevelRes[0] }),
+                entry.thickness + nextLevelRes[1], // the pressure builds
+            ];
+        });
+        return buildNodes(entriesByLevel.length
+            ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length }
+            : null, buildNode)[0];
+    }
+    function buildNodes(siblingRange, buildNode) {
+        if (!siblingRange) {
+            return [[], 0];
+        }
+        var level = siblingRange.level, lateralStart = siblingRange.lateralStart, lateralEnd = siblingRange.lateralEnd;
+        var lateral = lateralStart;
+        var pairs = [];
+        while (lateral < lateralEnd) {
+            pairs.push(buildNode(level, lateral));
+            lateral += 1;
+        }
+        pairs.sort(cmpDescPressures);
+        return [
+            pairs.map(extractNode),
+            pairs[0][1], // first item's pressure
+        ];
+    }
+    function cmpDescPressures(a, b) {
+        return b[1] - a[1];
+    }
+    function extractNode(a) {
+        return a[0];
+    }
+    function findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) {
+        var levelCoords = hierarchy.levelCoords, entriesByLevel = hierarchy.entriesByLevel;
+        var subjectEntry = entriesByLevel[subjectLevel][subjectLateral];
+        var afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness;
+        var levelCnt = levelCoords.length;
+        var level = subjectLevel;
+        // skip past levels that are too high up
+        for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1)
+            ; // do nothing
+        for (; level < levelCnt; level += 1) {
+            var entries = entriesByLevel[level];
+            var entry = void 0;
+            var searchIndex = binarySearch(entries, subjectEntry.span.start, getEntrySpanEnd);
+            var lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one
+            var lateralEnd = lateralStart;
+            while ( // loop through entries that horizontally intersect
+            (entry = entries[lateralEnd]) && // but not past the whole seg list
+                entry.span.start < subjectEntry.span.end) {
+                lateralEnd += 1;
+            }
+            if (lateralStart < lateralEnd) {
+                return { level: level, lateralStart: lateralStart, lateralEnd: lateralEnd };
+            }
+        }
+        return null;
+    }
+    function stretchWeb(topLevelNodes, totalThickness) {
+        var stretchNode = cacheable(function (node, startCoord, prevThickness) { return buildEntryKey(node); }, function (node, startCoord, prevThickness) {
+            var nextLevelNodes = node.nextLevelNodes, thickness = node.thickness;
+            var allThickness = thickness + prevThickness;
+            var thicknessFraction = thickness / allThickness;
+            var endCoord;
+            var newChildren = [];
+            if (!nextLevelNodes.length) {
+                endCoord = totalThickness;
+            }
+            else {
+                for (var _i = 0, nextLevelNodes_1 = nextLevelNodes; _i < nextLevelNodes_1.length; _i++) {
+                    var childNode = nextLevelNodes_1[_i];
+                    if (endCoord === undefined) {
+                        var res = stretchNode(childNode, startCoord, allThickness);
+                        endCoord = res[0];
+                        newChildren.push(res[1]);
+                    }
+                    else {
+                        var res = stretchNode(childNode, endCoord, 0);
+                        newChildren.push(res[1]);
+                    }
+                }
+            }
+            var newThickness = (endCoord - startCoord) * thicknessFraction;
+            return [endCoord - newThickness, __assign(__assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })];
+        });
+        return topLevelNodes.map(function (node) { return stretchNode(node, 0, 0)[1]; });
+    }
+    // not sorted in any particular order
+    function webToRects(topLevelNodes) {
+        var rects = [];
+        var processNode = cacheable(function (node, levelCoord, stackDepth) { return buildEntryKey(node); }, function (node, levelCoord, stackDepth) {
+            var rect = __assign(__assign({}, node), { levelCoord: levelCoord,
+                stackDepth: stackDepth, stackForward: 0 });
+            rects.push(rect);
+            return (rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1);
+        });
+        function processNodes(nodes, levelCoord, stackDepth) {
+            var stackForward = 0;
+            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
+                var node = nodes_1[_i];
+                stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward);
+            }
+            return stackForward;
+        }
+        processNodes(topLevelNodes, 0, 0);
+        return rects; // TODO: sort rects by levelCoord to be consistent with toRects?
+    }
+    // TODO: move to general util
+    function cacheable(keyFunc, workFunc) {
+        var cache = {};
+        return function () {
+            var args = [];
+            for (var _i = 0; _i < arguments.length; _i++) {
+                args[_i] = arguments[_i];
+            }
+            var key = keyFunc.apply(void 0, args);
+            return (key in cache)
+                ? cache[key]
+                : (cache[key] = workFunc.apply(void 0, args));
+        };
+    }
+
+    function computeSegVCoords(segs, colDate, slatCoords, eventMinHeight) {
+        if (slatCoords === void 0) { slatCoords = null; }
+        if (eventMinHeight === void 0) { eventMinHeight = 0; }
+        var vcoords = [];
+        if (slatCoords) {
+            for (var i = 0; i < segs.length; i += 1) {
+                var seg = segs[i];
+                var spanStart = slatCoords.computeDateTop(seg.start, colDate);
+                var spanEnd = Math.max(spanStart + (eventMinHeight || 0), // :(
+                slatCoords.computeDateTop(seg.end, colDate));
+                vcoords.push({
+                    start: Math.round(spanStart),
+                    end: Math.round(spanEnd), //
+                });
+            }
+        }
+        return vcoords;
+    }
+    function computeFgSegPlacements(segs, segVCoords, // might not have for every seg
+    eventOrderStrict, eventMaxStack) {
+        var segInputs = [];
+        var dumbSegs = []; // segs without coords
+        for (var i = 0; i < segs.length; i += 1) {
+            var vcoords = segVCoords[i];
+            if (vcoords) {
+                segInputs.push({
+                    index: i,
+                    thickness: 1,
+                    span: vcoords,
+                });
+            }
+            else {
+                dumbSegs.push(segs[i]);
+            }
+        }
+        var _a = buildPositioning(segInputs, eventOrderStrict, eventMaxStack), segRects = _a.segRects, hiddenGroups = _a.hiddenGroups;
+        var segPlacements = [];
+        for (var _i = 0, segRects_1 = segRects; _i < segRects_1.length; _i++) {
+            var segRect = segRects_1[_i];
+            segPlacements.push({
+                seg: segs[segRect.index],
+                rect: segRect,
+            });
+        }
+        for (var _b = 0, dumbSegs_1 = dumbSegs; _b < dumbSegs_1.length; _b++) {
+            var dumbSeg = dumbSegs_1[_b];
+            segPlacements.push({ seg: dumbSeg, rect: null });
+        }
+        return { segPlacements: segPlacements, hiddenGroups: hiddenGroups };
+    }
+
+    var DEFAULT_TIME_FORMAT$1 = createFormatter({
+        hour: 'numeric',
+        minute: '2-digit',
+        meridiem: false,
+    });
+    var TimeColEvent = /** @class */ (function (_super) {
+        __extends(TimeColEvent, _super);
+        function TimeColEvent() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        TimeColEvent.prototype.render = function () {
+            var classNames = [
+                'fc-timegrid-event',
+                'fc-v-event',
+            ];
+            if (this.props.isShort) {
+                classNames.push('fc-timegrid-event-short');
+            }
+            return (createElement(StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT$1, extraClassNames: classNames })));
+        };
+        return TimeColEvent;
+    }(BaseComponent));
+
+    var TimeColMisc = /** @class */ (function (_super) {
+        __extends(TimeColMisc, _super);
+        function TimeColMisc() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        TimeColMisc.prototype.render = function () {
+            var props = this.props;
+            return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent &&
+                createElement("div", { className: "fc-timegrid-col-misc", ref: innerElRef }, innerContent)); }));
+        };
+        return TimeColMisc;
+    }(BaseComponent));
+
+    var TimeCol = /** @class */ (function (_super) {
+        __extends(TimeCol, _super);
+        function TimeCol() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.sortEventSegs = memoize(sortEventSegs);
+            return _this;
+        }
+        // TODO: memoize event-placement?
+        TimeCol.prototype.render = function () {
+            var _this = this;
+            var _a = this, props = _a.props, context = _a.context;
+            var isSelectMirror = context.options.selectMirror;
+            var mirrorSegs = (props.eventDrag && props.eventDrag.segs) ||
+                (props.eventResize && props.eventResize.segs) ||
+                (isSelectMirror && props.dateSelectionSegs) ||
+                [];
+            var interactionAffectedInstances = // TODO: messy way to compute this
+             (props.eventDrag && props.eventDrag.affectedInstances) ||
+                (props.eventResize && props.eventResize.affectedInstances) ||
+                {};
+            var sortedFgSegs = this.sortEventSegs(props.fgEventSegs, context.options.eventOrder);
+            return (createElement(DayCellRoot, { elRef: props.elRef, date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (rootElRef, classNames, dataAttrs) { return (createElement("td", __assign({ ref: rootElRef, role: "gridcell", className: ['fc-timegrid-col'].concat(classNames, props.extraClassNames || []).join(' ') }, dataAttrs, props.extraDataAttrs),
+                createElement("div", { className: "fc-timegrid-col-frame" },
+                    createElement("div", { className: "fc-timegrid-col-bg" },
+                        _this.renderFillSegs(props.businessHourSegs, 'non-business'),
+                        _this.renderFillSegs(props.bgEventSegs, 'bg-event'),
+                        _this.renderFillSegs(props.dateSelectionSegs, 'highlight')),
+                    createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(sortedFgSegs, interactionAffectedInstances, false, false, false)),
+                    createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))),
+                    createElement("div", { className: "fc-timegrid-now-indicator-container" }, _this.renderNowIndicator(props.nowIndicatorSegs)),
+                    createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); }));
+        };
+        TimeCol.prototype.renderFgSegs = function (sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting) {
+            var props = this.props;
+            if (props.forPrint) {
+                return renderPlainFgSegs(sortedFgSegs, props);
+            }
+            return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting);
+        };
+        TimeCol.prototype.renderPositionedFgSegs = function (segs, // if not mirror, needs to be sorted
+        segIsInvisible, isDragging, isResizing, isDateSelecting) {
+            var _this = this;
+            var _a = this.context.options, eventMaxStack = _a.eventMaxStack, eventShortHeight = _a.eventShortHeight, eventOrderStrict = _a.eventOrderStrict, eventMinHeight = _a.eventMinHeight;
+            var _b = this.props, date = _b.date, slatCoords = _b.slatCoords, eventSelection = _b.eventSelection, todayRange = _b.todayRange, nowDate = _b.nowDate;
+            var isMirror = isDragging || isResizing || isDateSelecting;
+            var segVCoords = computeSegVCoords(segs, date, slatCoords, eventMinHeight);
+            var _c = computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack), segPlacements = _c.segPlacements, hiddenGroups = _c.hiddenGroups;
+            return (createElement(Fragment, null,
+                this.renderHiddenGroups(hiddenGroups, segs),
+                segPlacements.map(function (segPlacement) {
+                    var seg = segPlacement.seg, rect = segPlacement.rect;
+                    var instanceId = seg.eventRange.instance.instanceId;
+                    var isVisible = isMirror || Boolean(!segIsInvisible[instanceId] && rect);
+                    var vStyle = computeSegVStyle(rect && rect.span);
+                    var hStyle = (!isMirror && rect) ? _this.computeSegHStyle(rect) : { left: 0, right: 0 };
+                    var isInset = Boolean(rect) && rect.stackForward > 0;
+                    var isShort = Boolean(rect) && (rect.span.end - rect.span.start) < eventShortHeight; // look at other places for this problem
+                    return (createElement("div", { className: 'fc-timegrid-event-harness' +
+                            (isInset ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign(__assign({ visibility: isVisible ? '' : 'hidden' }, vStyle), hStyle) },
+                        createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, isShort: isShort }, getSegMeta(seg, todayRange, nowDate)))));
+                })));
+        };
+        // will already have eventMinHeight applied because segInputs already had it
+        TimeCol.prototype.renderHiddenGroups = function (hiddenGroups, segs) {
+            var _a = this.props, extraDateSpan = _a.extraDateSpan, dateProfile = _a.dateProfile, todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize;
+            return (createElement(Fragment, null, hiddenGroups.map(function (hiddenGroup) {
+                var positionCss = computeSegVStyle(hiddenGroup.span);
+                var hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs);
+                return (createElement(TimeColMoreLink, { key: buildIsoString(computeEarliestSegStart(hiddenSegs)), hiddenSegs: hiddenSegs, top: positionCss.top, bottom: positionCss.bottom, extraDateSpan: extraDateSpan, dateProfile: dateProfile, todayRange: todayRange, nowDate: nowDate, eventSelection: eventSelection, eventDrag: eventDrag, eventResize: eventResize }));
+            })));
+        };
+        TimeCol.prototype.renderFillSegs = function (segs, fillType) {
+            var _a = this, props = _a.props, context = _a.context;
+            var segVCoords = computeSegVCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight); // don't assume all populated
+            var children = segVCoords.map(function (vcoords, i) {
+                var seg = segs[i];
+                return (createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-timegrid-bg-harness", style: computeSegVStyle(vcoords) }, fillType === 'bg-event' ?
+                    createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, props.todayRange, props.nowDate))) :
+                    renderFill(fillType)));
+            });
+            return createElement(Fragment, null, children);
+        };
+        TimeCol.prototype.renderNowIndicator = function (segs) {
+            var _a = this.props, slatCoords = _a.slatCoords, date = _a.date;
+            if (!slatCoords) {
+                return null;
+            }
+            return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date, 
+                // key doesn't matter. will only ever be one
+                key: i }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-line'].concat(classNames).join(' '), style: { top: slatCoords.computeDateTop(seg.start, date) } }, innerContent)); })); });
+        };
+        TimeCol.prototype.computeSegHStyle = function (segHCoords) {
+            var _a = this.context, isRtl = _a.isRtl, options = _a.options;
+            var shouldOverlap = options.slotEventOverlap;
+            var nearCoord = segHCoords.levelCoord; // the left side if LTR. the right side if RTL. floating-point
+            var farCoord = segHCoords.levelCoord + segHCoords.thickness; // the right side if LTR. the left side if RTL. floating-point
+            var left; // amount of space from left edge, a fraction of the total width
+            var right; // amount of space from right edge, a fraction of the total width
+            if (shouldOverlap) {
+                // double the width, but don't go beyond the maximum forward coordinate (1.0)
+                farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2);
+            }
+            if (isRtl) {
+                left = 1 - farCoord;
+                right = nearCoord;
+            }
+            else {
+                left = nearCoord;
+                right = 1 - farCoord;
+            }
+            var props = {
+                zIndex: segHCoords.stackDepth + 1,
+                left: left * 100 + '%',
+                right: right * 100 + '%',
+            };
+            if (shouldOverlap && !segHCoords.stackForward) {
+                // add padding to the edge so that forward stacked events don't cover the resizer's icon
+                props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
+            }
+            return props;
+        };
+        return TimeCol;
+    }(BaseComponent));
+    function renderPlainFgSegs(sortedFgSegs, _a) {
+        var todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize;
+        var hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) ||
+            (eventResize ? eventResize.affectedInstances : null) ||
+            {};
+        return (createElement(Fragment, null, sortedFgSegs.map(function (seg) {
+            var instanceId = seg.eventRange.instance.instanceId;
+            return (createElement("div", { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? 'hidden' : '' } },
+                createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, getSegMeta(seg, todayRange, nowDate)))));
+        })));
+    }
+    function computeSegVStyle(segVCoords) {
+        if (!segVCoords) {
+            return { top: '', bottom: '' };
+        }
+        return {
+            top: segVCoords.start,
+            bottom: -segVCoords.end,
+        };
+    }
+    function compileSegsFromEntries(segEntries, allSegs) {
+        return segEntries.map(function (segEntry) { return allSegs[segEntry.index]; });
+    }
+
+    var TimeColsContent = /** @class */ (function (_super) {
+        __extends(TimeColsContent, _super);
+        function TimeColsContent() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.splitFgEventSegs = memoize(splitSegsByCol);
+            _this.splitBgEventSegs = memoize(splitSegsByCol);
+            _this.splitBusinessHourSegs = memoize(splitSegsByCol);
+            _this.splitNowIndicatorSegs = memoize(splitSegsByCol);
+            _this.splitDateSelectionSegs = memoize(splitSegsByCol);
+            _this.splitEventDrag = memoize(splitInteractionByCol);
+            _this.splitEventResize = memoize(splitInteractionByCol);
+            _this.rootElRef = createRef();
+            _this.cellElRefs = new RefMap();
+            return _this;
+        }
+        TimeColsContent.prototype.render = function () {
+            var _this = this;
+            var _a = this, props = _a.props, context = _a.context;
+            var nowIndicatorTop = context.options.nowIndicator &&
+                props.slatCoords &&
+                props.slatCoords.safeComputeTop(props.nowDate); // might return void
+            var colCnt = props.cells.length;
+            var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt);
+            var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt);
+            var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt);
+            var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt);
+            var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt);
+            var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt);
+            var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt);
+            return (createElement("div", { className: "fc-timegrid-cols", ref: this.rootElRef },
+                createElement("table", { role: "presentation", style: {
+                        minWidth: props.tableMinWidth,
+                        width: props.clientWidth,
+                    } },
+                    props.tableColGroupNode,
+                    createElement("tbody", { role: "presentation" },
+                        createElement("tr", { role: "row" },
+                            props.axis && (createElement("td", { "aria-hidden": true, className: "fc-timegrid-col fc-timegrid-axis" },
+                                createElement("div", { className: "fc-timegrid-col-frame" },
+                                    createElement("div", { className: "fc-timegrid-now-indicator-container" }, typeof nowIndicatorTop === 'number' && (createElement(NowIndicatorRoot, { isAxis: true, date: props.nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); })))))),
+                            props.cells.map(function (cell, i) { return (createElement(TimeCol, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, fgEventSegs: fgEventSegsByRow[i], bgEventSegs: bgEventSegsByRow[i], businessHourSegs: businessHourSegsByRow[i], nowIndicatorSegs: nowIndicatorSegsByRow[i], dateSelectionSegs: dateSelectionSegsByRow[i], eventDrag: eventDragByRow[i], eventResize: eventResizeByRow[i], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint })); }))))));
+        };
+        TimeColsContent.prototype.componentDidMount = function () {
+            this.updateCoords();
+        };
+        TimeColsContent.prototype.componentDidUpdate = function () {
+            this.updateCoords();
+        };
+        TimeColsContent.prototype.updateCoords = function () {
+            var props = this.props;
+            if (props.onColCoords &&
+                props.clientWidth !== null // means sizing has stabilized
+            ) {
+                props.onColCoords(new PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal
+                false));
+            }
+        };
+        return TimeColsContent;
+    }(BaseComponent));
+    function collectCellEls(elMap, cells) {
+        return cells.map(function (cell) { return elMap[cell.key]; });
+    }
+
+    /* A component that renders one or more columns of vertical time slots
+    ----------------------------------------------------------------------------------------------------------------------*/
+    var TimeCols = /** @class */ (function (_super) {
+        __extends(TimeCols, _super);
+        function TimeCols() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.processSlotOptions = memoize(processSlotOptions);
+            _this.state = {
+                slatCoords: null,
+            };
+            _this.handleRootEl = function (el) {
+                if (el) {
+                    _this.context.registerInteractiveComponent(_this, {
+                        el: el,
+                        isHitComboAllowed: _this.props.isHitComboAllowed,
+                    });
+                }
+                else {
+                    _this.context.unregisterInteractiveComponent(_this);
+                }
+            };
+            _this.handleScrollRequest = function (request) {
+                var onScrollTopRequest = _this.props.onScrollTopRequest;
+                var slatCoords = _this.state.slatCoords;
+                if (onScrollTopRequest && slatCoords) {
+                    if (request.time) {
+                        var top_1 = slatCoords.computeTimeTop(request.time);
+                        top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further
+                        if (top_1) {
+                            top_1 += 1; // to overcome top border that slots beyond the first have. looks better
+                        }
+                        onScrollTopRequest(top_1);
+                    }
+                    return true;
+                }
+                return false;
+            };
+            _this.handleColCoords = function (colCoords) {
+                _this.colCoords = colCoords;
+            };
+            _this.handleSlatCoords = function (slatCoords) {
+                _this.setState({ slatCoords: slatCoords });
+                if (_this.props.onSlatCoords) {
+                    _this.props.onSlatCoords(slatCoords);
+                }
+            };
+            return _this;
+        }
+        TimeCols.prototype.render = function () {
+            var _a = this, props = _a.props, state = _a.state;
+            return (createElement("div", { className: "fc-timegrid-body", ref: this.handleRootEl, style: {
+                    // these props are important to give this wrapper correct dimensions for interactions
+                    // TODO: if we set it here, can we avoid giving to inner tables?
+                    width: props.clientWidth,
+                    minWidth: props.tableMinWidth,
+                } },
+                createElement(TimeColsSlats, { axis: props.axis, dateProfile: props.dateProfile, slatMetas: props.slatMetas, clientWidth: props.clientWidth, minHeight: props.expandRows ? props.clientHeight : '', tableMinWidth: props.tableMinWidth, tableColGroupNode: props.axis ? props.tableColGroupNode : null /* axis depends on the colgroup's shrinking */, onCoords: this.handleSlatCoords }),
+                createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bgEventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange, nowDate: props.nowDate, nowIndicatorSegs: props.nowIndicatorSegs, clientWidth: props.clientWidth, tableMinWidth: props.tableMinWidth, tableColGroupNode: props.tableColGroupNode, slatCoords: state.slatCoords, onColCoords: this.handleColCoords, forPrint: props.forPrint })));
+        };
+        TimeCols.prototype.componentDidMount = function () {
+            this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest);
+        };
+        TimeCols.prototype.componentDidUpdate = function (prevProps) {
+            this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile);
+        };
+        TimeCols.prototype.componentWillUnmount = function () {
+            this.scrollResponder.detach();
+        };
+        TimeCols.prototype.queryHit = function (positionLeft, positionTop) {
+            var _a = this.context, dateEnv = _a.dateEnv, options = _a.options;
+            var colCoords = this.colCoords;
+            var dateProfile = this.props.dateProfile;
+            var slatCoords = this.state.slatCoords;
+            var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot;
+            var colIndex = colCoords.leftToIndex(positionLeft);
+            var slatIndex = slatCoords.positions.topToIndex(positionTop);
+            if (colIndex != null && slatIndex != null) {
+                var cell = this.props.cells[colIndex];
+                var slatTop = slatCoords.positions.tops[slatIndex];
+                var slatHeight = slatCoords.positions.getHeight(slatIndex);
+                var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
+                var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
+                var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
+                var dayDate = this.props.cells[colIndex].date;
+                var time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex));
+                var start = dateEnv.add(dayDate, time);
+                var end = dateEnv.add(start, snapDuration);
+                return {
+                    dateProfile: dateProfile,
+                    dateSpan: __assign({ range: { start: start, end: end }, allDay: false }, cell.extraDateSpan),
+                    dayEl: colCoords.els[colIndex],
+                    rect: {
+                        left: colCoords.lefts[colIndex],
+                        right: colCoords.rights[colIndex],
+                        top: slatTop,
+                        bottom: slatTop + slatHeight,
+                    },
+                    layer: 0,
+                };
+            }
+            return null;
+        };
+        return TimeCols;
+    }(DateComponent));
+    function processSlotOptions(slotDuration, snapDurationOverride) {
+        var snapDuration = snapDurationOverride || slotDuration;
+        var snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration);
+        if (snapsPerSlot === null) {
+            snapDuration = slotDuration;
+            snapsPerSlot = 1;
+            // TODO: say warning?
+        }
+        return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot };
+    }
+
+    var DayTimeColsSlicer = /** @class */ (function (_super) {
+        __extends(DayTimeColsSlicer, _super);
+        function DayTimeColsSlicer() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) {
+            var segs = [];
+            for (var col = 0; col < dayRanges.length; col += 1) {
+                var segRange = intersectRanges(range, dayRanges[col]);
+                if (segRange) {
+                    segs.push({
+                        start: segRange.start,
+                        end: segRange.end,
+                        isStart: segRange.start.valueOf() === range.start.valueOf(),
+                        isEnd: segRange.end.valueOf() === range.end.valueOf(),
+                        col: col,
+                    });
+                }
+            }
+            return segs;
+        };
+        return DayTimeColsSlicer;
+    }(Slicer));
+
+    var DayTimeCols = /** @class */ (function (_super) {
+        __extends(DayTimeCols, _super);
+        function DayTimeCols() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.buildDayRanges = memoize(buildDayRanges);
+            _this.slicer = new DayTimeColsSlicer();
+            _this.timeColsRef = createRef();
+            return _this;
+        }
+        DayTimeCols.prototype.render = function () {
+            var _this = this;
+            var _a = this, props = _a.props, context = _a.context;
+            var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel;
+            var isNowIndicator = context.options.nowIndicator;
+            var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv);
+            // give it the first row of cells
+            // TODO: would move this further down hierarchy, but sliceNowDate needs it
+            return (createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' }, function (nowDate, todayRange) { return (createElement(TimeCols, __assign({ ref: _this.timeColsRef }, _this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile: dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate: nowDate, nowIndicatorSegs: isNowIndicator && _this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); }));
+        };
+        return DayTimeCols;
+    }(DateComponent));
+    function buildDayRanges(dayTableModel, dateProfile, dateEnv) {
+        var ranges = [];
+        for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) {
+            var date = _a[_i];
+            ranges.push({
+                start: dateEnv.add(date, dateProfile.slotMinTime),
+                end: dateEnv.add(date, dateProfile.slotMaxTime),
+            });
+        }
+        return ranges;
+    }
+
+    // potential nice values for the slot-duration and interval-duration
+    // from largest to smallest
+    var STOCK_SUB_DURATIONS = [
+        { hours: 1 },
+        { minutes: 30 },
+        { minutes: 15 },
+        { seconds: 30 },
+        { seconds: 15 },
+    ];
+    function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) {
+        var dayStart = new Date(0);
+        var slatTime = slotMinTime;
+        var slatIterator = createDuration(0);
+        var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration);
+        var metas = [];
+        while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) {
+            var date = dateEnv.add(dayStart, slatTime);
+            var isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null;
+            metas.push({
+                date: date,
+                time: slatTime,
+                key: date.toISOString(),
+                isoTimeStr: formatIsoTimeString(date),
+                isLabeled: isLabeled,
+            });
+            slatTime = addDurations(slatTime, slotDuration);
+            slatIterator = addDurations(slatIterator, slotDuration);
+        }
+        return metas;
+    }
+    // Computes an automatic value for slotLabelInterval
+    function computeLabelInterval(slotDuration) {
+        var i;
+        var labelInterval;
+        var slotsPerLabel;
+        // find the smallest stock label interval that results in more than one slots-per-label
+        for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) {
+            labelInterval = createDuration(STOCK_SUB_DURATIONS[i]);
+            slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);
+            if (slotsPerLabel !== null && slotsPerLabel > 1) {
+                return labelInterval;
+            }
+        }
+        return slotDuration; // fall back
+    }
+
+    var DayTimeColsView = /** @class */ (function (_super) {
+        __extends(DayTimeColsView, _super);
+        function DayTimeColsView() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.buildTimeColsModel = memoize(buildTimeColsModel);
+            _this.buildSlatMetas = memoize(buildSlatMetas);
+            return _this;
+        }
+        DayTimeColsView.prototype.render = function () {
+            var _this = this;
+            var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator;
+            var props = this.props;
+            var dateProfile = props.dateProfile;
+            var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator);
+            var splitProps = this.allDaySplitter.splitProps(props);
+            var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv);
+            var dayMinWidth = options.dayMinWidth;
+            var hasAttachedAxis = !dayMinWidth;
+            var hasDetachedAxis = dayMinWidth;
+            var headerContent = options.dayHeaders && (createElement(DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null }));
+            var allDayContent = (options.allDaySlot !== false) && (function (contentArg) { return (createElement(DayTable, __assign({}, splitProps.allDay, { dateProfile: dateProfile, dayTableModel: dayTableModel, nextDayThreshold: options.nextDayThreshold, tableMinWidth: contentArg.tableMinWidth, colGroupNode: contentArg.tableColGroupNode, renderRowIntro: hasAttachedAxis ? _this.renderTableRowAxis : null, showWeekNumbers: false, expandRows: false, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }, _this.getAllDayMaxEventProps()))); });
+            var timeGridContent = function (contentArg) { return (createElement(DayTimeCols, __assign({}, splitProps.timed, { dayTableModel: dayTableModel, dateProfile: dateProfile, axis: hasAttachedAxis, slotDuration: options.slotDuration, slatMetas: slatMetas, forPrint: props.forPrint, tableColGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, onSlatCoords: _this.handleSlatCoords, expandRows: contentArg.expandRows, onScrollTopRequest: _this.handleScrollTopRequest }))); };
+            return hasDetachedAxis
+                ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords)
+                : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent);
+        };
+        return DayTimeColsView;
+    }(TimeColsView));
+    function buildTimeColsModel(dateProfile, dateProfileGenerator) {
+        var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
+        return new DayTableModel(daySeries, false);
+    }
+
+    var OPTION_REFINERS$2 = {
+        allDaySlot: Boolean,
+    };
+
+    var timeGridPlugin = createPlugin({
+        initialView: 'timeGridWeek',
+        optionRefiners: OPTION_REFINERS$2,
+        views: {
+            timeGrid: {
+                component: DayTimeColsView,
+                usesMinMaxTime: true,
+                allDaySlot: true,
+                slotDuration: '00:30:00',
+                slotEventOverlap: true, // a bad name. confused with overlap/constraint system
+            },
+            timeGridDay: {
+                type: 'timeGrid',
+                duration: { days: 1 },
+            },
+            timeGridWeek: {
+                type: 'timeGrid',
+                duration: { weeks: 1 },
+            },
+        },
+    });
+
+    var ListViewHeaderRow = /** @class */ (function (_super) {
+        __extends(ListViewHeaderRow, _super);
+        function ListViewHeaderRow() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.state = {
+                textId: getUniqueDomId(),
+            };
+            return _this;
+        }
+        ListViewHeaderRow.prototype.render = function () {
+            var _a = this.context, theme = _a.theme, dateEnv = _a.dateEnv, options = _a.options, viewApi = _a.viewApi;
+            var _b = this.props, cellId = _b.cellId, dayDate = _b.dayDate, todayRange = _b.todayRange;
+            var textId = this.state.textId;
+            var dayMeta = getDateMeta(dayDate, todayRange);
+            // will ever be falsy?
+            var text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : '';
+            // will ever be falsy? also, BAD NAME "alt"
+            var sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : '';
+            var hookProps = __assign({ date: dateEnv.toDate(dayDate), view: viewApi, textId: textId,
+                text: text,
+                sideText: sideText, navLinkAttrs: buildNavLinkAttrs(this.context, dayDate), sideNavLinkAttrs: buildNavLinkAttrs(this.context, dayDate, 'day', false) }, dayMeta);
+            var classNames = ['fc-list-day'].concat(getDayClassNames(dayMeta, theme));
+            // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too)
+            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInnerContent, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("tr", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-date": formatDayString(dayDate) },
+                createElement("th", { scope: "colgroup", colSpan: 3, id: cellId, "aria-labelledby": textId },
+                    createElement("div", { className: 'fc-list-day-cushion ' + theme.getClass('tableCellShaded'), ref: innerElRef }, innerContent)))); }));
+        };
+        return ListViewHeaderRow;
+    }(BaseComponent));
+    function renderInnerContent(props) {
+        return (createElement(Fragment, null,
+            props.text && (createElement("a", __assign({ id: props.textId, className: "fc-list-day-text" }, props.navLinkAttrs), props.text)),
+            props.sideText && ( /* not keyboard tabbable */createElement("a", __assign({ "aria-hidden": true, className: "fc-list-day-side-text" }, props.sideNavLinkAttrs), props.sideText))));
+    }
+
+    var DEFAULT_TIME_FORMAT = createFormatter({
+        hour: 'numeric',
+        minute: '2-digit',
+        meridiem: 'short',
+    });
+    var ListViewEventRow = /** @class */ (function (_super) {
+        __extends(ListViewEventRow, _super);
+        function ListViewEventRow() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        ListViewEventRow.prototype.render = function () {
+            var _a = this, props = _a.props, context = _a.context;
+            var seg = props.seg, timeHeaderId = props.timeHeaderId, eventHeaderId = props.eventHeaderId, dateHeaderId = props.dateHeaderId;
+            var timeFormat = context.options.eventTimeFormat || DEFAULT_TIME_FORMAT;
+            return (createElement(EventRoot, { seg: seg, timeText: "" // BAD. because of all-day content
+                , disableDragging: true, disableResizing: true, defaultContent: function () { return renderEventInnerContent(seg, context); } /* weird */, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday, isSelected: props.isSelected, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("tr", { className: ['fc-list-event', hookProps.event.url ? 'fc-event-forced-url' : ''].concat(classNames).join(' '), ref: rootElRef },
+                buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId),
+                createElement("td", { "aria-hidden": true, className: "fc-list-event-graphic" },
+                    createElement("span", { className: "fc-list-event-dot", style: { borderColor: hookProps.borderColor || hookProps.backgroundColor } })),
+                createElement("td", { ref: innerElRef, headers: eventHeaderId + " " + dateHeaderId, className: "fc-list-event-title" }, innerContent))); }));
+        };
+        return ListViewEventRow;
+    }(BaseComponent));
+    function renderEventInnerContent(seg, context) {
+        var interactiveAttrs = getSegAnchorAttrs(seg, context);
+        return (createElement("a", __assign({}, interactiveAttrs), seg.eventRange.def.title));
+    }
+    function buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId) {
+        var options = context.options;
+        if (options.displayEventTime !== false) {
+            var eventDef = seg.eventRange.def;
+            var eventInstance = seg.eventRange.instance;
+            var doAllDay = false;
+            var timeText = void 0;
+            if (eventDef.allDay) {
+                doAllDay = true;
+            }
+            else if (isMultiDayRange(seg.eventRange.range)) { // TODO: use (!isStart || !isEnd) instead?
+                if (seg.isStart) {
+                    timeText = buildSegTimeText(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end);
+                }
+                else if (seg.isEnd) {
+                    timeText = buildSegTimeText(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end);
+                }
+                else {
+                    doAllDay = true;
+                }
+            }
+            else {
+                timeText = buildSegTimeText(seg, timeFormat, context);
+            }
+            if (doAllDay) {
+                var hookProps = {
+                    text: context.options.allDayText,
+                    view: context.viewApi,
+                };
+                return (createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, headers: timeHeaderId + " " + dateHeaderId, className: ['fc-list-event-time'].concat(classNames).join(' ') }, innerContent)); }));
+            }
+            return (createElement("td", { className: "fc-list-event-time" }, timeText));
+        }
+        return null;
+    }
+    function renderAllDayInner(hookProps) {
+        return hookProps.text;
+    }
+
+    /*
+    Responsible for the scroller, and forwarding event-related actions into the "grid".
+    */
+    var ListView = /** @class */ (function (_super) {
+        __extends(ListView, _super);
+        function ListView() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.computeDateVars = memoize(computeDateVars);
+            _this.eventStoreToSegs = memoize(_this._eventStoreToSegs);
+            _this.state = {
+                timeHeaderId: getUniqueDomId(),
+                eventHeaderId: getUniqueDomId(),
+                dateHeaderIdRoot: getUniqueDomId(),
+            };
+            _this.setRootEl = function (rootEl) {
+                if (rootEl) {
+                    _this.context.registerInteractiveComponent(_this, {
+                        el: rootEl,
+                    });
+                }
+                else {
+                    _this.context.unregisterInteractiveComponent(_this);
+                }
+            };
+            return _this;
+        }
+        ListView.prototype.render = function () {
+            var _this = this;
+            var _a = this, props = _a.props, context = _a.context;
+            var extraClassNames = [
+                'fc-list',
+                context.theme.getClass('table'),
+                context.options.stickyHeaderDates !== false ? 'fc-list-sticky' : '',
+            ];
+            var _b = this.computeDateVars(props.dateProfile), dayDates = _b.dayDates, dayRanges = _b.dayRanges;
+            var eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);
+            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.setRootEl }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: extraClassNames.concat(classNames).join(' ') },
+                createElement(Scroller, { liquid: !props.isHeightAuto, overflowX: props.isHeightAuto ? 'visible' : 'hidden', overflowY: props.isHeightAuto ? 'visible' : 'auto' }, eventSegs.length > 0 ?
+                    _this.renderSegList(eventSegs, dayDates) :
+                    _this.renderEmptyMessage()))); }));
+        };
+        ListView.prototype.renderEmptyMessage = function () {
+            var _a = this.context, options = _a.options, viewApi = _a.viewApi;
+            var hookProps = {
+                text: options.noEventsText,
+                view: viewApi,
+            };
+            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.noEventsClassNames, content: options.noEventsContent, defaultContent: renderNoEventsInner, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { className: ['fc-list-empty'].concat(classNames).join(' '), ref: rootElRef },
+                createElement("div", { className: "fc-list-empty-cushion", ref: innerElRef }, innerContent))); }));
+        };
+        ListView.prototype.renderSegList = function (allSegs, dayDates) {
+            var _a = this.context, theme = _a.theme, options = _a.options;
+            var _b = this.state, timeHeaderId = _b.timeHeaderId, eventHeaderId = _b.eventHeaderId, dateHeaderIdRoot = _b.dateHeaderIdRoot;
+            var segsByDay = groupSegsByDay(allSegs); // sparse array
+            return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) {
+                var innerNodes = [];
+                for (var dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) {
+                    var daySegs = segsByDay[dayIndex];
+                    if (daySegs) { // sparse array, so might be undefined
+                        var dayStr = formatDayString(dayDates[dayIndex]);
+                        var dateHeaderId = dateHeaderIdRoot + '-' + dayStr;
+                        // append a day header
+                        innerNodes.push(createElement(ListViewHeaderRow, { key: dayStr, cellId: dateHeaderId, dayDate: dayDates[dayIndex], todayRange: todayRange }));
+                        daySegs = sortEventSegs(daySegs, options.eventOrder);
+                        for (var _i = 0, daySegs_1 = daySegs; _i < daySegs_1.length; _i++) {
+                            var seg = daySegs_1[_i];
+                            innerNodes.push(createElement(ListViewEventRow, __assign({ key: dayStr + ':' + seg.eventRange.instance.instanceId /* are multiple segs for an instanceId */, seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, timeHeaderId: timeHeaderId, eventHeaderId: eventHeaderId, dateHeaderId: dateHeaderId }, getSegMeta(seg, todayRange, nowDate))));
+                        }
+                    }
+                }
+                return (createElement("table", { className: 'fc-list-table ' + theme.getClass('table') },
+                    createElement("thead", null,
+                        createElement("tr", null,
+                            createElement("th", { scope: "col", id: timeHeaderId }, options.timeHint),
+                            createElement("th", { scope: "col", "aria-hidden": true }),
+                            createElement("th", { scope: "col", id: eventHeaderId }, options.eventHint))),
+                    createElement("tbody", null, innerNodes)));
+            }));
+        };
+        ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) {
+            return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);
+        };
+        ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) {
+            var segs = [];
+            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
+                var eventRange = eventRanges_1[_i];
+                segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges));
+            }
+            return segs;
+        };
+        ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) {
+            var dateEnv = this.context.dateEnv;
+            var nextDayThreshold = this.context.options.nextDayThreshold;
+            var range = eventRange.range;
+            var allDay = eventRange.def.allDay;
+            var dayIndex;
+            var segRange;
+            var seg;
+            var segs = [];
+            for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) {
+                segRange = intersectRanges(range, dayRanges[dayIndex]);
+                if (segRange) {
+                    seg = {
+                        component: this,
+                        eventRange: eventRange,
+                        start: segRange.start,
+                        end: segRange.end,
+                        isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(),
+                        isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(),
+                        dayIndex: dayIndex,
+                    };
+                    segs.push(seg);
+                    // detect when range won't go fully into the next day,
+                    // and mutate the latest seg to the be the end.
+                    if (!seg.isEnd && !allDay &&
+                        dayIndex + 1 < dayRanges.length &&
+                        range.end <
+                            dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) {
+                        seg.end = range.end;
+                        seg.isEnd = true;
+                        break;
+                    }
+                }
+            }
+            return segs;
+        };
+        return ListView;
+    }(DateComponent));
+    function renderNoEventsInner(hookProps) {
+        return hookProps.text;
+    }
+    function computeDateVars(dateProfile) {
+        var dayStart = startOfDay(dateProfile.renderRange.start);
+        var viewEnd = dateProfile.renderRange.end;
+        var dayDates = [];
+        var dayRanges = [];
+        while (dayStart < viewEnd) {
+            dayDates.push(dayStart);
+            dayRanges.push({
+                start: dayStart,
+                end: addDays(dayStart, 1),
+            });
+            dayStart = addDays(dayStart, 1);
+        }
+        return { dayDates: dayDates, dayRanges: dayRanges };
+    }
+    // Returns a sparse array of arrays, segs grouped by their dayIndex
+    function groupSegsByDay(segs) {
+        var segsByDay = []; // sparse array
+        var i;
+        var seg;
+        for (i = 0; i < segs.length; i += 1) {
+            seg = segs[i];
+            (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
+                .push(seg);
+        }
+        return segsByDay;
+    }
+
+    var OPTION_REFINERS$1 = {
+        listDayFormat: createFalsableFormatter,
+        listDaySideFormat: createFalsableFormatter,
+        noEventsClassNames: identity,
+        noEventsContent: identity,
+        noEventsDidMount: identity,
+        noEventsWillUnmount: identity,
+        // noEventsText is defined in base options
+    };
+    function createFalsableFormatter(input) {
+        return input === false ? null : createFormatter(input);
+    }
+
+    var listPlugin = createPlugin({
+        optionRefiners: OPTION_REFINERS$1,
+        views: {
+            list: {
+                component: ListView,
+                buttonTextKey: 'list',
+                listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' }, // like "January 1, 2016"
+            },
+            listDay: {
+                type: 'list',
+                duration: { days: 1 },
+                listDayFormat: { weekday: 'long' }, // day-of-week is all we need. full date is probably in headerToolbar
+            },
+            listWeek: {
+                type: 'list',
+                duration: { weeks: 1 },
+                listDayFormat: { weekday: 'long' },
+                listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' },
+            },
+            listMonth: {
+                type: 'list',
+                duration: { month: 1 },
+                listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have
+            },
+            listYear: {
+                type: 'list',
+                duration: { year: 1 },
+                listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have
+            },
+        },
+    });
+
+    var BootstrapTheme$1 = /** @class */ (function (_super) {
+        __extends(BootstrapTheme, _super);
+        function BootstrapTheme() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        return BootstrapTheme;
+    }(Theme));
+    BootstrapTheme$1.prototype.classes = {
+        root: 'fc-theme-bootstrap',
+        table: 'table-bordered',
+        tableCellShaded: 'table-active',
+        buttonGroup: 'btn-group',
+        button: 'btn btn-primary',
+        buttonActive: 'active',
+        popover: 'popover',
+        popoverHeader: 'popover-header',
+        popoverContent: 'popover-body',
+    };
+    BootstrapTheme$1.prototype.baseIconClass = 'fa';
+    BootstrapTheme$1.prototype.iconClasses = {
+        close: 'fa-times',
+        prev: 'fa-chevron-left',
+        next: 'fa-chevron-right',
+        prevYear: 'fa-angle-double-left',
+        nextYear: 'fa-angle-double-right',
+    };
+    BootstrapTheme$1.prototype.rtlIconClasses = {
+        prev: 'fa-chevron-right',
+        next: 'fa-chevron-left',
+        prevYear: 'fa-angle-double-right',
+        nextYear: 'fa-angle-double-left',
+    };
+    BootstrapTheme$1.prototype.iconOverrideOption = 'bootstrapFontAwesome'; // TODO: make TS-friendly. move the option-processing into this plugin
+    BootstrapTheme$1.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome';
+    BootstrapTheme$1.prototype.iconOverridePrefix = 'fa-';
+    var plugin$1 = createPlugin({
+        themeClasses: {
+            bootstrap: BootstrapTheme$1,
+        },
+    });
+
+    var BootstrapTheme = /** @class */ (function (_super) {
+        __extends(BootstrapTheme, _super);
+        function BootstrapTheme() {
+            return _super !== null && _super.apply(this, arguments) || this;
+        }
+        return BootstrapTheme;
+    }(Theme));
+    BootstrapTheme.prototype.classes = {
+        root: 'fc-theme-bootstrap5',
+        tableCellShaded: 'fc-theme-bootstrap5-shaded',
+        buttonGroup: 'btn-group',
+        button: 'btn btn-primary',
+        buttonActive: 'active',
+        popover: 'popover',
+        popoverHeader: 'popover-header',
+        popoverContent: 'popover-body',
+    };
+    BootstrapTheme.prototype.baseIconClass = 'bi';
+    BootstrapTheme.prototype.iconClasses = {
+        close: 'bi-x-lg',
+        prev: 'bi-chevron-left',
+        next: 'bi-chevron-right',
+        prevYear: 'bi-chevron-double-left',
+        nextYear: 'bi-chevron-double-right',
+    };
+    BootstrapTheme.prototype.rtlIconClasses = {
+        prev: 'bi-chevron-right',
+        next: 'bi-chevron-left',
+        prevYear: 'bi-chevron-double-right',
+        nextYear: 'bi-chevron-double-left',
+    };
+    // wtf
+    BootstrapTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly
+    BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'icon';
+    BootstrapTheme.prototype.iconOverridePrefix = 'bi-';
+    var plugin = createPlugin({
+        themeClasses: {
+            bootstrap5: BootstrapTheme,
+        },
+    });
+
+    // rename this file to options.ts like other packages?
+    var OPTION_REFINERS = {
+        googleCalendarApiKey: String,
+    };
+
+    var EVENT_SOURCE_REFINERS = {
+        googleCalendarApiKey: String,
+        googleCalendarId: String,
+        googleCalendarApiBase: String,
+        extraParams: identity,
+    };
+
+    // TODO: expose somehow
+    var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';
+    var eventSourceDef = {
+        parseMeta: function (refined) {
+            var googleCalendarId = refined.googleCalendarId;
+            if (!googleCalendarId && refined.url) {
+                googleCalendarId = parseGoogleCalendarId(refined.url);
+            }
+            if (googleCalendarId) {
+                return {
+                    googleCalendarId: googleCalendarId,
+                    googleCalendarApiKey: refined.googleCalendarApiKey,
+                    googleCalendarApiBase: refined.googleCalendarApiBase,
+                    extraParams: refined.extraParams,
+                };
+            }
+            return null;
+        },
+        fetch: function (arg, onSuccess, onFailure) {
+            var _a = arg.context, dateEnv = _a.dateEnv, options = _a.options;
+            var meta = arg.eventSource.meta;
+            var apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey;
+            if (!apiKey) {
+                onFailure({
+                    message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/',
+                });
+            }
+            else {
+                var url = buildUrl(meta);
+                // TODO: make DRY with json-feed-event-source
+                var extraParams = meta.extraParams;
+                var extraParamsObj = typeof extraParams === 'function' ? extraParams() : extraParams;
+                var requestParams_1 = buildRequestParams(arg.range, apiKey, extraParamsObj, dateEnv);
+                requestJson('GET', url, requestParams_1, function (body, xhr) {
+                    if (body.error) {
+                        onFailure({
+                            message: 'Google Calendar API: ' + body.error.message,
+                            errors: body.error.errors,
+                            xhr: xhr,
+                        });
+                    }
+                    else {
+                        onSuccess({
+                            rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone),
+                            xhr: xhr,
+                        });
+                    }
+                }, function (message, xhr) {
+                    onFailure({ message: message, xhr: xhr });
+                });
+            }
+        },
+    };
+    function parseGoogleCalendarId(url) {
+        var match;
+        // detect if the ID was specified as a single string.
+        // will match calendars like "asdf1234@calendar.google.com" in addition to person email calendars.
+        if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) {
+            return url;
+        }
+        if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(url)) ||
+            (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url))) {
+            return decodeURIComponent(match[1]);
+        }
+        return null;
+    }
+    function buildUrl(meta) {
+        var apiBase = meta.googleCalendarApiBase;
+        if (!apiBase) {
+            apiBase = API_BASE;
+        }
+        return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events';
+    }
+    function buildRequestParams(range, apiKey, extraParams, dateEnv) {
+        var params;
+        var startStr;
+        var endStr;
+        if (dateEnv.canComputeOffset) {
+            // strings will naturally have offsets, which GCal needs
+            startStr = dateEnv.formatIso(range.start);
+            endStr = dateEnv.formatIso(range.end);
+        }
+        else {
+            // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day
+            // from the UTC day-start to guarantee we're getting all the events
+            // (start/end will be UTC-coerced dates, so toISOString is okay)
+            startStr = addDays(range.start, -1).toISOString();
+            endStr = addDays(range.end, 1).toISOString();
+        }
+        params = __assign(__assign({}, (extraParams || {})), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 });
+        if (dateEnv.timeZone !== 'local') {
+            params.timeZone = dateEnv.timeZone;
+        }
+        return params;
+    }
+    function gcalItemsToRawEventDefs(items, gcalTimezone) {
+        return items.map(function (item) { return gcalItemToRawEventDef(item, gcalTimezone); });
+    }
+    function gcalItemToRawEventDef(item, gcalTimezone) {
+        var url = item.htmlLink || null;
+        // make the URLs for each event show times in the correct timezone
+        if (url && gcalTimezone) {
+            url = injectQsComponent(url, 'ctz=' + gcalTimezone);
+        }
+        return {
+            id: item.id,
+            title: item.summary,
+            start: item.start.dateTime || item.start.date,
+            end: item.end.dateTime || item.end.date,
+            url: url,
+            location: item.location,
+            description: item.description,
+            attachments: item.attachments || [],
+            extendedProps: (item.extendedProperties || {}).shared || {},
+        };
+    }
+    // Injects a string like "arg=value" into the querystring of a URL
+    // TODO: move to a general util file?
+    function injectQsComponent(url, component) {
+        // inject it after the querystring but before the fragment
+        return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { return (qs ? qs + '&' : '?') + component + hash; });
+    }
+    var googleCalendarPlugin = createPlugin({
+        eventSourceDefs: [eventSourceDef],
+        optionRefiners: OPTION_REFINERS,
+        eventSourceRefiners: EVENT_SOURCE_REFINERS,
+    });
+
+    globalPlugins.push(interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, plugin$1, plugin, googleCalendarPlugin);
+
+    exports.BASE_OPTION_DEFAULTS = BASE_OPTION_DEFAULTS;
+    exports.BASE_OPTION_REFINERS = BASE_OPTION_REFINERS;
+    exports.BaseComponent = BaseComponent;
+    exports.BgEvent = BgEvent;
+    exports.BootstrapTheme = BootstrapTheme$1;
+    exports.Calendar = Calendar;
+    exports.CalendarApi = CalendarApi;
+    exports.CalendarContent = CalendarContent;
+    exports.CalendarDataManager = CalendarDataManager;
+    exports.CalendarDataProvider = CalendarDataProvider;
+    exports.CalendarRoot = CalendarRoot;
+    exports.Component = Component;
+    exports.ContentHook = ContentHook;
+    exports.CustomContentRenderContext = CustomContentRenderContext;
+    exports.DateComponent = DateComponent;
+    exports.DateEnv = DateEnv;
+    exports.DateProfileGenerator = DateProfileGenerator;
+    exports.DayCellContent = DayCellContent;
+    exports.DayCellRoot = DayCellRoot;
+    exports.DayGridView = DayTableView;
+    exports.DayHeader = DayHeader;
+    exports.DaySeriesModel = DaySeriesModel;
+    exports.DayTable = DayTable;
+    exports.DayTableModel = DayTableModel;
+    exports.DayTableSlicer = DayTableSlicer;
+    exports.DayTimeCols = DayTimeCols;
+    exports.DayTimeColsSlicer = DayTimeColsSlicer;
+    exports.DayTimeColsView = DayTimeColsView;
+    exports.DelayedRunner = DelayedRunner;
+    exports.Draggable = ExternalDraggable;
+    exports.ElementDragging = ElementDragging;
+    exports.ElementScrollController = ElementScrollController;
+    exports.Emitter = Emitter;
+    exports.EventApi = EventApi;
+    exports.EventRoot = EventRoot;
+    exports.EventSourceApi = EventSourceApi;
+    exports.FeaturefulElementDragging = FeaturefulElementDragging;
+    exports.Fragment = Fragment;
+    exports.Interaction = Interaction;
+    exports.ListView = ListView;
+    exports.MoreLinkRoot = MoreLinkRoot;
+    exports.MountHook = MountHook;
+    exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
+    exports.NowIndicatorRoot = NowIndicatorRoot;
+    exports.NowTimer = NowTimer;
+    exports.PointerDragging = PointerDragging;
+    exports.PositionCache = PositionCache;
+    exports.RefMap = RefMap;
+    exports.RenderHook = RenderHook;
+    exports.ScrollController = ScrollController;
+    exports.ScrollResponder = ScrollResponder;
+    exports.Scroller = Scroller;
+    exports.SegHierarchy = SegHierarchy;
+    exports.SimpleScrollGrid = SimpleScrollGrid;
+    exports.Slicer = Slicer;
+    exports.Splitter = Splitter;
+    exports.StandardEvent = StandardEvent;
+    exports.Table = Table;
+    exports.TableDateCell = TableDateCell;
+    exports.TableDowCell = TableDowCell;
+    exports.TableView = TableView;
+    exports.Theme = Theme;
+    exports.ThirdPartyDraggable = ThirdPartyDraggable;
+    exports.TimeCols = TimeCols;
+    exports.TimeColsSlatsCoords = TimeColsSlatsCoords;
+    exports.TimeColsView = TimeColsView;
+    exports.ViewApi = ViewApi;
+    exports.ViewContextType = ViewContextType;
+    exports.ViewRoot = ViewRoot;
+    exports.WeekNumberRoot = WeekNumberRoot;
+    exports.WindowScrollController = WindowScrollController;
+    exports.addDays = addDays;
+    exports.addDurations = addDurations;
+    exports.addMs = addMs;
+    exports.addWeeks = addWeeks;
+    exports.allowContextMenu = allowContextMenu;
+    exports.allowSelection = allowSelection;
+    exports.applyMutationToEventStore = applyMutationToEventStore;
+    exports.applyStyle = applyStyle;
+    exports.applyStyleProp = applyStyleProp;
+    exports.asCleanDays = asCleanDays;
+    exports.asRoughMinutes = asRoughMinutes;
+    exports.asRoughMs = asRoughMs;
+    exports.asRoughSeconds = asRoughSeconds;
+    exports.binarySearch = binarySearch;
+    exports.buildClassNameNormalizer = buildClassNameNormalizer;
+    exports.buildDayRanges = buildDayRanges;
+    exports.buildDayTableModel = buildDayTableModel;
+    exports.buildEntryKey = buildEntryKey;
+    exports.buildEventApis = buildEventApis;
+    exports.buildEventRangeKey = buildEventRangeKey;
+    exports.buildHashFromArray = buildHashFromArray;
+    exports.buildIsoString = buildIsoString;
+    exports.buildNavLinkAttrs = buildNavLinkAttrs;
+    exports.buildSegCompareObj = buildSegCompareObj;
+    exports.buildSegTimeText = buildSegTimeText;
+    exports.buildSlatMetas = buildSlatMetas;
+    exports.buildTimeColsModel = buildTimeColsModel;
+    exports.collectFromHash = collectFromHash;
+    exports.combineEventUis = combineEventUis;
+    exports.compareByFieldSpec = compareByFieldSpec;
+    exports.compareByFieldSpecs = compareByFieldSpecs;
+    exports.compareNumbers = compareNumbers;
+    exports.compareObjs = compareObjs;
+    exports.computeEarliestSegStart = computeEarliestSegStart;
+    exports.computeEdges = computeEdges;
+    exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat;
+    exports.computeHeightAndMargins = computeHeightAndMargins;
+    exports.computeInnerRect = computeInnerRect;
+    exports.computeRect = computeRect;
+    exports.computeSegDraggable = computeSegDraggable;
+    exports.computeSegEndResizable = computeSegEndResizable;
+    exports.computeSegStartResizable = computeSegStartResizable;
+    exports.computeShrinkWidth = computeShrinkWidth;
+    exports.computeSmallestCellWidth = computeSmallestCellWidth;
+    exports.computeVisibleDayRange = computeVisibleDayRange;
+    exports.config = config;
+    exports.constrainPoint = constrainPoint;
+    exports.createAriaClickAttrs = createAriaClickAttrs;
+    exports.createContext = createContext;
+    exports.createDuration = createDuration;
+    exports.createElement = createElement;
+    exports.createEmptyEventStore = createEmptyEventStore;
+    exports.createEventInstance = createEventInstance;
+    exports.createEventUi = createEventUi;
+    exports.createFormatter = createFormatter;
+    exports.createPlugin = createPlugin;
+    exports.createPortal = createPortal;
+    exports.createRef = createRef;
+    exports.diffDates = diffDates;
+    exports.diffDayAndTime = diffDayAndTime;
+    exports.diffDays = diffDays;
+    exports.diffPoints = diffPoints;
+    exports.diffWeeks = diffWeeks;
+    exports.diffWholeDays = diffWholeDays;
+    exports.diffWholeWeeks = diffWholeWeeks;
+    exports.disableCursor = disableCursor;
+    exports.elementClosest = elementClosest;
+    exports.elementMatches = elementMatches;
+    exports.enableCursor = enableCursor;
+    exports.eventTupleToStore = eventTupleToStore;
+    exports.filterEventStoreDefs = filterEventStoreDefs;
+    exports.filterHash = filterHash;
+    exports.findDirectChildren = findDirectChildren;
+    exports.findElements = findElements;
+    exports.flexibleCompare = flexibleCompare;
+    exports.flushSync = flushSync;
+    exports.formatDate = formatDate;
+    exports.formatDayString = formatDayString;
+    exports.formatIsoTimeString = formatIsoTimeString;
+    exports.formatRange = formatRange;
+    exports.getAllowYScrolling = getAllowYScrolling;
+    exports.getCanVGrowWithinCell = getCanVGrowWithinCell;
+    exports.getClippingParents = getClippingParents;
+    exports.getDateMeta = getDateMeta;
+    exports.getDayClassNames = getDayClassNames;
+    exports.getDefaultEventEnd = getDefaultEventEnd;
+    exports.getElRoot = getElRoot;
+    exports.getElSeg = getElSeg;
+    exports.getEntrySpanEnd = getEntrySpanEnd;
+    exports.getEventClassNames = getEventClassNames;
+    exports.getEventTargetViaRoot = getEventTargetViaRoot;
+    exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft;
+    exports.getRectCenter = getRectCenter;
+    exports.getRelevantEvents = getRelevantEvents;
+    exports.getScrollGridClassNames = getScrollGridClassNames;
+    exports.getScrollbarWidths = getScrollbarWidths;
+    exports.getSectionClassNames = getSectionClassNames;
+    exports.getSectionHasLiquidHeight = getSectionHasLiquidHeight;
+    exports.getSegAnchorAttrs = getSegAnchorAttrs;
+    exports.getSegMeta = getSegMeta;
+    exports.getSlotClassNames = getSlotClassNames;
+    exports.getStickyFooterScrollbar = getStickyFooterScrollbar;
+    exports.getStickyHeaderDates = getStickyHeaderDates;
+    exports.getUnequalProps = getUnequalProps;
+    exports.getUniqueDomId = getUniqueDomId;
+    exports.globalLocales = globalLocales;
+    exports.globalPlugins = globalPlugins;
+    exports.greatestDurationDenominator = greatestDurationDenominator;
+    exports.groupIntersectingEntries = groupIntersectingEntries;
+    exports.guid = guid;
+    exports.hasBgRendering = hasBgRendering;
+    exports.hasShrinkWidth = hasShrinkWidth;
+    exports.identity = identity;
+    exports.interactionSettingsStore = interactionSettingsStore;
+    exports.interactionSettingsToStore = interactionSettingsToStore;
+    exports.intersectRanges = intersectRanges;
+    exports.intersectRects = intersectRects;
+    exports.intersectSpans = intersectSpans;
+    exports.isArraysEqual = isArraysEqual;
+    exports.isColPropsEqual = isColPropsEqual;
+    exports.isDateSelectionValid = isDateSelectionValid;
+    exports.isDateSpansEqual = isDateSpansEqual;
+    exports.isInt = isInt;
+    exports.isInteractionValid = isInteractionValid;
+    exports.isMultiDayRange = isMultiDayRange;
+    exports.isPropsEqual = isPropsEqual;
+    exports.isPropsValid = isPropsValid;
+    exports.isValidDate = isValidDate;
+    exports.joinSpans = joinSpans;
+    exports.listenBySelector = listenBySelector;
+    exports.mapHash = mapHash;
+    exports.memoize = memoize;
+    exports.memoizeArraylike = memoizeArraylike;
+    exports.memoizeHashlike = memoizeHashlike;
+    exports.memoizeObjArg = memoizeObjArg;
+    exports.mergeEventStores = mergeEventStores;
+    exports.multiplyDuration = multiplyDuration;
+    exports.padStart = padStart;
+    exports.parseBusinessHours = parseBusinessHours;
+    exports.parseClassNames = parseClassNames;
+    exports.parseDragMeta = parseDragMeta;
+    exports.parseEventDef = parseEventDef;
+    exports.parseFieldSpecs = parseFieldSpecs;
+    exports.parseMarker = parse;
+    exports.pointInsideRect = pointInsideRect;
+    exports.preventContextMenu = preventContextMenu;
+    exports.preventDefault = preventDefault;
+    exports.preventSelection = preventSelection;
+    exports.rangeContainsMarker = rangeContainsMarker;
+    exports.rangeContainsRange = rangeContainsRange;
+    exports.rangesEqual = rangesEqual;
+    exports.rangesIntersect = rangesIntersect;
+    exports.refineEventDef = refineEventDef;
+    exports.refineProps = refineProps;
+    exports.removeElement = removeElement;
+    exports.removeExact = removeExact;
+    exports.render = render;
+    exports.renderChunkContent = renderChunkContent;
+    exports.renderFill = renderFill;
+    exports.renderMicroColGroup = renderMicroColGroup;
+    exports.renderScrollShim = renderScrollShim;
+    exports.requestJson = requestJson;
+    exports.sanitizeShrinkWidth = sanitizeShrinkWidth;
+    exports.setElSeg = setElSeg;
+    exports.setRef = setRef;
+    exports.sliceEventStore = sliceEventStore;
+    exports.sliceEvents = sliceEvents;
+    exports.sortEventSegs = sortEventSegs;
+    exports.startOfDay = startOfDay;
+    exports.translateRect = translateRect;
+    exports.triggerDateSelect = triggerDateSelect;
+    exports.unmountComponentAtNode = unmountComponentAtNode;
+    exports.unpromisify = unpromisify;
+    exports.version = version;
+    exports.whenTransitionDone = whenTransitionDone;
+    exports.wholeDivideDurations = wholeDivideDurations;
+
+    Object.defineProperty(exports, '__esModule', { value: true });
+
+    return exports;
+
+}({}));
diff --git a/static_common/common/vendor/fullcalendar/main.min.css b/static_common/common/vendor/fullcalendar/main.min.css
new file mode 100644
index 0000000000000000000000000000000000000000..5c0056ea8251a9b8c8db14e117008f7a961c360c
--- /dev/null
+++ b/static_common/common/vendor/fullcalendar/main.min.css
@@ -0,0 +1 @@
+.fc-icon,.fc-unselectable{-moz-user-select:none;-ms-user-select:none}.fc .fc-button,.fc-icon{text-transform:none;font-weight:400}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc .fc-button:not(:disabled),.fc a[data-navlink],.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-unselectable{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}.fc{display:flex;flex-direction:column;font-size:1em}.fc .fc-button,.fc-icon{display:inline-block;text-align:center}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{vertical-align:top;padding:0}.fc .fc-button,.fc .fc-button .fc-icon,.fc .fc-button-group,.fc .fc-timegrid-slot-label{vertical-align:middle}.fc a[data-navlink]:hover{text-decoration:underline}.fc .fc-button:hover,.fc .fc-list-event-title a,a.fc-event,a.fc-event:hover{text-decoration:none}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid #ddd;border:1px solid var(--fc-border-color,#ddd)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;src:url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyYiDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format('truetype');font-weight:400;font-style:normal}.fc-icon{width:1em;height:1em;-webkit-user-select:none;user-select:none;font-family:fcicons!important;speak:none;font-style:normal;font-variant:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fc-icon-chevron-left:before{content:"\e900"}.fc-icon-chevron-right:before{content:"\e901"}.fc-icon-chevrons-left:before{content:"\e902"}.fc-icon-chevrons-right:before{content:"\e903"}.fc-icon-minus-square:before{content:"\e904"}.fc-icon-plus-square:before{content:"\e905"}.fc-icon-x:before{content:"\e906"}.fc .fc-button{overflow:visible;text-transform:none;margin:0;font-family:inherit}.fc .fc-button::-moz-focus-inner{padding:0;border-style:none}.fc .fc-button{-webkit-appearance:button;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.4em .65em;font-size:1em;line-height:1.5;border-radius:.25em}.fc .fc-button:focus{outline:0;box-shadow:0 0 0 .2rem rgba(44,62,80,.25)}.fc .fc-button-primary:focus,.fc .fc-button-primary:not(:disabled).fc-button-active:focus,.fc .fc-button-primary:not(:disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button:disabled{opacity:.65}.fc .fc-button-primary{color:#fff;color:var(--fc-button-text-color,#fff);background-color:#2C3E50;background-color:var(--fc-button-bg-color,#2C3E50);border-color:#2C3E50;border-color:var(--fc-button-border-color,#2C3E50)}.fc .fc-button-primary:hover{color:#fff;color:var(--fc-button-text-color,#fff);background-color:#1e2b37;background-color:var(--fc-button-hover-bg-color,#1e2b37);border-color:#1a252f;border-color:var(--fc-button-hover-border-color,#1a252f)}.fc .fc-button-primary:disabled{color:#fff;color:var(--fc-button-text-color,#fff);background-color:#2C3E50;background-color:var(--fc-button-bg-color,#2C3E50);border-color:#2C3E50;border-color:var(--fc-button-border-color,#2C3E50)}.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{color:#fff;color:var(--fc-button-text-color,#fff);background-color:#1a252f;background-color:var(--fc-button-active-bg-color,#1a252f);border-color:#151e27;border-color:var(--fc-button-active-border-color,#151e27)}.fc .fc-button .fc-icon{font-size:1.5em}.fc .fc-button-group{position:relative;display:inline-flex}.fc .fc-button-group>.fc-button{position:relative;flex:1 1 auto}.fc .fc-button-group>.fc-button.fc-button-active,.fc .fc-button-group>.fc-button:active,.fc .fc-button-group>.fc-button:focus,.fc .fc-button-group>.fc-button:hover{z-index:1}.fc-direction-ltr .fc-button-group>.fc-button:not(:first-child){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.fc-direction-ltr .fc-button-group>.fc-button:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:first-child){margin-right:-1px;border-top-right-radius:0;border-bottom-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:last-child){border-top-left-radius:0;border-bottom-left-radius:0}.fc .fc-toolbar{display:flex;justify-content:space-between;align-items:center}.fc .fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc .fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc .fc-toolbar-title{font-size:1.75em;margin:0}.fc-direction-ltr .fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-direction-rtl .fc-toolbar>*>:not(:first-child){margin-right:.75em}.fc-direction-rtl .fc-toolbar-ltr{flex-direction:row-reverse}.fc .fc-scroller{-webkit-overflow-scrolling:touch;position:relative}.fc .fc-scroller-liquid{height:100%}.fc .fc-scroller-liquid-absolute{position:absolute;top:0;right:0;left:0;bottom:0}.fc .fc-scroller-harness{position:relative;overflow:hidden;direction:ltr}.fc .fc-scroller-harness-liquid{height:100%}.fc-direction-rtl .fc-scroller-harness>.fc-scroller{direction:rtl}.fc-theme-standard .fc-scrollgrid{border:1px solid #ddd;border:1px solid var(--fc-border-color,#ddd)}.fc .fc-scrollgrid,.fc .fc-scrollgrid-section-footer>*,.fc .fc-scrollgrid-section-header>*{border-bottom-width:0}.fc .fc-scrollgrid,.fc .fc-scrollgrid table{width:100%;table-layout:fixed}.fc .fc-scrollgrid table{border-top-style:hidden;border-left-style:hidden;border-right-style:hidden}.fc .fc-scrollgrid{border-collapse:separate;border-right-width:0}.fc .fc-scrollgrid-liquid{height:100%}.fc .fc-scrollgrid-section,.fc .fc-scrollgrid-section table,.fc .fc-scrollgrid-section>td{height:1px}.fc .fc-scrollgrid-section-liquid>td{height:100%}.fc .fc-scrollgrid-section>*{border-top-width:0;border-left-width:0}.fc .fc-scrollgrid-section-body table,.fc .fc-scrollgrid-section-footer table{border-bottom-style:hidden}.fc .fc-scrollgrid-section-sticky>*{background:var(--fc-page-bg-color,#fff);position:sticky;z-index:3}.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky>*{top:0}.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky>*{bottom:0}.fc .fc-scrollgrid-sticky-shim{height:1px;margin-bottom:-1px}.fc-sticky{position:sticky}.fc .fc-view-harness{flex-grow:1;position:relative}.fc .fc-bg-event,.fc .fc-highlight,.fc .fc-non-business,.fc .fc-view-harness-active>.fc-view{position:absolute;top:0;left:0;right:0;bottom:0}.fc .fc-col-header-cell-cushion{display:inline-block;padding:2px 4px}.fc .fc-non-business{background:rgba(215,215,215,.3);background:var(--fc-non-business-color,rgba(215,215,215,.3))}.fc .fc-bg-event{background:var(--fc-bg-event-color,#8fdf82);opacity:.3;opacity:var(--fc-bg-event-opacity,.3)}.fc .fc-bg-event .fc-event-title{margin:.5em;font-size:.85em;font-size:var(--fc-small-font-size,.85em);font-style:italic}.fc .fc-highlight{background:rgba(188,232,241,.3);background:var(--fc-highlight-color,rgba(188,232,241,.3))}.fc .fc-cell-shaded,.fc .fc-day-disabled{background:rgba(208,208,208,.3);background:var(--fc-neutral-bg-color,rgba(208,208,208,.3))}.fc-event .fc-event-main{position:relative;z-index:2}.fc-event-dragging:not(.fc-event-selected){opacity:.75}.fc-event-dragging.fc-event-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event .fc-event-resizer{display:none;position:absolute;z-index:4}.fc-event-selected .fc-event-resizer,.fc-event:hover .fc-event-resizer,.fc-h-event,.fc-v-event{display:block}.fc-event-selected .fc-event-resizer{border-radius:4px;border-radius:calc(var(--fc-event-resizer-dot-total-width,8px)/ 2);border-width:1px;border-width:var(--fc-event-resizer-dot-border-width,1px);width:8px;width:var(--fc-event-resizer-dot-total-width,8px);height:8px;height:var(--fc-event-resizer-dot-total-width,8px);border-style:solid;border-color:inherit;background:var(--fc-page-bg-color,#fff)}.fc-event-selected .fc-event-resizer:before{content:'';position:absolute;top:-20px;left:-20px;right:-20px;bottom:-20px}.fc-event-selected,.fc-event:focus{box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event-selected:before,.fc-event:focus:before{content:"";position:absolute;z-index:3;top:0;left:0;right:0;bottom:0}.fc-event-selected:after,.fc-event:focus:after{content:"";background:rgba(0,0,0,.25);background:var(--fc-event-selected-overlay-color,rgba(0,0,0,.25));position:absolute;z-index:1;top:-1px;left:-1px;right:-1px;bottom:-1px}.fc-h-event{border:1px solid #3788d8;border:1px solid var(--fc-event-border-color,#3788d8);background-color:#3788d8;background-color:var(--fc-event-bg-color,#3788d8)}.fc-h-event .fc-event-main{color:#fff;color:var(--fc-event-text-color,#fff)}.fc-h-event .fc-event-main-frame{display:flex}.fc-h-event .fc-event-time{max-width:100%;overflow:hidden}.fc-h-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-width:0}.fc-h-event .fc-event-title{display:inline-block;vertical-align:top;left:0;right:0;max-width:100%;overflow:hidden}.fc-h-event.fc-event-selected:before{top:-10px;bottom:-10px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-top-left-radius:0;border-bottom-left-radius:0;border-left-width:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-top-right-radius:0;border-bottom-right-radius:0;border-right-width:0}.fc-h-event:not(.fc-event-selected) .fc-event-resizer{top:0;bottom:0;width:8px;width:var(--fc-event-resizer-thickness,8px)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end{cursor:w-resize;left:-4px;left:calc(-.5 * var(--fc-event-resizer-thickness,8px))}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start{cursor:e-resize;right:-4px;right:calc(-.5 * var(--fc-event-resizer-thickness,8px))}.fc-h-event.fc-event-selected .fc-event-resizer{top:50%;margin-top:-4px;margin-top:calc(-.5 * var(--fc-event-resizer-dot-total-width,8px))}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end{left:-4px;left:calc(-.5 * var(--fc-event-resizer-dot-total-width,8px))}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start{right:-4px;right:calc(-.5 * var(--fc-event-resizer-dot-total-width,8px))}.fc .fc-popover{position:absolute;z-index:9999;box-shadow:0 2px 6px rgba(0,0,0,.15)}.fc .fc-popover-header{display:flex;flex-direction:row;justify-content:space-between;align-items:center;padding:3px 4px}.fc .fc-popover-title{margin:0 2px}.fc .fc-popover-close{cursor:pointer;opacity:.65;font-size:1.1em}.fc-theme-standard .fc-popover{border:1px solid #ddd;border:1px solid var(--fc-border-color,#ddd);background:var(--fc-page-bg-color,#fff)}.fc-theme-standard .fc-popover-header{background:rgba(208,208,208,.3);background:var(--fc-neutral-bg-color,rgba(208,208,208,.3))}:root{--fc-daygrid-event-dot-width:8px;--fc-list-event-dot-width:10px;--fc-list-event-hover-bg-color:#f5f5f5}.fc-daygrid-day-events:after,.fc-daygrid-day-events:before,.fc-daygrid-day-frame:after,.fc-daygrid-day-frame:before,.fc-daygrid-event-harness:after,.fc-daygrid-event-harness:before{content:"";clear:both;display:table}.fc .fc-daygrid-body{position:relative;z-index:1}.fc .fc-daygrid-day.fc-day-today{background-color:rgba(255,220,40,.15);background-color:var(--fc-today-bg-color,rgba(255,220,40,.15))}.fc .fc-daygrid-day-frame{position:relative;min-height:100%}.fc .fc-daygrid-day-top{display:flex;flex-direction:row-reverse}.fc .fc-day-other .fc-daygrid-day-top{opacity:.3}.fc .fc-daygrid-day-number{position:relative;z-index:4;padding:4px}.fc .fc-daygrid-day-events{margin-top:1px}.fc .fc-daygrid-body-balanced .fc-daygrid-day-events{position:absolute;left:0;right:0}.fc .fc-daygrid-body-unbalanced .fc-daygrid-day-events{position:relative;min-height:2em}.fc .fc-daygrid-body-natural .fc-daygrid-day-events{margin-bottom:1em}.fc .fc-daygrid-event-harness{position:relative}.fc .fc-daygrid-event-harness-abs{position:absolute;top:0;left:0;right:0}.fc .fc-daygrid-bg-harness{position:absolute;top:0;bottom:0}.fc .fc-daygrid-day-bg .fc-non-business{z-index:1}.fc .fc-daygrid-day-bg .fc-bg-event{z-index:2}.fc .fc-daygrid-day-bg .fc-highlight{z-index:3}.fc .fc-daygrid-event{z-index:6;margin-top:1px}.fc .fc-daygrid-event.fc-event-mirror{z-index:7}.fc .fc-daygrid-day-bottom{font-size:.85em;padding:2px 3px 0}.fc .fc-daygrid-day-bottom:before{content:"";clear:both;display:table}.fc .fc-daygrid-more-link{position:relative;z-index:4;cursor:pointer}.fc .fc-daygrid-week-number{position:absolute;z-index:5;top:0;padding:2px;min-width:1.5em;text-align:center;background-color:rgba(208,208,208,.3);background-color:var(--fc-neutral-bg-color,rgba(208,208,208,.3));color:grey;color:var(--fc-neutral-text-color,grey)}.fc .fc-more-popover .fc-popover-body{min-width:220px;padding:10px}.fc-direction-ltr .fc-daygrid-event.fc-event-start,.fc-direction-rtl .fc-daygrid-event.fc-event-end{margin-left:2px}.fc-direction-ltr .fc-daygrid-event.fc-event-end,.fc-direction-rtl .fc-daygrid-event.fc-event-start{margin-right:2px}.fc-direction-ltr .fc-daygrid-week-number{left:0;border-radius:0 0 3px}.fc-direction-rtl .fc-daygrid-week-number{right:0;border-radius:0 0 0 3px}.fc-liquid-hack .fc-daygrid-day-frame{position:static}.fc-daygrid-event{position:relative;white-space:nowrap;border-radius:3px;font-size:.85em;font-size:var(--fc-small-font-size,.85em)}.fc-daygrid-block-event .fc-event-time{font-weight:700}.fc-daygrid-block-event .fc-event-time,.fc-daygrid-block-event .fc-event-title{padding:1px}.fc-daygrid-dot-event{display:flex;align-items:center;padding:2px 0}.fc-daygrid-dot-event .fc-event-title{flex-grow:1;flex-shrink:1;min-width:0;overflow:hidden;font-weight:700}.fc-daygrid-dot-event.fc-event-mirror,.fc-daygrid-dot-event:hover{background:rgba(0,0,0,.1)}.fc-daygrid-dot-event.fc-event-selected:before{top:-10px;bottom:-10px}.fc-daygrid-event-dot{margin:0 4px;box-sizing:content-box;width:0;height:0;border:4px solid #3788d8;border:calc(var(--fc-daygrid-event-dot-width,8px)/ 2) solid var(--fc-event-border-color,#3788d8);border-radius:4px;border-radius:calc(var(--fc-daygrid-event-dot-width,8px)/ 2)}.fc-direction-ltr .fc-daygrid-event .fc-event-time{margin-right:3px}.fc-direction-rtl .fc-daygrid-event .fc-event-time{margin-left:3px}.fc-v-event{border:1px solid #3788d8;border:1px solid var(--fc-event-border-color,#3788d8);background-color:#3788d8;background-color:var(--fc-event-bg-color,#3788d8)}.fc-v-event .fc-event-main{color:#fff;color:var(--fc-event-text-color,#fff);height:100%}.fc-v-event .fc-event-main-frame{height:100%;display:flex;flex-direction:column}.fc-v-event .fc-event-time{flex-grow:0;flex-shrink:0;max-height:100%;overflow:hidden}.fc-v-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-height:0}.fc-v-event .fc-event-title{top:0;bottom:0;max-height:100%;overflow:hidden}.fc-v-event:not(.fc-event-start){border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.fc-v-event:not(.fc-event-end){border-bottom-width:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.fc-v-event.fc-event-selected:before{left:-10px;right:-10px}.fc-v-event .fc-event-resizer-start{cursor:n-resize}.fc-v-event .fc-event-resizer-end{cursor:s-resize}.fc-v-event:not(.fc-event-selected) .fc-event-resizer{height:8px;height:var(--fc-event-resizer-thickness,8px);left:0;right:0}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-start{top:-4px;top:calc(var(--fc-event-resizer-thickness,8px)/ -2)}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-end{bottom:-4px;bottom:calc(var(--fc-event-resizer-thickness,8px)/ -2)}.fc-v-event.fc-event-selected .fc-event-resizer{left:50%;margin-left:-4px;margin-left:calc(var(--fc-event-resizer-dot-total-width,8px)/ -2)}.fc-v-event.fc-event-selected .fc-event-resizer-start{top:-4px;top:calc(var(--fc-event-resizer-dot-total-width,8px)/ -2)}.fc-v-event.fc-event-selected .fc-event-resizer-end{bottom:-4px;bottom:calc(var(--fc-event-resizer-dot-total-width,8px)/ -2)}.fc .fc-timegrid .fc-daygrid-body{z-index:2}.fc .fc-timegrid-axis-chunk>table,.fc .fc-timegrid-body,.fc .fc-timegrid-slots{position:relative;z-index:1}.fc .fc-timegrid-divider{padding:0 0 2px}.fc .fc-timegrid-body{min-height:100%}.fc .fc-timegrid-axis-chunk{position:relative}.fc .fc-timegrid-slot{height:1.5em;border-bottom:0}.fc .fc-timegrid-slot:empty:before{content:'\00a0'}.fc .fc-timegrid-slot-minor{border-top-style:dotted}.fc .fc-timegrid-slot-label-cushion{display:inline-block;white-space:nowrap}.fc .fc-timegrid-axis-cushion,.fc .fc-timegrid-slot-label-cushion{padding:0 4px}.fc .fc-timegrid-axis-frame-liquid{height:100%}.fc .fc-timegrid-axis-frame{overflow:hidden;display:flex;align-items:center;justify-content:flex-end}.fc .fc-timegrid-axis-cushion{max-width:60px;flex-shrink:0}.fc-direction-ltr .fc-timegrid-slot-label-frame{text-align:right}.fc-direction-rtl .fc-timegrid-slot-label-frame{text-align:left}.fc-liquid-hack .fc-timegrid-axis-frame-liquid{height:auto;position:absolute;top:0;right:0;bottom:0;left:0}.fc .fc-timegrid-col.fc-day-today{background-color:rgba(255,220,40,.15);background-color:var(--fc-today-bg-color,rgba(255,220,40,.15))}.fc .fc-timegrid-col-frame{min-height:100%;position:relative}.fc-media-screen.fc-liquid-hack .fc-timegrid-col-frame{height:auto;position:absolute;top:0;right:0;bottom:0;left:0}.fc-media-screen .fc-timegrid-cols{position:absolute;top:0;left:0;right:0;bottom:0}.fc-media-screen .fc-timegrid-cols>table{height:100%}.fc-media-screen .fc-timegrid-col-bg,.fc-media-screen .fc-timegrid-col-events,.fc-media-screen .fc-timegrid-now-indicator-container{position:absolute;top:0;left:0;right:0}.fc .fc-timegrid-col-bg{z-index:2}.fc .fc-timegrid-col-bg .fc-non-business{z-index:1}.fc .fc-timegrid-col-bg .fc-bg-event{z-index:2}.fc .fc-timegrid-col-bg .fc-highlight,.fc .fc-timegrid-col-events{z-index:3}.fc .fc-timegrid-bg-harness{position:absolute;left:0;right:0}.fc .fc-timegrid-now-indicator-container{bottom:0;overflow:hidden}.fc-direction-ltr .fc-timegrid-col-events{margin:0 2.5% 0 2px}.fc-direction-rtl .fc-timegrid-col-events{margin:0 2px 0 2.5%}.fc-timegrid-event-harness{position:absolute}.fc-timegrid-event-harness>.fc-timegrid-event{position:absolute;top:0;bottom:0;left:0;right:0}.fc-timegrid-event-harness-inset .fc-timegrid-event,.fc-timegrid-event.fc-event-mirror,.fc-timegrid-more-link{box-shadow:0 0 0 1px #fff;box-shadow:0 0 0 1px var(--fc-page-bg-color,#fff)}.fc-timegrid-event,.fc-timegrid-more-link{font-size:.85em;font-size:var(--fc-small-font-size,.85em);border-radius:3px}.fc-timegrid-event{margin-bottom:1px}.fc-timegrid-event .fc-event-main{padding:1px 1px 0}.fc-timegrid-event .fc-event-time{white-space:nowrap;font-size:.85em;font-size:var(--fc-small-font-size,.85em);margin-bottom:1px}.fc-timegrid-event-short .fc-event-main-frame{flex-direction:row;overflow:hidden}.fc-timegrid-event-short .fc-event-time:after{content:'\00a0-\00a0'}.fc-timegrid-event-short .fc-event-title{font-size:.85em;font-size:var(--fc-small-font-size,.85em)}.fc-timegrid-more-link{position:absolute;z-index:9999;color:inherit;color:var(--fc-more-link-text-color,inherit);background:var(--fc-more-link-bg-color,#d0d0d0);cursor:pointer;margin-bottom:1px}.fc-timegrid-more-link-inner{padding:3px 2px;top:0}.fc-direction-ltr .fc-timegrid-more-link{right:0}.fc-direction-rtl .fc-timegrid-more-link{left:0}.fc .fc-timegrid-now-indicator-line{position:absolute;z-index:4;left:0;right:0;border-style:solid;border-color:red;border-color:var(--fc-now-indicator-color,red);border-width:1px 0 0}.fc .fc-timegrid-now-indicator-arrow{position:absolute;z-index:4;margin-top:-5px;border-style:solid;border-color:red;border-color:var(--fc-now-indicator-color,red)}.fc-direction-ltr .fc-timegrid-now-indicator-arrow{left:0;border-width:5px 0 5px 6px;border-top-color:transparent;border-bottom-color:transparent}.fc-direction-rtl .fc-timegrid-now-indicator-arrow{right:0;border-width:5px 6px 5px 0;border-top-color:transparent;border-bottom-color:transparent}.fc-theme-standard .fc-list{border:1px solid #ddd;border:1px solid var(--fc-border-color,#ddd)}.fc .fc-list-empty{background-color:rgba(208,208,208,.3);background-color:var(--fc-neutral-bg-color,rgba(208,208,208,.3));height:100%;display:flex;justify-content:center;align-items:center}.fc .fc-list-empty-cushion{margin:5em 0}.fc .fc-list-table{width:100%;border-style:hidden}.fc .fc-list-table tr>*{border-left:0;border-right:0}.fc .fc-list-sticky .fc-list-day>*{position:sticky;top:0;background:var(--fc-page-bg-color,#fff)}.fc .fc-list-table thead{position:absolute;left:-10000px}.fc .fc-list-table tbody>tr:first-child th{border-top:0}.fc .fc-list-table th{padding:0}.fc .fc-list-day-cushion,.fc .fc-list-table td{padding:8px 14px}.fc .fc-list-day-cushion:after{content:"";clear:both;display:table}.fc-theme-standard .fc-list-day-cushion{background-color:rgba(208,208,208,.3);background-color:var(--fc-neutral-bg-color,rgba(208,208,208,.3))}.fc-direction-ltr .fc-list-day-text,.fc-direction-rtl .fc-list-day-side-text{float:left}.fc-direction-ltr .fc-list-day-side-text,.fc-direction-rtl .fc-list-day-text{float:right}.fc-direction-ltr .fc-list-table .fc-list-event-graphic{padding-right:0}.fc-direction-rtl .fc-list-table .fc-list-event-graphic{padding-left:0}.fc .fc-list-event.fc-event-forced-url{cursor:pointer}.fc .fc-list-event:hover td{background-color:#f5f5f5;background-color:var(--fc-list-event-hover-bg-color,#f5f5f5)}.fc .fc-list-event-graphic,.fc .fc-list-event-time{white-space:nowrap;width:1px}.fc .fc-list-event-dot{display:inline-block;box-sizing:content-box;width:0;height:0;border:5px solid #3788d8;border:calc(var(--fc-list-event-dot-width,10px)/ 2) solid var(--fc-event-border-color,#3788d8);border-radius:5px;border-radius:calc(var(--fc-list-event-dot-width,10px)/ 2)}.fc .fc-list-event-title a{color:inherit}.fc .fc-list-event.fc-event-forced-url:hover a{text-decoration:underline}.fc-theme-bootstrap a:not([href]){color:inherit}.fc-theme-bootstrap5 a:not([href]){color:inherit;text-decoration:inherit}.fc-theme-bootstrap5 .fc-list,.fc-theme-bootstrap5 .fc-scrollgrid,.fc-theme-bootstrap5 td,.fc-theme-bootstrap5 th{border:1px solid var(--bs-gray-400)}.fc-theme-bootstrap5 .fc-scrollgrid{border-right-width:0;border-bottom-width:0}.fc-theme-bootstrap5-shaded{background-color:var(--bs-gray-200)}
\ No newline at end of file
diff --git a/static_common/common/vendor/fullcalendar/main.min.js b/static_common/common/vendor/fullcalendar/main.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..186f4c0f717ae566c3cbb6ce390d61b675cf6918
--- /dev/null
+++ b/static_common/common/vendor/fullcalendar/main.min.js
@@ -0,0 +1,6 @@
+/*!
+FullCalendar v5.11.3
+Docs & License: https://fullcalendar.io/
+(c) 2022 Adam Shaw
+*/
+var FullCalendar=function(e){"use strict";var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])})(e,n)};function n(e,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}var r=function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function o(e,t,n){if(n||2===arguments.length)for(var r,o=0,i=t.length;o<i;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||t)}var i,a,s,l,u,c={},d=[],p=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function f(e,t){for(var n in t)e[n]=t[n];return e}function h(e){var t=e.parentNode;t&&t.removeChild(e)}function v(e,t,n){var r,o,i,a=arguments,s={};for(i in t)"key"==i?r=t[i]:"ref"==i?o=t[i]:s[i]=t[i];if(arguments.length>3)for(n=[n],i=3;i<arguments.length;i++)n.push(a[i]);if(null!=n&&(s.children=n),"function"==typeof e&&null!=e.defaultProps)for(i in e.defaultProps)void 0===s[i]&&(s[i]=e.defaultProps[i]);return g(e,s,r,o,null)}function g(e,t,n,r,o){var a={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++i.__v:o};return null!=i.vnode&&i.vnode(a),a}function m(e){return e.children}function y(e,t){this.props=e,this.context=t}function E(e,t){if(null==t)return e.__?E(e.__,e.__.__k.indexOf(e)+1):null;for(var n;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e)return n.__e;return"function"==typeof e.type?E(e):null}function S(e){var t,n;if(null!=(e=e.__)&&null!=e.__c){for(e.__e=e.__c.base=null,t=0;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e){e.__e=e.__c.base=n.__e;break}return S(e)}}function b(e){(!e.__d&&(e.__d=!0)&&a.push(e)&&!D.__r++||l!==i.debounceRendering)&&((l=i.debounceRendering)||s)(D)}function D(){for(var e;D.__r=a.length;)e=a.sort((function(e,t){return e.__v.__b-t.__v.__b})),a=[],e.some((function(e){var t,n,r,o,i,a;e.__d&&(i=(o=(t=e).__v).__e,(a=t.__P)&&(n=[],(r=f({},o)).__v=o.__v+1,I(a,o,r,t.__n,void 0!==a.ownerSVGElement,null!=o.__h?[i]:null,n,null==i?E(o):i,o.__h),P(n,o),o.__e!=i&&S(o)))}))}function C(e,t,n,r,o,i,a,s,l,u){var p,f,h,v,y,S,b,D=r&&r.__k||d,C=D.length;for(n.__k=[],p=0;p<t.length;p++)if(null!=(v=n.__k[p]=null==(v=t[p])||"boolean"==typeof v?null:"string"==typeof v||"number"==typeof v||"bigint"==typeof v?g(null,v,null,null,v):Array.isArray(v)?g(m,{children:v},null,null,null):v.__b>0?g(v.type,v.props,v.key,null,v.__v):v)){if(v.__=n,v.__b=n.__b+1,null===(h=D[p])||h&&v.key==h.key&&v.type===h.type)D[p]=void 0;else for(f=0;f<C;f++){if((h=D[f])&&v.key==h.key&&v.type===h.type){D[f]=void 0;break}h=null}I(e,v,h=h||c,o,i,a,s,l,u),y=v.__e,(f=v.ref)&&h.ref!=f&&(b||(b=[]),h.ref&&b.push(h.ref,null,v),b.push(f,v.__c||y,v)),null!=y?(null==S&&(S=y),"function"==typeof v.type&&null!=v.__k&&v.__k===h.__k?v.__d=l=w(v,l,e):l=_(e,v,h,D,y,l),u||"option"!==n.type?"function"==typeof n.type&&(n.__d=l):e.value=""):l&&h.__e==l&&l.parentNode!=e&&(l=E(h))}for(n.__e=S,p=C;p--;)null!=D[p]&&("function"==typeof n.type&&null!=D[p].__e&&D[p].__e==n.__d&&(n.__d=E(r,p+1)),O(D[p],D[p]));if(b)for(p=0;p<b.length;p++)H(b[p],b[++p],b[++p])}function w(e,t,n){var r,o;for(r=0;r<e.__k.length;r++)(o=e.__k[r])&&(o.__=e,t="function"==typeof o.type?w(o,t,n):_(n,o,o,e.__k,o.__e,t));return t}function R(e,t){return t=t||[],null==e||"boolean"==typeof e||(Array.isArray(e)?e.some((function(e){R(e,t)})):t.push(e)),t}function _(e,t,n,r,o,i){var a,s,l;if(void 0!==t.__d)a=t.__d,t.__d=void 0;else if(null==n||o!=i||null==o.parentNode)e:if(null==i||i.parentNode!==e)e.appendChild(o),a=null;else{for(s=i,l=0;(s=s.nextSibling)&&l<r.length;l+=2)if(s==o)break e;e.insertBefore(o,i),a=i}return void 0!==a?a:o.nextSibling}function T(e,t,n){"-"===t[0]?e.setProperty(t,n):e[t]=null==n?"":"number"!=typeof n||p.test(t)?n:n+"px"}function k(e,t,n,r,o){var i;e:if("style"===t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||T(e.style,t,"");if(n)for(t in n)r&&n[t]===r[t]||T(e.style,t,n[t])}else if("o"===t[0]&&"n"===t[1])i=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in e?t.toLowerCase().slice(2):t.slice(2),e.l||(e.l={}),e.l[t+i]=n,n?r||e.addEventListener(t,i?M:x,i):e.removeEventListener(t,i?M:x,i);else if("dangerouslySetInnerHTML"!==t){if(o)t=t.replace(/xlink[H:h]/,"h").replace(/sName$/,"s");else if("href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in e)try{e[t]=null==n?"":n;break e}catch(e){}"function"==typeof n||(null!=n&&(!1!==n||"a"===t[0]&&"r"===t[1])?e.setAttribute(t,n):e.removeAttribute(t))}}function x(e){this.l[e.type+!1](i.event?i.event(e):e)}function M(e){this.l[e.type+!0](i.event?i.event(e):e)}function I(e,t,n,r,o,a,s,l,u){var c,d,p,h,v,g,E,S,b,D,w,R=t.type;if(void 0!==t.constructor)return null;null!=n.__h&&(u=n.__h,l=t.__e=n.__e,t.__h=null,a=[l]),(c=i.__b)&&c(t);try{e:if("function"==typeof R){if(S=t.props,b=(c=R.contextType)&&r[c.__c],D=c?b?b.props.value:c.__:r,n.__c?E=(d=t.__c=n.__c).__=d.__E:("prototype"in R&&R.prototype.render?t.__c=d=new R(S,D):(t.__c=d=new y(S,D),d.constructor=R,d.render=A),b&&b.sub(d),d.props=S,d.state||(d.state={}),d.context=D,d.__n=r,p=d.__d=!0,d.__h=[]),null==d.__s&&(d.__s=d.state),null!=R.getDerivedStateFromProps&&(d.__s==d.state&&(d.__s=f({},d.__s)),f(d.__s,R.getDerivedStateFromProps(S,d.__s))),h=d.props,v=d.state,p)null==R.getDerivedStateFromProps&&null!=d.componentWillMount&&d.componentWillMount(),null!=d.componentDidMount&&d.__h.push(d.componentDidMount);else{if(null==R.getDerivedStateFromProps&&S!==h&&null!=d.componentWillReceiveProps&&d.componentWillReceiveProps(S,D),!d.__e&&null!=d.shouldComponentUpdate&&!1===d.shouldComponentUpdate(S,d.__s,D)||t.__v===n.__v){d.props=S,d.state=d.__s,t.__v!==n.__v&&(d.__d=!1),d.__v=t,t.__e=n.__e,t.__k=n.__k,t.__k.forEach((function(e){e&&(e.__=t)})),d.__h.length&&s.push(d);break e}null!=d.componentWillUpdate&&d.componentWillUpdate(S,d.__s,D),null!=d.componentDidUpdate&&d.__h.push((function(){d.componentDidUpdate(h,v,g)}))}d.context=D,d.props=S,d.state=d.__s,(c=i.__r)&&c(t),d.__d=!1,d.__v=t,d.__P=e,c=d.render(d.props,d.state,d.context),d.state=d.__s,null!=d.getChildContext&&(r=f(f({},r),d.getChildContext())),p||null==d.getSnapshotBeforeUpdate||(g=d.getSnapshotBeforeUpdate(h,v)),w=null!=c&&c.type===m&&null==c.key?c.props.children:c,C(e,Array.isArray(w)?w:[w],t,n,r,o,a,s,l,u),d.base=t.__e,t.__h=null,d.__h.length&&s.push(d),E&&(d.__E=d.__=null),d.__e=!1}else null==a&&t.__v===n.__v?(t.__k=n.__k,t.__e=n.__e):t.__e=N(n.__e,t,n,r,o,a,s,u);(c=i.diffed)&&c(t)}catch(e){t.__v=null,(u||null!=a)&&(t.__e=l,t.__h=!!u,a[a.indexOf(l)]=null),i.__e(e,t,n)}}function P(e,t){i.__c&&i.__c(t,e),e.some((function(t){try{e=t.__h,t.__h=[],e.some((function(e){e.call(t)}))}catch(e){i.__e(e,t.__v)}}))}function N(e,t,n,r,o,i,a,s){var l,u,p,f,v=n.props,g=t.props,m=t.type,y=0;if("svg"===m&&(o=!0),null!=i)for(;y<i.length;y++)if((l=i[y])&&(l===e||(m?l.localName==m:3==l.nodeType))){e=l,i[y]=null;break}if(null==e){if(null===m)return document.createTextNode(g);e=o?document.createElementNS("http://www.w3.org/2000/svg",m):document.createElement(m,g.is&&g),i=null,s=!1}if(null===m)v===g||s&&e.data===g||(e.data=g);else{if(i=i&&d.slice.call(e.childNodes),u=(v=n.props||c).dangerouslySetInnerHTML,p=g.dangerouslySetInnerHTML,!s){if(null!=i)for(v={},f=0;f<e.attributes.length;f++)v[e.attributes[f].name]=e.attributes[f].value;(p||u)&&(p&&(u&&p.__html==u.__html||p.__html===e.innerHTML)||(e.innerHTML=p&&p.__html||""))}if(function(e,t,n,r,o){var i;for(i in n)"children"===i||"key"===i||i in t||k(e,i,null,n[i],r);for(i in t)o&&"function"!=typeof t[i]||"children"===i||"key"===i||"value"===i||"checked"===i||n[i]===t[i]||k(e,i,t[i],n[i],r)}(e,g,v,o,s),p)t.__k=[];else if(y=t.props.children,C(e,Array.isArray(y)?y:[y],t,n,r,o&&"foreignObject"!==m,i,a,e.firstChild,s),null!=i)for(y=i.length;y--;)null!=i[y]&&h(i[y]);s||("value"in g&&void 0!==(y=g.value)&&(y!==e.value||"progress"===m&&!y)&&k(e,"value",y,v.value,!1),"checked"in g&&void 0!==(y=g.checked)&&y!==e.checked&&k(e,"checked",y,v.checked,!1))}return e}function H(e,t,n){try{"function"==typeof e?e(t):e.current=t}catch(e){i.__e(e,n)}}function O(e,t,n){var r,o,a;if(i.unmount&&i.unmount(e),(r=e.ref)&&(r.current&&r.current!==e.__e||H(r,null,t)),n||"function"==typeof e.type||(n=null!=(o=e.__e)),e.__e=e.__d=void 0,null!=(r=e.__c)){if(r.componentWillUnmount)try{r.componentWillUnmount()}catch(e){i.__e(e,t)}r.base=r.__P=null}if(r=e.__k)for(a=0;a<r.length;a++)r[a]&&O(r[a],t,n);null!=o&&h(o)}function A(e,t,n){return this.constructor(e,n)}function L(e,t,n){var r,o,a;i.__&&i.__(e,t),o=(r="function"==typeof n)?null:n&&n.__k||t.__k,a=[],I(t,e=(!r&&n||t).__k=v(m,null,[e]),o||c,c,void 0!==t.ownerSVGElement,!r&&n?[n]:o?null:t.firstChild?d.slice.call(t.childNodes):null,a,!r&&n?n:o?o.__e:t.firstChild,r),P(a,e)}i={__e:function(e,t){for(var n,r,o;t=t.__;)if((n=t.__c)&&!n.__)try{if((r=n.constructor)&&null!=r.getDerivedStateFromError&&(n.setState(r.getDerivedStateFromError(e)),o=n.__d),null!=n.componentDidCatch&&(n.componentDidCatch(e),o=n.__d),o)return n.__E=n}catch(t){e=t}throw e},__v:0},y.prototype.setState=function(e,t){var n;n=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=f({},this.state),"function"==typeof e&&(e=e(f({},n),this.props)),e&&f(n,e),null!=e&&this.__v&&(t&&this.__h.push(t),b(this))},y.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),b(this))},y.prototype.render=m,a=[],s="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,D.__r=0,u=0;var U,W=[],V=i.__b,F=i.__r,B=i.diffed,z=i.__c,j=i.unmount;function G(){W.forEach((function(e){if(e.__P)try{e.__H.__h.forEach(Y),e.__H.__h.forEach(Z),e.__H.__h=[]}catch(t){e.__H.__h=[],i.__e(t,e.__v)}})),W=[]}i.__b=function(e){V&&V(e)},i.__r=function(e){F&&F(e);var t=e.__c.__H;t&&(t.__h.forEach(Y),t.__h.forEach(Z),t.__h=[])},i.diffed=function(e){B&&B(e);var t=e.__c;t&&t.__H&&t.__H.__h.length&&(1!==W.push(t)&&U===i.requestAnimationFrame||((U=i.requestAnimationFrame)||function(e){var t,n=function(){clearTimeout(r),q&&cancelAnimationFrame(t),setTimeout(e)},r=setTimeout(n,100);q&&(t=requestAnimationFrame(n))})(G))},i.__c=function(e,t){t.some((function(e){try{e.__h.forEach(Y),e.__h=e.__h.filter((function(e){return!e.__||Z(e)}))}catch(n){t.some((function(e){e.__h&&(e.__h=[])})),t=[],i.__e(n,e.__v)}})),z&&z(e,t)},i.unmount=function(e){j&&j(e);var t=e.__c;if(t&&t.__H)try{t.__H.__.forEach(Y)}catch(e){i.__e(e,t.__v)}};var q="function"==typeof requestAnimationFrame;function Y(e){"function"==typeof e.__c&&e.__c()}function Z(e){e.__c=e.__()}function X(e,t){for(var n in e)if("__source"!==n&&!(n in t))return!0;for(var r in t)if("__source"!==r&&e[r]!==t[r])return!0;return!1}function K(e){this.props=e}(K.prototype=new y).isPureReactComponent=!0,K.prototype.shouldComponentUpdate=function(e,t){return X(this.props,e)||X(this.state,t)};var $=i.__b;i.__b=function(e){e.type&&e.type.__f&&e.ref&&(e.props.ref=e.ref,e.ref=null),$&&$(e)};var J=i.__e;i.__e=function(e,t,n){if(e.then)for(var r,o=t;o=o.__;)if((r=o.__c)&&r.__c)return null==t.__e&&(t.__e=n.__e,t.__k=n.__k),r.__c(e,t);J(e,t,n)};var Q=i.unmount;function ee(){this.__u=0,this.t=null,this.__b=null}function te(e){var t=e.__.__c;return t&&t.__e&&t.__e(e)}function ne(){this.u=null,this.o=null}i.unmount=function(e){var t=e.__c;t&&t.__R&&t.__R(),t&&!0===e.__h&&(e.type=null),Q&&Q(e)},(ee.prototype=new y).__c=function(e,t){var n=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(n);var o=te(r.__v),i=!1,a=function(){i||(i=!0,n.__R=null,o?o(s):s())};n.__R=a;var s=function(){if(!--r.__u){if(r.state.__e){var e=r.state.__e;r.__v.__k[0]=function e(t,n,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map((function(t){return e(t,n,r)})),t.__c&&t.__c.__P===n&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(e,e.__c.__P,e.__c.__O)}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate()}},l=!0===t.__h;r.__u++||l||r.setState({__e:r.__b=r.__v.__k[0]}),e.then(a,a)},ee.prototype.componentWillUnmount=function(){this.t=[]},ee.prototype.render=function(e,t){if(this.__b){if(this.__v.__k){var n=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function e(t,n,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach((function(e){"function"==typeof e.__c&&e.__c()})),t.__c.__H=null),null!=(t=function(e,t){for(var n in t)e[n]=t[n];return e}({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=n),t.__c=null),t.__k=t.__k&&t.__k.map((function(t){return e(t,n,r)}))),t}(this.__b,n,r.__O=r.__P)}this.__b=null}var o=t.__e&&v(m,null,e.fallback);return o&&(o.__h=null),[v(m,null,t.__e?null:e.children),o]};var re=function(e,t,n){if(++n[1]===n[0]&&e.o.delete(t),e.props.revealOrder&&("t"!==e.props.revealOrder[0]||!e.o.size))for(n=e.u;n;){for(;n.length>3;)n.pop()();if(n[1]<n[0])break;e.u=n=n[2]}};function oe(e){return this.getChildContext=function(){return e.context},e.children}function ie(e){var t=this,n=e.i;t.componentWillUnmount=function(){L(null,t.l),t.l=null,t.i=null},t.i&&t.i!==n&&t.componentWillUnmount(),e.__v?(t.l||(t.i=n,t.l={nodeType:1,parentNode:n,childNodes:[],appendChild:function(e){this.childNodes.push(e),t.i.appendChild(e)},insertBefore:function(e,n){this.childNodes.push(e),t.i.appendChild(e)},removeChild:function(e){this.childNodes.splice(this.childNodes.indexOf(e)>>>1,1),t.i.removeChild(e)}}),L(v(oe,{context:t.context},e.__v),t.l)):t.l&&t.componentWillUnmount()}(ne.prototype=new y).__e=function(e){var t=this,n=te(t.__v),r=t.o.get(e);return r[0]++,function(o){var i=function(){t.props.revealOrder?(r.push(o),re(t,e,r)):o()};n?n(i):i()}},ne.prototype.render=function(e){this.u=null,this.o=new Map;var t=R(e.children);e.revealOrder&&"b"===e.revealOrder[0]&&t.reverse();for(var n=t.length;n--;)this.o.set(t[n],this.u=[1,0,this.u]);return e.children},ne.prototype.componentDidUpdate=ne.prototype.componentDidMount=function(){var e=this;this.o.forEach((function(t,n){re(e,n,t)}))};var ae="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,se=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,le=function(e){return("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(e)};y.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach((function(e){Object.defineProperty(y.prototype,e,{configurable:!0,get:function(){return this["UNSAFE_"+e]},set:function(t){Object.defineProperty(this,e,{configurable:!0,writable:!0,value:t})}})}));var ue=i.event;function ce(){}function de(){return this.cancelBubble}function pe(){return this.defaultPrevented}i.event=function(e){return ue&&(e=ue(e)),e.persist=ce,e.isPropagationStopped=de,e.isDefaultPrevented=pe,e.nativeEvent=e};var fe={configurable:!0,get:function(){return this.class}},he=i.vnode;i.vnode=function(e){var t=e.type,n=e.props,r=n;if("string"==typeof t){for(var o in r={},n){var i=n[o];"value"===o&&"defaultValue"in n&&null==i||("defaultValue"===o&&"value"in n&&null==n.value?o="value":"download"===o&&!0===i?i="":/ondoubleclick/i.test(o)?o="ondblclick":/^onchange(textarea|input)/i.test(o+t)&&!le(n.type)?o="oninput":/^on(Ani|Tra|Tou|BeforeInp)/.test(o)?o=o.toLowerCase():se.test(o)?o=o.replace(/[A-Z0-9]/,"-$&").toLowerCase():null===i&&(i=void 0),r[o]=i)}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=R(n.children).forEach((function(e){e.props.selected=-1!=r.value.indexOf(e.props.value)}))),"select"==t&&null!=r.defaultValue&&(r.value=R(n.children).forEach((function(e){e.props.selected=r.multiple?-1!=r.defaultValue.indexOf(e.props.value):r.defaultValue==e.props.value}))),e.props=r}t&&n.class!=n.className&&(fe.enumerable="className"in n,null!=n.className&&(r.class=n.className),Object.defineProperty(r,"className",fe)),e.$$typeof=ae,he&&he(e)};var ve=i.__r;i.__r=function(e){ve&&ve(e)},"object"==typeof performance&&"function"==typeof performance.now&&performance.now.bind(performance);var ge="undefined"!=typeof globalThis?globalThis:window;ge.FullCalendarVDom?console.warn("FullCalendar VDOM already loaded"):ge.FullCalendarVDom={Component:y,createElement:v,render:L,createRef:function(){return{current:null}},Fragment:m,createContext:function(e){var t=function(e,t){var n={__c:t="__cC"+u++,__:e,Consumer:function(e,t){return e.children(t)},Provider:function(e){var n,r;return this.getChildContext||(n=[],(r={})[t]=this,this.getChildContext=function(){return r},this.shouldComponentUpdate=function(e){this.props.value!==e.value&&n.some(b)},this.sub=function(e){n.push(e);var t=e.componentWillUnmount;e.componentWillUnmount=function(){n.splice(n.indexOf(e),1),t&&t.call(e)}}),e.children}};return n.Provider.__=n.Consumer.contextType=n}(e),n=t.Provider;return t.Provider=function(){var e=this,t=!this.getChildContext,r=n.apply(this,arguments);if(t){var o=[];this.shouldComponentUpdate=function(t){e.props.value!==t.value&&o.forEach((function(e){e.context=t.value,e.forceUpdate()}))},this.sub=function(e){o.push(e);var t=e.componentWillUnmount;e.componentWillUnmount=function(){o.splice(o.indexOf(e),1),t&&t.call(e)}}}return r},t},createPortal:function(e,t){return v(ie,{__v:e,i:t})},flushSync:function(e){e();var t=i.debounceRendering,n=[];function r(e){n.push(e)}i.debounceRendering=r,L(v(me,{}),document.createElement("div"));for(;n.length;)n.shift()();i.debounceRendering=t},unmountComponentAtNode:function(e){L(null,e)}};var me=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){return v("div",{})},t.prototype.componentDidMount=function(){this.setState({})},t}(y);var ye=function(){function e(e,t){this.context=e,this.internalEventSource=t}return e.prototype.remove=function(){this.context.dispatch({type:"REMOVE_EVENT_SOURCE",sourceId:this.internalEventSource.sourceId})},e.prototype.refetch=function(){this.context.dispatch({type:"FETCH_EVENT_SOURCES",sourceIds:[this.internalEventSource.sourceId],isRefetch:!0})},Object.defineProperty(e.prototype,"id",{get:function(){return this.internalEventSource.publicId},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"url",{get:function(){return this.internalEventSource.meta.url},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"format",{get:function(){return this.internalEventSource.meta.format},enumerable:!1,configurable:!0}),e}();function Ee(e){e.parentNode&&e.parentNode.removeChild(e)}function Se(e,t){if(e.closest)return e.closest(t);if(!document.documentElement.contains(e))return null;do{if(be(e,t))return e;e=e.parentElement||e.parentNode}while(null!==e&&1===e.nodeType);return null}function be(e,t){return(e.matches||e.matchesSelector||e.msMatchesSelector).call(e,t)}function De(e,t){for(var n=e instanceof HTMLElement?[e]:e,r=[],o=0;o<n.length;o+=1)for(var i=n[o].querySelectorAll(t),a=0;a<i.length;a+=1)r.push(i[a]);return r}var Ce=/(top|left|right|bottom|width|height)$/i;function we(e,t){for(var n in t)Re(e,n,t[n])}function Re(e,t,n){null==n?e.style[t]="":"number"==typeof n&&Ce.test(t)?e.style[t]=n+"px":e.style[t]=n}function _e(e){var t,n;return null!==(n=null===(t=e.composedPath)||void 0===t?void 0:t.call(e)[0])&&void 0!==n?n:e.target}function Te(e){return e.getRootNode?e.getRootNode():document}var ke=0;function xe(){return"fc-dom-"+(ke+=1)}function Me(e){e.preventDefault()}function Ie(e,t,n,r){var o=function(e,t){return function(n){var r=Se(n.target,e);r&&t.call(r,n,r)}}(n,r);return e.addEventListener(t,o),function(){e.removeEventListener(t,o)}}var Pe=["webkitTransitionEnd","otransitionend","oTransitionEnd","msTransitionEnd","transitionend"];function Ne(e,t){var n=function(r){t(r),Pe.forEach((function(t){e.removeEventListener(t,n)}))};Pe.forEach((function(t){e.addEventListener(t,n)}))}function He(e){return r({onClick:e},Oe(e))}function Oe(e){return{tabIndex:0,onKeyDown:function(t){"Enter"!==t.key&&" "!==t.key||(e(t),t.preventDefault())}}}var Ae=0;function Le(){return String(Ae+=1)}function Ue(){document.body.classList.add("fc-not-allowed")}function We(){document.body.classList.remove("fc-not-allowed")}function Ve(e){e.classList.add("fc-unselectable"),e.addEventListener("selectstart",Me)}function Fe(e){e.classList.remove("fc-unselectable"),e.removeEventListener("selectstart",Me)}function Be(e){e.addEventListener("contextmenu",Me)}function ze(e){e.removeEventListener("contextmenu",Me)}function je(e){var t,n,r=[],o=[];for("string"==typeof e?o=e.split(/\s*,\s*/):"function"==typeof e?o=[e]:Array.isArray(e)&&(o=e),t=0;t<o.length;t+=1)"string"==typeof(n=o[t])?r.push("-"===n.charAt(0)?{field:n.substring(1),order:-1}:{field:n,order:1}):"function"==typeof n&&r.push({func:n});return r}function Ge(e,t,n){var r,o;for(r=0;r<n.length;r+=1)if(o=qe(e,t,n[r]))return o;return 0}function qe(e,t,n){return n.func?n.func(e,t):Ye(e[n.field],t[n.field])*(n.order||1)}function Ye(e,t){return e||t?null==t?-1:null==e?1:"string"==typeof e||"string"==typeof t?String(e).localeCompare(String(t)):e-t:0}function Ze(e,t){var n=String(e);return"000".substr(0,t-n.length)+n}function Xe(e,t,n){return"function"==typeof e?e.apply(void 0,t):"string"==typeof e?t.reduce((function(e,t,n){return e.replace("$"+n,t||"")}),e):n}function Ke(e,t){return e-t}function $e(e){return e%1==0}function Je(e){var t=e.querySelector(".fc-scrollgrid-shrink-frame"),n=e.querySelector(".fc-scrollgrid-shrink-cushion");if(!t)throw new Error("needs fc-scrollgrid-shrink-frame className");if(!n)throw new Error("needs fc-scrollgrid-shrink-cushion className");return e.getBoundingClientRect().width-t.getBoundingClientRect().width+n.getBoundingClientRect().width}var Qe=["sun","mon","tue","wed","thu","fri","sat"];function et(e,t){var n=ft(e);return n[2]+=7*t,ht(n)}function tt(e,t){var n=ft(e);return n[2]+=t,ht(n)}function nt(e,t){var n=ft(e);return n[6]+=t,ht(n)}function rt(e,t){return ot(e,t)/7}function ot(e,t){return(t.valueOf()-e.valueOf())/864e5}function it(e,t){var n=lt(e),r=lt(t);return{years:0,months:0,days:Math.round(ot(n,r)),milliseconds:t.valueOf()-r.valueOf()-(e.valueOf()-n.valueOf())}}function at(e,t){var n=st(e,t);return null!==n&&n%7==0?n/7:null}function st(e,t){return gt(e)===gt(t)?Math.round(ot(e,t)):null}function lt(e){return ht([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()])}function ut(e,t,n,r){var o=ht([t,0,1+ct(t,n,r)]),i=lt(e),a=Math.round(ot(o,i));return Math.floor(a/7)+1}function ct(e,t,n){var r=7+t-n;return-((7+ht([e,0,r]).getUTCDay()-t)%7)+r-1}function dt(e){return[e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds()]}function pt(e){return new Date(e[0],e[1]||0,null==e[2]?1:e[2],e[3]||0,e[4]||0,e[5]||0)}function ft(e){return[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds()]}function ht(e){return 1===e.length&&(e=e.concat([0])),new Date(Date.UTC.apply(Date,e))}function vt(e){return!isNaN(e.valueOf())}function gt(e){return 1e3*e.getUTCHours()*60*60+1e3*e.getUTCMinutes()*60+1e3*e.getUTCSeconds()+e.getUTCMilliseconds()}function mt(e,t,n,r){return{instanceId:Le(),defId:e,range:t,forcedStartTzo:null==n?null:n,forcedEndTzo:null==r?null:r}}var yt=Object.prototype.hasOwnProperty;function Et(e,t){var n={};if(t)for(var r in t){for(var o=[],i=e.length-1;i>=0;i-=1){var a=e[i][r];if("object"==typeof a&&a)o.unshift(a);else if(void 0!==a){n[r]=a;break}}o.length&&(n[r]=Et(o))}for(i=e.length-1;i>=0;i-=1){var s=e[i];for(var l in s)l in n||(n[l]=s[l])}return n}function St(e,t){var n={};for(var r in e)t(e[r],r)&&(n[r]=e[r]);return n}function bt(e,t){var n={};for(var r in e)n[r]=t(e[r],r);return n}function Dt(e){for(var t={},n=0,r=e;n<r.length;n++){t[r[n]]=!0}return t}function Ct(e){var t=[];for(var n in e)t.push(e[n]);return t}function wt(e,t){if(e===t)return!0;for(var n in e)if(yt.call(e,n)&&!(n in t))return!1;for(var n in t)if(yt.call(t,n)&&e[n]!==t[n])return!1;return!0}function Rt(e,t){var n=[];for(var r in e)yt.call(e,r)&&(r in t||n.push(r));for(var r in t)yt.call(t,r)&&e[r]!==t[r]&&n.push(r);return n}function _t(e,t,n){if(void 0===n&&(n={}),e===t)return!0;for(var r in t)if(!(r in e)||!Tt(e[r],t[r],n[r]))return!1;for(var r in e)if(!(r in t))return!1;return!0}function Tt(e,t,n){return e===t||!0===n||!!n&&n(e,t)}function kt(e,t,n,r){void 0===t&&(t=0),void 0===r&&(r=1);var o=[];null==n&&(n=Object.keys(e).length);for(var i=t;i<n;i+=r){var a=e[i];void 0!==a&&o.push(a)}return o}function xt(e,t,n){var r=n.dateEnv,o=n.pluginHooks,i=n.options,a=e.defs,s=e.instances;for(var l in s=St(s,(function(e){return!a[e.defId].recurringDef})),a){var u=a[l];if(u.recurringDef){var c=u.recurringDef.duration;c||(c=u.allDay?i.defaultAllDayEventDuration:i.defaultTimedEventDuration);for(var d=0,p=Mt(u,c,t,r,o.recurringTypes);d<p.length;d++){var f=p[d],h=mt(l,{start:f,end:r.add(f,c)});s[h.instanceId]=h}}}return{defs:a,instances:s}}function Mt(e,t,n,r,o){var i=o[e.recurringDef.typeId].expand(e.recurringDef.typeData,{start:r.subtract(n.start,t),end:n.end},r);return e.allDay&&(i=i.map(lt)),i}var It=["years","months","days","milliseconds"],Pt=/^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;function Nt(e,t){var n;return"string"==typeof e?function(e){var t=Pt.exec(e);if(t){var n=t[1]?-1:1;return{years:0,months:0,days:n*(t[2]?parseInt(t[2],10):0),milliseconds:n*(60*(t[3]?parseInt(t[3],10):0)*60*1e3+60*(t[4]?parseInt(t[4],10):0)*1e3+1e3*(t[5]?parseInt(t[5],10):0)+(t[6]?parseInt(t[6],10):0))}}return null}(e):"object"==typeof e&&e?Ht(e):"number"==typeof e?Ht(((n={})[t||"milliseconds"]=e,n)):null}function Ht(e){var t={years:e.years||e.year||0,months:e.months||e.month||0,days:e.days||e.day||0,milliseconds:60*(e.hours||e.hour||0)*60*1e3+60*(e.minutes||e.minute||0)*1e3+1e3*(e.seconds||e.second||0)+(e.milliseconds||e.millisecond||e.ms||0)},n=e.weeks||e.week;return n&&(t.days+=7*n,t.specifiedWeeks=!0),t}function Ot(e,t){return{years:e.years+t.years,months:e.months+t.months,days:e.days+t.days,milliseconds:e.milliseconds+t.milliseconds}}function At(e,t){return{years:e.years*t,months:e.months*t,days:e.days*t,milliseconds:e.milliseconds*t}}function Lt(e){return Ut(e)/864e5}function Ut(e){return 31536e6*e.years+2592e6*e.months+864e5*e.days+e.milliseconds}function Wt(e,t){for(var n=null,r=0;r<It.length;r+=1){var o=It[r];if(t[o]){var i=e[o]/t[o];if(!$e(i)||null!==n&&n!==i)return null;n=i}else if(e[o])return null}return n}function Vt(e){var t=e.milliseconds;if(t){if(t%1e3!=0)return{unit:"millisecond",value:t};if(t%6e4!=0)return{unit:"second",value:t/1e3};if(t%36e5!=0)return{unit:"minute",value:t/6e4};if(t)return{unit:"hour",value:t/36e5}}return e.days?e.specifiedWeeks&&e.days%7==0?{unit:"week",value:e.days/7}:{unit:"day",value:e.days}:e.months?{unit:"month",value:e.months}:e.years?{unit:"year",value:e.years}:{unit:"millisecond",value:0}}function Ft(e,t,n){void 0===n&&(n=!1);var r=e.toISOString();return r=r.replace(".000",""),n&&(r=r.replace("T00:00:00Z","")),r.length>10&&(null==t?r=r.replace("Z",""):0!==t&&(r=r.replace("Z",jt(t,!0)))),r}function Bt(e){return e.toISOString().replace(/T.*$/,"")}function zt(e){return Ze(e.getUTCHours(),2)+":"+Ze(e.getUTCMinutes(),2)+":"+Ze(e.getUTCSeconds(),2)}function jt(e,t){void 0===t&&(t=!1);var n=e<0?"-":"+",r=Math.abs(e),o=Math.floor(r/60),i=Math.round(r%60);return t?n+Ze(o,2)+":"+Ze(i,2):"GMT"+n+o+(i?":"+Ze(i,2):"")}function Gt(e,t,n){if(e===t)return!0;var r,o=e.length;if(o!==t.length)return!1;for(r=0;r<o;r+=1)if(!(n?n(e[r],t[r]):e[r]===t[r]))return!1;return!0}function qt(e,t,n){var r,o;return function(){for(var i=[],a=0;a<arguments.length;a++)i[a]=arguments[a];if(r){if(!Gt(r,i)){n&&n(o);var s=e.apply(this,i);t&&t(s,o)||(o=s)}}else o=e.apply(this,i);return r=i,o}}function Yt(e,t,n){var r,o,i=this;return function(a){if(r){if(!wt(r,a)){n&&n(o);var s=e.call(i,a);t&&t(s,o)||(o=s)}}else o=e.call(i,a);return r=a,o}}var Zt={week:3,separator:0,omitZeroMinute:0,meridiem:0,omitCommas:0},Xt={timeZoneName:7,era:6,year:5,month:4,day:2,weekday:2,hour:1,minute:1,second:1},Kt=/\s*([ap])\.?m\.?/i,$t=/,/g,Jt=/\s+/g,Qt=/\u200e/g,en=/UTC|GMT/,tn=function(){function e(e){var t={},n={},r=0;for(var o in e)o in Zt?(n[o]=e[o],r=Math.max(Zt[o],r)):(t[o]=e[o],o in Xt&&(r=Math.max(Xt[o],r)));this.standardDateProps=t,this.extendedSettings=n,this.severity=r,this.buildFormattingFunc=qt(nn)}return e.prototype.format=function(e,t){return this.buildFormattingFunc(this.standardDateProps,this.extendedSettings,t)(e)},e.prototype.formatRange=function(e,t,n,r){var o=this.standardDateProps,i=this.extendedSettings,a=function(e,t,n){if(n.getMarkerYear(e)!==n.getMarkerYear(t))return 5;if(n.getMarkerMonth(e)!==n.getMarkerMonth(t))return 4;if(n.getMarkerDay(e)!==n.getMarkerDay(t))return 2;if(gt(e)!==gt(t))return 1;return 0}(e.marker,t.marker,n.calendarSystem);if(!a)return this.format(e,n);var s=a;!(s>1)||"numeric"!==o.year&&"2-digit"!==o.year||"numeric"!==o.month&&"2-digit"!==o.month||"numeric"!==o.day&&"2-digit"!==o.day||(s=1);var l=this.format(e,n),u=this.format(t,n);if(l===u)return l;var c=nn(function(e,t){var n={};for(var r in e)(!(r in Xt)||Xt[r]<=t)&&(n[r]=e[r]);return n}(o,s),i,n),d=c(e),p=c(t),f=function(e,t,n,r){var o=0;for(;o<e.length;){var i=e.indexOf(t,o);if(-1===i)break;var a=e.substr(0,i);o=i+t.length;for(var s=e.substr(o),l=0;l<n.length;){var u=n.indexOf(r,l);if(-1===u)break;var c=n.substr(0,u);l=u+r.length;var d=n.substr(l);if(a===c&&s===d)return{before:a,after:s}}}return null}(l,d,u,p),h=i.separator||r||n.defaultSeparator||"";return f?f.before+d+h+p+f.after:l+h+u},e.prototype.getLargestUnit=function(){switch(this.severity){case 7:case 6:case 5:return"year";case 4:return"month";case 3:return"week";case 2:return"day";default:return"time"}},e}();function nn(e,t,n){var o=Object.keys(e).length;return 1===o&&"short"===e.timeZoneName?function(e){return jt(e.timeZoneOffset)}:0===o&&t.week?function(e){return function(e,t,n,r,o){var i=[];"long"===o?i.push(n):"short"!==o&&"narrow"!==o||i.push(t);"long"!==o&&"short"!==o||i.push(" ");i.push(r.simpleNumberFormat.format(e)),"rtl"===r.options.direction&&i.reverse();return i.join("")}(n.computeWeekNumber(e.marker),n.weekText,n.weekTextLong,n.locale,t.week)}:function(e,t,n){e=r({},e),t=r({},t),function(e,t){e.timeZoneName&&(e.hour||(e.hour="2-digit"),e.minute||(e.minute="2-digit"));"long"===e.timeZoneName&&(e.timeZoneName="short");t.omitZeroMinute&&(e.second||e.millisecond)&&delete t.omitZeroMinute}(e,t),e.timeZone="UTC";var o,i=new Intl.DateTimeFormat(n.locale.codes,e);if(t.omitZeroMinute){var a=r({},e);delete a.minute,o=new Intl.DateTimeFormat(n.locale.codes,a)}return function(r){var a=r.marker;return function(e,t,n,r,o){e=e.replace(Qt,""),"short"===n.timeZoneName&&(e=function(e,t){var n=!1;e=e.replace(en,(function(){return n=!0,t})),n||(e+=" "+t);return e}(e,"UTC"===o.timeZone||null==t.timeZoneOffset?"UTC":jt(t.timeZoneOffset)));r.omitCommas&&(e=e.replace($t,"").trim());r.omitZeroMinute&&(e=e.replace(":00",""));!1===r.meridiem?e=e.replace(Kt,"").trim():"narrow"===r.meridiem?e=e.replace(Kt,(function(e,t){return t.toLocaleLowerCase()})):"short"===r.meridiem?e=e.replace(Kt,(function(e,t){return t.toLocaleLowerCase()+"m"})):"lowercase"===r.meridiem&&(e=e.replace(Kt,(function(e){return e.toLocaleLowerCase()})));return e=(e=e.replace(Jt," ")).trim()}((o&&!a.getUTCMinutes()?o:i).format(a),r,e,t,n)}}(e,t,n)}function rn(e,t){var n=t.markerToArray(e.marker);return{marker:e.marker,timeZoneOffset:e.timeZoneOffset,array:n,year:n[0],month:n[1],day:n[2],hour:n[3],minute:n[4],second:n[5],millisecond:n[6]}}function on(e,t,n,r){var o=rn(e,n.calendarSystem);return{date:o,start:o,end:t?rn(t,n.calendarSystem):null,timeZone:n.timeZone,localeCodes:n.locale.codes,defaultSeparator:r||n.defaultSeparator}}var an=function(){function e(e){this.cmdStr=e}return e.prototype.format=function(e,t,n){return t.cmdFormatter(this.cmdStr,on(e,null,t,n))},e.prototype.formatRange=function(e,t,n,r){return n.cmdFormatter(this.cmdStr,on(e,t,n,r))},e}(),sn=function(){function e(e){this.func=e}return e.prototype.format=function(e,t,n){return this.func(on(e,null,t,n))},e.prototype.formatRange=function(e,t,n,r){return this.func(on(e,t,n,r))},e}();function ln(e){return"object"==typeof e&&e?new tn(e):"string"==typeof e?new an(e):"function"==typeof e?new sn(e):null}var un={navLinkDayClick:yn,navLinkWeekClick:yn,duration:Nt,bootstrapFontAwesome:yn,buttonIcons:yn,customButtons:yn,defaultAllDayEventDuration:Nt,defaultTimedEventDuration:Nt,nextDayThreshold:Nt,scrollTime:Nt,scrollTimeReset:Boolean,slotMinTime:Nt,slotMaxTime:Nt,dayPopoverFormat:ln,slotDuration:Nt,snapDuration:Nt,headerToolbar:yn,footerToolbar:yn,defaultRangeSeparator:String,titleRangeSeparator:String,forceEventDuration:Boolean,dayHeaders:Boolean,dayHeaderFormat:ln,dayHeaderClassNames:yn,dayHeaderContent:yn,dayHeaderDidMount:yn,dayHeaderWillUnmount:yn,dayCellClassNames:yn,dayCellContent:yn,dayCellDidMount:yn,dayCellWillUnmount:yn,initialView:String,aspectRatio:Number,weekends:Boolean,weekNumberCalculation:yn,weekNumbers:Boolean,weekNumberClassNames:yn,weekNumberContent:yn,weekNumberDidMount:yn,weekNumberWillUnmount:yn,editable:Boolean,viewClassNames:yn,viewDidMount:yn,viewWillUnmount:yn,nowIndicator:Boolean,nowIndicatorClassNames:yn,nowIndicatorContent:yn,nowIndicatorDidMount:yn,nowIndicatorWillUnmount:yn,showNonCurrentDates:Boolean,lazyFetching:Boolean,startParam:String,endParam:String,timeZoneParam:String,timeZone:String,locales:yn,locale:yn,themeSystem:String,dragRevertDuration:Number,dragScroll:Boolean,allDayMaintainDuration:Boolean,unselectAuto:Boolean,dropAccept:yn,eventOrder:je,eventOrderStrict:Boolean,handleWindowResize:Boolean,windowResizeDelay:Number,longPressDelay:Number,eventDragMinDistance:Number,expandRows:Boolean,height:yn,contentHeight:yn,direction:String,weekNumberFormat:ln,eventResizableFromStart:Boolean,displayEventTime:Boolean,displayEventEnd:Boolean,weekText:String,weekTextLong:String,progressiveEventRendering:Boolean,businessHours:yn,initialDate:yn,now:yn,eventDataTransform:yn,stickyHeaderDates:yn,stickyFooterScrollbar:yn,viewHeight:yn,defaultAllDay:Boolean,eventSourceFailure:yn,eventSourceSuccess:yn,eventDisplay:String,eventStartEditable:Boolean,eventDurationEditable:Boolean,eventOverlap:yn,eventConstraint:yn,eventAllow:yn,eventBackgroundColor:String,eventBorderColor:String,eventTextColor:String,eventColor:String,eventClassNames:yn,eventContent:yn,eventDidMount:yn,eventWillUnmount:yn,selectConstraint:yn,selectOverlap:yn,selectAllow:yn,droppable:Boolean,unselectCancel:String,slotLabelFormat:yn,slotLaneClassNames:yn,slotLaneContent:yn,slotLaneDidMount:yn,slotLaneWillUnmount:yn,slotLabelClassNames:yn,slotLabelContent:yn,slotLabelDidMount:yn,slotLabelWillUnmount:yn,dayMaxEvents:yn,dayMaxEventRows:yn,dayMinWidth:Number,slotLabelInterval:Nt,allDayText:String,allDayClassNames:yn,allDayContent:yn,allDayDidMount:yn,allDayWillUnmount:yn,slotMinWidth:Number,navLinks:Boolean,eventTimeFormat:ln,rerenderDelay:Number,moreLinkText:yn,moreLinkHint:yn,selectMinDistance:Number,selectable:Boolean,selectLongPressDelay:Number,eventLongPressDelay:Number,selectMirror:Boolean,eventMaxStack:Number,eventMinHeight:Number,eventMinWidth:Number,eventShortHeight:Number,slotEventOverlap:Boolean,plugins:yn,firstDay:Number,dayCount:Number,dateAlignment:String,dateIncrement:Nt,hiddenDays:yn,monthMode:Boolean,fixedWeekCount:Boolean,validRange:yn,visibleRange:yn,titleFormat:yn,eventInteractive:Boolean,noEventsText:String,viewHint:yn,navLinkHint:yn,closeHint:String,timeHint:String,eventHint:String,moreLinkClick:yn,moreLinkClassNames:yn,moreLinkContent:yn,moreLinkDidMount:yn,moreLinkWillUnmount:yn},cn={eventDisplay:"auto",defaultRangeSeparator:" - ",titleRangeSeparator:" – ",defaultTimedEventDuration:"01:00:00",defaultAllDayEventDuration:{day:1},forceEventDuration:!1,nextDayThreshold:"00:00:00",dayHeaders:!0,initialView:"",aspectRatio:1.35,headerToolbar:{start:"title",center:"",end:"today prev,next"},weekends:!0,weekNumbers:!1,weekNumberCalculation:"local",editable:!1,nowIndicator:!1,scrollTime:"06:00:00",scrollTimeReset:!0,slotMinTime:"00:00:00",slotMaxTime:"24:00:00",showNonCurrentDates:!0,lazyFetching:!0,startParam:"start",endParam:"end",timeZoneParam:"timeZone",timeZone:"local",locales:[],locale:"",themeSystem:"standard",dragRevertDuration:500,dragScroll:!0,allDayMaintainDuration:!1,unselectAuto:!0,dropAccept:"*",eventOrder:"start,-duration,allDay,title",dayPopoverFormat:{month:"long",day:"numeric",year:"numeric"},handleWindowResize:!0,windowResizeDelay:100,longPressDelay:1e3,eventDragMinDistance:5,expandRows:!1,navLinks:!1,selectable:!1,eventMinHeight:15,eventMinWidth:30,eventShortHeight:30},dn={datesSet:yn,eventsSet:yn,eventAdd:yn,eventChange:yn,eventRemove:yn,windowResize:yn,eventClick:yn,eventMouseEnter:yn,eventMouseLeave:yn,select:yn,unselect:yn,loading:yn,_unmount:yn,_beforeprint:yn,_afterprint:yn,_noEventDrop:yn,_noEventResize:yn,_resize:yn,_scrollRequest:yn},pn={buttonText:yn,buttonHints:yn,views:yn,plugins:yn,initialEvents:yn,events:yn,eventSources:yn},fn={headerToolbar:hn,footerToolbar:hn,buttonText:hn,buttonHints:hn,buttonIcons:hn,dateIncrement:hn};function hn(e,t){return"object"==typeof e&&"object"==typeof t&&e&&t?wt(e,t):e===t}var vn={type:String,component:yn,buttonText:String,buttonTextKey:String,dateProfileGeneratorClass:yn,usesMinMaxTime:Boolean,classNames:yn,content:yn,didMount:yn,willUnmount:yn};function gn(e){return Et(e,fn)}function mn(e,t){var n={},r={};for(var o in t)o in e&&(n[o]=t[o](e[o]));for(var o in e)o in t||(r[o]=e[o]);return{refined:n,extra:r}}function yn(e){return e}function En(e,t,n,r){for(var o={defs:{},instances:{}},i=An(n),a=0,s=e;a<s.length;a++){var l=Hn(s[a],t,n,r,i);l&&Sn(l,o)}return o}function Sn(e,t){return void 0===t&&(t={defs:{},instances:{}}),t.defs[e.def.defId]=e.def,e.instance&&(t.instances[e.instance.instanceId]=e.instance),t}function bn(e,t){var n=e.instances[t];if(n){var r=e.defs[n.defId],o=wn(e,(function(e){return t=r,n=e,Boolean(t.groupId&&t.groupId===n.groupId);var t,n}));return o.defs[r.defId]=r,o.instances[n.instanceId]=n,o}return{defs:{},instances:{}}}function Dn(){return{defs:{},instances:{}}}function Cn(e,t){return{defs:r(r({},e.defs),t.defs),instances:r(r({},e.instances),t.instances)}}function wn(e,t){var n=St(e.defs,t),r=St(e.instances,(function(e){return n[e.defId]}));return{defs:n,instances:r}}function Rn(e){return Array.isArray(e)?e:"string"==typeof e?e.split(/\s+/):[]}var _n={display:String,editable:Boolean,startEditable:Boolean,durationEditable:Boolean,constraint:yn,overlap:yn,allow:yn,className:Rn,classNames:Rn,color:String,backgroundColor:String,borderColor:String,textColor:String},Tn={display:null,startEditable:null,durationEditable:null,constraints:[],overlap:null,allows:[],backgroundColor:"",borderColor:"",textColor:"",classNames:[]};function kn(e,t){var n=function(e,t){return Array.isArray(e)?En(e,null,t,!0):"object"==typeof e&&e?En([e],null,t,!0):null!=e?String(e):null}(e.constraint,t);return{display:e.display||null,startEditable:null!=e.startEditable?e.startEditable:e.editable,durationEditable:null!=e.durationEditable?e.durationEditable:e.editable,constraints:null!=n?[n]:[],overlap:null!=e.overlap?e.overlap:null,allows:null!=e.allow?[e.allow]:[],backgroundColor:e.backgroundColor||e.color||"",borderColor:e.borderColor||e.color||"",textColor:e.textColor||"",classNames:(e.className||[]).concat(e.classNames||[])}}function xn(e){return e.reduce(Mn,Tn)}function Mn(e,t){return{display:null!=t.display?t.display:e.display,startEditable:null!=t.startEditable?t.startEditable:e.startEditable,durationEditable:null!=t.durationEditable?t.durationEditable:e.durationEditable,constraints:e.constraints.concat(t.constraints),overlap:"boolean"==typeof t.overlap?t.overlap:e.overlap,allows:e.allows.concat(t.allows),backgroundColor:t.backgroundColor||e.backgroundColor,borderColor:t.borderColor||e.borderColor,textColor:t.textColor||e.textColor,classNames:e.classNames.concat(t.classNames)}}var In={id:String,groupId:String,title:String,url:String,interactive:Boolean},Pn={start:yn,end:yn,date:yn,allDay:Boolean},Nn=r(r(r({},In),Pn),{extendedProps:yn});function Hn(e,t,n,r,o){void 0===o&&(o=An(n));var i=On(e,n,o),a=i.refined,s=i.extra,l=function(e,t){var n=null;e&&(n=e.defaultAllDay);null==n&&(n=t.options.defaultAllDay);return n}(t,n),u=function(e,t,n,r){for(var o=0;o<r.length;o+=1){var i=r[o].parse(e,n);if(i){var a=e.allDay;return null==a&&null==(a=t)&&null==(a=i.allDayGuess)&&(a=!1),{allDay:a,duration:i.duration,typeData:i.typeData,typeId:o}}}return null}(a,l,n.dateEnv,n.pluginHooks.recurringTypes);if(u)return(c=Ln(a,s,t?t.sourceId:"",u.allDay,Boolean(u.duration),n)).recurringDef={typeId:u.typeId,typeData:u.typeData,duration:u.duration},{def:c,instance:null};var c,d=function(e,t,n,r){var o,i,a=e.allDay,s=null,l=!1,u=null,c=null!=e.start?e.start:e.date;if(o=n.dateEnv.createMarkerMeta(c))s=o.marker;else if(!r)return null;null!=e.end&&(i=n.dateEnv.createMarkerMeta(e.end));null==a&&(a=null!=t?t:(!o||o.isTimeUnspecified)&&(!i||i.isTimeUnspecified));a&&s&&(s=lt(s));i&&(u=i.marker,a&&(u=lt(u)),s&&u<=s&&(u=null));u?l=!0:r||(l=n.options.forceEventDuration||!1,u=n.dateEnv.add(s,a?n.options.defaultAllDayEventDuration:n.options.defaultTimedEventDuration));return{allDay:a,hasEnd:l,range:{start:s,end:u},forcedStartTzo:o?o.forcedTzo:null,forcedEndTzo:i?i.forcedTzo:null}}(a,l,n,r);return d?{def:c=Ln(a,s,t?t.sourceId:"",d.allDay,d.hasEnd,n),instance:mt(c.defId,d.range,d.forcedStartTzo,d.forcedEndTzo)}:null}function On(e,t,n){return void 0===n&&(n=An(t)),mn(e,n)}function An(e){return r(r(r({},_n),Nn),e.pluginHooks.eventRefiners)}function Ln(e,t,n,o,i,a){for(var s={title:e.title||"",groupId:e.groupId||"",publicId:e.id||"",url:e.url||"",recurringDef:null,defId:Le(),sourceId:n,allDay:o,hasEnd:i,interactive:e.interactive,ui:kn(e,a),extendedProps:r(r({},e.extendedProps||{}),t)},l=0,u=a.pluginHooks.eventDefMemberAdders;l<u.length;l++){var c=u[l];r(s,c(e))}return Object.freeze(s.ui.classNames),Object.freeze(s.extendedProps),s}function Un(e){var t=Math.floor(ot(e.start,e.end))||1,n=lt(e.start);return{start:n,end:tt(n,t)}}function Wn(e,t){void 0===t&&(t=Nt(0));var n=null,r=null;if(e.end){r=lt(e.end);var o=e.end.valueOf()-r.valueOf();o&&o>=Ut(t)&&(r=tt(r,1))}return e.start&&(n=lt(e.start),r&&r<=n&&(r=tt(n,1))),{start:n,end:r}}function Vn(e){var t=Wn(e);return ot(t.start,t.end)>1}function Fn(e,t,n,r){return"year"===r?Nt(n.diffWholeYears(e,t),"year"):"month"===r?Nt(n.diffWholeMonths(e,t),"month"):it(e,t)}function Bn(e,t){var n,r,o=[],i=t.start;for(e.sort(zn),n=0;n<e.length;n+=1)(r=e[n]).start>i&&o.push({start:i,end:r.start}),r.end>i&&(i=r.end);return i<t.end&&o.push({start:i,end:t.end}),o}function zn(e,t){return e.start.valueOf()-t.start.valueOf()}function jn(e,t){var n=e.start,r=e.end,o=null;return null!==t.start&&(n=null===n?t.start:new Date(Math.max(n.valueOf(),t.start.valueOf()))),null!=t.end&&(r=null===r?t.end:new Date(Math.min(r.valueOf(),t.end.valueOf()))),(null===n||null===r||n<r)&&(o={start:n,end:r}),o}function Gn(e,t){return(null===e.start?null:e.start.valueOf())===(null===t.start?null:t.start.valueOf())&&(null===e.end?null:e.end.valueOf())===(null===t.end?null:t.end.valueOf())}function qn(e,t){return(null===e.end||null===t.start||e.end>t.start)&&(null===e.start||null===t.end||e.start<t.end)}function Yn(e,t){return(null===e.start||null!==t.start&&t.start>=e.start)&&(null===e.end||null!==t.end&&t.end<=e.end)}function Zn(e,t){return(null===e.start||t>=e.start)&&(null===e.end||t<e.end)}function Xn(e,t,n,r){var o={},i={},a={},s=[],l=[],u=Qn(e.defs,t);for(var c in e.defs){"inverse-background"===(f=u[(S=e.defs[c]).defId]).display&&(S.groupId?(o[S.groupId]=[],a[S.groupId]||(a[S.groupId]=S)):i[c]=[])}for(var d in e.instances){var p=e.instances[d],f=u[(S=e.defs[p.defId]).defId],h=p.range,v=!S.allDay&&r?Wn(h,r):h,g=jn(v,n);g&&("inverse-background"===f.display?S.groupId?o[S.groupId].push(g):i[p.defId].push(g):"none"!==f.display&&("background"===f.display?s:l).push({def:S,ui:f,instance:p,range:g,isStart:v.start&&v.start.valueOf()===g.start.valueOf(),isEnd:v.end&&v.end.valueOf()===g.end.valueOf()}))}for(var m in o)for(var y=0,E=Bn(o[m],n);y<E.length;y++){var S,b=E[y];f=u[(S=a[m]).defId];s.push({def:S,ui:f,instance:null,range:b,isStart:!1,isEnd:!1})}for(var c in i)for(var D=0,C=Bn(i[c],n);D<C.length;D++){b=C[D];s.push({def:e.defs[c],ui:u[c],instance:null,range:b,isStart:!1,isEnd:!1})}return{bg:s,fg:l}}function Kn(e){return"background"===e.ui.display||"inverse-background"===e.ui.display}function $n(e,t){e.fcSeg=t}function Jn(e){return e.fcSeg||e.parentNode.fcSeg||null}function Qn(e,t){return bt(e,(function(e){return er(e,t)}))}function er(e,t){var n=[];return t[""]&&n.push(t[""]),t[e.defId]&&n.push(t[e.defId]),n.push(e.ui),xn(n)}function tr(e,t){var n=e.map(nr);return n.sort((function(e,n){return Ge(e,n,t)})),n.map((function(e){return e._seg}))}function nr(e){var t=e.eventRange,n=t.def,o=t.instance?t.instance.range:t.range,i=o.start?o.start.valueOf():0,a=o.end?o.end.valueOf():0;return r(r(r({},n.extendedProps),n),{id:n.publicId,start:i,end:a,duration:a-i,allDay:Number(n.allDay),_seg:e})}function rr(e,t){for(var n=t.pluginHooks.isDraggableTransformers,r=e.eventRange,o=r.def,i=r.ui,a=i.startEditable,s=0,l=n;s<l.length;s++){a=(0,l[s])(a,o,i,t)}return a}function or(e,t){return e.isStart&&e.eventRange.ui.durationEditable&&t.options.eventResizableFromStart}function ir(e,t){return e.isEnd&&e.eventRange.ui.durationEditable}function ar(e,t,n,r,o,i,a){var s=n.dateEnv,l=n.options,u=l.displayEventTime,c=l.displayEventEnd,d=e.eventRange.def,p=e.eventRange.instance;null==u&&(u=!1!==r),null==c&&(c=!1!==o);var f=p.range.start,h=p.range.end,v=i||e.start||e.eventRange.range.start,g=a||e.end||e.eventRange.range.end,m=lt(f).valueOf()===lt(v).valueOf(),y=lt(nt(h,-1)).valueOf()===lt(nt(g,-1)).valueOf();return u&&!d.allDay&&(m||y)?(v=m?f:v,g=y?h:g,c&&d.hasEnd?s.formatRange(v,g,t,{forcedStartTzo:i?null:p.forcedStartTzo,forcedEndTzo:a?null:p.forcedEndTzo}):s.format(v,t,{forcedTzo:i?null:p.forcedStartTzo})):""}function sr(e,t,n){var r=e.eventRange.range;return{isPast:r.end<(n||t.start),isFuture:r.start>=(n||t.end),isToday:t&&Zn(t,r.start)}}function lr(e){var t=["fc-event"];return e.isMirror&&t.push("fc-event-mirror"),e.isDraggable&&t.push("fc-event-draggable"),(e.isStartResizable||e.isEndResizable)&&t.push("fc-event-resizable"),e.isDragging&&t.push("fc-event-dragging"),e.isResizing&&t.push("fc-event-resizing"),e.isSelected&&t.push("fc-event-selected"),e.isStart&&t.push("fc-event-start"),e.isEnd&&t.push("fc-event-end"),e.isPast&&t.push("fc-event-past"),e.isToday&&t.push("fc-event-today"),e.isFuture&&t.push("fc-event-future"),t}function ur(e){return e.instance?e.instance.instanceId:e.def.defId+":"+e.range.start.toISOString()}function cr(e,t){var n=e.eventRange,r=n.def,o=n.instance,i=r.url;if(i)return{href:i};var a=t.emitter,s=t.options.eventInteractive;return null==s&&null==(s=r.interactive)&&(s=Boolean(a.hasHandlers("eventClick"))),s?Oe((function(e){a.trigger("eventClick",{el:e.target,event:new xr(t,r,o),jsEvent:e,view:t.viewApi})})):{}}var dr={start:yn,end:yn,allDay:Boolean};function pr(e,t,n){var o=function(e,t){var n=mn(e,dr),o=n.refined,i=n.extra,a=o.start?t.createMarkerMeta(o.start):null,s=o.end?t.createMarkerMeta(o.end):null,l=o.allDay;null==l&&(l=a&&a.isTimeUnspecified&&(!s||s.isTimeUnspecified));return r({range:{start:a?a.marker:null,end:s?s.marker:null},allDay:l},i)}(e,t),i=o.range;if(!i.start)return null;if(!i.end){if(null==n)return null;i.end=t.add(i.start,n)}return o}function fr(e,t){return Gn(e.range,t.range)&&e.allDay===t.allDay&&function(e,t){for(var n in t)if("range"!==n&&"allDay"!==n&&e[n]!==t[n])return!1;for(var n in e)if(!(n in t))return!1;return!0}(e,t)}function hr(e,t,n){return r(r({},vr(e,t,n)),{timeZone:t.timeZone})}function vr(e,t,n){return{start:t.toDate(e.start),end:t.toDate(e.end),startStr:t.formatIso(e.start,{omitTime:n}),endStr:t.formatIso(e.end,{omitTime:n})}}function gr(e,t,n){var r=On({editable:!1},n),o=Ln(r.refined,r.extra,"",e.allDay,!0,n);return{def:o,ui:er(o,t),instance:mt(o.defId,e.range),range:e.range,isStart:!0,isEnd:!0}}function mr(e,t,n){n.emitter.trigger("select",r(r({},yr(e,n)),{jsEvent:t?t.origEvent:null,view:n.viewApi||n.calendarApi.view}))}function yr(e,t){for(var n,o,i={},a=0,s=t.pluginHooks.dateSpanTransforms;a<s.length;a++){var l=s[a];r(i,l(e,t))}return r(i,(n=e,o=t.dateEnv,r(r({},vr(n.range,o,n.allDay)),{allDay:n.allDay}))),i}function Er(e,t,n){var r=n.dateEnv,o=n.options,i=t;return e?(i=lt(i),i=r.add(i,o.defaultAllDayEventDuration)):i=r.add(i,o.defaultTimedEventDuration),i}function Sr(e,t,n,r){var o=Qn(e.defs,t),i={defs:{},instances:{}};for(var a in e.defs){var s=e.defs[a];i.defs[a]=br(s,o[a],n,r)}for(var l in e.instances){var u=e.instances[l];s=i.defs[u.defId];i.instances[l]=Dr(u,s,o[u.defId],n,r)}return i}function br(e,t,n,o){var i=n.standardProps||{};null==i.hasEnd&&t.durationEditable&&(n.startDelta||n.endDelta)&&(i.hasEnd=!0);var a=r(r(r({},e),i),{ui:r(r({},e.ui),i.ui)});n.extendedProps&&(a.extendedProps=r(r({},a.extendedProps),n.extendedProps));for(var s=0,l=o.pluginHooks.eventDefMutationAppliers;s<l.length;s++){(0,l[s])(a,n,o)}return!a.hasEnd&&o.options.forceEventDuration&&(a.hasEnd=!0),a}function Dr(e,t,n,o,i){var a=i.dateEnv,s=o.standardProps&&!0===o.standardProps.allDay,l=o.standardProps&&!1===o.standardProps.hasEnd,u=r({},e);return s&&(u.range=Un(u.range)),o.datesDelta&&n.startEditable&&(u.range={start:a.add(u.range.start,o.datesDelta),end:a.add(u.range.end,o.datesDelta)}),o.startDelta&&n.durationEditable&&(u.range={start:a.add(u.range.start,o.startDelta),end:u.range.end}),o.endDelta&&n.durationEditable&&(u.range={start:u.range.start,end:a.add(u.range.end,o.endDelta)}),l&&(u.range={start:u.range.start,end:Er(t.allDay,u.range.start,i)}),t.allDay&&(u.range={start:lt(u.range.start),end:lt(u.range.end)}),u.range.end<u.range.start&&(u.range.end=Er(t.allDay,u.range.start,i)),u}var Cr=function(){function e(e,t,n){this.type=e,this.getCurrentData=t,this.dateEnv=n}return Object.defineProperty(e.prototype,"calendar",{get:function(){return this.getCurrentData().calendarApi},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"title",{get:function(){return this.getCurrentData().viewTitle},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"activeStart",{get:function(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"activeEnd",{get:function(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"currentStart",{get:function(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start)},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"currentEnd",{get:function(){return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end)},enumerable:!1,configurable:!0}),e.prototype.getOption=function(e){return this.getCurrentData().options[e]},e}(),wr={id:String,defaultAllDay:Boolean,url:String,format:String,events:yn,eventDataTransform:yn,success:yn,failure:yn};function Rr(e,t,n){var r;if(void 0===n&&(n=_r(t)),"string"==typeof e?r={url:e}:"function"==typeof e||Array.isArray(e)?r={events:e}:"object"==typeof e&&e&&(r=e),r){var o=mn(r,n),i=o.refined,a=o.extra,s=function(e,t){for(var n=t.pluginHooks.eventSourceDefs,r=n.length-1;r>=0;r-=1){var o=n[r].parseMeta(e);if(o)return{sourceDefId:r,meta:o}}return null}(i,t);if(s)return{_raw:e,isFetching:!1,latestFetchId:"",fetchRange:null,defaultAllDay:i.defaultAllDay,eventDataTransform:i.eventDataTransform,success:i.success,failure:i.failure,publicId:i.id||"",sourceId:Le(),sourceDefId:s.sourceDefId,meta:s.meta,ui:kn(i,t),extendedProps:a}}return null}function _r(e){return r(r(r({},_n),wr),e.pluginHooks.eventSourceRefiners)}function Tr(e,t){return"function"==typeof e&&(e=e()),null==e?t.createNowMarker():t.createMarker(e)}var kr=function(){function e(){}return e.prototype.getCurrentData=function(){return this.currentDataManager.getCurrentData()},e.prototype.dispatch=function(e){return this.currentDataManager.dispatch(e)},Object.defineProperty(e.prototype,"view",{get:function(){return this.getCurrentData().viewApi},enumerable:!1,configurable:!0}),e.prototype.batchRendering=function(e){e()},e.prototype.updateSize=function(){this.trigger("_resize",!0)},e.prototype.setOption=function(e,t){this.dispatch({type:"SET_OPTION",optionName:e,rawOptionValue:t})},e.prototype.getOption=function(e){return this.currentDataManager.currentCalendarOptionsInput[e]},e.prototype.getAvailableLocaleCodes=function(){return Object.keys(this.getCurrentData().availableRawLocales)},e.prototype.on=function(e,t){var n=this.currentDataManager;n.currentCalendarOptionsRefiners[e]?n.emitter.on(e,t):console.warn("Unknown listener name '"+e+"'")},e.prototype.off=function(e,t){this.currentDataManager.emitter.off(e,t)},e.prototype.trigger=function(e){for(var t,n=[],r=1;r<arguments.length;r++)n[r-1]=arguments[r];(t=this.currentDataManager.emitter).trigger.apply(t,o([e],n))},e.prototype.changeView=function(e,t){var n=this;this.batchRendering((function(){if(n.unselect(),t)if(t.start&&t.end)n.dispatch({type:"CHANGE_VIEW_TYPE",viewType:e}),n.dispatch({type:"SET_OPTION",optionName:"visibleRange",rawOptionValue:t});else{var r=n.getCurrentData().dateEnv;n.dispatch({type:"CHANGE_VIEW_TYPE",viewType:e,dateMarker:r.createMarker(t)})}else n.dispatch({type:"CHANGE_VIEW_TYPE",viewType:e})}))},e.prototype.zoomTo=function(e,t){var n;t=t||"day",n=this.getCurrentData().viewSpecs[t]||this.getUnitViewSpec(t),this.unselect(),n?this.dispatch({type:"CHANGE_VIEW_TYPE",viewType:n.type,dateMarker:e}):this.dispatch({type:"CHANGE_DATE",dateMarker:e})},e.prototype.getUnitViewSpec=function(e){var t,n,r=this.getCurrentData(),o=r.viewSpecs,i=r.toolbarConfig,a=[].concat(i.header?i.header.viewsWithButtons:[],i.footer?i.footer.viewsWithButtons:[]);for(var s in o)a.push(s);for(t=0;t<a.length;t+=1)if((n=o[a[t]])&&n.singleUnit===e)return n;return null},e.prototype.prev=function(){this.unselect(),this.dispatch({type:"PREV"})},e.prototype.next=function(){this.unselect(),this.dispatch({type:"NEXT"})},e.prototype.prevYear=function(){var e=this.getCurrentData();this.unselect(),this.dispatch({type:"CHANGE_DATE",dateMarker:e.dateEnv.addYears(e.currentDate,-1)})},e.prototype.nextYear=function(){var e=this.getCurrentData();this.unselect(),this.dispatch({type:"CHANGE_DATE",dateMarker:e.dateEnv.addYears(e.currentDate,1)})},e.prototype.today=function(){var e=this.getCurrentData();this.unselect(),this.dispatch({type:"CHANGE_DATE",dateMarker:Tr(e.calendarOptions.now,e.dateEnv)})},e.prototype.gotoDate=function(e){var t=this.getCurrentData();this.unselect(),this.dispatch({type:"CHANGE_DATE",dateMarker:t.dateEnv.createMarker(e)})},e.prototype.incrementDate=function(e){var t=this.getCurrentData(),n=Nt(e);n&&(this.unselect(),this.dispatch({type:"CHANGE_DATE",dateMarker:t.dateEnv.add(t.currentDate,n)}))},e.prototype.getDate=function(){var e=this.getCurrentData();return e.dateEnv.toDate(e.currentDate)},e.prototype.formatDate=function(e,t){var n=this.getCurrentData().dateEnv;return n.format(n.createMarker(e),ln(t))},e.prototype.formatRange=function(e,t,n){var r=this.getCurrentData().dateEnv;return r.formatRange(r.createMarker(e),r.createMarker(t),ln(n),n)},e.prototype.formatIso=function(e,t){var n=this.getCurrentData().dateEnv;return n.formatIso(n.createMarker(e),{omitTime:t})},e.prototype.select=function(e,t){var n;n=null==t?null!=e.start?e:{start:e,end:null}:{start:e,end:t};var r=this.getCurrentData(),o=pr(n,r.dateEnv,Nt({days:1}));o&&(this.dispatch({type:"SELECT_DATES",selection:o}),mr(o,null,r))},e.prototype.unselect=function(e){var t=this.getCurrentData();t.dateSelection&&(this.dispatch({type:"UNSELECT_DATES"}),function(e,t){t.emitter.trigger("unselect",{jsEvent:e?e.origEvent:null,view:t.viewApi||t.calendarApi.view})}(e,t))},e.prototype.addEvent=function(e,t){if(e instanceof xr){var n=e._def,r=e._instance;return this.getCurrentData().eventStore.defs[n.defId]||(this.dispatch({type:"ADD_EVENTS",eventStore:Sn({def:n,instance:r})}),this.triggerEventAdd(e)),e}var o,i=this.getCurrentData();if(t instanceof ye)o=t.internalEventSource;else if("boolean"==typeof t)t&&(o=Ct(i.eventSources)[0]);else if(null!=t){var a=this.getEventSourceById(t);if(!a)return console.warn('Could not find an event source with ID "'+t+'"'),null;o=a.internalEventSource}var s=Hn(e,o,i,!1);if(s){var l=new xr(i,s.def,s.def.recurringDef?null:s.instance);return this.dispatch({type:"ADD_EVENTS",eventStore:Sn(s)}),this.triggerEventAdd(l),l}return null},e.prototype.triggerEventAdd=function(e){var t=this;this.getCurrentData().emitter.trigger("eventAdd",{event:e,relatedEvents:[],revert:function(){t.dispatch({type:"REMOVE_EVENTS",eventStore:Mr(e)})}})},e.prototype.getEventById=function(e){var t=this.getCurrentData(),n=t.eventStore,r=n.defs,o=n.instances;for(var i in e=String(e),r){var a=r[i];if(a.publicId===e){if(a.recurringDef)return new xr(t,a,null);for(var s in o){var l=o[s];if(l.defId===a.defId)return new xr(t,a,l)}}}return null},e.prototype.getEvents=function(){var e=this.getCurrentData();return Ir(e.eventStore,e)},e.prototype.removeAllEvents=function(){this.dispatch({type:"REMOVE_ALL_EVENTS"})},e.prototype.getEventSources=function(){var e=this.getCurrentData(),t=e.eventSources,n=[];for(var r in t)n.push(new ye(e,t[r]));return n},e.prototype.getEventSourceById=function(e){var t=this.getCurrentData(),n=t.eventSources;for(var r in e=String(e),n)if(n[r].publicId===e)return new ye(t,n[r]);return null},e.prototype.addEventSource=function(e){var t=this.getCurrentData();if(e instanceof ye)return t.eventSources[e.internalEventSource.sourceId]||this.dispatch({type:"ADD_EVENT_SOURCES",sources:[e.internalEventSource]}),e;var n=Rr(e,t);return n?(this.dispatch({type:"ADD_EVENT_SOURCES",sources:[n]}),new ye(t,n)):null},e.prototype.removeAllEventSources=function(){this.dispatch({type:"REMOVE_ALL_EVENT_SOURCES"})},e.prototype.refetchEvents=function(){this.dispatch({type:"FETCH_EVENT_SOURCES",isRefetch:!0})},e.prototype.scrollToTime=function(e){var t=Nt(e);t&&this.trigger("_scrollRequest",{time:t})},e}(),xr=function(){function e(e,t,n){this._context=e,this._def=t,this._instance=n||null}return e.prototype.setProp=function(e,t){var n,r;if(e in Pn)console.warn("Could not set date-related prop 'name'. Use one of the date-related methods instead.");else if("id"===e)t=In[e](t),this.mutate({standardProps:{publicId:t}});else if(e in In)t=In[e](t),this.mutate({standardProps:(n={},n[e]=t,n)});else if(e in _n){var o=_n[e](t);"color"===e?o={backgroundColor:t,borderColor:t}:"editable"===e?o={startEditable:t,durationEditable:t}:((r={})[e]=t,o=r),this.mutate({standardProps:{ui:o}})}else console.warn("Could not set prop '"+e+"'. Use setExtendedProp instead.")},e.prototype.setExtendedProp=function(e,t){var n;this.mutate({extendedProps:(n={},n[e]=t,n)})},e.prototype.setStart=function(e,t){void 0===t&&(t={});var n=this._context.dateEnv,r=n.createMarker(e);if(r&&this._instance){var o=Fn(this._instance.range.start,r,n,t.granularity);t.maintainDuration?this.mutate({datesDelta:o}):this.mutate({startDelta:o})}},e.prototype.setEnd=function(e,t){void 0===t&&(t={});var n,r=this._context.dateEnv;if((null==e||(n=r.createMarker(e)))&&this._instance)if(n){var o=Fn(this._instance.range.end,n,r,t.granularity);this.mutate({endDelta:o})}else this.mutate({standardProps:{hasEnd:!1}})},e.prototype.setDates=function(e,t,n){void 0===n&&(n={});var r,o,i,a=this._context.dateEnv,s={allDay:n.allDay},l=a.createMarker(e);if(l&&((null==t||(r=a.createMarker(t)))&&this._instance)){var u=this._instance.range;!0===n.allDay&&(u=Un(u));var c=Fn(u.start,l,a,n.granularity);if(r){var d=Fn(u.end,r,a,n.granularity);i=d,(o=c).years===i.years&&o.months===i.months&&o.days===i.days&&o.milliseconds===i.milliseconds?this.mutate({datesDelta:c,standardProps:s}):this.mutate({startDelta:c,endDelta:d,standardProps:s})}else s.hasEnd=!1,this.mutate({datesDelta:c,standardProps:s})}},e.prototype.moveStart=function(e){var t=Nt(e);t&&this.mutate({startDelta:t})},e.prototype.moveEnd=function(e){var t=Nt(e);t&&this.mutate({endDelta:t})},e.prototype.moveDates=function(e){var t=Nt(e);t&&this.mutate({datesDelta:t})},e.prototype.setAllDay=function(e,t){void 0===t&&(t={});var n={allDay:e},r=t.maintainDuration;null==r&&(r=this._context.options.allDayMaintainDuration),this._def.allDay!==e&&(n.hasEnd=r),this.mutate({standardProps:n})},e.prototype.formatRange=function(e){var t=this._context.dateEnv,n=this._instance,r=ln(e);return this._def.hasEnd?t.formatRange(n.range.start,n.range.end,r,{forcedStartTzo:n.forcedStartTzo,forcedEndTzo:n.forcedEndTzo}):t.format(n.range.start,r,{forcedTzo:n.forcedStartTzo})},e.prototype.mutate=function(t){var n=this._instance;if(n){var r=this._def,o=this._context,i=o.getCurrentData().eventStore,a=bn(i,n.instanceId);a=Sr(a,{"":{display:"",startEditable:!0,durationEditable:!0,constraints:[],overlap:null,allows:[],backgroundColor:"",borderColor:"",textColor:"",classNames:[]}},t,o);var s=new e(o,r,n);this._def=a.defs[r.defId],this._instance=a.instances[n.instanceId],o.dispatch({type:"MERGE_EVENTS",eventStore:a}),o.emitter.trigger("eventChange",{oldEvent:s,event:this,relatedEvents:Ir(a,o,n),revert:function(){o.dispatch({type:"RESET_EVENTS",eventStore:i})}})}},e.prototype.remove=function(){var e=this._context,t=Mr(this);e.dispatch({type:"REMOVE_EVENTS",eventStore:t}),e.emitter.trigger("eventRemove",{event:this,relatedEvents:[],revert:function(){e.dispatch({type:"MERGE_EVENTS",eventStore:t})}})},Object.defineProperty(e.prototype,"source",{get:function(){var e=this._def.sourceId;return e?new ye(this._context,this._context.getCurrentData().eventSources[e]):null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"start",{get:function(){return this._instance?this._context.dateEnv.toDate(this._instance.range.start):null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"end",{get:function(){return this._instance&&this._def.hasEnd?this._context.dateEnv.toDate(this._instance.range.end):null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"startStr",{get:function(){var e=this._instance;return e?this._context.dateEnv.formatIso(e.range.start,{omitTime:this._def.allDay,forcedTzo:e.forcedStartTzo}):""},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"endStr",{get:function(){var e=this._instance;return e&&this._def.hasEnd?this._context.dateEnv.formatIso(e.range.end,{omitTime:this._def.allDay,forcedTzo:e.forcedEndTzo}):""},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"id",{get:function(){return this._def.publicId},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"groupId",{get:function(){return this._def.groupId},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"allDay",{get:function(){return this._def.allDay},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"title",{get:function(){return this._def.title},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"url",{get:function(){return this._def.url},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"display",{get:function(){return this._def.ui.display||"auto"},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"startEditable",{get:function(){return this._def.ui.startEditable},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"durationEditable",{get:function(){return this._def.ui.durationEditable},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"constraint",{get:function(){return this._def.ui.constraints[0]||null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"overlap",{get:function(){return this._def.ui.overlap},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"allow",{get:function(){return this._def.ui.allows[0]||null},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"backgroundColor",{get:function(){return this._def.ui.backgroundColor},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"borderColor",{get:function(){return this._def.ui.borderColor},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"textColor",{get:function(){return this._def.ui.textColor},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"classNames",{get:function(){return this._def.ui.classNames},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"extendedProps",{get:function(){return this._def.extendedProps},enumerable:!1,configurable:!0}),e.prototype.toPlainObject=function(e){void 0===e&&(e={});var t=this._def,n=t.ui,o=this.startStr,i=this.endStr,a={};return t.title&&(a.title=t.title),o&&(a.start=o),i&&(a.end=i),t.publicId&&(a.id=t.publicId),t.groupId&&(a.groupId=t.groupId),t.url&&(a.url=t.url),n.display&&"auto"!==n.display&&(a.display=n.display),e.collapseColor&&n.backgroundColor&&n.backgroundColor===n.borderColor?a.color=n.backgroundColor:(n.backgroundColor&&(a.backgroundColor=n.backgroundColor),n.borderColor&&(a.borderColor=n.borderColor)),n.textColor&&(a.textColor=n.textColor),n.classNames.length&&(a.classNames=n.classNames),Object.keys(t.extendedProps).length&&(e.collapseExtendedProps?r(a,t.extendedProps):a.extendedProps=t.extendedProps),a},e.prototype.toJSON=function(){return this.toPlainObject()},e}();function Mr(e){var t,n,r=e._def,o=e._instance;return{defs:(t={},t[r.defId]=r,t),instances:o?(n={},n[o.instanceId]=o,n):{}}}function Ir(e,t,n){var r=e.defs,o=e.instances,i=[],a=n?n.instanceId:"";for(var s in o){var l=o[s],u=r[l.defId];l.instanceId!==a&&i.push(new xr(t,u,l))}return i}var Pr={};var Nr,Hr=function(){function e(){}return e.prototype.getMarkerYear=function(e){return e.getUTCFullYear()},e.prototype.getMarkerMonth=function(e){return e.getUTCMonth()},e.prototype.getMarkerDay=function(e){return e.getUTCDate()},e.prototype.arrayToMarker=function(e){return ht(e)},e.prototype.markerToArray=function(e){return ft(e)},e}();Nr=Hr,Pr["gregory"]=Nr;var Or=/^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;function Ar(e){var t=Or.exec(e);if(t){var n=new Date(Date.UTC(Number(t[1]),t[3]?Number(t[3])-1:0,Number(t[5]||1),Number(t[7]||0),Number(t[8]||0),Number(t[10]||0),t[12]?1e3*Number("0."+t[12]):0));if(vt(n)){var r=null;return t[13]&&(r=("-"===t[15]?-1:1)*(60*Number(t[16]||0)+Number(t[18]||0))),{marker:n,isTimeUnspecified:!t[6],timeZoneOffset:r}}}return null}var Lr=function(){function e(e){var t=this.timeZone=e.timeZone,n="local"!==t&&"UTC"!==t;e.namedTimeZoneImpl&&n&&(this.namedTimeZoneImpl=new e.namedTimeZoneImpl(t)),this.canComputeOffset=Boolean(!n||this.namedTimeZoneImpl),this.calendarSystem=function(e){return new Pr[e]}(e.calendarSystem),this.locale=e.locale,this.weekDow=e.locale.week.dow,this.weekDoy=e.locale.week.doy,"ISO"===e.weekNumberCalculation&&(this.weekDow=1,this.weekDoy=4),"number"==typeof e.firstDay&&(this.weekDow=e.firstDay),"function"==typeof e.weekNumberCalculation&&(this.weekNumberFunc=e.weekNumberCalculation),this.weekText=null!=e.weekText?e.weekText:e.locale.options.weekText,this.weekTextLong=(null!=e.weekTextLong?e.weekTextLong:e.locale.options.weekTextLong)||this.weekText,this.cmdFormatter=e.cmdFormatter,this.defaultSeparator=e.defaultSeparator}return e.prototype.createMarker=function(e){var t=this.createMarkerMeta(e);return null===t?null:t.marker},e.prototype.createNowMarker=function(){return this.canComputeOffset?this.timestampToMarker((new Date).valueOf()):ht(dt(new Date))},e.prototype.createMarkerMeta=function(e){if("string"==typeof e)return this.parse(e);var t=null;return"number"==typeof e?t=this.timestampToMarker(e):e instanceof Date?(e=e.valueOf(),isNaN(e)||(t=this.timestampToMarker(e))):Array.isArray(e)&&(t=ht(e)),null!==t&&vt(t)?{marker:t,isTimeUnspecified:!1,forcedTzo:null}:null},e.prototype.parse=function(e){var t=Ar(e);if(null===t)return null;var n=t.marker,r=null;return null!==t.timeZoneOffset&&(this.canComputeOffset?n=this.timestampToMarker(n.valueOf()-60*t.timeZoneOffset*1e3):r=t.timeZoneOffset),{marker:n,isTimeUnspecified:t.isTimeUnspecified,forcedTzo:r}},e.prototype.getYear=function(e){return this.calendarSystem.getMarkerYear(e)},e.prototype.getMonth=function(e){return this.calendarSystem.getMarkerMonth(e)},e.prototype.add=function(e,t){var n=this.calendarSystem.markerToArray(e);return n[0]+=t.years,n[1]+=t.months,n[2]+=t.days,n[6]+=t.milliseconds,this.calendarSystem.arrayToMarker(n)},e.prototype.subtract=function(e,t){var n=this.calendarSystem.markerToArray(e);return n[0]-=t.years,n[1]-=t.months,n[2]-=t.days,n[6]-=t.milliseconds,this.calendarSystem.arrayToMarker(n)},e.prototype.addYears=function(e,t){var n=this.calendarSystem.markerToArray(e);return n[0]+=t,this.calendarSystem.arrayToMarker(n)},e.prototype.addMonths=function(e,t){var n=this.calendarSystem.markerToArray(e);return n[1]+=t,this.calendarSystem.arrayToMarker(n)},e.prototype.diffWholeYears=function(e,t){var n=this.calendarSystem;return gt(e)===gt(t)&&n.getMarkerDay(e)===n.getMarkerDay(t)&&n.getMarkerMonth(e)===n.getMarkerMonth(t)?n.getMarkerYear(t)-n.getMarkerYear(e):null},e.prototype.diffWholeMonths=function(e,t){var n=this.calendarSystem;return gt(e)===gt(t)&&n.getMarkerDay(e)===n.getMarkerDay(t)?n.getMarkerMonth(t)-n.getMarkerMonth(e)+12*(n.getMarkerYear(t)-n.getMarkerYear(e)):null},e.prototype.greatestWholeUnit=function(e,t){var n=this.diffWholeYears(e,t);return null!==n?{unit:"year",value:n}:null!==(n=this.diffWholeMonths(e,t))?{unit:"month",value:n}:null!==(n=at(e,t))?{unit:"week",value:n}:null!==(n=st(e,t))?{unit:"day",value:n}:$e(n=function(e,t){return(t.valueOf()-e.valueOf())/36e5}(e,t))?{unit:"hour",value:n}:$e(n=function(e,t){return(t.valueOf()-e.valueOf())/6e4}(e,t))?{unit:"minute",value:n}:$e(n=function(e,t){return(t.valueOf()-e.valueOf())/1e3}(e,t))?{unit:"second",value:n}:{unit:"millisecond",value:t.valueOf()-e.valueOf()}},e.prototype.countDurationsBetween=function(e,t,n){var r;return n.years&&null!==(r=this.diffWholeYears(e,t))?r/(Lt(n)/365):n.months&&null!==(r=this.diffWholeMonths(e,t))?r/function(e){return Lt(e)/30}(n):n.days&&null!==(r=st(e,t))?r/Lt(n):(t.valueOf()-e.valueOf())/Ut(n)},e.prototype.startOf=function(e,t){return"year"===t?this.startOfYear(e):"month"===t?this.startOfMonth(e):"week"===t?this.startOfWeek(e):"day"===t?lt(e):"hour"===t?function(e){return ht([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours()])}(e):"minute"===t?function(e){return ht([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes()])}(e):"second"===t?function(e){return ht([e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate(),e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds()])}(e):null},e.prototype.startOfYear=function(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e)])},e.prototype.startOfMonth=function(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e),this.calendarSystem.getMarkerMonth(e)])},e.prototype.startOfWeek=function(e){return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(e),this.calendarSystem.getMarkerMonth(e),e.getUTCDate()-(e.getUTCDay()-this.weekDow+7)%7])},e.prototype.computeWeekNumber=function(e){return this.weekNumberFunc?this.weekNumberFunc(this.toDate(e)):function(e,t,n){var r=e.getUTCFullYear(),o=ut(e,r,t,n);if(o<1)return ut(e,r-1,t,n);var i=ut(e,r+1,t,n);return i>=1?Math.min(o,i):o}(e,this.weekDow,this.weekDoy)},e.prototype.format=function(e,t,n){return void 0===n&&(n={}),t.format({marker:e,timeZoneOffset:null!=n.forcedTzo?n.forcedTzo:this.offsetForMarker(e)},this)},e.prototype.formatRange=function(e,t,n,r){return void 0===r&&(r={}),r.isEndExclusive&&(t=nt(t,-1)),n.formatRange({marker:e,timeZoneOffset:null!=r.forcedStartTzo?r.forcedStartTzo:this.offsetForMarker(e)},{marker:t,timeZoneOffset:null!=r.forcedEndTzo?r.forcedEndTzo:this.offsetForMarker(t)},this,r.defaultSeparator)},e.prototype.formatIso=function(e,t){void 0===t&&(t={});var n=null;return t.omitTimeZoneOffset||(n=null!=t.forcedTzo?t.forcedTzo:this.offsetForMarker(e)),Ft(e,n,t.omitTime)},e.prototype.timestampToMarker=function(e){return"local"===this.timeZone?ht(dt(new Date(e))):"UTC"!==this.timeZone&&this.namedTimeZoneImpl?ht(this.namedTimeZoneImpl.timestampToArray(e)):new Date(e)},e.prototype.offsetForMarker=function(e){return"local"===this.timeZone?-pt(ft(e)).getTimezoneOffset():"UTC"===this.timeZone?0:this.namedTimeZoneImpl?this.namedTimeZoneImpl.offsetForArray(ft(e)):null},e.prototype.toDate=function(e,t){return"local"===this.timeZone?pt(ft(e)):"UTC"===this.timeZone?new Date(e.valueOf()):this.namedTimeZoneImpl?new Date(e.valueOf()-1e3*this.namedTimeZoneImpl.offsetForArray(ft(e))*60):new Date(e.valueOf()-(t||0))},e}(),Ur=[],Wr={code:"en",week:{dow:0,doy:4},direction:"ltr",buttonText:{prev:"prev",next:"next",prevYear:"prev year",nextYear:"next year",year:"year",today:"today",month:"month",week:"week",day:"day",list:"list"},weekText:"W",weekTextLong:"Week",closeHint:"Close",timeHint:"Time",eventHint:"Event",allDayText:"all-day",moreLinkText:"more",noEventsText:"No events to display"},Vr=r(r({},Wr),{buttonHints:{prev:"Previous $0",next:"Next $0",today:function(e,t){return"day"===t?"Today":"This "+e}},viewHint:"$0 view",navLinkHint:"Go to $0",moreLinkHint:function(e){return"Show "+e+" more event"+(1===e?"":"s")}});function Fr(e){for(var t=e.length>0?e[0].code:"en",n=Ur.concat(e),r={en:Vr},o=0,i=n;o<i.length;o++){var a=i[o];r[a.code]=a}return{map:r,defaultCode:t}}function Br(e,t){return"object"!=typeof e||Array.isArray(e)?function(e,t){var n=[].concat(e||[]),r=function(e,t){for(var n=0;n<e.length;n+=1)for(var r=e[n].toLocaleLowerCase().split("-"),o=r.length;o>0;o-=1){var i=r.slice(0,o).join("-");if(t[i])return t[i]}return null}(n,t)||Vr;return zr(e,n,r)}(e,t):zr(e.code,[e.code],e)}function zr(e,t,n){var r=Et([Wr,n],["buttonText"]);delete r.code;var o=r.week;return delete r.week,{codeArg:e,codes:t,week:o,simpleNumberFormat:new Intl.NumberFormat(e),options:r}}function jr(e){var t=Br(e.locale||"en",Fr([]).map);return new Lr(r(r({timeZone:cn.timeZone,calendarSystem:"gregory"},e),{locale:t}))}var Gr,qr={startTime:"09:00",endTime:"17:00",daysOfWeek:[1,2,3,4,5],display:"inverse-background",classNames:"fc-non-business",groupId:"_businessHours"};function Yr(e,t){return En(function(e){var t;t=!0===e?[{}]:Array.isArray(e)?e.filter((function(e){return e.daysOfWeek})):"object"==typeof e&&e?[e]:[];return t=t.map((function(e){return r(r({},qr),e)}))}(e),null,t)}function Zr(e,t){return e.left>=t.left&&e.left<t.right&&e.top>=t.top&&e.top<t.bottom}function Xr(e,t){var n={left:Math.max(e.left,t.left),right:Math.min(e.right,t.right),top:Math.max(e.top,t.top),bottom:Math.min(e.bottom,t.bottom)};return n.left<n.right&&n.top<n.bottom&&n}function Kr(e,t){return{left:Math.min(Math.max(e.left,t.left),t.right),top:Math.min(Math.max(e.top,t.top),t.bottom)}}function $r(e){return{left:(e.left+e.right)/2,top:(e.top+e.bottom)/2}}function Jr(e,t){return{left:e.left-t.left,top:e.top-t.top}}function Qr(){return null==Gr&&(Gr=function(){if("undefined"==typeof document)return!0;var e=document.createElement("div");e.style.position="absolute",e.style.top="0px",e.style.left="0px",e.innerHTML="<table><tr><td><div></div></td></tr></table>",e.querySelector("table").style.height="100px",e.querySelector("div").style.height="100%",document.body.appendChild(e);var t=e.querySelector("div").offsetHeight>0;return document.body.removeChild(e),t}()),Gr}var eo={defs:{},instances:{}},to=function(){function e(){this.getKeysForEventDefs=qt(this._getKeysForEventDefs),this.splitDateSelection=qt(this._splitDateSpan),this.splitEventStore=qt(this._splitEventStore),this.splitIndividualUi=qt(this._splitIndividualUi),this.splitEventDrag=qt(this._splitInteraction),this.splitEventResize=qt(this._splitInteraction),this.eventUiBuilders={}}return e.prototype.splitProps=function(e){var t=this,n=this.getKeyInfo(e),r=this.getKeysForEventDefs(e.eventStore),o=this.splitDateSelection(e.dateSelection),i=this.splitIndividualUi(e.eventUiBases,r),a=this.splitEventStore(e.eventStore,r),s=this.splitEventDrag(e.eventDrag),l=this.splitEventResize(e.eventResize),u={};for(var c in this.eventUiBuilders=bt(n,(function(e,n){return t.eventUiBuilders[n]||qt(no)})),n){var d=n[c],p=a[c]||eo,f=this.eventUiBuilders[c];u[c]={businessHours:d.businessHours||e.businessHours,dateSelection:o[c]||null,eventStore:p,eventUiBases:f(e.eventUiBases[""],d.ui,i[c]),eventSelection:p.instances[e.eventSelection]?e.eventSelection:"",eventDrag:s[c]||null,eventResize:l[c]||null}}return u},e.prototype._splitDateSpan=function(e){var t={};if(e)for(var n=0,r=this.getKeysForDateSpan(e);n<r.length;n++){t[r[n]]=e}return t},e.prototype._getKeysForEventDefs=function(e){var t=this;return bt(e.defs,(function(e){return t.getKeysForEventDef(e)}))},e.prototype._splitEventStore=function(e,t){var n=e.defs,r=e.instances,o={};for(var i in n)for(var a=0,s=t[i];a<s.length;a++){o[p=s[a]]||(o[p]={defs:{},instances:{}}),o[p].defs[i]=n[i]}for(var l in r)for(var u=r[l],c=0,d=t[u.defId];c<d.length;c++){var p;o[p=d[c]]&&(o[p].instances[l]=u)}return o},e.prototype._splitIndividualUi=function(e,t){var n={};for(var r in e)if(r)for(var o=0,i=t[r];o<i.length;o++){var a=i[o];n[a]||(n[a]={}),n[a][r]=e[r]}return n},e.prototype._splitInteraction=function(e){var t={};if(e){var n=this._splitEventStore(e.affectedEvents,this._getKeysForEventDefs(e.affectedEvents)),r=this._getKeysForEventDefs(e.mutatedEvents),o=this._splitEventStore(e.mutatedEvents,r),i=function(r){t[r]||(t[r]={affectedEvents:n[r]||eo,mutatedEvents:o[r]||eo,isEvent:e.isEvent})};for(var a in n)i(a);for(var a in o)i(a)}return t},e}();function no(e,t,n){var o=[];e&&o.push(e),t&&o.push(t);var i={"":xn(o)};return n&&r(i,n),i}function ro(e,t,n,r){return{dow:e.getUTCDay(),isDisabled:Boolean(r&&!Zn(r.activeRange,e)),isOther:Boolean(r&&!Zn(r.currentRange,e)),isToday:Boolean(t&&Zn(t,e)),isPast:Boolean(n?e<n:!!t&&e<t.start),isFuture:Boolean(n?e>n:!!t&&e>=t.end)}}function oo(e,t){var n=["fc-day","fc-day-"+Qe[e.dow]];return e.isDisabled?n.push("fc-day-disabled"):(e.isToday&&(n.push("fc-day-today"),n.push(t.getClass("today"))),e.isPast&&n.push("fc-day-past"),e.isFuture&&n.push("fc-day-future"),e.isOther&&n.push("fc-day-other")),n}var io=ln({year:"numeric",month:"long",day:"numeric"}),ao=ln({week:"long"});function so(e,t,n,o){void 0===n&&(n="day"),void 0===o&&(o=!0);var i=e.dateEnv,a=e.options,s=e.calendarApi,l=i.format(t,"week"===n?ao:io);if(a.navLinks){var u=i.toDate(t),c=function(e){var r="day"===n?a.navLinkDayClick:"week"===n?a.navLinkWeekClick:null;"function"==typeof r?r.call(s,i.toDate(t),e):("string"==typeof r&&(n=r),s.zoomTo(t,n))};return r({title:Xe(a.navLinkHint,[l,u],l),"data-navlink":""},o?He(c):{onClick:c})}return{"aria-label":l}}var lo,uo=null;function co(){return null===uo&&(uo=function(){var e=document.createElement("div");we(e,{position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}),e.innerHTML="<div></div>",document.body.appendChild(e);var t=e.firstChild.getBoundingClientRect().left>e.getBoundingClientRect().left;return Ee(e),t}()),uo}function po(){return lo||(lo=function(){var e=document.createElement("div");e.style.overflow="scroll",e.style.position="absolute",e.style.top="-9999px",e.style.left="-9999px",document.body.appendChild(e);var t=fo(e);return document.body.removeChild(e),t}()),lo}function fo(e){return{x:e.offsetHeight-e.clientHeight,y:e.offsetWidth-e.clientWidth}}function ho(e,t){void 0===t&&(t=!1);var n=window.getComputedStyle(e),r=parseInt(n.borderLeftWidth,10)||0,o=parseInt(n.borderRightWidth,10)||0,i=parseInt(n.borderTopWidth,10)||0,a=parseInt(n.borderBottomWidth,10)||0,s=fo(e),l=s.y-r-o,u={borderLeft:r,borderRight:o,borderTop:i,borderBottom:a,scrollbarBottom:s.x-i-a,scrollbarLeft:0,scrollbarRight:0};return co()&&"rtl"===n.direction?u.scrollbarLeft=l:u.scrollbarRight=l,t&&(u.paddingLeft=parseInt(n.paddingLeft,10)||0,u.paddingRight=parseInt(n.paddingRight,10)||0,u.paddingTop=parseInt(n.paddingTop,10)||0,u.paddingBottom=parseInt(n.paddingBottom,10)||0),u}function vo(e,t,n){void 0===t&&(t=!1);var r=n?e.getBoundingClientRect():go(e),o=ho(e,t),i={left:r.left+o.borderLeft+o.scrollbarLeft,right:r.right-o.borderRight-o.scrollbarRight,top:r.top+o.borderTop,bottom:r.bottom-o.borderBottom-o.scrollbarBottom};return t&&(i.left+=o.paddingLeft,i.right-=o.paddingRight,i.top+=o.paddingTop,i.bottom-=o.paddingBottom),i}function go(e){var t=e.getBoundingClientRect();return{left:t.left+window.pageXOffset,top:t.top+window.pageYOffset,right:t.right+window.pageXOffset,bottom:t.bottom+window.pageYOffset}}function mo(e){for(var t=[];e instanceof HTMLElement;){var n=window.getComputedStyle(e);if("fixed"===n.position)break;/(auto|scroll)/.test(n.overflow+n.overflowY+n.overflowX)&&t.push(e),e=e.parentNode}return t}function yo(e,t,n){var r=!1,o=function(){r||(r=!0,t.apply(this,arguments))},i=function(){r||(r=!0,n&&n.apply(this,arguments))},a=e(o,i);a&&"function"==typeof a.then&&a.then(o,i)}var Eo=function(){function e(){this.handlers={},this.thisContext=null}return e.prototype.setThisContext=function(e){this.thisContext=e},e.prototype.setOptions=function(e){this.options=e},e.prototype.on=function(e,t){!function(e,t,n){(e[t]||(e[t]=[])).push(n)}(this.handlers,e,t)},e.prototype.off=function(e,t){!function(e,t,n){n?e[t]&&(e[t]=e[t].filter((function(e){return e!==n}))):delete e[t]}(this.handlers,e,t)},e.prototype.trigger=function(e){for(var t=[],n=1;n<arguments.length;n++)t[n-1]=arguments[n];for(var r=this.handlers[e]||[],o=this.options&&this.options[e],i=[].concat(o||[],r),a=0,s=i;a<s.length;a++){var l=s[a];l.apply(this.thisContext,t)}},e.prototype.hasHandlers=function(e){return Boolean(this.handlers[e]&&this.handlers[e].length||this.options&&this.options[e])},e}();var So=function(){function e(e,t,n,r){this.els=t;var o=this.originClientRect=e.getBoundingClientRect();n&&this.buildElHorizontals(o.left),r&&this.buildElVerticals(o.top)}return e.prototype.buildElHorizontals=function(e){for(var t=[],n=[],r=0,o=this.els;r<o.length;r++){var i=o[r].getBoundingClientRect();t.push(i.left-e),n.push(i.right-e)}this.lefts=t,this.rights=n},e.prototype.buildElVerticals=function(e){for(var t=[],n=[],r=0,o=this.els;r<o.length;r++){var i=o[r].getBoundingClientRect();t.push(i.top-e),n.push(i.bottom-e)}this.tops=t,this.bottoms=n},e.prototype.leftToIndex=function(e){var t,n=this.lefts,r=this.rights,o=n.length;for(t=0;t<o;t+=1)if(e>=n[t]&&e<r[t])return t},e.prototype.topToIndex=function(e){var t,n=this.tops,r=this.bottoms,o=n.length;for(t=0;t<o;t+=1)if(e>=n[t]&&e<r[t])return t},e.prototype.getWidth=function(e){return this.rights[e]-this.lefts[e]},e.prototype.getHeight=function(e){return this.bottoms[e]-this.tops[e]},e}(),bo=function(){function e(){}return e.prototype.getMaxScrollTop=function(){return this.getScrollHeight()-this.getClientHeight()},e.prototype.getMaxScrollLeft=function(){return this.getScrollWidth()-this.getClientWidth()},e.prototype.canScrollVertically=function(){return this.getMaxScrollTop()>0},e.prototype.canScrollHorizontally=function(){return this.getMaxScrollLeft()>0},e.prototype.canScrollUp=function(){return this.getScrollTop()>0},e.prototype.canScrollDown=function(){return this.getScrollTop()<this.getMaxScrollTop()},e.prototype.canScrollLeft=function(){return this.getScrollLeft()>0},e.prototype.canScrollRight=function(){return this.getScrollLeft()<this.getMaxScrollLeft()},e}(),Do=function(e){function t(t){var n=e.call(this)||this;return n.el=t,n}return n(t,e),t.prototype.getScrollTop=function(){return this.el.scrollTop},t.prototype.getScrollLeft=function(){return this.el.scrollLeft},t.prototype.setScrollTop=function(e){this.el.scrollTop=e},t.prototype.setScrollLeft=function(e){this.el.scrollLeft=e},t.prototype.getScrollWidth=function(){return this.el.scrollWidth},t.prototype.getScrollHeight=function(){return this.el.scrollHeight},t.prototype.getClientHeight=function(){return this.el.clientHeight},t.prototype.getClientWidth=function(){return this.el.clientWidth},t}(bo),Co=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.getScrollTop=function(){return window.pageYOffset},t.prototype.getScrollLeft=function(){return window.pageXOffset},t.prototype.setScrollTop=function(e){window.scroll(window.pageXOffset,e)},t.prototype.setScrollLeft=function(e){window.scroll(e,window.pageYOffset)},t.prototype.getScrollWidth=function(){return document.documentElement.scrollWidth},t.prototype.getScrollHeight=function(){return document.documentElement.scrollHeight},t.prototype.getClientHeight=function(){return document.documentElement.clientHeight},t.prototype.getClientWidth=function(){return document.documentElement.clientWidth},t}(bo),wo=function(){function e(e){this.iconOverrideOption&&this.setIconOverride(e[this.iconOverrideOption])}return e.prototype.setIconOverride=function(e){var t,n;if("object"==typeof e&&e){for(n in t=r({},this.iconClasses),e)t[n]=this.applyIconOverridePrefix(e[n]);this.iconClasses=t}else!1===e&&(this.iconClasses={})},e.prototype.applyIconOverridePrefix=function(e){var t=this.iconOverridePrefix;return t&&0!==e.indexOf(t)&&(e=t+e),e},e.prototype.getClass=function(e){return this.classes[e]||""},e.prototype.getIconClass=function(e,t){var n;return(n=t&&this.rtlIconClasses&&this.rtlIconClasses[e]||this.iconClasses[e])?this.baseIconClass+" "+n:""},e.prototype.getCustomButtonIconClass=function(e){var t;return this.iconOverrideCustomButtonOption&&(t=e[this.iconOverrideCustomButtonOption])?this.baseIconClass+" "+this.applyIconOverridePrefix(t):""},e}();if(wo.prototype.classes={},wo.prototype.iconClasses={},wo.prototype.baseIconClass="",wo.prototype.iconOverridePrefix="","undefined"==typeof FullCalendarVDom)throw new Error("Please import the top-level fullcalendar lib before attempting to import a plugin.");var Ro=FullCalendarVDom.Component,_o=FullCalendarVDom.createElement,To=FullCalendarVDom.render,ko=FullCalendarVDom.createRef,xo=FullCalendarVDom.Fragment,Mo=FullCalendarVDom.createContext,Io=FullCalendarVDom.createPortal,Po=FullCalendarVDom.flushSync,No=FullCalendarVDom.unmountComponentAtNode,Ho=function(){function e(e,t,n,o){var i=this;this.execFunc=e,this.emitter=t,this.scrollTime=n,this.scrollTimeReset=o,this.handleScrollRequest=function(e){i.queuedRequest=r({},i.queuedRequest||{},e),i.drain()},t.on("_scrollRequest",this.handleScrollRequest),this.fireInitialScroll()}return e.prototype.detach=function(){this.emitter.off("_scrollRequest",this.handleScrollRequest)},e.prototype.update=function(e){e&&this.scrollTimeReset?this.fireInitialScroll():this.drain()},e.prototype.fireInitialScroll=function(){this.handleScrollRequest({time:this.scrollTime})},e.prototype.drain=function(){this.queuedRequest&&this.execFunc(this.queuedRequest)&&(this.queuedRequest=null)},e}(),Oo=Mo({});function Ao(e,t,n,r,o,i,a,s,l,u,c,d,p){return{dateEnv:o,options:n,pluginHooks:a,emitter:u,dispatch:s,getCurrentData:l,calendarApi:c,viewSpec:e,viewApi:t,dateProfileGenerator:r,theme:i,isRtl:"rtl"===n.direction,addResizeHandler:function(e){u.on("_resize",e)},removeResizeHandler:function(e){u.off("_resize",e)},createScrollResponder:function(e){return new Ho(e,u,Nt(n.scrollTime),n.scrollTimeReset)},registerInteractiveComponent:d,unregisterInteractiveComponent:p}}var Lo=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.shouldComponentUpdate=function(e,t){return this.debug&&console.log(Rt(e,this.props),Rt(t,this.state)),!_t(this.props,e,this.propEquality)||!_t(this.state,t,this.stateEquality)},t.prototype.safeSetState=function(e){_t(this.state,r(r({},this.state),e),this.stateEquality)||this.setState(e)},t.addPropsEquality=Wo,t.addStateEquality=Vo,t.contextType=Oo,t}(Ro);Lo.prototype.propEquality={},Lo.prototype.stateEquality={};var Uo=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.contextType=Oo,t}(Lo);function Wo(e){var t=Object.create(this.prototype.propEquality);r(t,e),this.prototype.propEquality=t}function Vo(e){var t=Object.create(this.prototype.stateEquality);r(t,e),this.prototype.stateEquality=t}function Fo(e,t){"function"==typeof e?e(t):e&&(e.current=t)}var Bo=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.uid=Le(),t}return n(t,e),t.prototype.prepareHits=function(){},t.prototype.queryHit=function(e,t,n,r){return null},t.prototype.isValidSegDownEl=function(e){return!this.props.eventDrag&&!this.props.eventResize&&!Se(e,".fc-event-mirror")},t.prototype.isValidDateDownEl=function(e){return!(Se(e,".fc-event:not(.fc-bg-event)")||Se(e,".fc-more-link")||Se(e,"a[data-navlink]")||Se(e,".fc-popover"))},t}(Uo);function zo(e){return{id:Le(),deps:e.deps||[],reducers:e.reducers||[],isLoadingFuncs:e.isLoadingFuncs||[],contextInit:[].concat(e.contextInit||[]),eventRefiners:e.eventRefiners||{},eventDefMemberAdders:e.eventDefMemberAdders||[],eventSourceRefiners:e.eventSourceRefiners||{},isDraggableTransformers:e.isDraggableTransformers||[],eventDragMutationMassagers:e.eventDragMutationMassagers||[],eventDefMutationAppliers:e.eventDefMutationAppliers||[],dateSelectionTransformers:e.dateSelectionTransformers||[],datePointTransforms:e.datePointTransforms||[],dateSpanTransforms:e.dateSpanTransforms||[],views:e.views||{},viewPropsTransformers:e.viewPropsTransformers||[],isPropsValid:e.isPropsValid||null,externalDefTransforms:e.externalDefTransforms||[],viewContainerAppends:e.viewContainerAppends||[],eventDropTransformers:e.eventDropTransformers||[],componentInteractions:e.componentInteractions||[],calendarInteractions:e.calendarInteractions||[],themeClasses:e.themeClasses||{},eventSourceDefs:e.eventSourceDefs||[],cmdFormatter:e.cmdFormatter,recurringTypes:e.recurringTypes||[],namedTimeZonedImpl:e.namedTimeZonedImpl,initialView:e.initialView||"",elementDraggingImpl:e.elementDraggingImpl,optionChangeHandlers:e.optionChangeHandlers||{},scrollGridImpl:e.scrollGridImpl||null,contentTypeHandlers:e.contentTypeHandlers||{},listenerRefiners:e.listenerRefiners||{},optionRefiners:e.optionRefiners||{},propSetHandlers:e.propSetHandlers||{}}}function jo(){var e,t=[],n=[];return function(o,i){return e&&Gt(o,t)&&Gt(i,n)||(e=function(e,t){var n={},o={reducers:[],isLoadingFuncs:[],contextInit:[],eventRefiners:{},eventDefMemberAdders:[],eventSourceRefiners:{},isDraggableTransformers:[],eventDragMutationMassagers:[],eventDefMutationAppliers:[],dateSelectionTransformers:[],datePointTransforms:[],dateSpanTransforms:[],views:{},viewPropsTransformers:[],isPropsValid:null,externalDefTransforms:[],viewContainerAppends:[],eventDropTransformers:[],componentInteractions:[],calendarInteractions:[],themeClasses:{},eventSourceDefs:[],cmdFormatter:null,recurringTypes:[],namedTimeZonedImpl:null,initialView:"",elementDraggingImpl:null,optionChangeHandlers:{},scrollGridImpl:null,contentTypeHandlers:{},listenerRefiners:{},optionRefiners:{},propSetHandlers:{}};function i(e){for(var t=0,a=e;t<a.length;t++){var s=a[t];n[s.id]||(n[s.id]=!0,i(s.deps),u=s,o={reducers:(l=o).reducers.concat(u.reducers),isLoadingFuncs:l.isLoadingFuncs.concat(u.isLoadingFuncs),contextInit:l.contextInit.concat(u.contextInit),eventRefiners:r(r({},l.eventRefiners),u.eventRefiners),eventDefMemberAdders:l.eventDefMemberAdders.concat(u.eventDefMemberAdders),eventSourceRefiners:r(r({},l.eventSourceRefiners),u.eventSourceRefiners),isDraggableTransformers:l.isDraggableTransformers.concat(u.isDraggableTransformers),eventDragMutationMassagers:l.eventDragMutationMassagers.concat(u.eventDragMutationMassagers),eventDefMutationAppliers:l.eventDefMutationAppliers.concat(u.eventDefMutationAppliers),dateSelectionTransformers:l.dateSelectionTransformers.concat(u.dateSelectionTransformers),datePointTransforms:l.datePointTransforms.concat(u.datePointTransforms),dateSpanTransforms:l.dateSpanTransforms.concat(u.dateSpanTransforms),views:r(r({},l.views),u.views),viewPropsTransformers:l.viewPropsTransformers.concat(u.viewPropsTransformers),isPropsValid:u.isPropsValid||l.isPropsValid,externalDefTransforms:l.externalDefTransforms.concat(u.externalDefTransforms),viewContainerAppends:l.viewContainerAppends.concat(u.viewContainerAppends),eventDropTransformers:l.eventDropTransformers.concat(u.eventDropTransformers),calendarInteractions:l.calendarInteractions.concat(u.calendarInteractions),componentInteractions:l.componentInteractions.concat(u.componentInteractions),themeClasses:r(r({},l.themeClasses),u.themeClasses),eventSourceDefs:l.eventSourceDefs.concat(u.eventSourceDefs),cmdFormatter:u.cmdFormatter||l.cmdFormatter,recurringTypes:l.recurringTypes.concat(u.recurringTypes),namedTimeZonedImpl:u.namedTimeZonedImpl||l.namedTimeZonedImpl,initialView:l.initialView||u.initialView,elementDraggingImpl:l.elementDraggingImpl||u.elementDraggingImpl,optionChangeHandlers:r(r({},l.optionChangeHandlers),u.optionChangeHandlers),scrollGridImpl:u.scrollGridImpl||l.scrollGridImpl,contentTypeHandlers:r(r({},l.contentTypeHandlers),u.contentTypeHandlers),listenerRefiners:r(r({},l.listenerRefiners),u.listenerRefiners),optionRefiners:r(r({},l.optionRefiners),u.optionRefiners),propSetHandlers:r(r({},l.propSetHandlers),u.propSetHandlers)})}var l,u}return e&&i(e),i(t),o}(o,i)),t=o,n=i,e}}var Go=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t}(wo);function qo(e,t,n,o){if(t[e])return t[e];var i=function(e,t,n,o){var i=n[e],a=o[e],s=function(e){return i&&null!==i[e]?i[e]:a&&null!==a[e]?a[e]:null},l=s("component"),u=s("superType"),c=null;if(u){if(u===e)throw new Error("Can't have a custom view type that references itself");c=qo(u,t,n,o)}!l&&c&&(l=c.component);if(!l)return null;return{type:e,component:l,defaults:r(r({},c?c.defaults:{}),i?i.rawOptions:{}),overrides:r(r({},c?c.overrides:{}),a?a.rawOptions:{})}}(e,t,n,o);return i&&(t[e]=i),i}Go.prototype.classes={root:"fc-theme-standard",tableCellShaded:"fc-cell-shaded",buttonGroup:"fc-button-group",button:"fc-button fc-button-primary",buttonActive:"fc-button-active"},Go.prototype.baseIconClass="fc-icon",Go.prototype.iconClasses={close:"fc-icon-x",prev:"fc-icon-chevron-left",next:"fc-icon-chevron-right",prevYear:"fc-icon-chevrons-left",nextYear:"fc-icon-chevrons-right"},Go.prototype.rtlIconClasses={prev:"fc-icon-chevron-right",next:"fc-icon-chevron-left",prevYear:"fc-icon-chevrons-right",nextYear:"fc-icon-chevrons-left"},Go.prototype.iconOverrideOption="buttonIcons",Go.prototype.iconOverrideCustomButtonOption="icon",Go.prototype.iconOverridePrefix="fc-icon-";var Yo=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.rootElRef=ko(),t.handleRootEl=function(e){Fo(t.rootElRef,e),t.props.elRef&&Fo(t.props.elRef,e)},t}return n(t,e),t.prototype.render=function(){var e=this,t=this.props,n=t.hookProps;return _o($o,{hookProps:n,didMount:t.didMount,willUnmount:t.willUnmount,elRef:this.handleRootEl},(function(r){return _o(Xo,{hookProps:n,content:t.content,defaultContent:t.defaultContent,backupElRef:e.rootElRef},(function(e,o){return t.children(r,Qo(t.classNames,n),e,o)}))}))},t}(Uo),Zo=Mo(0);function Xo(e){return _o(Zo.Consumer,null,(function(t){return _o(Ko,r({renderId:t},e))}))}var Ko=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.innerElRef=ko(),t}return n(t,e),t.prototype.render=function(){return this.props.children(this.innerElRef,this.renderInnerContent())},t.prototype.componentDidMount=function(){this.updateCustomContent()},t.prototype.componentDidUpdate=function(){this.updateCustomContent()},t.prototype.componentWillUnmount=function(){this.customContentInfo&&this.customContentInfo.destroy&&this.customContentInfo.destroy()},t.prototype.renderInnerContent=function(){var e=this.customContentInfo,t=this.getInnerContent(),n=this.getContentMeta(t);return e&&e.contentKey===n.contentKey?e&&(e.contentVal=t[n.contentKey]):(e&&(e.destroy&&e.destroy(),e=this.customContentInfo=null),n.contentKey&&(e=this.customContentInfo=r({contentKey:n.contentKey,contentVal:t[n.contentKey]},n.buildLifecycleFuncs()))),e?[]:t},t.prototype.getInnerContent=function(){var e=this.props,t=ei(e.content,e.hookProps);return void 0===t&&(t=ei(e.defaultContent,e.hookProps)),null==t?null:t},t.prototype.getContentMeta=function(e){var t=this.context.pluginHooks.contentTypeHandlers,n="",r=null;if(e)for(var o in t)if(void 0!==e[o]){n=o,r=t[o];break}return{contentKey:n,buildLifecycleFuncs:r}},t.prototype.updateCustomContent=function(){this.customContentInfo&&this.customContentInfo.render(this.innerElRef.current||this.props.backupElRef.current,this.customContentInfo.contentVal)},t}(Uo),$o=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.handleRootEl=function(e){t.rootEl=e,t.props.elRef&&Fo(t.props.elRef,e)},t}return n(t,e),t.prototype.render=function(){return this.props.children(this.handleRootEl)},t.prototype.componentDidMount=function(){var e=this.props.didMount;e&&e(r(r({},this.props.hookProps),{el:this.rootEl}))},t.prototype.componentWillUnmount=function(){var e=this.props.willUnmount;e&&e(r(r({},this.props.hookProps),{el:this.rootEl}))},t}(Uo);function Jo(){var e,t,n=[];return function(r,o){return t&&wt(t,o)&&r===e||(e=r,t=o,n=Qo(r,o)),n}}function Qo(e,t){return"function"==typeof e&&(e=e(t)),Rn(e)}function ei(e,t){return"function"==typeof e?e(t,_o):e}var ti=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.normalizeClassNames=Jo(),t}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context,n=t.options,r={view:t.viewApi},o=this.normalizeClassNames(n.viewClassNames,r);return _o($o,{hookProps:r,didMount:n.viewDidMount,willUnmount:n.viewWillUnmount,elRef:e.elRef},(function(t){return e.children(t,["fc-"+e.viewSpec.type+"-view","fc-view"].concat(o))}))},t}(Uo);function ni(e){return bt(e,ri)}function ri(e){var t,n="function"==typeof e?{component:e}:e,o=n.component;return n.content&&(t=n,o=function(e){return _o(Oo.Consumer,null,(function(n){return _o(ti,{viewSpec:n.viewSpec},(function(o,i){var a=r(r({},e),{nextDayThreshold:n.options.nextDayThreshold});return _o(Yo,{hookProps:a,classNames:t.classNames,content:t.content,didMount:t.didMount,willUnmount:t.willUnmount,elRef:o},(function(e,t,n,r){return _o("div",{className:i.concat(t).join(" "),ref:e},r)}))}))}))}),{superType:n.type,component:o,rawOptions:n}}function oi(e,t,n,o){var i=ni(e),a=ni(t.views);return bt(function(e,t){var n,r={};for(n in e)qo(n,r,e,t);for(n in t)qo(n,r,e,t);return r}(i,a),(function(e){return function(e,t,n,o,i){var a=e.overrides.duration||e.defaults.duration||o.duration||n.duration,s=null,l="",u="",c={};if(a&&(s=function(e){var t=JSON.stringify(e),n=ii[t];void 0===n&&(n=Nt(e),ii[t]=n);return n}(a))){var d=Vt(s);l=d.unit,1===d.value&&(u=l,c=t[l]?t[l].rawOptions:{})}var p=function(t){var n=t.buttonText||{},r=e.defaults.buttonTextKey;return null!=r&&null!=n[r]?n[r]:null!=n[e.type]?n[e.type]:null!=n[u]?n[u]:null},f=function(t){var n=t.buttonHints||{},r=e.defaults.buttonTextKey;return null!=r&&null!=n[r]?n[r]:null!=n[e.type]?n[e.type]:null!=n[u]?n[u]:null};return{type:e.type,component:e.component,duration:s,durationUnit:l,singleUnit:u,optionDefaults:e.defaults,optionOverrides:r(r({},c),e.overrides),buttonTextOverride:p(o)||p(n)||e.overrides.buttonText,buttonTextDefault:p(i)||e.defaults.buttonText||p(cn)||e.type,buttonTitleOverride:f(o)||f(n)||e.overrides.buttonHint,buttonTitleDefault:f(i)||e.defaults.buttonHint||f(cn)}}(e,a,t,n,o)}))}var ii={};var ai=function(){function e(e){this.props=e,this.nowDate=Tr(e.nowInput,e.dateEnv),this.initHiddenDays()}return e.prototype.buildPrev=function(e,t,n){var r=this.props.dateEnv,o=r.subtract(r.startOf(t,e.currentRangeUnit),e.dateIncrement);return this.build(o,-1,n)},e.prototype.buildNext=function(e,t,n){var r=this.props.dateEnv,o=r.add(r.startOf(t,e.currentRangeUnit),e.dateIncrement);return this.build(o,1,n)},e.prototype.build=function(e,t,n){void 0===n&&(n=!0);var r,o,i,a,s,l,u,c,d=this.props;return r=this.buildValidRange(),r=this.trimHiddenDays(r),n&&(u=e,e=null!=(c=r).start&&u<c.start?c.start:null!=c.end&&u>=c.end?new Date(c.end.valueOf()-1):u),o=this.buildCurrentRangeInfo(e,t),i=/^(year|month|week|day)$/.test(o.unit),a=this.buildRenderRange(this.trimHiddenDays(o.range),o.unit,i),s=a=this.trimHiddenDays(a),d.showNonCurrentDates||(s=jn(s,o.range)),s=jn(s=this.adjustActiveRange(s),r),l=qn(o.range,r),{validRange:r,currentRange:o.range,currentRangeUnit:o.unit,isRangeAllDay:i,activeRange:s,renderRange:a,slotMinTime:d.slotMinTime,slotMaxTime:d.slotMaxTime,isValid:l,dateIncrement:this.buildDateIncrement(o.duration)}},e.prototype.buildValidRange=function(){var e=this.props.validRangeInput,t="function"==typeof e?e.call(this.props.calendarApi,this.nowDate):e;return this.refineRange(t)||{start:null,end:null}},e.prototype.buildCurrentRangeInfo=function(e,t){var n,r=this.props,o=null,i=null,a=null;return r.duration?(o=r.duration,i=r.durationUnit,a=this.buildRangeFromDuration(e,t,o,i)):(n=this.props.dayCount)?(i="day",a=this.buildRangeFromDayCount(e,t,n)):(a=this.buildCustomVisibleRange(e))?i=r.dateEnv.greatestWholeUnit(a.start,a.end).unit:(i=Vt(o=this.getFallbackDuration()).unit,a=this.buildRangeFromDuration(e,t,o,i)),{duration:o,unit:i,range:a}},e.prototype.getFallbackDuration=function(){return Nt({day:1})},e.prototype.adjustActiveRange=function(e){var t=this.props,n=t.dateEnv,r=t.usesMinMaxTime,o=t.slotMinTime,i=t.slotMaxTime,a=e.start,s=e.end;return r&&(Lt(o)<0&&(a=lt(a),a=n.add(a,o)),Lt(i)>1&&(s=tt(s=lt(s),-1),s=n.add(s,i))),{start:a,end:s}},e.prototype.buildRangeFromDuration=function(e,t,n,r){var o,i,a,s=this.props,l=s.dateEnv,u=s.dateAlignment;if(!u){var c=this.props.dateIncrement;u=c&&Ut(c)<Ut(n)?Vt(c).unit:r}function d(){o=l.startOf(e,u),i=l.add(o,n),a={start:o,end:i}}return Lt(n)<=1&&this.isHiddenDay(o)&&(o=lt(o=this.skipHiddenDays(o,t))),d(),this.trimHiddenDays(a)||(e=this.skipHiddenDays(e,t),d()),a},e.prototype.buildRangeFromDayCount=function(e,t,n){var r,o=this.props,i=o.dateEnv,a=o.dateAlignment,s=0,l=e;a&&(l=i.startOf(l,a)),l=lt(l),r=l=this.skipHiddenDays(l,t);do{r=tt(r,1),this.isHiddenDay(r)||(s+=1)}while(s<n);return{start:l,end:r}},e.prototype.buildCustomVisibleRange=function(e){var t=this.props,n=t.visibleRangeInput,r="function"==typeof n?n.call(t.calendarApi,t.dateEnv.toDate(e)):n,o=this.refineRange(r);return!o||null!=o.start&&null!=o.end?o:null},e.prototype.buildRenderRange=function(e,t,n){return e},e.prototype.buildDateIncrement=function(e){var t,n=this.props.dateIncrement;return n||((t=this.props.dateAlignment)?Nt(1,t):e||Nt({days:1}))},e.prototype.refineRange=function(e){if(e){var t=(n=e,r=this.props.dateEnv,o=null,i=null,n.start&&(o=r.createMarker(n.start)),n.end&&(i=r.createMarker(n.end)),o||i?o&&i&&i<o?null:{start:o,end:i}:null);return t&&(t=Wn(t)),t}var n,r,o,i;return null},e.prototype.initHiddenDays=function(){var e,t=this.props.hiddenDays||[],n=[],r=0;for(!1===this.props.weekends&&t.push(0,6),e=0;e<7;e+=1)(n[e]=-1!==t.indexOf(e))||(r+=1);if(!r)throw new Error("invalid hiddenDays");this.isHiddenDayHash=n},e.prototype.trimHiddenDays=function(e){var t=e.start,n=e.end;return t&&(t=this.skipHiddenDays(t)),n&&(n=this.skipHiddenDays(n,-1,!0)),null==t||null==n||t<n?{start:t,end:n}:null},e.prototype.isHiddenDay=function(e){return e instanceof Date&&(e=e.getUTCDay()),this.isHiddenDayHash[e]},e.prototype.skipHiddenDays=function(e,t,n){for(void 0===t&&(t=1),void 0===n&&(n=!1);this.isHiddenDayHash[(e.getUTCDay()+(n?t:0)+7)%7];)e=tt(e,t);return e},e}();function si(e,t,n){var r=t?t.activeRange:null;return ci({},function(e,t){var n=_r(t),r=[].concat(e.eventSources||[]),o=[];e.initialEvents&&r.unshift(e.initialEvents);e.events&&r.unshift(e.events);for(var i=0,a=r;i<a.length;i++){var s=Rr(a[i],t,n);s&&o.push(s)}return o}(e,n),r,n)}function li(e,t,n,o){var i,a,s=n?n.activeRange:null;switch(t.type){case"ADD_EVENT_SOURCES":return ci(e,t.sources,s,o);case"REMOVE_EVENT_SOURCE":return i=e,a=t.sourceId,St(i,(function(e){return e.sourceId!==a}));case"PREV":case"NEXT":case"CHANGE_DATE":case"CHANGE_VIEW_TYPE":return n?di(e,s,o):e;case"FETCH_EVENT_SOURCES":return pi(e,t.sourceIds?Dt(t.sourceIds):hi(e,o),s,t.isRefetch||!1,o);case"RECEIVE_EVENTS":case"RECEIVE_EVENT_ERROR":return function(e,t,n,o){var i,a=e[t];if(a&&n===a.latestFetchId)return r(r({},e),((i={})[t]=r(r({},a),{isFetching:!1,fetchRange:o}),i));return e}(e,t.sourceId,t.fetchId,t.fetchRange);case"REMOVE_ALL_EVENT_SOURCES":return{};default:return e}}function ui(e){for(var t in e)if(e[t].isFetching)return!0;return!1}function ci(e,t,n,o){for(var i={},a=0,s=t;a<s.length;a++){var l=s[a];i[l.sourceId]=l}return n&&(i=di(i,n,o)),r(r({},e),i)}function di(e,t,n){return pi(e,St(e,(function(e){return function(e,t,n){if(!vi(e,n))return!e.latestFetchId;return!n.options.lazyFetching||!e.fetchRange||e.isFetching||t.start<e.fetchRange.start||t.end>e.fetchRange.end}(e,t,n)})),t,!1,n)}function pi(e,t,n,r,o){var i={};for(var a in e){var s=e[a];t[a]?i[a]=fi(s,n,r,o):i[a]=s}return i}function fi(e,t,n,o){var i=o.options,a=o.calendarApi,s=o.pluginHooks.eventSourceDefs[e.sourceDefId],l=Le();return s.fetch({eventSource:e,range:t,isRefetch:n,context:o},(function(n){var r=n.rawEvents;i.eventSourceSuccess&&(r=i.eventSourceSuccess.call(a,r,n.xhr)||r),e.success&&(r=e.success.call(a,r,n.xhr)||r),o.dispatch({type:"RECEIVE_EVENTS",sourceId:e.sourceId,fetchId:l,fetchRange:t,rawEvents:r})}),(function(n){console.warn(n.message,n),i.eventSourceFailure&&i.eventSourceFailure.call(a,n),e.failure&&e.failure(n),o.dispatch({type:"RECEIVE_EVENT_ERROR",sourceId:e.sourceId,fetchId:l,fetchRange:t,error:n})})),r(r({},e),{isFetching:!0,latestFetchId:l})}function hi(e,t){return St(e,(function(e){return vi(e,t)}))}function vi(e,t){return!t.pluginHooks.eventSourceDefs[e.sourceDefId].ignoreRange}function gi(e,t,n,r,o){switch(t.type){case"RECEIVE_EVENTS":return function(e,t,n,r,o,i){if(t&&n===t.latestFetchId){var a=En(function(e,t,n){var r=n.options.eventDataTransform,o=t?t.eventDataTransform:null;o&&(e=mi(e,o));r&&(e=mi(e,r));return e}(o,t,i),t,i);return r&&(a=xt(a,r,i)),Cn(yi(e,t.sourceId),a)}return e}(e,n[t.sourceId],t.fetchId,t.fetchRange,t.rawEvents,o);case"ADD_EVENTS":return function(e,t,n,r){n&&(t=xt(t,n,r));return Cn(e,t)}(e,t.eventStore,r?r.activeRange:null,o);case"RESET_EVENTS":return t.eventStore;case"MERGE_EVENTS":return Cn(e,t.eventStore);case"PREV":case"NEXT":case"CHANGE_DATE":case"CHANGE_VIEW_TYPE":return r?xt(e,r.activeRange,o):e;case"REMOVE_EVENTS":return function(e,t){var n=e.defs,r=e.instances,o={},i={};for(var a in n)t.defs[a]||(o[a]=n[a]);for(var s in r)!t.instances[s]&&o[r[s].defId]&&(i[s]=r[s]);return{defs:o,instances:i}}(e,t.eventStore);case"REMOVE_EVENT_SOURCE":return yi(e,t.sourceId);case"REMOVE_ALL_EVENT_SOURCES":return wn(e,(function(e){return!e.sourceId}));case"REMOVE_ALL_EVENTS":return{defs:{},instances:{}};default:return e}}function mi(e,t){var n;if(t){n=[];for(var r=0,o=e;r<o.length;r++){var i=o[r],a=t(i);a?n.push(a):null==a&&n.push(i)}}else n=e;return n}function yi(e,t){return wn(e,(function(e){return e.sourceId!==t}))}function Ei(e,t){switch(t.type){case"UNSELECT_DATES":return null;case"SELECT_DATES":return t.selection;default:return e}}function Si(e,t){switch(t.type){case"UNSELECT_EVENT":return"";case"SELECT_EVENT":return t.eventInstanceId;default:return e}}function bi(e,t){var n;switch(t.type){case"UNSET_EVENT_DRAG":return null;case"SET_EVENT_DRAG":return{affectedEvents:(n=t.state).affectedEvents,mutatedEvents:n.mutatedEvents,isEvent:n.isEvent};default:return e}}function Di(e,t){var n;switch(t.type){case"UNSET_EVENT_RESIZE":return null;case"SET_EVENT_RESIZE":return{affectedEvents:(n=t.state).affectedEvents,mutatedEvents:n.mutatedEvents,isEvent:n.isEvent};default:return e}}function Ci(e,t,n,r,o){return{header:e.headerToolbar?wi(e.headerToolbar,e,t,n,r,o):null,footer:e.footerToolbar?wi(e.footerToolbar,e,t,n,r,o):null}}function wi(e,t,n,r,o,i){var a={},s=[],l=!1;for(var u in e){var c=Ri(e[u],t,n,r,o,i);a[u]=c.widgets,s.push.apply(s,c.viewsWithButtons),l=l||c.hasTitle}return{sectionWidgets:a,viewsWithButtons:s,hasTitle:l}}function Ri(e,t,n,r,o,i){var a="rtl"===t.direction,s=t.customButtons||{},l=n.buttonText||{},u=t.buttonText||{},c=n.buttonHints||{},d=t.buttonHints||{},p=e?e.split(" "):[],f=[],h=!1;return{widgets:p.map((function(e){return e.split(",").map((function(e){if("title"===e)return h=!0,{buttonName:e};var n,p,v,g,m,y;if(n=s[e])v=function(e){n.click&&n.click.call(e.target,e,e.target)},(g=r.getCustomButtonIconClass(n))||(g=r.getIconClass(e,a))||(m=n.text),y=n.hint||n.text;else if(p=o[e]){f.push(e),v=function(){i.changeView(e)},(m=p.buttonTextOverride)||(g=r.getIconClass(e,a))||(m=p.buttonTextDefault);var E=p.buttonTextOverride||p.buttonTextDefault;y=Xe(p.buttonTitleOverride||p.buttonTitleDefault||t.viewHint,[E,e],E)}else if(i[e])if(v=function(){i[e]()},(m=l[e])||(g=r.getIconClass(e,a))||(m=u[e]),"prevYear"===e||"nextYear"===e){var S="prevYear"===e?"prev":"next";y=Xe(c[S]||d[S],[u.year||"year","year"],u[e])}else y=function(t){return Xe(c[e]||d[e],[u[t]||t,t],u[e])};return{buttonName:e,buttonClick:v,buttonIcon:g,buttonText:m,buttonHint:y}}))})),viewsWithButtons:f,hasTitle:h}}function _i(e,t,n,r,o){var i=null;"GET"===(e=e.toUpperCase())?t=function(e,t){return e+(-1===e.indexOf("?")?"?":"&")+Ti(t)}(t,n):i=Ti(n);var a=new XMLHttpRequest;a.open(e,t,!0),"GET"!==e&&a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.onload=function(){if(a.status>=200&&a.status<400){var e=!1,t=void 0;try{t=JSON.parse(a.responseText),e=!0}catch(e){}e?r(t,a):o("Failure parsing JSON",a)}else o("Request failed",a)},a.onerror=function(){o("Request failed",a)},a.send(i)}function Ti(e){var t=[];for(var n in e)t.push(encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return t.join("&")}function ki(e,t){for(var n=Ct(t.getCurrentData().eventSources),r=[],o=0,i=e;o<i.length;o++){for(var a=i[o],s=!1,l=0;l<n.length;l+=1)if(n[l]._raw===a){n.splice(l,1),s=!0;break}s||r.push(a)}for(var u=0,c=n;u<c.length;u++){var d=c[u];t.dispatch({type:"REMOVE_EVENT_SOURCE",sourceId:d.sourceId})}for(var p=0,f=r;p<f.length;p++){var h=f[p];t.calendarApi.addEventSource(h)}}var xi=[zo({eventSourceDefs:[{ignoreRange:!0,parseMeta:function(e){return Array.isArray(e.events)?e.events:null},fetch:function(e,t){t({rawEvents:e.eventSource.meta})}}]}),zo({eventSourceDefs:[{parseMeta:function(e){return"function"==typeof e.events?e.events:null},fetch:function(e,t,n){var r=e.context.dateEnv;yo(e.eventSource.meta.bind(null,hr(e.range,r)),(function(e){t({rawEvents:e})}),n)}}]}),zo({eventSourceRefiners:{method:String,extraParams:yn,startParam:String,endParam:String,timeZoneParam:String},eventSourceDefs:[{parseMeta:function(e){return!e.url||"json"!==e.format&&e.format?null:{url:e.url,format:"json",method:(e.method||"GET").toUpperCase(),extraParams:e.extraParams,startParam:e.startParam,endParam:e.endParam,timeZoneParam:e.timeZoneParam}},fetch:function(e,t,n){var o=e.eventSource.meta,i=function(e,t,n){var o,i,a,s,l=n.dateEnv,u=n.options,c={};null==(o=e.startParam)&&(o=u.startParam);null==(i=e.endParam)&&(i=u.endParam);null==(a=e.timeZoneParam)&&(a=u.timeZoneParam);s="function"==typeof e.extraParams?e.extraParams():e.extraParams||{};r(c,s),c[o]=l.formatIso(t.start),c[i]=l.formatIso(t.end),"local"!==l.timeZone&&(c[a]=l.timeZone);return c}(o,e.range,e.context);_i(o.method,o.url,i,(function(e,n){t({rawEvents:e,xhr:n})}),(function(e,t){n({message:e,xhr:t})}))}}]}),zo({recurringTypes:[{parse:function(e,t){if(e.daysOfWeek||e.startTime||e.endTime||e.startRecur||e.endRecur){var n={daysOfWeek:e.daysOfWeek||null,startTime:e.startTime||null,endTime:e.endTime||null,startRecur:e.startRecur?t.createMarker(e.startRecur):null,endRecur:e.endRecur?t.createMarker(e.endRecur):null},r=void 0;return e.duration&&(r=e.duration),!r&&e.startTime&&e.endTime&&(o=e.endTime,i=e.startTime,r={years:o.years-i.years,months:o.months-i.months,days:o.days-i.days,milliseconds:o.milliseconds-i.milliseconds}),{allDayGuess:Boolean(!e.startTime&&!e.endTime),duration:r,typeData:n}}var o,i;return null},expand:function(e,t,n){var r=jn(t,{start:e.startRecur,end:e.endRecur});return r?function(e,t,n,r){var o=e?Dt(e):null,i=lt(n.start),a=n.end,s=[];for(;i<a;){var l=void 0;o&&!o[i.getUTCDay()]||(l=t?r.add(i,t):i,s.push(l)),i=tt(i,1)}return s}(e.daysOfWeek,e.startTime,r,n):[]}}],eventRefiners:{daysOfWeek:yn,startTime:Nt,endTime:Nt,duration:Nt,startRecur:yn,endRecur:yn}}),zo({optionChangeHandlers:{events:function(e,t){ki([e],t)},eventSources:ki}}),zo({isLoadingFuncs:[function(e){return ui(e.eventSources)}],contentTypeHandlers:{html:function(){var e=null,t="";return{render:function(n,r){n===e&&r===t||(n.innerHTML=r),e=n,t=r},destroy:function(){e.innerHTML="",e=null,t=""}}},domNodes:function(){var e=null,t=[];function n(){t.forEach(Ee),t=[],e=null}return{render:function(r,o){var i=Array.prototype.slice.call(o);if(r!==e||!Gt(t,i)){for(var a=0,s=i;a<s.length;a++){var l=s[a];r.appendChild(l)}n()}e=r,t=i},destroy:n}}},propSetHandlers:{dateProfile:function(e,t){t.emitter.trigger("datesSet",r(r({},hr(e.activeRange,t.dateEnv)),{view:t.viewApi}))},eventStore:function(e,t){var n=t.emitter;n.hasHandlers("eventsSet")&&n.trigger("eventsSet",Ir(e,t))}}})];var Mi=function(){function e(e){this.drainedOption=e,this.isRunning=!1,this.isDirty=!1,this.pauseDepths={},this.timeoutId=0}return e.prototype.request=function(e){this.isDirty=!0,this.isPaused()||(this.clearTimeout(),null==e?this.tryDrain():this.timeoutId=setTimeout(this.tryDrain.bind(this),e))},e.prototype.pause=function(e){void 0===e&&(e="");var t=this.pauseDepths;t[e]=(t[e]||0)+1,this.clearTimeout()},e.prototype.resume=function(e,t){void 0===e&&(e="");var n=this.pauseDepths;if(e in n){if(t)delete n[e];else n[e]-=1,n[e]<=0&&delete n[e];this.tryDrain()}},e.prototype.isPaused=function(){return Object.keys(this.pauseDepths).length},e.prototype.tryDrain=function(){if(!this.isRunning&&!this.isPaused()){for(this.isRunning=!0;this.isDirty;)this.isDirty=!1,this.drained();this.isRunning=!1}},e.prototype.clear=function(){this.clearTimeout(),this.isDirty=!1,this.pauseDepths={}},e.prototype.clearTimeout=function(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=0)},e.prototype.drained=function(){this.drainedOption&&this.drainedOption()},e}(),Ii=function(){function e(e,t){this.runTaskOption=e,this.drainedOption=t,this.queue=[],this.delayedRunner=new Mi(this.drain.bind(this))}return e.prototype.request=function(e,t){this.queue.push(e),this.delayedRunner.request(t)},e.prototype.pause=function(e){this.delayedRunner.pause(e)},e.prototype.resume=function(e,t){this.delayedRunner.resume(e,t)},e.prototype.drain=function(){for(var e=this.queue;e.length;){for(var t=[],n=void 0;n=e.shift();)this.runTask(n),t.push(n);this.drained(t)}},e.prototype.runTask=function(e){this.runTaskOption&&this.runTaskOption(e)},e.prototype.drained=function(e){this.drainedOption&&this.drainedOption(e)},e}();function Pi(e,t,n){var r;return r=/^(year|month)$/.test(e.currentRangeUnit)?e.currentRange:e.activeRange,n.formatRange(r.start,r.end,ln(t.titleFormat||function(e){var t=e.currentRangeUnit;if("year"===t)return{year:"numeric"};if("month"===t)return{year:"numeric",month:"long"};var n=st(e.currentRange.start,e.currentRange.end);if(null!==n&&n>1)return{year:"numeric",month:"short",day:"numeric"};return{year:"numeric",month:"long",day:"numeric"}}(e)),{isEndExclusive:e.isRangeAllDay,defaultSeparator:t.titleRangeSeparator})}var Ni=function(){function e(e){var t=this;this.computeOptionsData=qt(this._computeOptionsData),this.computeCurrentViewData=qt(this._computeCurrentViewData),this.organizeRawLocales=qt(Fr),this.buildLocale=qt(Br),this.buildPluginHooks=jo(),this.buildDateEnv=qt(Hi),this.buildTheme=qt(Oi),this.parseToolbars=qt(Ci),this.buildViewSpecs=qt(oi),this.buildDateProfileGenerator=Yt(Ai),this.buildViewApi=qt(Li),this.buildViewUiProps=Yt(Vi),this.buildEventUiBySource=qt(Ui,wt),this.buildEventUiBases=qt(Wi),this.parseContextBusinessHours=Yt(Bi),this.buildTitle=qt(Pi),this.emitter=new Eo,this.actionRunner=new Ii(this._handleAction.bind(this),this.updateData.bind(this)),this.currentCalendarOptionsInput={},this.currentCalendarOptionsRefined={},this.currentViewOptionsInput={},this.currentViewOptionsRefined={},this.currentCalendarOptionsRefiners={},this.getCurrentData=function(){return t.data},this.dispatch=function(e){t.actionRunner.request(e)},this.props=e,this.actionRunner.pause();var n={},o=this.computeOptionsData(e.optionOverrides,n,e.calendarApi),i=o.calendarOptions.initialView||o.pluginHooks.initialView,a=this.computeCurrentViewData(i,o,e.optionOverrides,n);e.calendarApi.currentDataManager=this,this.emitter.setThisContext(e.calendarApi),this.emitter.setOptions(a.options);var s,l,u,c=(s=o.calendarOptions,l=o.dateEnv,null!=(u=s.initialDate)?l.createMarker(u):Tr(s.now,l)),d=a.dateProfileGenerator.build(c);Zn(d.activeRange,c)||(c=d.currentRange.start);for(var p={dateEnv:o.dateEnv,options:o.calendarOptions,pluginHooks:o.pluginHooks,calendarApi:e.calendarApi,dispatch:this.dispatch,emitter:this.emitter,getCurrentData:this.getCurrentData},f=0,h=o.pluginHooks.contextInit;f<h.length;f++){(0,h[f])(p)}for(var v=si(o.calendarOptions,d,p),g={dynamicOptionOverrides:n,currentViewType:i,currentDate:c,dateProfile:d,businessHours:this.parseContextBusinessHours(p),eventSources:v,eventUiBases:{},eventStore:{defs:{},instances:{}},renderableEventStore:{defs:{},instances:{}},dateSelection:null,eventSelection:"",eventDrag:null,eventResize:null,selectionConfig:this.buildViewUiProps(p).selectionConfig},m=r(r({},p),g),y=0,E=o.pluginHooks.reducers;y<E.length;y++){var S=E[y];r(g,S(null,null,m))}Fi(g,p)&&this.emitter.trigger("loading",!0),this.state=g,this.updateData(),this.actionRunner.resume()}return e.prototype.resetOptions=function(e,t){var n=this.props;n.optionOverrides=t?r(r({},n.optionOverrides),e):e,this.actionRunner.request({type:"NOTHING"})},e.prototype._handleAction=function(e){var t=this,n=t.props,o=t.state,i=t.emitter,a=function(e,t){var n;switch(t.type){case"SET_OPTION":return r(r({},e),((n={})[t.optionName]=t.rawOptionValue,n));default:return e}}(o.dynamicOptionOverrides,e),s=this.computeOptionsData(n.optionOverrides,a,n.calendarApi),l=function(e,t){switch(t.type){case"CHANGE_VIEW_TYPE":e=t.viewType}return e}(o.currentViewType,e),u=this.computeCurrentViewData(l,s,n.optionOverrides,a);n.calendarApi.currentDataManager=this,i.setThisContext(n.calendarApi),i.setOptions(u.options);var c={dateEnv:s.dateEnv,options:s.calendarOptions,pluginHooks:s.pluginHooks,calendarApi:n.calendarApi,dispatch:this.dispatch,emitter:i,getCurrentData:this.getCurrentData},d=o.currentDate,p=o.dateProfile;this.data&&this.data.dateProfileGenerator!==u.dateProfileGenerator&&(p=u.dateProfileGenerator.build(d)),p=function(e,t,n,r){var o;switch(t.type){case"CHANGE_VIEW_TYPE":return r.build(t.dateMarker||n);case"CHANGE_DATE":return r.build(t.dateMarker);case"PREV":if((o=r.buildPrev(e,n)).isValid)return o;break;case"NEXT":if((o=r.buildNext(e,n)).isValid)return o}return e}(p,e,d=function(e,t){switch(t.type){case"CHANGE_DATE":return t.dateMarker;default:return e}}(d,e),u.dateProfileGenerator),"PREV"!==e.type&&"NEXT"!==e.type&&Zn(p.currentRange,d)||(d=p.currentRange.start);for(var f=li(o.eventSources,e,p,c),h=gi(o.eventStore,e,f,p,c),v=ui(f)&&!u.options.progressiveEventRendering&&o.renderableEventStore||h,g=this.buildViewUiProps(c),m=g.eventUiSingleBase,y=g.selectionConfig,E=this.buildEventUiBySource(f),S={dynamicOptionOverrides:a,currentViewType:l,currentDate:d,dateProfile:p,eventSources:f,eventStore:h,renderableEventStore:v,selectionConfig:y,eventUiBases:this.buildEventUiBases(v.defs,m,E),businessHours:this.parseContextBusinessHours(c),dateSelection:Ei(o.dateSelection,e),eventSelection:Si(o.eventSelection,e),eventDrag:bi(o.eventDrag,e),eventResize:Di(o.eventResize,e)},b=r(r({},c),S),D=0,C=s.pluginHooks.reducers;D<C.length;D++){var w=C[D];r(S,w(o,e,b))}var R=Fi(o,c),_=Fi(S,c);!R&&_?i.trigger("loading",!0):R&&!_&&i.trigger("loading",!1),this.state=S,n.onAction&&n.onAction(e)},e.prototype.updateData=function(){var e,t,n,o,i,a,s,l,u,c=this.props,d=this.state,p=this.data,f=this.computeOptionsData(c.optionOverrides,d.dynamicOptionOverrides,c.calendarApi),h=this.computeCurrentViewData(d.currentViewType,f,c.optionOverrides,d.dynamicOptionOverrides),v=this.data=r(r(r({viewTitle:this.buildTitle(d.dateProfile,h.options,f.dateEnv),calendarApi:c.calendarApi,dispatch:this.dispatch,emitter:this.emitter,getCurrentData:this.getCurrentData},f),h),d),g=f.pluginHooks.optionChangeHandlers,m=p&&p.calendarOptions,y=f.calendarOptions;if(m&&m!==y)for(var E in m.timeZone!==y.timeZone&&(d.eventSources=v.eventSources=(a=v.eventSources,s=d.dateProfile,l=v,u=s?s.activeRange:null,pi(a,hi(a,l),u,!0,l)),d.eventStore=v.eventStore=(e=v.eventStore,t=p.dateEnv,n=v.dateEnv,o=e.defs,i=bt(e.instances,(function(e){var i=o[e.defId];return i.allDay||i.recurringDef?e:r(r({},e),{range:{start:n.createMarker(t.toDate(e.range.start,e.forcedStartTzo)),end:n.createMarker(t.toDate(e.range.end,e.forcedEndTzo))},forcedStartTzo:n.canComputeOffset?null:e.forcedStartTzo,forcedEndTzo:n.canComputeOffset?null:e.forcedEndTzo})})),{defs:o,instances:i})),g)m[E]!==y[E]&&g[E](y[E],v);c.onData&&c.onData(v)},e.prototype._computeOptionsData=function(e,t,n){var r=this.processRawCalendarOptions(e,t),o=r.refinedOptions,i=r.pluginHooks,a=r.localeDefaults,s=r.availableLocaleData;zi(r.extra);var l=this.buildDateEnv(o.timeZone,o.locale,o.weekNumberCalculation,o.firstDay,o.weekText,i,s,o.defaultRangeSeparator),u=this.buildViewSpecs(i.views,e,t,a),c=this.buildTheme(o,i);return{calendarOptions:o,pluginHooks:i,dateEnv:l,viewSpecs:u,theme:c,toolbarConfig:this.parseToolbars(o,e,c,u,n),localeDefaults:a,availableRawLocales:s.map}},e.prototype.processRawCalendarOptions=function(e,t){var n=gn([cn,e,t]),o=n.locales,i=n.locale,a=this.organizeRawLocales(o),s=a.map,l=this.buildLocale(i||a.defaultCode,s).options,u=this.buildPluginHooks(e.plugins||[],xi),c=this.currentCalendarOptionsRefiners=r(r(r(r(r({},un),dn),pn),u.listenerRefiners),u.optionRefiners),d={},p=gn([cn,l,e,t]),f={},h=this.currentCalendarOptionsInput,v=this.currentCalendarOptionsRefined,g=!1;for(var m in p)"plugins"!==m&&(p[m]===h[m]||fn[m]&&m in h&&fn[m](h[m],p[m])?f[m]=v[m]:c[m]?(f[m]=c[m](p[m]),g=!0):d[m]=h[m]);return g&&(this.currentCalendarOptionsInput=p,this.currentCalendarOptionsRefined=f),{rawOptions:this.currentCalendarOptionsInput,refinedOptions:this.currentCalendarOptionsRefined,pluginHooks:u,availableLocaleData:a,localeDefaults:l,extra:d}},e.prototype._computeCurrentViewData=function(e,t,n,r){var o=t.viewSpecs[e];if(!o)throw new Error('viewType "'+e+"\" is not available. Please make sure you've loaded all neccessary plugins");var i=this.processRawViewOptions(o,t.pluginHooks,t.localeDefaults,n,r),a=i.refinedOptions;return zi(i.extra),{viewSpec:o,options:a,dateProfileGenerator:this.buildDateProfileGenerator({dateProfileGeneratorClass:o.optionDefaults.dateProfileGeneratorClass,duration:o.duration,durationUnit:o.durationUnit,usesMinMaxTime:o.optionDefaults.usesMinMaxTime,dateEnv:t.dateEnv,calendarApi:this.props.calendarApi,slotMinTime:a.slotMinTime,slotMaxTime:a.slotMaxTime,showNonCurrentDates:a.showNonCurrentDates,dayCount:a.dayCount,dateAlignment:a.dateAlignment,dateIncrement:a.dateIncrement,hiddenDays:a.hiddenDays,weekends:a.weekends,nowInput:a.now,validRangeInput:a.validRange,visibleRangeInput:a.visibleRange,monthMode:a.monthMode,fixedWeekCount:a.fixedWeekCount}),viewApi:this.buildViewApi(e,this.getCurrentData,t.dateEnv)}},e.prototype.processRawViewOptions=function(e,t,n,o,i){var a=gn([cn,e.optionDefaults,n,o,e.optionOverrides,i]),s=r(r(r(r(r(r({},un),dn),pn),vn),t.listenerRefiners),t.optionRefiners),l={},u=this.currentViewOptionsInput,c=this.currentViewOptionsRefined,d=!1,p={};for(var f in a)a[f]===u[f]||fn[f]&&fn[f](a[f],u[f])?l[f]=c[f]:(a[f]===this.currentCalendarOptionsInput[f]||fn[f]&&fn[f](a[f],this.currentCalendarOptionsInput[f])?f in this.currentCalendarOptionsRefined&&(l[f]=this.currentCalendarOptionsRefined[f]):s[f]?l[f]=s[f](a[f]):p[f]=a[f],d=!0);return d&&(this.currentViewOptionsInput=a,this.currentViewOptionsRefined=l),{rawOptions:this.currentViewOptionsInput,refinedOptions:this.currentViewOptionsRefined,extra:p}},e}();function Hi(e,t,n,r,o,i,a,s){var l=Br(t||a.defaultCode,a.map);return new Lr({calendarSystem:"gregory",timeZone:e,namedTimeZoneImpl:i.namedTimeZonedImpl,locale:l,weekNumberCalculation:n,firstDay:r,weekText:o,cmdFormatter:i.cmdFormatter,defaultSeparator:s})}function Oi(e,t){return new(t.themeClasses[e.themeSystem]||Go)(e)}function Ai(e){return new(e.dateProfileGeneratorClass||ai)(e)}function Li(e,t,n){return new Cr(e,t,n)}function Ui(e){return bt(e,(function(e){return e.ui}))}function Wi(e,t,n){var r={"":t};for(var o in e){var i=e[o];i.sourceId&&n[i.sourceId]&&(r[o]=n[i.sourceId])}return r}function Vi(e){var t=e.options;return{eventUiSingleBase:kn({display:t.eventDisplay,editable:t.editable,startEditable:t.eventStartEditable,durationEditable:t.eventDurationEditable,constraint:t.eventConstraint,overlap:"boolean"==typeof t.eventOverlap?t.eventOverlap:void 0,allow:t.eventAllow,backgroundColor:t.eventBackgroundColor,borderColor:t.eventBorderColor,textColor:t.eventTextColor,color:t.eventColor},e),selectionConfig:kn({constraint:t.selectConstraint,overlap:"boolean"==typeof t.selectOverlap?t.selectOverlap:void 0,allow:t.selectAllow},e)}}function Fi(e,t){for(var n=0,r=t.pluginHooks.isLoadingFuncs;n<r.length;n++){if((0,r[n])(e))return!0}return!1}function Bi(e){return Yr(e.options.businessHours,e)}function zi(e,t){for(var n in e)console.warn("Unknown option '"+n+"'"+(t?" for view '"+t+"'":""))}var ji=function(e){function t(t){var n=e.call(this,t)||this;return n.handleData=function(e){n.dataManager?n.setState(e):n.state=e},n.dataManager=new Ni({optionOverrides:t.optionOverrides,calendarApi:t.calendarApi,onData:n.handleData}),n}return n(t,e),t.prototype.render=function(){return this.props.children(this.state)},t.prototype.componentDidUpdate=function(e){var t=this.props.optionOverrides;t!==e.optionOverrides&&this.dataManager.resetOptions(t)},t}(Ro);var Gi=function(e){this.timeZoneName=e},qi=function(){function e(){this.strictOrder=!1,this.allowReslicing=!1,this.maxCoord=-1,this.maxStackCnt=-1,this.levelCoords=[],this.entriesByLevel=[],this.stackCnts={}}return e.prototype.addSegs=function(e){for(var t=[],n=0,r=e;n<r.length;n++){var o=r[n];this.insertEntry(o,t)}return t},e.prototype.insertEntry=function(e,t){var n=this.findInsertion(e);return this.isInsertionValid(n,e)?(this.insertEntryAt(e,n),1):this.handleInvalidInsertion(n,e,t)},e.prototype.isInsertionValid=function(e,t){return(-1===this.maxCoord||e.levelCoord+t.thickness<=this.maxCoord)&&(-1===this.maxStackCnt||e.stackCnt<this.maxStackCnt)},e.prototype.handleInvalidInsertion=function(e,t,n){return this.allowReslicing&&e.touchingEntry?this.splitEntry(t,e.touchingEntry,n):(n.push(t),0)},e.prototype.splitEntry=function(e,t,n){var r=0,i=[],a=e.span,s=t.span;return a.start<s.start&&(r+=this.insertEntry({index:e.index,thickness:e.thickness,span:{start:a.start,end:s.start}},i)),a.end>s.end&&(r+=this.insertEntry({index:e.index,thickness:e.thickness,span:{start:s.end,end:a.end}},i)),r?(n.push.apply(n,o([{index:e.index,thickness:e.thickness,span:$i(s,a)}],i)),r):(n.push(e),0)},e.prototype.insertEntryAt=function(e,t){var n=this.entriesByLevel,r=this.levelCoords;-1===t.lateral?(Ji(r,t.level,t.levelCoord),Ji(n,t.level,[e])):Ji(n[t.level],t.lateral,e),this.stackCnts[Zi(e)]=t.stackCnt},e.prototype.findInsertion=function(e){for(var t=this,n=t.levelCoords,r=t.entriesByLevel,o=t.strictOrder,i=t.stackCnts,a=n.length,s=0,l=-1,u=-1,c=null,d=0,p=0;p<a;p+=1){var f=n[p];if(!o&&f>=s+e.thickness)break;for(var h=r[p],v=void 0,g=Qi(h,e.span.start,Yi),m=g[0]+g[1];(v=h[m])&&v.span.start<e.span.end;){var y=f+v.thickness;y>s&&(s=y,c=v,l=p,u=m),y===s&&(d=Math.max(d,i[Zi(v)]+1)),m+=1}}var E=0;if(c)for(E=l+1;E<a&&n[E]<s;)E+=1;var S=-1;return E<a&&n[E]===s&&(S=Qi(r[E],e.span.end,Yi)[0]),{touchingLevel:l,touchingLateral:u,touchingEntry:c,stackCnt:d,levelCoord:s,level:E,lateral:S}},e.prototype.toRects=function(){for(var e=this.entriesByLevel,t=this.levelCoords,n=e.length,o=[],i=0;i<n;i+=1)for(var a=e[i],s=t[i],l=0,u=a;l<u.length;l++){var c=u[l];o.push(r(r({},c),{levelCoord:s}))}return o},e}();function Yi(e){return e.span.end}function Zi(e){return e.index+":"+e.span.start}function Xi(e){for(var t=[],n=0,r=e;n<r.length;n++){for(var o=r[n],i=[],a={span:o.span,entries:[o]},s=0,l=t;s<l.length;s++){var u=l[s];$i(u.span,a.span)?a={entries:u.entries.concat(a.entries),span:Ki(u.span,a.span)}:i.push(u)}i.push(a),t=i}return t}function Ki(e,t){return{start:Math.min(e.start,t.start),end:Math.max(e.end,t.end)}}function $i(e,t){var n=Math.max(e.start,t.start),r=Math.min(e.end,t.end);return n<r?{start:n,end:r}:null}function Ji(e,t,n){e.splice(t,0,n)}function Qi(e,t,n){var r=0,o=e.length;if(!o||t<n(e[r]))return[0,0];if(t>n(e[o-1]))return[o,0];for(;r<o;){var i=Math.floor(r+(o-r)/2),a=n(e[i]);if(t<a)o=i;else{if(!(t>a))return[i,1];r=i+1}}return[r,0]}var ea=function(){function e(e){this.component=e.component,this.isHitComboAllowed=e.isHitComboAllowed||null}return e.prototype.destroy=function(){},e}();function ta(e,t){return{component:e,el:t.el,useEventCenter:null==t.useEventCenter||t.useEventCenter,isHitComboAllowed:t.isHitComboAllowed||null}}function na(e){var t;return(t={})[e.component.uid]=e,t}var ra={},oa=function(){function e(e,t){this.emitter=new Eo}return e.prototype.destroy=function(){},e.prototype.setMirrorIsVisible=function(e){},e.prototype.setMirrorNeedsRevert=function(e){},e.prototype.setAutoScrollEnabled=function(e){},e}(),ia={},aa={startTime:Nt,duration:Nt,create:Boolean,sourceId:String};function sa(e){var t=mn(e,aa),n=t.refined,r=t.extra;return{startTime:n.startTime||null,duration:n.duration||null,create:null==n.create||n.create,sourceId:n.sourceId,leftoverProps:r}}var la=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this,t=this.props.widgetGroups.map((function(t){return e.renderWidgetGroup(t)}));return _o.apply(void 0,o(["div",{className:"fc-toolbar-chunk"}],t))},t.prototype.renderWidgetGroup=function(e){for(var t=this.props,n=this.context.theme,r=[],i=!0,a=0,s=e;a<s.length;a++){var l=s[a],u=l.buttonName,c=l.buttonClick,d=l.buttonText,p=l.buttonIcon,f=l.buttonHint;if("title"===u)i=!1,r.push(_o("h2",{className:"fc-toolbar-title",id:t.titleId},t.title));else{var h=u===t.activeButton,v=!t.isTodayEnabled&&"today"===u||!t.isPrevEnabled&&"prev"===u||!t.isNextEnabled&&"next"===u,g=["fc-"+u+"-button",n.getClass("button")];h&&g.push(n.getClass("buttonActive")),r.push(_o("button",{type:"button",title:"function"==typeof f?f(t.navUnit):f,disabled:v,"aria-pressed":h,className:g.join(" "),onClick:c},d||(p?_o("span",{className:p}):"")))}}if(r.length>1){var m=i&&n.getClass("buttonGroup")||"";return _o.apply(void 0,o(["div",{className:m}],r))}return r[0]},t}(Uo),ua=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e,t,n=this.props,r=n.model,o=n.extraClassName,i=!1,a=r.sectionWidgets,s=a.center;return a.left?(i=!0,e=a.left):e=a.start,a.right?(i=!0,t=a.right):t=a.end,_o("div",{className:[o||"","fc-toolbar",i?"fc-toolbar-ltr":""].join(" ")},this.renderSection("start",e||[]),this.renderSection("center",s||[]),this.renderSection("end",t||[]))},t.prototype.renderSection=function(e,t){var n=this.props;return _o(la,{key:e,widgetGroups:t,title:n.title,navUnit:n.navUnit,activeButton:n.activeButton,isTodayEnabled:n.isTodayEnabled,isPrevEnabled:n.isPrevEnabled,isNextEnabled:n.isNextEnabled,titleId:n.titleId})},t}(Uo),ca=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.state={availableWidth:null},t.handleEl=function(e){t.el=e,Fo(t.props.elRef,e),t.updateAvailableWidth()},t.handleResize=function(){t.updateAvailableWidth()},t}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.state,n=e.aspectRatio,r=["fc-view-harness",n||e.liquid||e.height?"fc-view-harness-active":"fc-view-harness-passive"],o="",i="";return n?null!==t.availableWidth?o=t.availableWidth/n:i=1/n*100+"%":o=e.height||"",_o("div",{"aria-labelledby":e.labeledById,ref:this.handleEl,className:r.join(" "),style:{height:o,paddingBottom:i}},e.children)},t.prototype.componentDidMount=function(){this.context.addResizeHandler(this.handleResize)},t.prototype.componentWillUnmount=function(){this.context.removeResizeHandler(this.handleResize)},t.prototype.updateAvailableWidth=function(){this.el&&this.props.aspectRatio&&this.setState({availableWidth:this.el.offsetWidth})},t}(Uo),da=function(e){function t(t){var n=e.call(this,t)||this;return n.handleSegClick=function(e,t){var r=n.component,o=r.context,i=Jn(t);if(i&&r.isValidSegDownEl(e.target)){var a=Se(e.target,".fc-event-forced-url"),s=a?a.querySelector("a[href]").href:"";o.emitter.trigger("eventClick",{el:t,event:new xr(r.context,i.eventRange.def,i.eventRange.instance),jsEvent:e,view:o.viewApi}),s&&!e.defaultPrevented&&(window.location.href=s)}},n.destroy=Ie(t.el,"click",".fc-event",n.handleSegClick),n}return n(t,e),t}(ea),pa=function(e){function t(t){var n,r,o,i,a,s=e.call(this,t)||this;return s.handleEventElRemove=function(e){e===s.currentSegEl&&s.handleSegLeave(null,s.currentSegEl)},s.handleSegEnter=function(e,t){Jn(t)&&(s.currentSegEl=t,s.triggerEvent("eventMouseEnter",e,t))},s.handleSegLeave=function(e,t){s.currentSegEl&&(s.currentSegEl=null,s.triggerEvent("eventMouseLeave",e,t))},s.removeHoverListeners=(n=t.el,r=".fc-event",o=s.handleSegEnter,i=s.handleSegLeave,Ie(n,"mouseover",r,(function(e,t){if(t!==a){a=t,o(e,t);var n=function(e){a=null,i(e,t),t.removeEventListener("mouseleave",n)};t.addEventListener("mouseleave",n)}}))),s}return n(t,e),t.prototype.destroy=function(){this.removeHoverListeners()},t.prototype.triggerEvent=function(e,t,n){var r=this.component,o=r.context,i=Jn(n);t&&!r.isValidSegDownEl(t.target)||o.emitter.trigger(e,{el:n,event:new xr(o,i.eventRange.def,i.eventRange.instance),jsEvent:t,view:o.viewApi})},t}(ea),fa=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.buildViewContext=qt(Ao),t.buildViewPropTransformers=qt(va),t.buildToolbarProps=qt(ha),t.headerRef=ko(),t.footerRef=ko(),t.interactionsStore={},t.state={viewLabelId:xe()},t.registerInteractiveComponent=function(e,n){var r=ta(e,n),o=[da,pa].concat(t.props.pluginHooks.componentInteractions).map((function(e){return new e(r)}));t.interactionsStore[e.uid]=o,ra[e.uid]=r},t.unregisterInteractiveComponent=function(e){var n=t.interactionsStore[e.uid];if(n){for(var r=0,o=n;r<o.length;r++){o[r].destroy()}delete t.interactionsStore[e.uid]}delete ra[e.uid]},t.resizeRunner=new Mi((function(){t.props.emitter.trigger("_resize",!0),t.props.emitter.trigger("windowResize",{view:t.props.viewApi})})),t.handleWindowResize=function(e){var n=t.props.options;n.handleWindowResize&&e.target===window&&t.resizeRunner.request(n.windowResizeDelay)},t}return n(t,e),t.prototype.render=function(){var e,t=this.props,n=t.toolbarConfig,o=t.options,i=this.buildToolbarProps(t.viewSpec,t.dateProfile,t.dateProfileGenerator,t.currentDate,Tr(t.options.now,t.dateEnv),t.viewTitle),a=!1,s="";t.isHeightAuto||t.forPrint?s="":null!=o.height?a=!0:null!=o.contentHeight?s=o.contentHeight:e=Math.max(o.aspectRatio,.5);var l=this.buildViewContext(t.viewSpec,t.viewApi,t.options,t.dateProfileGenerator,t.dateEnv,t.theme,t.pluginHooks,t.dispatch,t.getCurrentData,t.emitter,t.calendarApi,this.registerInteractiveComponent,this.unregisterInteractiveComponent),u=n.header&&n.header.hasTitle?this.state.viewLabelId:"";return _o(Oo.Provider,{value:l},n.header&&_o(ua,r({ref:this.headerRef,extraClassName:"fc-header-toolbar",model:n.header,titleId:u},i)),_o(ca,{liquid:a,height:s,aspectRatio:e,labeledById:u},this.renderView(t),this.buildAppendContent()),n.footer&&_o(ua,r({ref:this.footerRef,extraClassName:"fc-footer-toolbar",model:n.footer,titleId:""},i)))},t.prototype.componentDidMount=function(){var e=this.props;this.calendarInteractions=e.pluginHooks.calendarInteractions.map((function(t){return new t(e)})),window.addEventListener("resize",this.handleWindowResize);var t=e.pluginHooks.propSetHandlers;for(var n in t)t[n](e[n],e)},t.prototype.componentDidUpdate=function(e){var t=this.props,n=t.pluginHooks.propSetHandlers;for(var r in n)t[r]!==e[r]&&n[r](t[r],t)},t.prototype.componentWillUnmount=function(){window.removeEventListener("resize",this.handleWindowResize),this.resizeRunner.clear();for(var e=0,t=this.calendarInteractions;e<t.length;e++){t[e].destroy()}this.props.emitter.trigger("_unmount")},t.prototype.buildAppendContent=function(){var e=this.props,t=e.pluginHooks.viewContainerAppends.map((function(t){return t(e)}));return _o.apply(void 0,o([xo,{}],t))},t.prototype.renderView=function(e){for(var t=e.pluginHooks,n=e.viewSpec,o={dateProfile:e.dateProfile,businessHours:e.businessHours,eventStore:e.renderableEventStore,eventUiBases:e.eventUiBases,dateSelection:e.dateSelection,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,isHeightAuto:e.isHeightAuto,forPrint:e.forPrint},i=0,a=this.buildViewPropTransformers(t.viewPropsTransformers);i<a.length;i++){var s=a[i];r(o,s.transform(o,e))}var l=n.component;return _o(l,r({},o))},t}(Lo);function ha(e,t,n,r,o,i){var a=n.build(o,void 0,!1),s=n.buildPrev(t,r,!1),l=n.buildNext(t,r,!1);return{title:i,activeButton:e.type,navUnit:e.singleUnit,isTodayEnabled:a.isValid&&!Zn(t.currentRange,o),isPrevEnabled:s.isValid,isNextEnabled:l.isValid}}function va(e){return e.map((function(e){return new e}))}var ga=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.state={forPrint:!1},t.handleBeforePrint=function(){t.setState({forPrint:!0})},t.handleAfterPrint=function(){t.setState({forPrint:!1})},t}return n(t,e),t.prototype.render=function(){var e=this.props,t=e.options,n=this.state.forPrint,r=n||"auto"===t.height||"auto"===t.contentHeight,o=r||null==t.height?"":t.height,i=["fc",n?"fc-media-print":"fc-media-screen","fc-direction-"+t.direction,e.theme.getClass("root")];return Qr()||i.push("fc-liquid-hack"),e.children(i,o,r,n)},t.prototype.componentDidMount=function(){var e=this.props.emitter;e.on("_beforeprint",this.handleBeforePrint),e.on("_afterprint",this.handleAfterPrint)},t.prototype.componentWillUnmount=function(){var e=this.props.emitter;e.off("_beforeprint",this.handleBeforePrint),e.off("_afterprint",this.handleAfterPrint)},t}(Uo);function ma(e,t){return ln(!e||t>10?{weekday:"short"}:t>1?{weekday:"short",month:"numeric",day:"numeric",omitCommas:!0}:{weekday:"long"})}var ya="fc-col-header-cell";function Ea(e){return e.text}var Sa=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.context,t=e.dateEnv,n=e.options,o=e.theme,i=e.viewApi,a=this.props,s=a.date,l=a.dateProfile,u=ro(s,a.todayRange,null,l),c=[ya].concat(oo(u,o)),d=t.format(s,a.dayHeaderFormat),p=!u.isDisabled&&a.colCnt>1?so(this.context,s):{},f=r(r(r({date:t.toDate(s),view:i},a.extraHookProps),{text:d}),u);return _o(Yo,{hookProps:f,classNames:n.dayHeaderClassNames,content:n.dayHeaderContent,defaultContent:Ea,didMount:n.dayHeaderDidMount,willUnmount:n.dayHeaderWillUnmount},(function(e,t,n,o){return _o("th",r({ref:e,role:"columnheader",className:c.concat(t).join(" "),"data-date":u.isDisabled?void 0:Bt(s),colSpan:a.colSpan},a.extraDataAttrs),_o("div",{className:"fc-scrollgrid-sync-inner"},!u.isDisabled&&_o("a",r({ref:n,className:["fc-col-header-cell-cushion",a.isSticky?"fc-sticky":""].join(" ")},p),o)))}))},t}(Uo),ba=ln({weekday:"long"}),Da=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context,n=t.dateEnv,o=t.theme,i=t.viewApi,a=t.options,s=tt(new Date(2592e5),e.dow),l={dow:e.dow,isDisabled:!1,isFuture:!1,isPast:!1,isToday:!1,isOther:!1},u=[ya].concat(oo(l,o),e.extraClassNames||[]),c=n.format(s,e.dayHeaderFormat),d=r(r(r(r({date:s},l),{view:i}),e.extraHookProps),{text:c});return _o(Yo,{hookProps:d,classNames:a.dayHeaderClassNames,content:a.dayHeaderContent,defaultContent:Ea,didMount:a.dayHeaderDidMount,willUnmount:a.dayHeaderWillUnmount},(function(t,o,i,a){return _o("th",r({ref:t,role:"columnheader",className:u.concat(o).join(" "),colSpan:e.colSpan},e.extraDataAttrs),_o("div",{className:"fc-scrollgrid-sync-inner"},_o("a",{"aria-label":n.format(s,ba),className:["fc-col-header-cell-cushion",e.isSticky?"fc-sticky":""].join(" "),ref:i},a)))}))},t}(Uo),Ca=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.initialNowDate=Tr(n.options.now,n.dateEnv),r.initialNowQueriedMs=(new Date).valueOf(),r.state=r.computeTiming().currentState,r}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.state;return e.children(t.nowDate,t.todayRange)},t.prototype.componentDidMount=function(){this.setTimeout()},t.prototype.componentDidUpdate=function(e){e.unit!==this.props.unit&&(this.clearTimeout(),this.setTimeout())},t.prototype.componentWillUnmount=function(){this.clearTimeout()},t.prototype.computeTiming=function(){var e=this.props,t=this.context,n=nt(this.initialNowDate,(new Date).valueOf()-this.initialNowQueriedMs),r=t.dateEnv.startOf(n,e.unit),o=t.dateEnv.add(r,Nt(1,e.unit)),i=o.valueOf()-n.valueOf();return i=Math.min(864e5,i),{currentState:{nowDate:r,todayRange:wa(r)},nextState:{nowDate:o,todayRange:wa(o)},waitMs:i}},t.prototype.setTimeout=function(){var e=this,t=this.computeTiming(),n=t.nextState,r=t.waitMs;this.timeoutId=setTimeout((function(){e.setState(n,(function(){e.setTimeout()}))}),r)},t.prototype.clearTimeout=function(){this.timeoutId&&clearTimeout(this.timeoutId)},t.contextType=Oo,t}(Ro);function wa(e){var t=lt(e);return{start:t,end:tt(t,1)}}var Ra=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.createDayHeaderFormatter=qt(_a),t}return n(t,e),t.prototype.render=function(){var e=this.context,t=this.props,n=t.dates,r=t.dateProfile,o=t.datesRepDistinctDays,i=t.renderIntro,a=this.createDayHeaderFormatter(e.options.dayHeaderFormat,o,n.length);return _o(Ca,{unit:"day"},(function(e,t){return _o("tr",{role:"row"},i&&i("day"),n.map((function(e){return o?_o(Sa,{key:e.toISOString(),date:e,dateProfile:r,todayRange:t,colCnt:n.length,dayHeaderFormat:a}):_o(Da,{key:e.getUTCDay(),dow:e.getUTCDay(),dayHeaderFormat:a})})))}))},t}(Uo);function _a(e,t,n){return e||ma(t,n)}var Ta=function(){function e(e,t){for(var n=e.start,r=e.end,o=[],i=[],a=-1;n<r;)t.isHiddenDay(n)?o.push(a+.5):(a+=1,o.push(a),i.push(n)),n=tt(n,1);this.dates=i,this.indices=o,this.cnt=i.length}return e.prototype.sliceRange=function(e){var t=this.getDateDayIndex(e.start),n=this.getDateDayIndex(tt(e.end,-1)),r=Math.max(0,t),o=Math.min(this.cnt-1,n);return(r=Math.ceil(r))<=(o=Math.floor(o))?{firstIndex:r,lastIndex:o,isStart:t===r,isEnd:n===o}:null},e.prototype.getDateDayIndex=function(e){var t=this.indices,n=Math.floor(ot(this.dates[0],e));return n<0?t[0]-1:n>=t.length?t[t.length-1]+1:t[n]},e}(),ka=function(){function e(e,t){var n,r,o,i=e.dates;if(t){for(r=i[0].getUTCDay(),n=1;n<i.length&&i[n].getUTCDay()!==r;n+=1);o=Math.ceil(i.length/n)}else o=1,n=i.length;this.rowCnt=o,this.colCnt=n,this.daySeries=e,this.cells=this.buildCells(),this.headerDates=this.buildHeaderDates()}return e.prototype.buildCells=function(){for(var e=[],t=0;t<this.rowCnt;t+=1){for(var n=[],r=0;r<this.colCnt;r+=1)n.push(this.buildCell(t,r));e.push(n)}return e},e.prototype.buildCell=function(e,t){var n=this.daySeries.dates[e*this.colCnt+t];return{key:n.toISOString(),date:n}},e.prototype.buildHeaderDates=function(){for(var e=[],t=0;t<this.colCnt;t+=1)e.push(this.cells[0][t].date);return e},e.prototype.sliceRange=function(e){var t=this.colCnt,n=this.daySeries.sliceRange(e),r=[];if(n)for(var o=n.firstIndex,i=n.lastIndex,a=o;a<=i;){var s=Math.floor(a/t),l=Math.min((s+1)*t,i+1);r.push({row:s,firstCol:a%t,lastCol:(l-1)%t,isStart:n.isStart&&a===o,isEnd:n.isEnd&&l-1===i}),a=l}return r},e}(),xa=function(){function e(){this.sliceBusinessHours=qt(this._sliceBusinessHours),this.sliceDateSelection=qt(this._sliceDateSpan),this.sliceEventStore=qt(this._sliceEventStore),this.sliceEventDrag=qt(this._sliceInteraction),this.sliceEventResize=qt(this._sliceInteraction),this.forceDayIfListItem=!1}return e.prototype.sliceProps=function(e,t,n,r){for(var i=[],a=4;a<arguments.length;a++)i[a-4]=arguments[a];var s=e.eventUiBases,l=this.sliceEventStore.apply(this,o([e.eventStore,s,t,n],i));return{dateSelectionSegs:this.sliceDateSelection.apply(this,o([e.dateSelection,s,r],i)),businessHourSegs:this.sliceBusinessHours.apply(this,o([e.businessHours,t,n,r],i)),fgEventSegs:l.fg,bgEventSegs:l.bg,eventDrag:this.sliceEventDrag.apply(this,o([e.eventDrag,s,t,n],i)),eventResize:this.sliceEventResize.apply(this,o([e.eventResize,s,t,n],i)),eventSelection:e.eventSelection}},e.prototype.sliceNowDate=function(e,t){for(var n=[],r=2;r<arguments.length;r++)n[r-2]=arguments[r];return this._sliceDateSpan.apply(this,o([{range:{start:e,end:nt(e,1)},allDay:!1},{},t],n))},e.prototype._sliceBusinessHours=function(e,t,n,r){for(var i=[],a=4;a<arguments.length;a++)i[a-4]=arguments[a];return e?this._sliceEventStore.apply(this,o([xt(e,Ma(t,Boolean(n)),r),{},t,n],i)).bg:[]},e.prototype._sliceEventStore=function(e,t,n,r){for(var o=[],i=4;i<arguments.length;i++)o[i-4]=arguments[i];if(e){var a=Xn(e,t,Ma(n,Boolean(r)),r);return{bg:this.sliceEventRanges(a.bg,o),fg:this.sliceEventRanges(a.fg,o)}}return{bg:[],fg:[]}},e.prototype._sliceInteraction=function(e,t,n,r){for(var o=[],i=4;i<arguments.length;i++)o[i-4]=arguments[i];if(!e)return null;var a=Xn(e.mutatedEvents,t,Ma(n,Boolean(r)),r);return{segs:this.sliceEventRanges(a.fg,o),affectedInstances:e.affectedEvents.instances,isEvent:e.isEvent}},e.prototype._sliceDateSpan=function(e,t,n){for(var r=[],i=3;i<arguments.length;i++)r[i-3]=arguments[i];if(!e)return[];for(var a=gr(e,t,n),s=this.sliceRange.apply(this,o([e.range],r)),l=0,u=s;l<u.length;l++){var c=u[l];c.eventRange=a}return s},e.prototype.sliceEventRanges=function(e,t){for(var n=[],r=0,o=e;r<o.length;r++){var i=o[r];n.push.apply(n,this.sliceEventRange(i,t))}return n},e.prototype.sliceEventRange=function(e,t){var n=e.range;this.forceDayIfListItem&&"list-item"===e.ui.display&&(n={start:n.start,end:tt(n.start,1)});for(var r=this.sliceRange.apply(this,o([n],t)),i=0,a=r;i<a.length;i++){var s=a[i];s.eventRange=e,s.isStart=e.isStart&&s.isStart,s.isEnd=e.isEnd&&s.isEnd}return r},e}();function Ma(e,t){var n=e.activeRange;return t?n:{start:nt(n.start,e.slotMinTime.milliseconds),end:nt(n.end,e.slotMaxTime.milliseconds-864e5)}}function Ia(e,t,n){var r=e.mutatedEvents.instances;for(var o in r)if(!Yn(t.validRange,r[o].range))return!1;return Na({eventDrag:e},n)}function Pa(e,t,n){return!!Yn(t.validRange,e.range)&&Na({dateSelection:e},n)}function Na(e,t){var n=t.getCurrentData(),o=r({businessHours:n.businessHours,dateSelection:"",eventStore:n.eventStore,eventUiBases:n.eventUiBases,eventSelection:"",eventDrag:null,eventResize:null},e);return(t.pluginHooks.isPropsValid||Ha)(o,t)}function Ha(e,t,n,o){return void 0===n&&(n={}),!(e.eventDrag&&!function(e,t,n,o){var i=t.getCurrentData(),a=e.eventDrag,s=a.mutatedEvents,l=s.defs,u=s.instances,c=Qn(l,a.isEvent?e.eventUiBases:{"":i.selectionConfig});o&&(c=bt(c,o));var d=(v=e.eventStore,g=a.affectedEvents.instances,{defs:v.defs,instances:St(v.instances,(function(e){return!g[e.instanceId]}))}),p=d.defs,f=d.instances,h=Qn(p,e.eventUiBases);var v,g;for(var m in u){var y=u[m],E=y.range,S=c[y.defId],b=l[y.defId];if(!Oa(S.constraints,E,d,e.businessHours,t))return!1;var D=t.options.eventOverlap,C="function"==typeof D?D:null;for(var w in f){var R=f[w];if(qn(E,R.range)){if(!1===h[R.defId].overlap&&a.isEvent)return!1;if(!1===S.overlap)return!1;if(C&&!C(new xr(t,p[R.defId],R),new xr(t,b,y)))return!1}}for(var _=i.eventStore,T=0,k=S.allows;T<k.length;T++){var x=k[T],M=r(r({},n),{range:y.range,allDay:b.allDay}),I=_.defs[b.defId],P=_.instances[m],N=void 0;if(N=I?new xr(t,I,P):new xr(t,b),!x(yr(M,t),N))return!1}}return!0}(e,t,n,o))&&!(e.dateSelection&&!function(e,t,n,o){var i=e.eventStore,a=i.defs,s=i.instances,l=e.dateSelection,u=l.range,c=t.getCurrentData().selectionConfig;o&&(c=o(c));if(!Oa(c.constraints,u,i,e.businessHours,t))return!1;var d=t.options.selectOverlap,p="function"==typeof d?d:null;for(var f in s){var h=s[f];if(qn(u,h.range)){if(!1===c.overlap)return!1;if(p&&!p(new xr(t,a[h.defId],h),null))return!1}}for(var v=0,g=c.allows;v<g.length;v++){if(!(0,g[v])(yr(r(r({},n),l),t),null))return!1}return!0}(e,t,n,o))}function Oa(e,t,n,r,o){for(var i=0,a=e;i<a.length;i++){if(!Ua(Aa(a[i],t,n,r,o),t))return!1}return!0}function Aa(e,t,n,r,o){return"businessHours"===e?La(xt(r,t,o)):"string"==typeof e?La(wn(n,(function(t){return t.groupId===e}))):"object"==typeof e&&e?La(xt(e,t,o)):[]}function La(e){var t=e.instances,n=[];for(var r in t)n.push(t[r].range);return n}function Ua(e,t){for(var n=0,r=e;n<r.length;n++){if(Yn(r[n],t))return!0}return!1}var Wa=/^(visible|hidden)$/,Va=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.handleEl=function(e){t.el=e,Fo(t.props.elRef,e)},t}return n(t,e),t.prototype.render=function(){var e=this.props,t=e.liquid,n=e.liquidIsAbsolute,r=t&&n,o=["fc-scroller"];return t&&(n?o.push("fc-scroller-liquid-absolute"):o.push("fc-scroller-liquid")),_o("div",{ref:this.handleEl,className:o.join(" "),style:{overflowX:e.overflowX,overflowY:e.overflowY,left:r&&-(e.overcomeLeft||0)||"",right:r&&-(e.overcomeRight||0)||"",bottom:r&&-(e.overcomeBottom||0)||"",marginLeft:!r&&-(e.overcomeLeft||0)||"",marginRight:!r&&-(e.overcomeRight||0)||"",marginBottom:!r&&-(e.overcomeBottom||0)||"",maxHeight:e.maxHeight||""}},e.children)},t.prototype.needsXScrolling=function(){if(Wa.test(this.props.overflowX))return!1;for(var e=this.el,t=this.el.getBoundingClientRect().width-this.getYScrollbarWidth(),n=e.children,r=0;r<n.length;r+=1){if(n[r].getBoundingClientRect().width>t)return!0}return!1},t.prototype.needsYScrolling=function(){if(Wa.test(this.props.overflowY))return!1;for(var e=this.el,t=this.el.getBoundingClientRect().height-this.getXScrollbarWidth(),n=e.children,r=0;r<n.length;r+=1){if(n[r].getBoundingClientRect().height>t)return!0}return!1},t.prototype.getXScrollbarWidth=function(){return Wa.test(this.props.overflowX)?0:this.el.offsetHeight-this.el.clientHeight},t.prototype.getYScrollbarWidth=function(){return Wa.test(this.props.overflowY)?0:this.el.offsetWidth-this.el.clientWidth},t}(Uo),Fa=function(){function e(e){var t=this;this.masterCallback=e,this.currentMap={},this.depths={},this.callbackMap={},this.handleValue=function(e,n){var r=t,o=r.depths,i=r.currentMap,a=!1,s=!1;null!==e?(a=n in i,i[n]=e,o[n]=(o[n]||0)+1,s=!0):(o[n]-=1,o[n]||(delete i[n],delete t.callbackMap[n],a=!0)),t.masterCallback&&(a&&t.masterCallback(null,String(n)),s&&t.masterCallback(e,String(n)))}}return e.prototype.createRef=function(e){var t=this,n=this.callbackMap[e];return n||(n=this.callbackMap[e]=function(n){t.handleValue(n,String(e))}),n},e.prototype.collect=function(e,t,n){return kt(this.currentMap,e,t,n)},e.prototype.getAll=function(){return Ct(this.currentMap)},e}();function Ba(e){for(var t=0,n=0,r=De(e,".fc-scrollgrid-shrink");n<r.length;n++){var o=r[n];t=Math.max(t,Je(o))}return Math.ceil(t)}function za(e,t){return e.liquid&&t.liquid}function ja(e,t){return null!=t.maxHeight||za(e,t)}function Ga(e,t,n,r){var o=n.expandRows;return"function"==typeof t.content?t.content(n):_o("table",{role:"presentation",className:[t.tableClassName,e.syncRowHeights?"fc-scrollgrid-sync-table":""].join(" "),style:{minWidth:n.tableMinWidth,width:n.clientWidth,height:o?n.clientHeight:""}},n.tableColGroupNode,_o(r?"thead":"tbody",{role:"presentation"},"function"==typeof t.rowContent?t.rowContent(n):t.rowContent))}function qa(e,t){return Gt(e,t,wt)}function Ya(e,t){for(var n=[],r=0,i=e;r<i.length;r++)for(var a=i[r],s=a.span||1,l=0;l<s;l+=1)n.push(_o("col",{style:{width:"shrink"===a.width?Za(t):a.width||"",minWidth:a.minWidth||""}}));return _o.apply(void 0,o(["colgroup",{}],n))}function Za(e){return null==e?4:e}function Xa(e){for(var t=0,n=e;t<n.length;t++){if("shrink"===n[t].width)return!0}return!1}function Ka(e,t){var n=["fc-scrollgrid",t.theme.getClass("table")];return e&&n.push("fc-scrollgrid-liquid"),n}function $a(e,t){var n=["fc-scrollgrid-section","fc-scrollgrid-section-"+e.type,e.className];return t&&e.liquid&&null==e.maxHeight&&n.push("fc-scrollgrid-section-liquid"),e.isSticky&&n.push("fc-scrollgrid-section-sticky"),n}function Ja(e){return _o("div",{className:"fc-scrollgrid-sticky-shim",style:{width:e.clientWidth,minWidth:e.tableMinWidth}})}function Qa(e){var t=e.stickyHeaderDates;return null!=t&&"auto"!==t||(t="auto"===e.height||"auto"===e.viewHeight),t}function es(e){var t=e.stickyFooterScrollbar;return null!=t&&"auto"!==t||(t="auto"===e.height||"auto"===e.viewHeight),t}var ts=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.processCols=qt((function(e){return e}),qa),t.renderMicroColGroup=qt(Ya),t.scrollerRefs=new Fa,t.scrollerElRefs=new Fa(t._handleScrollerEl.bind(t)),t.state={shrinkWidth:null,forceYScrollbars:!1,scrollerClientWidths:{},scrollerClientHeights:{}},t.handleSizing=function(){t.safeSetState(r({shrinkWidth:t.computeShrinkWidth()},t.computeScrollerDims()))},t}return n(t,e),t.prototype.render=function(){var e=this,t=e.props,n=e.state,r=e.context,i=t.sections||[],a=this.processCols(t.cols),s=this.renderMicroColGroup(a,n.shrinkWidth),l=Ka(t.liquid,r);t.collapsibleWidth&&l.push("fc-scrollgrid-collapsible");for(var u,c=i.length,d=0,p=[],f=[],h=[];d<c&&"header"===(u=i[d]).type;)p.push(this.renderSection(u,s,!0)),d+=1;for(;d<c&&"body"===(u=i[d]).type;)f.push(this.renderSection(u,s,!1)),d+=1;for(;d<c&&"footer"===(u=i[d]).type;)h.push(this.renderSection(u,s,!0)),d+=1;var v=!Qr(),g={role:"rowgroup"};return _o("table",{role:"grid",className:l.join(" "),style:{height:t.height}},Boolean(!v&&p.length)&&_o.apply(void 0,o(["thead",g],p)),Boolean(!v&&f.length)&&_o.apply(void 0,o(["tbody",g],f)),Boolean(!v&&h.length)&&_o.apply(void 0,o(["tfoot",g],h)),v&&_o.apply(void 0,o(o(o(["tbody",g],p),f),h)))},t.prototype.renderSection=function(e,t,n){return"outerContent"in e?_o(xo,{key:e.key},e.outerContent):_o("tr",{key:e.key,role:"presentation",className:$a(e,this.props.liquid).join(" ")},this.renderChunkTd(e,t,e.chunk,n))},t.prototype.renderChunkTd=function(e,t,n,r){if("outerContent"in n)return n.outerContent;var o=this.props,i=this.state,a=i.forceYScrollbars,s=i.scrollerClientWidths,l=i.scrollerClientHeights,u=ja(o,e),c=za(o,e),d=o.liquid?a?"scroll":u?"auto":"hidden":"visible",p=e.key,f=Ga(e,n,{tableColGroupNode:t,tableMinWidth:"",clientWidth:o.collapsibleWidth||void 0===s[p]?null:s[p],clientHeight:void 0!==l[p]?l[p]:null,expandRows:e.expandRows,syncRowHeights:!1,rowSyncHeights:[],reportRowHeightChange:function(){}},r);return _o(r?"th":"td",{ref:n.elRef,role:"presentation"},_o("div",{className:"fc-scroller-harness"+(c?" fc-scroller-harness-liquid":"")},_o(Va,{ref:this.scrollerRefs.createRef(p),elRef:this.scrollerElRefs.createRef(p),overflowY:d,overflowX:o.liquid?"hidden":"visible",maxHeight:e.maxHeight,liquid:c,liquidIsAbsolute:!0},f)))},t.prototype._handleScrollerEl=function(e,t){var n=function(e,t){for(var n=0,r=e;n<r.length;n++){var o=r[n];if(o.key===t)return o}return null}(this.props.sections,t);n&&Fo(n.chunk.scrollerElRef,e)},t.prototype.componentDidMount=function(){this.handleSizing(),this.context.addResizeHandler(this.handleSizing)},t.prototype.componentDidUpdate=function(){this.handleSizing()},t.prototype.componentWillUnmount=function(){this.context.removeResizeHandler(this.handleSizing)},t.prototype.computeShrinkWidth=function(){return Xa(this.props.cols)?Ba(this.scrollerElRefs.getAll()):0},t.prototype.computeScrollerDims=function(){var e=po(),t=this.scrollerRefs,n=this.scrollerElRefs,r=!1,o={},i={};for(var a in t.currentMap){var s=t.currentMap[a];if(s&&s.needsYScrolling()){r=!0;break}}for(var l=0,u=this.props.sections;l<u.length;l++){a=u[l].key;var c=n.currentMap[a];if(c){var d=c.parentNode;o[a]=Math.floor(d.getBoundingClientRect().width-(r?e.y:0)),i[a]=Math.floor(d.getBoundingClientRect().height)}}return{forceYScrollbars:r,scrollerClientWidths:o,scrollerClientHeights:i}},t}(Uo);ts.addStateEquality({scrollerClientWidths:wt,scrollerClientHeights:wt});var ns=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.elRef=ko(),t}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context,n=t.options,r=e.seg,o=r.eventRange,i=o.ui,a={event:new xr(t,o.def,o.instance),view:t.viewApi,timeText:e.timeText,textColor:i.textColor,backgroundColor:i.backgroundColor,borderColor:i.borderColor,isDraggable:!e.disableDragging&&rr(r,t),isStartResizable:!e.disableResizing&&or(r,t),isEndResizable:!e.disableResizing&&ir(r),isMirror:Boolean(e.isDragging||e.isResizing||e.isDateSelecting),isStart:Boolean(r.isStart),isEnd:Boolean(r.isEnd),isPast:Boolean(e.isPast),isFuture:Boolean(e.isFuture),isToday:Boolean(e.isToday),isSelected:Boolean(e.isSelected),isDragging:Boolean(e.isDragging),isResizing:Boolean(e.isResizing)},s=lr(a).concat(i.classNames);return _o(Yo,{hookProps:a,classNames:n.eventClassNames,content:n.eventContent,defaultContent:e.defaultContent,didMount:n.eventDidMount,willUnmount:n.eventWillUnmount,elRef:this.elRef},(function(t,n,r,o){return e.children(t,s.concat(n),r,o,a)}))},t.prototype.componentDidMount=function(){$n(this.elRef.current,this.props.seg)},t.prototype.componentDidUpdate=function(e){var t=this.props.seg;t!==e.seg&&$n(this.elRef.current,t)},t}(Uo),rs=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context,n=e.seg,o=t.options.eventTimeFormat||e.defaultTimeFormat,i=ar(n,o,t,e.defaultDisplayEventTime,e.defaultDisplayEventEnd);return _o(ns,{seg:n,timeText:i,disableDragging:e.disableDragging,disableResizing:e.disableResizing,defaultContent:e.defaultContent||os,isDragging:e.isDragging,isResizing:e.isResizing,isDateSelecting:e.isDateSelecting,isSelected:e.isSelected,isPast:e.isPast,isFuture:e.isFuture,isToday:e.isToday},(function(o,i,a,s,l){return _o("a",r({className:e.extraClassNames.concat(i).join(" "),style:{borderColor:l.borderColor,backgroundColor:l.backgroundColor},ref:o},cr(n,t)),_o("div",{className:"fc-event-main",ref:a,style:{color:l.textColor}},s),l.isStartResizable&&_o("div",{className:"fc-event-resizer fc-event-resizer-start"}),l.isEndResizable&&_o("div",{className:"fc-event-resizer fc-event-resizer-end"}))}))},t}(Uo);function os(e){return _o("div",{className:"fc-event-main-frame"},e.timeText&&_o("div",{className:"fc-event-time"},e.timeText),_o("div",{className:"fc-event-title-container"},_o("div",{className:"fc-event-title fc-sticky"},e.event.title||_o(xo,null," "))))}var is=function(e){return _o(Oo.Consumer,null,(function(t){var n=t.options,r={isAxis:e.isAxis,date:t.dateEnv.toDate(e.date),view:t.viewApi};return _o(Yo,{hookProps:r,classNames:n.nowIndicatorClassNames,content:n.nowIndicatorContent,didMount:n.nowIndicatorDidMount,willUnmount:n.nowIndicatorWillUnmount},e.children)}))},as=ln({day:"numeric"}),ss=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context,n=t.options,r=ls({date:e.date,dateProfile:e.dateProfile,todayRange:e.todayRange,showDayNumber:e.showDayNumber,extraProps:e.extraHookProps,viewApi:t.viewApi,dateEnv:t.dateEnv});return _o(Xo,{hookProps:r,content:n.dayCellContent,defaultContent:e.defaultContent},e.children)},t}(Uo);function ls(e){var t=e.date,n=e.dateEnv,o=ro(t,e.todayRange,null,e.dateProfile);return r(r(r({date:n.toDate(t),view:e.viewApi},o),{dayNumberText:e.showDayNumber?n.format(t,as):""}),e.extraProps)}var us=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.refineHookProps=Yt(ls),t.normalizeClassNames=Jo(),t}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context,n=t.options,r=this.refineHookProps({date:e.date,dateProfile:e.dateProfile,todayRange:e.todayRange,showDayNumber:e.showDayNumber,extraProps:e.extraHookProps,viewApi:t.viewApi,dateEnv:t.dateEnv}),o=oo(r,t.theme).concat(r.isDisabled?[]:this.normalizeClassNames(n.dayCellClassNames,r)),i=r.isDisabled?{}:{"data-date":Bt(e.date)};return _o($o,{hookProps:r,didMount:n.dayCellDidMount,willUnmount:n.dayCellWillUnmount,elRef:e.elRef},(function(t){return e.children(t,o,i,r.isDisabled)}))},t}(Uo);function cs(e){return _o("div",{className:"fc-"+e})}var ds=function(e){return _o(ns,{defaultContent:ps,seg:e.seg,timeText:"",disableDragging:!0,disableResizing:!0,isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:!1,isPast:e.isPast,isFuture:e.isFuture,isToday:e.isToday},(function(e,t,n,r,o){return _o("div",{ref:e,className:["fc-bg-event"].concat(t).join(" "),style:{backgroundColor:o.backgroundColor}},r)}))};function ps(e){return e.event.title&&_o("div",{className:"fc-event-title"},e.event.title)}var fs=function(e){return _o(Oo.Consumer,null,(function(t){var n=t.dateEnv,r=t.options,o=e.date,i=r.weekNumberFormat||e.defaultFormat,a=n.computeWeekNumber(o),s=n.format(o,i);return _o(Yo,{hookProps:{num:a,text:s,date:o},classNames:r.weekNumberClassNames,content:r.weekNumberContent,defaultContent:hs,didMount:r.weekNumberDidMount,willUnmount:r.weekNumberWillUnmount},e.children)}))};function hs(e){return e.text}var vs=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.state={titleId:xe()},t.handleRootEl=function(e){t.rootEl=e,t.props.elRef&&Fo(t.props.elRef,e)},t.handleDocumentMouseDown=function(e){var n=_e(e);t.rootEl.contains(n)||t.handleCloseClick()},t.handleDocumentKeyDown=function(e){"Escape"===e.key&&t.handleCloseClick()},t.handleCloseClick=function(){var e=t.props.onClose;e&&e()},t}return n(t,e),t.prototype.render=function(){var e=this.context,t=e.theme,n=e.options,o=this.props,i=this.state,a=["fc-popover",t.getClass("popover")].concat(o.extraClassNames||[]);return Io(_o("div",r({id:o.id,className:a.join(" "),"aria-labelledby":i.titleId},o.extraAttrs,{ref:this.handleRootEl}),_o("div",{className:"fc-popover-header "+t.getClass("popoverHeader")},_o("span",{className:"fc-popover-title",id:i.titleId},o.title),_o("span",{className:"fc-popover-close "+t.getIconClass("close"),title:n.closeHint,onClick:this.handleCloseClick})),_o("div",{className:"fc-popover-body "+t.getClass("popoverContent")},o.children)),o.parentEl)},t.prototype.componentDidMount=function(){document.addEventListener("mousedown",this.handleDocumentMouseDown),document.addEventListener("keydown",this.handleDocumentKeyDown),this.updateSize()},t.prototype.componentWillUnmount=function(){document.removeEventListener("mousedown",this.handleDocumentMouseDown),document.removeEventListener("keydown",this.handleDocumentKeyDown)},t.prototype.updateSize=function(){var e=this.context.isRtl,t=this.props,n=t.alignmentEl,r=t.alignGridTop,o=this.rootEl,i=function(e){for(var t=mo(e),n=e.getBoundingClientRect(),r=0,o=t;r<o.length;r++){var i=Xr(n,o[r].getBoundingClientRect());if(!i)return null;n=i}return n}(n);if(i){var a=o.getBoundingClientRect(),s=r?Se(n,".fc-scrollgrid").getBoundingClientRect().top:i.top,l=e?i.right-a.width:i.left;s=Math.max(s,10),l=Math.min(l,document.documentElement.clientWidth-10-a.width),l=Math.max(l,10);var u=o.offsetParent.getBoundingClientRect();we(o,{top:s-u.top,left:l-u.left})}},t}(Uo),gs=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.handleRootEl=function(e){t.rootEl=e,e?t.context.registerInteractiveComponent(t,{el:e,useEventCenter:!1}):t.context.unregisterInteractiveComponent(t)},t}return n(t,e),t.prototype.render=function(){var e=this.context,t=e.options,n=e.dateEnv,r=this.props,o=r.startDate,i=r.todayRange,a=r.dateProfile,s=n.format(o,t.dayPopoverFormat);return _o(us,{date:o,dateProfile:a,todayRange:i,elRef:this.handleRootEl},(function(e,t,n){return _o(vs,{elRef:e,id:r.id,title:s,extraClassNames:["fc-more-popover"].concat(t),extraAttrs:n,parentEl:r.parentEl,alignmentEl:r.alignmentEl,alignGridTop:r.alignGridTop,onClose:r.onClose},_o(ss,{date:o,dateProfile:a,todayRange:i},(function(e,t){return t&&_o("div",{className:"fc-more-popover-misc",ref:e},t)})),r.children)}))},t.prototype.queryHit=function(e,t,n,o){var i=this.rootEl,a=this.props;return e>=0&&e<n&&t>=0&&t<o?{dateProfile:a.dateProfile,dateSpan:r({allDay:!0,range:{start:a.startDate,end:a.endDate}},a.extraDateSpan),dayEl:i,rect:{left:0,top:0,right:n,bottom:o},layer:1}:null},t}(Bo),ms=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.linkElRef=ko(),t.state={isPopoverOpen:!1,popoverId:xe()},t.handleClick=function(e){var n=t,r=n.props,o=n.context,i=o.options.moreLinkClick,a=Es(r).start;function s(e){var t=e.eventRange,n=t.def,r=t.instance,i=t.range;return{event:new xr(o,n,r),start:o.dateEnv.toDate(i.start),end:o.dateEnv.toDate(i.end),isStart:e.isStart,isEnd:e.isEnd}}"function"==typeof i&&(i=i({date:a,allDay:Boolean(r.allDayDate),allSegs:r.allSegs.map(s),hiddenSegs:r.hiddenSegs.map(s),jsEvent:e,view:o.viewApi})),i&&"popover"!==i?"string"==typeof i&&o.calendarApi.zoomTo(a,i):t.setState({isPopoverOpen:!0})},t.handlePopoverClose=function(){t.setState({isPopoverOpen:!1})},t}return n(t,e),t.prototype.render=function(){var e=this,t=this.props,n=this.state;return _o(Oo.Consumer,null,(function(r){var o=r.viewApi,i=r.options,a=r.calendarApi,s=i.moreLinkText,l=t.moreCnt,u=Es(t),c="function"==typeof s?s.call(a,l):"+"+l+" "+s,d=Xe(i.moreLinkHint,[l],c),p={num:l,shortText:"+"+l,text:c,view:o};return _o(xo,null,Boolean(t.moreCnt)&&_o(Yo,{elRef:e.linkElRef,hookProps:p,classNames:i.moreLinkClassNames,content:i.moreLinkContent,defaultContent:t.defaultContent||ys,didMount:i.moreLinkDidMount,willUnmount:i.moreLinkWillUnmount},(function(r,o,i,a){return t.children(r,["fc-more-link"].concat(o),i,a,e.handleClick,d,n.isPopoverOpen,n.isPopoverOpen?n.popoverId:"")})),n.isPopoverOpen&&_o(gs,{id:n.popoverId,startDate:u.start,endDate:u.end,dateProfile:t.dateProfile,todayRange:t.todayRange,extraDateSpan:t.extraDateSpan,parentEl:e.parentEl,alignmentEl:t.alignmentElRef.current,alignGridTop:t.alignGridTop,onClose:e.handlePopoverClose},t.popoverContent()))}))},t.prototype.componentDidMount=function(){this.updateParentEl()},t.prototype.componentDidUpdate=function(){this.updateParentEl()},t.prototype.updateParentEl=function(){this.linkElRef.current&&(this.parentEl=Se(this.linkElRef.current,".fc-view-harness"))},t}(Uo);function ys(e){return e.text}function Es(e){if(e.allDayDate)return{start:e.allDayDate,end:tt(e.allDayDate,1)};var t,n=e.hiddenSegs;return{start:Ss(n),end:(t=n,t.reduce(Ds).eventRange.range.end)}}function Ss(e){return e.reduce(bs).eventRange.range.start}function bs(e,t){return e.eventRange.range.start<t.eventRange.range.start?e:t}function Ds(e,t){return e.eventRange.range.end>t.eventRange.range.end?e:t}var Cs=function(e){function t(t,n){void 0===n&&(n={});var o=e.call(this)||this;return o.isRendering=!1,o.isRendered=!1,o.currentClassNames=[],o.customContentRenderId=0,o.handleAction=function(e){switch(e.type){case"SET_EVENT_DRAG":case"SET_EVENT_RESIZE":o.renderRunner.tryDrain()}},o.handleData=function(e){o.currentData=e,o.renderRunner.request(e.calendarOptions.rerenderDelay)},o.handleRenderRequest=function(){if(o.isRendering){o.isRendered=!0;var e=o.currentData;Po((function(){To(_o(ga,{options:e.calendarOptions,theme:e.theme,emitter:e.emitter},(function(t,n,i,a){return o.setClassNames(t),o.setHeight(n),_o(Zo.Provider,{value:o.customContentRenderId},_o(fa,r({isHeightAuto:i,forPrint:a},e)))})),o.el)}))}else o.isRendered&&(o.isRendered=!1,No(o.el),o.setClassNames([]),o.setHeight(""))},o.el=t,o.renderRunner=new Mi(o.handleRenderRequest),new Ni({optionOverrides:n,calendarApi:o,onAction:o.handleAction,onData:o.handleData}),o}return n(t,e),Object.defineProperty(t.prototype,"view",{get:function(){return this.currentData.viewApi},enumerable:!1,configurable:!0}),t.prototype.render=function(){var e=this.isRendering;e?this.customContentRenderId+=1:this.isRendering=!0,this.renderRunner.request(),e&&this.updateSize()},t.prototype.destroy=function(){this.isRendering&&(this.isRendering=!1,this.renderRunner.request())},t.prototype.updateSize=function(){var t=this;Po((function(){e.prototype.updateSize.call(t)}))},t.prototype.batchRendering=function(e){this.renderRunner.pause("batchRendering"),e(),this.renderRunner.resume("batchRendering")},t.prototype.pauseRendering=function(){this.renderRunner.pause("pauseRendering")},t.prototype.resumeRendering=function(){this.renderRunner.resume("pauseRendering",!0)},t.prototype.resetOptions=function(e,t){this.currentDataManager.resetOptions(e,t)},t.prototype.setClassNames=function(e){if(!Gt(e,this.currentClassNames)){for(var t=this.el.classList,n=0,r=this.currentClassNames;n<r.length;n++){var o=r[n];t.remove(o)}for(var i=0,a=e;i<a.length;i++){o=a[i];t.add(o)}this.currentClassNames=e}},t.prototype.setHeight=function(e){Re(this.el,"height",e)},t}(kr);ia.touchMouseIgnoreWait=500;var ws=0,Rs=0,_s=!1,Ts=function(){function e(e){var t=this;this.subjectEl=null,this.selector="",this.handleSelector="",this.shouldIgnoreMove=!1,this.shouldWatchScroll=!0,this.isDragging=!1,this.isTouchDragging=!1,this.wasTouchScroll=!1,this.handleMouseDown=function(e){if(!t.shouldIgnoreMouse()&&function(e){return 0===e.button&&!e.ctrlKey}(e)&&t.tryStart(e)){var n=t.createEventFromMouse(e,!0);t.emitter.trigger("pointerdown",n),t.initScrollWatch(n),t.shouldIgnoreMove||document.addEventListener("mousemove",t.handleMouseMove),document.addEventListener("mouseup",t.handleMouseUp)}},this.handleMouseMove=function(e){var n=t.createEventFromMouse(e);t.recordCoords(n),t.emitter.trigger("pointermove",n)},this.handleMouseUp=function(e){document.removeEventListener("mousemove",t.handleMouseMove),document.removeEventListener("mouseup",t.handleMouseUp),t.emitter.trigger("pointerup",t.createEventFromMouse(e)),t.cleanup()},this.handleTouchStart=function(e){if(t.tryStart(e)){t.isTouchDragging=!0;var n=t.createEventFromTouch(e,!0);t.emitter.trigger("pointerdown",n),t.initScrollWatch(n);var r=e.target;t.shouldIgnoreMove||r.addEventListener("touchmove",t.handleTouchMove),r.addEventListener("touchend",t.handleTouchEnd),r.addEventListener("touchcancel",t.handleTouchEnd),window.addEventListener("scroll",t.handleTouchScroll,!0)}},this.handleTouchMove=function(e){var n=t.createEventFromTouch(e);t.recordCoords(n),t.emitter.trigger("pointermove",n)},this.handleTouchEnd=function(e){if(t.isDragging){var n=e.target;n.removeEventListener("touchmove",t.handleTouchMove),n.removeEventListener("touchend",t.handleTouchEnd),n.removeEventListener("touchcancel",t.handleTouchEnd),window.removeEventListener("scroll",t.handleTouchScroll,!0),t.emitter.trigger("pointerup",t.createEventFromTouch(e)),t.cleanup(),t.isTouchDragging=!1,ws+=1,setTimeout((function(){ws-=1}),ia.touchMouseIgnoreWait)}},this.handleTouchScroll=function(){t.wasTouchScroll=!0},this.handleScroll=function(e){if(!t.shouldIgnoreMove){var n=window.pageXOffset-t.prevScrollX+t.prevPageX,r=window.pageYOffset-t.prevScrollY+t.prevPageY;t.emitter.trigger("pointermove",{origEvent:e,isTouch:t.isTouchDragging,subjectEl:t.subjectEl,pageX:n,pageY:r,deltaX:n-t.origPageX,deltaY:r-t.origPageY})}},this.containerEl=e,this.emitter=new Eo,e.addEventListener("mousedown",this.handleMouseDown),e.addEventListener("touchstart",this.handleTouchStart,{passive:!0}),1===(Rs+=1)&&window.addEventListener("touchmove",ks,{passive:!1})}return e.prototype.destroy=function(){this.containerEl.removeEventListener("mousedown",this.handleMouseDown),this.containerEl.removeEventListener("touchstart",this.handleTouchStart,{passive:!0}),(Rs-=1)||window.removeEventListener("touchmove",ks,{passive:!1})},e.prototype.tryStart=function(e){var t=this.querySubjectEl(e),n=e.target;return!(!t||this.handleSelector&&!Se(n,this.handleSelector))&&(this.subjectEl=t,this.isDragging=!0,this.wasTouchScroll=!1,!0)},e.prototype.cleanup=function(){_s=!1,this.isDragging=!1,this.subjectEl=null,this.destroyScrollWatch()},e.prototype.querySubjectEl=function(e){return this.selector?Se(e.target,this.selector):this.containerEl},e.prototype.shouldIgnoreMouse=function(){return ws||this.isTouchDragging},e.prototype.cancelTouchScroll=function(){this.isDragging&&(_s=!0)},e.prototype.initScrollWatch=function(e){this.shouldWatchScroll&&(this.recordCoords(e),window.addEventListener("scroll",this.handleScroll,!0))},e.prototype.recordCoords=function(e){this.shouldWatchScroll&&(this.prevPageX=e.pageX,this.prevPageY=e.pageY,this.prevScrollX=window.pageXOffset,this.prevScrollY=window.pageYOffset)},e.prototype.destroyScrollWatch=function(){this.shouldWatchScroll&&window.removeEventListener("scroll",this.handleScroll,!0)},e.prototype.createEventFromMouse=function(e,t){var n=0,r=0;return t?(this.origPageX=e.pageX,this.origPageY=e.pageY):(n=e.pageX-this.origPageX,r=e.pageY-this.origPageY),{origEvent:e,isTouch:!1,subjectEl:this.subjectEl,pageX:e.pageX,pageY:e.pageY,deltaX:n,deltaY:r}},e.prototype.createEventFromTouch=function(e,t){var n,r,o=e.touches,i=0,a=0;return o&&o.length?(n=o[0].pageX,r=o[0].pageY):(n=e.pageX,r=e.pageY),t?(this.origPageX=n,this.origPageY=r):(i=n-this.origPageX,a=r-this.origPageY),{origEvent:e,isTouch:!0,subjectEl:this.subjectEl,pageX:n,pageY:r,deltaX:i,deltaY:a}},e}();function ks(e){_s&&e.preventDefault()}var xs=function(){function e(){this.isVisible=!1,this.sourceEl=null,this.mirrorEl=null,this.sourceElRect=null,this.parentNode=document.body,this.zIndex=9999,this.revertDuration=0}return e.prototype.start=function(e,t,n){this.sourceEl=e,this.sourceElRect=this.sourceEl.getBoundingClientRect(),this.origScreenX=t-window.pageXOffset,this.origScreenY=n-window.pageYOffset,this.deltaX=0,this.deltaY=0,this.updateElPosition()},e.prototype.handleMove=function(e,t){this.deltaX=e-window.pageXOffset-this.origScreenX,this.deltaY=t-window.pageYOffset-this.origScreenY,this.updateElPosition()},e.prototype.setIsVisible=function(e){e?this.isVisible||(this.mirrorEl&&(this.mirrorEl.style.display=""),this.isVisible=e,this.updateElPosition()):this.isVisible&&(this.mirrorEl&&(this.mirrorEl.style.display="none"),this.isVisible=e)},e.prototype.stop=function(e,t){var n=this,r=function(){n.cleanup(),t()};e&&this.mirrorEl&&this.isVisible&&this.revertDuration&&(this.deltaX||this.deltaY)?this.doRevertAnimation(r,this.revertDuration):setTimeout(r,0)},e.prototype.doRevertAnimation=function(e,t){var n=this.mirrorEl,r=this.sourceEl.getBoundingClientRect();n.style.transition="top "+t+"ms,left "+t+"ms",we(n,{left:r.left,top:r.top}),Ne(n,(function(){n.style.transition="",e()}))},e.prototype.cleanup=function(){this.mirrorEl&&(Ee(this.mirrorEl),this.mirrorEl=null),this.sourceEl=null},e.prototype.updateElPosition=function(){this.sourceEl&&this.isVisible&&we(this.getMirrorEl(),{left:this.sourceElRect.left+this.deltaX,top:this.sourceElRect.top+this.deltaY})},e.prototype.getMirrorEl=function(){var e=this.sourceElRect,t=this.mirrorEl;return t||((t=this.mirrorEl=this.sourceEl.cloneNode(!0)).classList.add("fc-unselectable"),t.classList.add("fc-event-dragging"),we(t,{position:"fixed",zIndex:this.zIndex,visibility:"",boxSizing:"border-box",width:e.right-e.left,height:e.bottom-e.top,right:"auto",bottom:"auto",margin:0}),this.parentNode.appendChild(t)),t},e}(),Ms=function(e){function t(t,n){var r=e.call(this)||this;return r.handleScroll=function(){r.scrollTop=r.scrollController.getScrollTop(),r.scrollLeft=r.scrollController.getScrollLeft(),r.handleScrollChange()},r.scrollController=t,r.doesListening=n,r.scrollTop=r.origScrollTop=t.getScrollTop(),r.scrollLeft=r.origScrollLeft=t.getScrollLeft(),r.scrollWidth=t.getScrollWidth(),r.scrollHeight=t.getScrollHeight(),r.clientWidth=t.getClientWidth(),r.clientHeight=t.getClientHeight(),r.clientRect=r.computeClientRect(),r.doesListening&&r.getEventTarget().addEventListener("scroll",r.handleScroll),r}return n(t,e),t.prototype.destroy=function(){this.doesListening&&this.getEventTarget().removeEventListener("scroll",this.handleScroll)},t.prototype.getScrollTop=function(){return this.scrollTop},t.prototype.getScrollLeft=function(){return this.scrollLeft},t.prototype.setScrollTop=function(e){this.scrollController.setScrollTop(e),this.doesListening||(this.scrollTop=Math.max(Math.min(e,this.getMaxScrollTop()),0),this.handleScrollChange())},t.prototype.setScrollLeft=function(e){this.scrollController.setScrollLeft(e),this.doesListening||(this.scrollLeft=Math.max(Math.min(e,this.getMaxScrollLeft()),0),this.handleScrollChange())},t.prototype.getClientWidth=function(){return this.clientWidth},t.prototype.getClientHeight=function(){return this.clientHeight},t.prototype.getScrollWidth=function(){return this.scrollWidth},t.prototype.getScrollHeight=function(){return this.scrollHeight},t.prototype.handleScrollChange=function(){},t}(bo),Is=function(e){function t(t,n){return e.call(this,new Do(t),n)||this}return n(t,e),t.prototype.getEventTarget=function(){return this.scrollController.el},t.prototype.computeClientRect=function(){return vo(this.scrollController.el)},t}(Ms),Ps=function(e){function t(t){return e.call(this,new Co,t)||this}return n(t,e),t.prototype.getEventTarget=function(){return window},t.prototype.computeClientRect=function(){return{left:this.scrollLeft,right:this.scrollLeft+this.clientWidth,top:this.scrollTop,bottom:this.scrollTop+this.clientHeight}},t.prototype.handleScrollChange=function(){this.clientRect=this.computeClientRect()},t}(Ms),Ns="function"==typeof performance?performance.now:Date.now,Hs=function(){function e(){var e=this;this.isEnabled=!0,this.scrollQuery=[window,".fc-scroller"],this.edgeThreshold=50,this.maxVelocity=300,this.pointerScreenX=null,this.pointerScreenY=null,this.isAnimating=!1,this.scrollCaches=null,this.everMovedUp=!1,this.everMovedDown=!1,this.everMovedLeft=!1,this.everMovedRight=!1,this.animate=function(){if(e.isAnimating){var t=e.computeBestEdge(e.pointerScreenX+window.pageXOffset,e.pointerScreenY+window.pageYOffset);if(t){var n=Ns();e.handleSide(t,(n-e.msSinceRequest)/1e3),e.requestAnimation(n)}else e.isAnimating=!1}}}return e.prototype.start=function(e,t,n){this.isEnabled&&(this.scrollCaches=this.buildCaches(n),this.pointerScreenX=null,this.pointerScreenY=null,this.everMovedUp=!1,this.everMovedDown=!1,this.everMovedLeft=!1,this.everMovedRight=!1,this.handleMove(e,t))},e.prototype.handleMove=function(e,t){if(this.isEnabled){var n=e-window.pageXOffset,r=t-window.pageYOffset,o=null===this.pointerScreenY?0:r-this.pointerScreenY,i=null===this.pointerScreenX?0:n-this.pointerScreenX;o<0?this.everMovedUp=!0:o>0&&(this.everMovedDown=!0),i<0?this.everMovedLeft=!0:i>0&&(this.everMovedRight=!0),this.pointerScreenX=n,this.pointerScreenY=r,this.isAnimating||(this.isAnimating=!0,this.requestAnimation(Ns()))}},e.prototype.stop=function(){if(this.isEnabled){this.isAnimating=!1;for(var e=0,t=this.scrollCaches;e<t.length;e++){t[e].destroy()}this.scrollCaches=null}},e.prototype.requestAnimation=function(e){this.msSinceRequest=e,requestAnimationFrame(this.animate)},e.prototype.handleSide=function(e,t){var n=e.scrollCache,r=this.edgeThreshold,o=r-e.distance,i=o*o/(r*r)*this.maxVelocity*t,a=1;switch(e.name){case"left":a=-1;case"right":n.setScrollLeft(n.getScrollLeft()+i*a);break;case"top":a=-1;case"bottom":n.setScrollTop(n.getScrollTop()+i*a)}},e.prototype.computeBestEdge=function(e,t){for(var n=this.edgeThreshold,r=null,o=0,i=this.scrollCaches||[];o<i.length;o++){var a=i[o],s=a.clientRect,l=e-s.left,u=s.right-e,c=t-s.top,d=s.bottom-t;l>=0&&u>=0&&c>=0&&d>=0&&(c<=n&&this.everMovedUp&&a.canScrollUp()&&(!r||r.distance>c)&&(r={scrollCache:a,name:"top",distance:c}),d<=n&&this.everMovedDown&&a.canScrollDown()&&(!r||r.distance>d)&&(r={scrollCache:a,name:"bottom",distance:d}),l<=n&&this.everMovedLeft&&a.canScrollLeft()&&(!r||r.distance>l)&&(r={scrollCache:a,name:"left",distance:l}),u<=n&&this.everMovedRight&&a.canScrollRight()&&(!r||r.distance>u)&&(r={scrollCache:a,name:"right",distance:u}))}return r},e.prototype.buildCaches=function(e){return this.queryScrollEls(e).map((function(e){return e===window?new Ps(!1):new Is(e,!1)}))},e.prototype.queryScrollEls=function(e){for(var t=[],n=0,r=this.scrollQuery;n<r.length;n++){var o=r[n];"object"==typeof o?t.push(o):t.push.apply(t,Array.prototype.slice.call(Te(e).querySelectorAll(o)))}return t},e}(),Os=function(e){function t(t,n){var r=e.call(this,t)||this;r.containerEl=t,r.delay=null,r.minDistance=0,r.touchScrollAllowed=!0,r.mirrorNeedsRevert=!1,r.isInteracting=!1,r.isDragging=!1,r.isDelayEnded=!1,r.isDistanceSurpassed=!1,r.delayTimeoutId=null,r.onPointerDown=function(e){r.isDragging||(r.isInteracting=!0,r.isDelayEnded=!1,r.isDistanceSurpassed=!1,Ve(document.body),Be(document.body),e.isTouch||e.origEvent.preventDefault(),r.emitter.trigger("pointerdown",e),r.isInteracting&&!r.pointer.shouldIgnoreMove&&(r.mirror.setIsVisible(!1),r.mirror.start(e.subjectEl,e.pageX,e.pageY),r.startDelay(e),r.minDistance||r.handleDistanceSurpassed(e)))},r.onPointerMove=function(e){if(r.isInteracting){if(r.emitter.trigger("pointermove",e),!r.isDistanceSurpassed){var t=r.minDistance,n=e.deltaX,o=e.deltaY;n*n+o*o>=t*t&&r.handleDistanceSurpassed(e)}r.isDragging&&("scroll"!==e.origEvent.type&&(r.mirror.handleMove(e.pageX,e.pageY),r.autoScroller.handleMove(e.pageX,e.pageY)),r.emitter.trigger("dragmove",e))}},r.onPointerUp=function(e){r.isInteracting&&(r.isInteracting=!1,Fe(document.body),ze(document.body),r.emitter.trigger("pointerup",e),r.isDragging&&(r.autoScroller.stop(),r.tryStopDrag(e)),r.delayTimeoutId&&(clearTimeout(r.delayTimeoutId),r.delayTimeoutId=null))};var o=r.pointer=new Ts(t);return o.emitter.on("pointerdown",r.onPointerDown),o.emitter.on("pointermove",r.onPointerMove),o.emitter.on("pointerup",r.onPointerUp),n&&(o.selector=n),r.mirror=new xs,r.autoScroller=new Hs,r}return n(t,e),t.prototype.destroy=function(){this.pointer.destroy(),this.onPointerUp({})},t.prototype.startDelay=function(e){var t=this;"number"==typeof this.delay?this.delayTimeoutId=setTimeout((function(){t.delayTimeoutId=null,t.handleDelayEnd(e)}),this.delay):this.handleDelayEnd(e)},t.prototype.handleDelayEnd=function(e){this.isDelayEnded=!0,this.tryStartDrag(e)},t.prototype.handleDistanceSurpassed=function(e){this.isDistanceSurpassed=!0,this.tryStartDrag(e)},t.prototype.tryStartDrag=function(e){this.isDelayEnded&&this.isDistanceSurpassed&&(this.pointer.wasTouchScroll&&!this.touchScrollAllowed||(this.isDragging=!0,this.mirrorNeedsRevert=!1,this.autoScroller.start(e.pageX,e.pageY,this.containerEl),this.emitter.trigger("dragstart",e),!1===this.touchScrollAllowed&&this.pointer.cancelTouchScroll()))},t.prototype.tryStopDrag=function(e){this.mirror.stop(this.mirrorNeedsRevert,this.stopDrag.bind(this,e))},t.prototype.stopDrag=function(e){this.isDragging=!1,this.emitter.trigger("dragend",e)},t.prototype.setIgnoreMove=function(e){this.pointer.shouldIgnoreMove=e},t.prototype.setMirrorIsVisible=function(e){this.mirror.setIsVisible(e)},t.prototype.setMirrorNeedsRevert=function(e){this.mirrorNeedsRevert=e},t.prototype.setAutoScrollEnabled=function(e){this.autoScroller.isEnabled=e},t}(oa),As=function(){function e(e){this.origRect=go(e),this.scrollCaches=mo(e).map((function(e){return new Is(e,!0)}))}return e.prototype.destroy=function(){for(var e=0,t=this.scrollCaches;e<t.length;e++){t[e].destroy()}},e.prototype.computeLeft=function(){for(var e=this.origRect.left,t=0,n=this.scrollCaches;t<n.length;t++){var r=n[t];e+=r.origScrollLeft-r.getScrollLeft()}return e},e.prototype.computeTop=function(){for(var e=this.origRect.top,t=0,n=this.scrollCaches;t<n.length;t++){var r=n[t];e+=r.origScrollTop-r.getScrollTop()}return e},e.prototype.isWithinClipping=function(e,t){for(var n,r,o={left:e,top:t},i=0,a=this.scrollCaches;i<a.length;i++){var s=a[i];if(n=s.getEventTarget(),r=void 0,"HTML"!==(r=n.tagName)&&"BODY"!==r&&!Zr(o,s.clientRect))return!1}return!0},e}();var Ls=function(){function e(e,t){var n=this;this.useSubjectCenter=!1,this.requireInitial=!0,this.initialHit=null,this.movingHit=null,this.finalHit=null,this.handlePointerDown=function(e){var t=n.dragging;n.initialHit=null,n.movingHit=null,n.finalHit=null,n.prepareHits(),n.processFirstCoord(e),n.initialHit||!n.requireInitial?(t.setIgnoreMove(!1),n.emitter.trigger("pointerdown",e)):t.setIgnoreMove(!0)},this.handleDragStart=function(e){n.emitter.trigger("dragstart",e),n.handleMove(e,!0)},this.handleDragMove=function(e){n.emitter.trigger("dragmove",e),n.handleMove(e)},this.handlePointerUp=function(e){n.releaseHits(),n.emitter.trigger("pointerup",e)},this.handleDragEnd=function(e){n.movingHit&&n.emitter.trigger("hitupdate",null,!0,e),n.finalHit=n.movingHit,n.movingHit=null,n.emitter.trigger("dragend",e)},this.droppableStore=t,e.emitter.on("pointerdown",this.handlePointerDown),e.emitter.on("dragstart",this.handleDragStart),e.emitter.on("dragmove",this.handleDragMove),e.emitter.on("pointerup",this.handlePointerUp),e.emitter.on("dragend",this.handleDragEnd),this.dragging=e,this.emitter=new Eo}return e.prototype.processFirstCoord=function(e){var t,n={left:e.pageX,top:e.pageY},r=n,o=e.subjectEl;o instanceof HTMLElement&&(r=Kr(r,t=go(o)));var i=this.initialHit=this.queryHitForOffset(r.left,r.top);if(i){if(this.useSubjectCenter&&t){var a=Xr(t,i.rect);a&&(r=$r(a))}this.coordAdjust=Jr(r,n)}else this.coordAdjust={left:0,top:0}},e.prototype.handleMove=function(e,t){var n=this.queryHitForOffset(e.pageX+this.coordAdjust.left,e.pageY+this.coordAdjust.top);!t&&Us(this.movingHit,n)||(this.movingHit=n,this.emitter.trigger("hitupdate",n,!1,e))},e.prototype.prepareHits=function(){this.offsetTrackers=bt(this.droppableStore,(function(e){return e.component.prepareHits(),new As(e.el)}))},e.prototype.releaseHits=function(){var e=this.offsetTrackers;for(var t in e)e[t].destroy();this.offsetTrackers={}},e.prototype.queryHitForOffset=function(e,t){var n=this.droppableStore,r=this.offsetTrackers,o=null;for(var i in n){var a=n[i].component,s=r[i];if(s&&s.isWithinClipping(e,t)){var l=s.computeLeft(),u=s.computeTop(),c=e-l,d=t-u,p=s.origRect,f=p.right-p.left,h=p.bottom-p.top;if(c>=0&&c<f&&d>=0&&d<h){var v=a.queryHit(c,d,f,h);v&&Yn(v.dateProfile.activeRange,v.dateSpan.range)&&(!o||v.layer>o.layer)&&(v.componentId=i,v.context=a.context,v.rect.left+=l,v.rect.right+=l,v.rect.top+=u,v.rect.bottom+=u,o=v)}}}return o},e}();function Us(e,t){return!e&&!t||Boolean(e)===Boolean(t)&&fr(e.dateSpan,t.dateSpan)}function Ws(e,t){for(var n,o,i={},a=0,s=t.pluginHooks.datePointTransforms;a<s.length;a++){var l=s[a];r(i,l(e,t))}return r(i,(n=e,{date:(o=t.dateEnv).toDate(n.range.start),dateStr:o.formatIso(n.range.start,{omitTime:n.allDay}),allDay:n.allDay})),i}var Vs=function(e){function t(t){var n=e.call(this,t)||this;n.handlePointerDown=function(e){var t=n.dragging,r=e.origEvent.target;t.setIgnoreMove(!n.component.isValidDateDownEl(r))},n.handleDragEnd=function(e){var t=n.component;if(!n.dragging.pointer.wasTouchScroll){var o=n.hitDragging,i=o.initialHit,a=o.finalHit;if(i&&a&&Us(i,a)){var s=t.context,l=r(r({},Ws(i.dateSpan,s)),{dayEl:i.dayEl,jsEvent:e.origEvent,view:s.viewApi||s.calendarApi.view});s.emitter.trigger("dateClick",l)}}},n.dragging=new Os(t.el),n.dragging.autoScroller.isEnabled=!1;var o=n.hitDragging=new Ls(n.dragging,na(t));return o.emitter.on("pointerdown",n.handlePointerDown),o.emitter.on("dragend",n.handleDragEnd),n}return n(t,e),t.prototype.destroy=function(){this.dragging.destroy()},t}(ea),Fs=function(e){function t(t){var n=e.call(this,t)||this;n.dragSelection=null,n.handlePointerDown=function(e){var t=n,r=t.component,o=t.dragging,i=r.context.options.selectable&&r.isValidDateDownEl(e.origEvent.target);o.setIgnoreMove(!i),o.delay=e.isTouch?function(e){var t=e.context.options,n=t.selectLongPressDelay;null==n&&(n=t.longPressDelay);return n}(r):null},n.handleDragStart=function(e){n.component.context.calendarApi.unselect(e)},n.handleHitUpdate=function(e,t){var o=n.component.context,i=null,a=!1;if(e){var s=n.hitDragging.initialHit;e.componentId===s.componentId&&n.isHitComboAllowed&&!n.isHitComboAllowed(s,e)||(i=function(e,t,n){var o=e.dateSpan,i=t.dateSpan,a=[o.range.start,o.range.end,i.range.start,i.range.end];a.sort(Ke);for(var s={},l=0,u=n;l<u.length;l++){var c=(0,u[l])(e,t);if(!1===c)return null;c&&r(s,c)}return s.range={start:a[0],end:a[3]},s.allDay=o.allDay,s}(s,e,o.pluginHooks.dateSelectionTransformers)),i&&Pa(i,e.dateProfile,o)||(a=!0,i=null)}i?o.dispatch({type:"SELECT_DATES",selection:i}):t||o.dispatch({type:"UNSELECT_DATES"}),a?Ue():We(),t||(n.dragSelection=i)},n.handlePointerUp=function(e){n.dragSelection&&(mr(n.dragSelection,e,n.component.context),n.dragSelection=null)};var o=t.component.context.options,i=n.dragging=new Os(t.el);i.touchScrollAllowed=!1,i.minDistance=o.selectMinDistance||0,i.autoScroller.isEnabled=o.dragScroll;var a=n.hitDragging=new Ls(n.dragging,na(t));return a.emitter.on("pointerdown",n.handlePointerDown),a.emitter.on("dragstart",n.handleDragStart),a.emitter.on("hitupdate",n.handleHitUpdate),a.emitter.on("pointerup",n.handlePointerUp),n}return n(t,e),t.prototype.destroy=function(){this.dragging.destroy()},t}(ea);var Bs=function(e){function t(n){var o=e.call(this,n)||this;o.subjectEl=null,o.subjectSeg=null,o.isDragging=!1,o.eventRange=null,o.relevantEvents=null,o.receivingContext=null,o.validMutation=null,o.mutatedRelevantEvents=null,o.handlePointerDown=function(e){var t=e.origEvent.target,n=o,r=n.component,i=n.dragging,a=i.mirror,s=r.context.options,l=r.context;o.subjectEl=e.subjectEl;var u=o.subjectSeg=Jn(e.subjectEl),c=(o.eventRange=u.eventRange).instance.instanceId;o.relevantEvents=bn(l.getCurrentData().eventStore,c),i.minDistance=e.isTouch?0:s.eventDragMinDistance,i.delay=e.isTouch&&c!==r.props.eventSelection?function(e){var t=e.context.options,n=t.eventLongPressDelay;null==n&&(n=t.longPressDelay);return n}(r):null,s.fixedMirrorParent?a.parentNode=s.fixedMirrorParent:a.parentNode=Se(t,".fc"),a.revertDuration=s.dragRevertDuration;var d=r.isValidSegDownEl(t)&&!Se(t,".fc-event-resizer");i.setIgnoreMove(!d),o.isDragging=d&&e.subjectEl.classList.contains("fc-event-draggable")},o.handleDragStart=function(e){var t=o.component.context,n=o.eventRange,r=n.instance.instanceId;e.isTouch?r!==o.component.props.eventSelection&&t.dispatch({type:"SELECT_EVENT",eventInstanceId:r}):t.dispatch({type:"UNSELECT_EVENT"}),o.isDragging&&(t.calendarApi.unselect(e),t.emitter.trigger("eventDragStart",{el:o.subjectEl,event:new xr(t,n.def,n.instance),jsEvent:e.origEvent,view:t.viewApi}))},o.handleHitUpdate=function(e,t){if(o.isDragging){var n=o.relevantEvents,r=o.hitDragging.initialHit,i=o.component.context,a=null,s=null,l=null,u=!1,c={affectedEvents:n,mutatedEvents:{defs:{},instances:{}},isEvent:!0};if(e){var d=(a=e.context).options;i===a||d.editable&&d.droppable?(s=function(e,t,n){var r=e.dateSpan,o=t.dateSpan,i=r.range.start,a=o.range.start,s={};r.allDay!==o.allDay&&(s.allDay=o.allDay,s.hasEnd=t.context.options.allDayMaintainDuration,o.allDay&&(i=lt(i)));var l=Fn(i,a,e.context.dateEnv,e.componentId===t.componentId?e.largeUnit:null);l.milliseconds&&(s.allDay=!1);for(var u={datesDelta:l,standardProps:s},c=0,d=n;c<d.length;c++){(0,d[c])(u,e,t)}return u}(r,e,a.getCurrentData().pluginHooks.eventDragMutationMassagers))&&(l=Sr(n,a.getCurrentData().eventUiBases,s,a),c.mutatedEvents=l,Ia(c,e.dateProfile,a)||(u=!0,s=null,l=null,c.mutatedEvents={defs:{},instances:{}})):a=null}o.displayDrag(a,c),u?Ue():We(),t||(i===a&&Us(r,e)&&(s=null),o.dragging.setMirrorNeedsRevert(!s),o.dragging.setMirrorIsVisible(!e||!Te(o.subjectEl).querySelector(".fc-event-mirror")),o.receivingContext=a,o.validMutation=s,o.mutatedRelevantEvents=l)}},o.handlePointerUp=function(){o.isDragging||o.cleanup()},o.handleDragEnd=function(e){if(o.isDragging){var t=o.component.context,n=t.viewApi,i=o,a=i.receivingContext,s=i.validMutation,l=o.eventRange.def,u=o.eventRange.instance,c=new xr(t,l,u),d=o.relevantEvents,p=o.mutatedRelevantEvents,f=o.hitDragging.finalHit;if(o.clearDrag(),t.emitter.trigger("eventDragStop",{el:o.subjectEl,event:c,jsEvent:e.origEvent,view:n}),s){if(a===t){var h=new xr(t,p.defs[l.defId],u?p.instances[u.instanceId]:null);t.dispatch({type:"MERGE_EVENTS",eventStore:p});for(var v={oldEvent:c,event:h,relatedEvents:Ir(p,t,u),revert:function(){t.dispatch({type:"MERGE_EVENTS",eventStore:d})}},g={},m=0,y=t.getCurrentData().pluginHooks.eventDropTransformers;m<y.length;m++){var E=y[m];r(g,E(s,t))}t.emitter.trigger("eventDrop",r(r(r({},v),g),{el:e.subjectEl,delta:s.datesDelta,jsEvent:e.origEvent,view:n})),t.emitter.trigger("eventChange",v)}else if(a){var S={event:c,relatedEvents:Ir(d,t,u),revert:function(){t.dispatch({type:"MERGE_EVENTS",eventStore:d})}};t.emitter.trigger("eventLeave",r(r({},S),{draggedEl:e.subjectEl,view:n})),t.dispatch({type:"REMOVE_EVENTS",eventStore:d}),t.emitter.trigger("eventRemove",S);var b=p.defs[l.defId],D=p.instances[u.instanceId],C=new xr(a,b,D);a.dispatch({type:"MERGE_EVENTS",eventStore:p});var w={event:C,relatedEvents:Ir(p,a,D),revert:function(){a.dispatch({type:"REMOVE_EVENTS",eventStore:p})}};a.emitter.trigger("eventAdd",w),e.isTouch&&a.dispatch({type:"SELECT_EVENT",eventInstanceId:u.instanceId}),a.emitter.trigger("drop",r(r({},Ws(f.dateSpan,a)),{draggedEl:e.subjectEl,jsEvent:e.origEvent,view:f.context.viewApi})),a.emitter.trigger("eventReceive",r(r({},w),{draggedEl:e.subjectEl,view:f.context.viewApi}))}}else t.emitter.trigger("_noEventDrop")}o.cleanup()};var i=o.component.context.options,a=o.dragging=new Os(n.el);a.pointer.selector=t.SELECTOR,a.touchScrollAllowed=!1,a.autoScroller.isEnabled=i.dragScroll;var s=o.hitDragging=new Ls(o.dragging,ra);return s.useSubjectCenter=n.useEventCenter,s.emitter.on("pointerdown",o.handlePointerDown),s.emitter.on("dragstart",o.handleDragStart),s.emitter.on("hitupdate",o.handleHitUpdate),s.emitter.on("pointerup",o.handlePointerUp),s.emitter.on("dragend",o.handleDragEnd),o}return n(t,e),t.prototype.destroy=function(){this.dragging.destroy()},t.prototype.displayDrag=function(e,t){var n=this.component.context,r=this.receivingContext;r&&r!==e&&(r===n?r.dispatch({type:"SET_EVENT_DRAG",state:{affectedEvents:t.affectedEvents,mutatedEvents:{defs:{},instances:{}},isEvent:!0}}):r.dispatch({type:"UNSET_EVENT_DRAG"})),e&&e.dispatch({type:"SET_EVENT_DRAG",state:t})},t.prototype.clearDrag=function(){var e=this.component.context,t=this.receivingContext;t&&t.dispatch({type:"UNSET_EVENT_DRAG"}),e!==t&&e.dispatch({type:"UNSET_EVENT_DRAG"})},t.prototype.cleanup=function(){this.subjectSeg=null,this.isDragging=!1,this.eventRange=null,this.relevantEvents=null,this.receivingContext=null,this.validMutation=null,this.mutatedRelevantEvents=null},t.SELECTOR=".fc-event-draggable, .fc-event-resizable",t}(ea);var zs=function(e){function t(t){var n=e.call(this,t)||this;n.draggingSegEl=null,n.draggingSeg=null,n.eventRange=null,n.relevantEvents=null,n.validMutation=null,n.mutatedRelevantEvents=null,n.handlePointerDown=function(e){var t=n.component,r=Jn(n.querySegEl(e)),o=n.eventRange=r.eventRange;n.dragging.minDistance=t.context.options.eventDragMinDistance,n.dragging.setIgnoreMove(!n.component.isValidSegDownEl(e.origEvent.target)||e.isTouch&&n.component.props.eventSelection!==o.instance.instanceId)},n.handleDragStart=function(e){var t=n.component.context,r=n.eventRange;n.relevantEvents=bn(t.getCurrentData().eventStore,n.eventRange.instance.instanceId);var o=n.querySegEl(e);n.draggingSegEl=o,n.draggingSeg=Jn(o),t.calendarApi.unselect(),t.emitter.trigger("eventResizeStart",{el:o,event:new xr(t,r.def,r.instance),jsEvent:e.origEvent,view:t.viewApi})},n.handleHitUpdate=function(e,t,r){var o=n.component.context,i=n.relevantEvents,a=n.hitDragging.initialHit,s=n.eventRange.instance,l=null,u=null,c=!1,d={affectedEvents:i,mutatedEvents:{defs:{},instances:{}},isEvent:!0};e&&(e.componentId===a.componentId&&n.isHitComboAllowed&&!n.isHitComboAllowed(a,e)||(l=function(e,t,n,r){var o=e.context.dateEnv,i=e.dateSpan.range.start,a=t.dateSpan.range.start,s=Fn(i,a,o,e.largeUnit);if(n){if(o.add(r.start,s)<r.end)return{startDelta:s}}else if(o.add(r.end,s)>r.start)return{endDelta:s};return null}(a,e,r.subjectEl.classList.contains("fc-event-resizer-start"),s.range)));l&&(u=Sr(i,o.getCurrentData().eventUiBases,l,o),d.mutatedEvents=u,Ia(d,e.dateProfile,o)||(c=!0,l=null,u=null,d.mutatedEvents=null)),u?o.dispatch({type:"SET_EVENT_RESIZE",state:d}):o.dispatch({type:"UNSET_EVENT_RESIZE"}),c?Ue():We(),t||(l&&Us(a,e)&&(l=null),n.validMutation=l,n.mutatedRelevantEvents=u)},n.handleDragEnd=function(e){var t=n.component.context,o=n.eventRange.def,i=n.eventRange.instance,a=new xr(t,o,i),s=n.relevantEvents,l=n.mutatedRelevantEvents;if(t.emitter.trigger("eventResizeStop",{el:n.draggingSegEl,event:a,jsEvent:e.origEvent,view:t.viewApi}),n.validMutation){var u=new xr(t,l.defs[o.defId],i?l.instances[i.instanceId]:null);t.dispatch({type:"MERGE_EVENTS",eventStore:l});var c={oldEvent:a,event:u,relatedEvents:Ir(l,t,i),revert:function(){t.dispatch({type:"MERGE_EVENTS",eventStore:s})}};t.emitter.trigger("eventResize",r(r({},c),{el:n.draggingSegEl,startDelta:n.validMutation.startDelta||Nt(0),endDelta:n.validMutation.endDelta||Nt(0),jsEvent:e.origEvent,view:t.viewApi})),t.emitter.trigger("eventChange",c)}else t.emitter.trigger("_noEventResize");n.draggingSeg=null,n.relevantEvents=null,n.validMutation=null};var o=t.component,i=n.dragging=new Os(t.el);i.pointer.selector=".fc-event-resizer",i.touchScrollAllowed=!1,i.autoScroller.isEnabled=o.context.options.dragScroll;var a=n.hitDragging=new Ls(n.dragging,na(t));return a.emitter.on("pointerdown",n.handlePointerDown),a.emitter.on("dragstart",n.handleDragStart),a.emitter.on("hitupdate",n.handleHitUpdate),a.emitter.on("dragend",n.handleDragEnd),n}return n(t,e),t.prototype.destroy=function(){this.dragging.destroy()},t.prototype.querySegEl=function(e){return Se(e.subjectEl,".fc-event")},t}(ea);var js=function(){function e(e){var t=this;this.context=e,this.isRecentPointerDateSelect=!1,this.matchesCancel=!1,this.matchesEvent=!1,this.onSelect=function(e){e.jsEvent&&(t.isRecentPointerDateSelect=!0)},this.onDocumentPointerDown=function(e){var n=t.context.options.unselectCancel,r=_e(e.origEvent);t.matchesCancel=!!Se(r,n),t.matchesEvent=!!Se(r,Bs.SELECTOR)},this.onDocumentPointerUp=function(e){var n=t.context,r=t.documentPointer,o=n.getCurrentData();if(!r.wasTouchScroll){if(o.dateSelection&&!t.isRecentPointerDateSelect){var i=n.options.unselectAuto;!i||i&&t.matchesCancel||n.calendarApi.unselect(e)}o.eventSelection&&!t.matchesEvent&&n.dispatch({type:"UNSELECT_EVENT"})}t.isRecentPointerDateSelect=!1};var n=this.documentPointer=new Ts(document);n.shouldIgnoreMove=!0,n.shouldWatchScroll=!1,n.emitter.on("pointerdown",this.onDocumentPointerDown),n.emitter.on("pointerup",this.onDocumentPointerUp),e.emitter.on("select",this.onSelect)}return e.prototype.destroy=function(){this.context.emitter.off("select",this.onSelect),this.documentPointer.destroy()},e}(),Gs={fixedMirrorParent:yn},qs={dateClick:yn,eventDragStart:yn,eventDragStop:yn,eventDrop:yn,eventResizeStart:yn,eventResizeStop:yn,eventResize:yn,drop:yn,eventReceive:yn,eventLeave:yn},Ys=function(){function e(e,t){var n=this;this.receivingContext=null,this.droppableEvent=null,this.suppliedDragMeta=null,this.dragMeta=null,this.handleDragStart=function(e){n.dragMeta=n.buildDragMeta(e.subjectEl)},this.handleHitUpdate=function(e,t,o){var i=n.hitDragging.dragging,a=null,s=null,l=!1,u={affectedEvents:{defs:{},instances:{}},mutatedEvents:{defs:{},instances:{}},isEvent:n.dragMeta.create};e&&(a=e.context,n.canDropElOnCalendar(o.subjectEl,a)&&(s=function(e,t,n){for(var o=r({},t.leftoverProps),i=0,a=n.pluginHooks.externalDefTransforms;i<a.length;i++){var s=a[i];r(o,s(e,t))}var l=On(o,n),u=l.refined,c=l.extra,d=Ln(u,c,t.sourceId,e.allDay,n.options.forceEventDuration||Boolean(t.duration),n),p=e.range.start;e.allDay&&t.startTime&&(p=n.dateEnv.add(p,t.startTime));var f=t.duration?n.dateEnv.add(p,t.duration):Er(e.allDay,p,n),h=mt(d.defId,{start:p,end:f});return{def:d,instance:h}}(e.dateSpan,n.dragMeta,a),u.mutatedEvents=Sn(s),(l=!Ia(u,e.dateProfile,a))&&(u.mutatedEvents={defs:{},instances:{}},s=null))),n.displayDrag(a,u),i.setMirrorIsVisible(t||!s||!document.querySelector(".fc-event-mirror")),l?Ue():We(),t||(i.setMirrorNeedsRevert(!s),n.receivingContext=a,n.droppableEvent=s)},this.handleDragEnd=function(e){var t=n,o=t.receivingContext,i=t.droppableEvent;if(n.clearDrag(),o&&i){var a=n.hitDragging.finalHit,s=a.context.viewApi,l=n.dragMeta;if(o.emitter.trigger("drop",r(r({},Ws(a.dateSpan,o)),{draggedEl:e.subjectEl,jsEvent:e.origEvent,view:s})),l.create){var u=Sn(i);o.dispatch({type:"MERGE_EVENTS",eventStore:u}),e.isTouch&&o.dispatch({type:"SELECT_EVENT",eventInstanceId:i.instance.instanceId}),o.emitter.trigger("eventReceive",{event:new xr(o,i.def,i.instance),relatedEvents:[],revert:function(){o.dispatch({type:"REMOVE_EVENTS",eventStore:u})},draggedEl:e.subjectEl,view:s})}}n.receivingContext=null,n.droppableEvent=null};var o=this.hitDragging=new Ls(e,ra);o.requireInitial=!1,o.emitter.on("dragstart",this.handleDragStart),o.emitter.on("hitupdate",this.handleHitUpdate),o.emitter.on("dragend",this.handleDragEnd),this.suppliedDragMeta=t}return e.prototype.buildDragMeta=function(e){return"object"==typeof this.suppliedDragMeta?sa(this.suppliedDragMeta):"function"==typeof this.suppliedDragMeta?sa(this.suppliedDragMeta(e)):sa((t=function(e,t){var n=ia.dataAttrPrefix,r=(n?n+"-":"")+t;return e.getAttribute("data-"+r)||""}(e,"event"))?JSON.parse(t):{create:!1});var t},e.prototype.displayDrag=function(e,t){var n=this.receivingContext;n&&n!==e&&n.dispatch({type:"UNSET_EVENT_DRAG"}),e&&e.dispatch({type:"SET_EVENT_DRAG",state:t})},e.prototype.clearDrag=function(){this.receivingContext&&this.receivingContext.dispatch({type:"UNSET_EVENT_DRAG"})},e.prototype.canDropElOnCalendar=function(e,t){var n=t.options.dropAccept;return"function"==typeof n?n.call(t.calendarApi,e):"string"!=typeof n||!n||Boolean(be(e,n))},e}();ia.dataAttrPrefix="";var Zs=function(){function e(e,t){var n=this;void 0===t&&(t={}),this.handlePointerDown=function(e){var t=n.dragging,r=n.settings,o=r.minDistance,i=r.longPressDelay;t.minDistance=null!=o?o:e.isTouch?0:cn.eventDragMinDistance,t.delay=e.isTouch?null!=i?i:cn.longPressDelay:0},this.handleDragStart=function(e){e.isTouch&&n.dragging.delay&&e.subjectEl.classList.contains("fc-event")&&n.dragging.mirror.getMirrorEl().classList.add("fc-event-selected")},this.settings=t;var r=this.dragging=new Os(e);r.touchScrollAllowed=!1,null!=t.itemSelector&&(r.pointer.selector=t.itemSelector),null!=t.appendTo&&(r.mirror.parentNode=t.appendTo),r.emitter.on("pointerdown",this.handlePointerDown),r.emitter.on("dragstart",this.handleDragStart),new Ys(r,t.eventData)}return e.prototype.destroy=function(){this.dragging.destroy()},e}(),Xs=function(e){function t(t){var n=e.call(this,t)||this;n.shouldIgnoreMove=!1,n.mirrorSelector="",n.currentMirrorEl=null,n.handlePointerDown=function(e){n.emitter.trigger("pointerdown",e),n.shouldIgnoreMove||n.emitter.trigger("dragstart",e)},n.handlePointerMove=function(e){n.shouldIgnoreMove||n.emitter.trigger("dragmove",e)},n.handlePointerUp=function(e){n.emitter.trigger("pointerup",e),n.shouldIgnoreMove||n.emitter.trigger("dragend",e)};var r=n.pointer=new Ts(t);return r.emitter.on("pointerdown",n.handlePointerDown),r.emitter.on("pointermove",n.handlePointerMove),r.emitter.on("pointerup",n.handlePointerUp),n}return n(t,e),t.prototype.destroy=function(){this.pointer.destroy()},t.prototype.setIgnoreMove=function(e){this.shouldIgnoreMove=e},t.prototype.setMirrorIsVisible=function(e){if(e)this.currentMirrorEl&&(this.currentMirrorEl.style.visibility="",this.currentMirrorEl=null);else{var t=this.mirrorSelector?document.querySelector(this.mirrorSelector):null;t&&(this.currentMirrorEl=t,t.style.visibility="hidden")}},t}(oa),Ks=function(){function e(e,t){var n=document;e===document||e instanceof Element?(n=e,t=t||{}):t=e||{};var r=this.dragging=new Xs(n);"string"==typeof t.itemSelector?r.pointer.selector=t.itemSelector:n===document&&(r.pointer.selector="[data-event]"),"string"==typeof t.mirrorSelector&&(r.mirrorSelector=t.mirrorSelector),new Ys(r,t.eventData)}return e.prototype.destroy=function(){this.dragging.destroy()},e}(),$s=zo({componentInteractions:[Vs,Fs,Bs,zs],calendarInteractions:[js],elementDraggingImpl:Os,optionRefiners:Gs,listenerRefiners:qs}),Js=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.headerElRef=ko(),t}return n(t,e),t.prototype.renderSimpleLayout=function(e,t){var n=this.props,r=this.context,o=[],i=Qa(r.options);return e&&o.push({type:"header",key:"header",isSticky:i,chunk:{elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}}),o.push({type:"body",key:"body",liquid:!0,chunk:{content:t}}),_o(ti,{viewSpec:r.viewSpec},(function(e,t){return _o("div",{ref:e,className:["fc-daygrid"].concat(t).join(" ")},_o(ts,{liquid:!n.isHeightAuto&&!n.forPrint,collapsibleWidth:n.forPrint,cols:[],sections:o}))}))},t.prototype.renderHScrollLayout=function(e,t,n,r){var o=this.context.pluginHooks.scrollGridImpl;if(!o)throw new Error("No ScrollGrid implementation");var i=this.props,a=this.context,s=!i.forPrint&&Qa(a.options),l=!i.forPrint&&es(a.options),u=[];return e&&u.push({type:"header",key:"header",isSticky:s,chunks:[{key:"main",elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}]}),u.push({type:"body",key:"body",liquid:!0,chunks:[{key:"main",content:t}]}),l&&u.push({type:"footer",key:"footer",isSticky:!0,chunks:[{key:"main",content:Ja}]}),_o(ti,{viewSpec:a.viewSpec},(function(e,t){return _o("div",{ref:e,className:["fc-daygrid"].concat(t).join(" ")},_o(o,{liquid:!i.isHeightAuto&&!i.forPrint,collapsibleWidth:i.forPrint,colGroups:[{cols:[{span:n,minWidth:r}]}],sections:u}))}))},t}(Bo);function Qs(e,t){for(var n=[],r=0;r<t;r+=1)n[r]=[];for(var o=0,i=e;o<i.length;o++){var a=i[o];n[a.row].push(a)}return n}function el(e,t){for(var n=[],r=0;r<t;r+=1)n[r]=[];for(var o=0,i=e;o<i.length;o++){var a=i[o];n[a.firstCol].push(a)}return n}function tl(e,t){var n=[];if(e){for(a=0;a<t;a+=1)n[a]={affectedInstances:e.affectedInstances,isEvent:e.isEvent,segs:[]};for(var r=0,o=e.segs;r<o.length;r++){var i=o[r];n[i.row].segs.push(i)}}else for(var a=0;a<t;a+=1)n[a]=null;return n}var nl=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.props,t=so(this.context,e.date);return _o(ss,{date:e.date,dateProfile:e.dateProfile,todayRange:e.todayRange,showDayNumber:e.showDayNumber,extraHookProps:e.extraHookProps,defaultContent:rl},(function(n,o){return(o||e.forceDayTop)&&_o("div",{className:"fc-daygrid-day-top",ref:n},_o("a",r({id:e.dayNumberId,className:"fc-daygrid-day-number"},t),o||_o(xo,null," ")))}))},t}(Uo);function rl(e){return e.dayNumberText}var ol=ln({hour:"numeric",minute:"2-digit",omitZeroMinute:!0,meridiem:"narrow"});function il(e){var t=e.eventRange.ui.display;return"list-item"===t||"auto"===t&&!e.eventRange.def.allDay&&e.firstCol===e.lastCol&&e.isStart&&e.isEnd}var al=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.props;return _o(rs,r({},e,{extraClassNames:["fc-daygrid-event","fc-daygrid-block-event","fc-h-event"],defaultTimeFormat:ol,defaultDisplayEventEnd:e.defaultDisplayEventEnd,disableResizing:!e.seg.eventRange.def.allDay}))},t}(Uo),sl=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context,n=t.options.eventTimeFormat||ol,o=ar(e.seg,n,t,!0,e.defaultDisplayEventEnd);return _o(ns,{seg:e.seg,timeText:o,defaultContent:ll,isDragging:e.isDragging,isResizing:!1,isDateSelecting:!1,isSelected:e.isSelected,isPast:e.isPast,isFuture:e.isFuture,isToday:e.isToday},(function(n,o,i,a){return _o("a",r({className:["fc-daygrid-event","fc-daygrid-dot-event"].concat(o).join(" "),ref:n},cr(e.seg,t)),a)}))},t}(Uo);function ll(e){return _o(xo,null,_o("div",{className:"fc-daygrid-event-dot",style:{borderColor:e.borderColor||e.backgroundColor}}),e.timeText&&_o("div",{className:"fc-event-time"},e.timeText),_o("div",{className:"fc-event-title"},e.event.title||_o(xo,null," ")))}var ul=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.compileSegs=qt(cl),t}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.compileSegs(e.singlePlacements),n=t.allSegs,o=t.invisibleSegs;return _o(ms,{dateProfile:e.dateProfile,todayRange:e.todayRange,allDayDate:e.allDayDate,moreCnt:e.moreCnt,allSegs:n,hiddenSegs:o,alignmentElRef:e.alignmentElRef,alignGridTop:e.alignGridTop,extraDateSpan:e.extraDateSpan,popoverContent:function(){var t=(e.eventDrag?e.eventDrag.affectedInstances:null)||(e.eventResize?e.eventResize.affectedInstances:null)||{};return _o(xo,null,n.map((function(n){var o=n.eventRange.instance.instanceId;return _o("div",{className:"fc-daygrid-event-harness",key:o,style:{visibility:t[o]?"hidden":""}},il(n)?_o(sl,r({seg:n,isDragging:!1,isSelected:o===e.eventSelection,defaultDisplayEventEnd:!1},sr(n,e.todayRange))):_o(al,r({seg:n,isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:o===e.eventSelection,defaultDisplayEventEnd:!1},sr(n,e.todayRange))))})))}},(function(e,t,n,o,i,a,s,l){return _o("a",r({ref:e,className:["fc-daygrid-more-link"].concat(t).join(" "),title:a,"aria-expanded":s,"aria-controls":l},He(i)),o)}))},t}(Uo);function cl(e){for(var t=[],n=[],r=0,o=e;r<o.length;r++){var i=o[r];t.push(i.seg),i.isVisible||n.push(i.seg)}return{allSegs:t,invisibleSegs:n}}var dl=ln({week:"narrow"}),pl=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.rootElRef=ko(),t.state={dayNumberId:xe()},t.handleRootEl=function(e){Fo(t.rootElRef,e),Fo(t.props.elRef,e)},t}return n(t,e),t.prototype.render=function(){var e=this,t=e.context,n=e.props,o=e.state,i=e.rootElRef,a=n.date,s=n.dateProfile,l=so(t,a,"week");return _o(us,{date:a,dateProfile:s,todayRange:n.todayRange,showDayNumber:n.showDayNumber,extraHookProps:n.extraHookProps,elRef:this.handleRootEl},(function(e,t,u,c){return _o("td",r({ref:e,role:"gridcell",className:["fc-daygrid-day"].concat(t,n.extraClassNames||[]).join(" ")},u,n.extraDataAttrs,n.showDayNumber?{"aria-labelledby":o.dayNumberId}:{}),_o("div",{className:"fc-daygrid-day-frame fc-scrollgrid-sync-inner",ref:n.innerElRef},n.showWeekNumber&&_o(fs,{date:a,defaultFormat:dl},(function(e,t,n,o){return _o("a",r({ref:e,className:["fc-daygrid-week-number"].concat(t).join(" ")},l),o)})),!c&&_o(nl,{date:a,dateProfile:s,showDayNumber:n.showDayNumber,dayNumberId:o.dayNumberId,forceDayTop:n.forceDayTop,todayRange:n.todayRange,extraHookProps:n.extraHookProps}),_o("div",{className:"fc-daygrid-day-events",ref:n.fgContentElRef},n.fgContent,_o("div",{className:"fc-daygrid-day-bottom",style:{marginTop:n.moreMarginTop}},_o(ul,{allDayDate:a,singlePlacements:n.singlePlacements,moreCnt:n.moreCnt,alignmentElRef:i,alignGridTop:!n.showDayNumber,extraDateSpan:n.extraDateSpan,dateProfile:n.dateProfile,eventSelection:n.eventSelection,eventDrag:n.eventDrag,eventResize:n.eventResize,todayRange:n.todayRange}))),_o("div",{className:"fc-daygrid-day-bg"},n.bgContent)))}))},t}(Bo);function fl(e,t,n,r,o,i,a){var s=new vl;s.allowReslicing=!0,s.strictOrder=r,!0===t||!0===n?(s.maxCoord=i,s.hiddenConsumes=!0):"number"==typeof t?s.maxStackCnt=t:"number"==typeof n&&(s.maxStackCnt=n,s.hiddenConsumes=!0);for(var l=[],u=[],c=0;c<e.length;c+=1){var d=o[(R=e[c]).eventRange.instance.instanceId];null!=d?l.push({index:c,thickness:d,span:{start:R.firstCol,end:R.lastCol+1}}):u.push(R)}for(var p=s.addSegs(l),f=function(e,t,n){for(var r=function(e,t){for(var n=[],r=0;r<t;r+=1)n.push([]);for(var o=0,i=e;o<i.length;o++){var a=i[o];for(r=a.span.start;r<a.span.end;r+=1)n[r].push(a)}return n}(e,n.length),o=[],i=[],a=[],s=0;s<n.length;s+=1){for(var l=r[s],u=[],c=0,d=0,p=0,f=l;p<f.length;p++){var h=t[(y=f[p]).index];u.push({seg:hl(h,s,s+1,n),isVisible:!0,isAbsolute:!1,absoluteTop:y.levelCoord,marginTop:y.levelCoord-c}),c=y.levelCoord+y.thickness}var v=[];c=0,d=0;for(var g=0,m=l;g<m.length;g++){h=t[(y=m[g]).index];var y,E=y.span.end-y.span.start>1,S=y.span.start===s;d+=y.levelCoord-c,c=y.levelCoord+y.thickness,E?(d+=y.thickness,S&&v.push({seg:hl(h,y.span.start,y.span.end,n),isVisible:!0,isAbsolute:!0,absoluteTop:y.levelCoord,marginTop:0})):S&&(v.push({seg:hl(h,y.span.start,y.span.end,n),isVisible:!0,isAbsolute:!1,absoluteTop:y.levelCoord,marginTop:d}),d=0)}o.push(u),i.push(v),a.push(d)}return{singleColPlacements:o,multiColPlacements:i,leftoverMargins:a}}(s.toRects(),e,a),h=f.singleColPlacements,v=f.multiColPlacements,g=f.leftoverMargins,m=[],y=[],E=0,S=u;E<S.length;E++){v[(R=S[E]).firstCol].push({seg:R,isVisible:!1,isAbsolute:!0,absoluteTop:0,marginTop:0});for(var b=R.firstCol;b<=R.lastCol;b+=1)h[b].push({seg:hl(R,b,b+1,a),isVisible:!1,isAbsolute:!1,absoluteTop:0,marginTop:0})}for(b=0;b<a.length;b+=1)m.push(0);for(var D=0,C=p;D<C.length;D++){var w=C[D],R=e[w.index],_=w.span;v[_.start].push({seg:hl(R,_.start,_.end,a),isVisible:!1,isAbsolute:!0,absoluteTop:0,marginTop:0});for(b=_.start;b<_.end;b+=1)m[b]+=1,h[b].push({seg:hl(R,b,b+1,a),isVisible:!1,isAbsolute:!1,absoluteTop:0,marginTop:0})}for(b=0;b<a.length;b+=1)y.push(g[b]);return{singleColPlacements:h,multiColPlacements:v,moreCnts:m,moreMarginTops:y}}function hl(e,t,n,o){if(e.firstCol===t&&e.lastCol===n-1)return e;var i=e.eventRange,a=i.range,s=jn(a,{start:o[t].date,end:tt(o[n-1].date,1)});return r(r({},e),{firstCol:t,lastCol:n-1,eventRange:{def:i.def,ui:r(r({},i.ui),{durationEditable:!1}),instance:i.instance,range:s},isStart:e.isStart&&s.start.valueOf()===a.start.valueOf(),isEnd:e.isEnd&&s.end.valueOf()===a.end.valueOf()})}var vl=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.hiddenConsumes=!1,t.forceHidden={},t}return n(t,e),t.prototype.addSegs=function(t){for(var n=this,r=e.prototype.addSegs.call(this,t),o=this.entriesByLevel,i=function(e){return!n.forceHidden[Zi(e)]},a=0;a<o.length;a+=1)o[a]=o[a].filter(i);return r},t.prototype.handleInvalidInsertion=function(t,n,o){var i=this.entriesByLevel,a=this.forceHidden,s=t.touchingEntry,l=t.touchingLevel,u=t.touchingLateral;if(this.hiddenConsumes&&s){var c=Zi(s);if(!a[c])if(this.allowReslicing){var d=r(r({},s),{span:$i(s.span,n.span)});a[Zi(d)]=!0,i[l][u]=d,this.splitEntry(s,n,o)}else a[c]=!0,o.push(s)}return e.prototype.handleInvalidInsertion.call(this,t,n,o)},t}(qi),gl=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.cellElRefs=new Fa,t.frameElRefs=new Fa,t.fgElRefs=new Fa,t.segHarnessRefs=new Fa,t.rootElRef=ko(),t.state={framePositions:null,maxContentHeight:null,eventInstanceHeights:{}},t}return n(t,e),t.prototype.render=function(){var e=this,t=this,n=t.props,r=t.state,o=t.context.options,i=n.cells.length,a=el(n.businessHourSegs,i),s=el(n.bgEventSegs,i),l=el(this.getHighlightSegs(),i),u=el(this.getMirrorSegs(),i),c=fl(tr(n.fgEventSegs,o.eventOrder),n.dayMaxEvents,n.dayMaxEventRows,o.eventOrderStrict,r.eventInstanceHeights,r.maxContentHeight,n.cells),d=c.singleColPlacements,p=c.multiColPlacements,f=c.moreCnts,h=c.moreMarginTops,v=n.eventDrag&&n.eventDrag.affectedInstances||n.eventResize&&n.eventResize.affectedInstances||{};return _o("tr",{ref:this.rootElRef,role:"row"},n.renderIntro&&n.renderIntro(),n.cells.map((function(t,r){var o=e.renderFgSegs(r,n.forPrint?d[r]:p[r],n.todayRange,v),i=e.renderFgSegs(r,function(e,t){if(!e.length)return[];var n=function(e){for(var t={},n=0,r=e;n<r.length;n++)for(var o=0,i=r[n];o<i.length;o++){var a=i[o];t[a.seg.eventRange.instance.instanceId]=a.absoluteTop}return t}(t);return e.map((function(e){return{seg:e,isVisible:!0,isAbsolute:!0,absoluteTop:n[e.eventRange.instance.instanceId],marginTop:0}}))}(u[r],p),n.todayRange,{},Boolean(n.eventDrag),Boolean(n.eventResize),!1);return _o(pl,{key:t.key,elRef:e.cellElRefs.createRef(t.key),innerElRef:e.frameElRefs.createRef(t.key),dateProfile:n.dateProfile,date:t.date,showDayNumber:n.showDayNumbers,showWeekNumber:n.showWeekNumbers&&0===r,forceDayTop:n.showWeekNumbers,todayRange:n.todayRange,eventSelection:n.eventSelection,eventDrag:n.eventDrag,eventResize:n.eventResize,extraHookProps:t.extraHookProps,extraDataAttrs:t.extraDataAttrs,extraClassNames:t.extraClassNames,extraDateSpan:t.extraDateSpan,moreCnt:f[r],moreMarginTop:h[r],singlePlacements:d[r],fgContentElRef:e.fgElRefs.createRef(t.key),fgContent:_o(xo,null,_o(xo,null,o),_o(xo,null,i)),bgContent:_o(xo,null,e.renderFillSegs(l[r],"highlight"),e.renderFillSegs(a[r],"non-business"),e.renderFillSegs(s[r],"bg-event"))})})))},t.prototype.componentDidMount=function(){this.updateSizing(!0)},t.prototype.componentDidUpdate=function(e,t){var n=this.props;this.updateSizing(!wt(e,n))},t.prototype.getHighlightSegs=function(){var e=this.props;return e.eventDrag&&e.eventDrag.segs.length?e.eventDrag.segs:e.eventResize&&e.eventResize.segs.length?e.eventResize.segs:e.dateSelectionSegs},t.prototype.getMirrorSegs=function(){var e=this.props;return e.eventResize&&e.eventResize.segs.length?e.eventResize.segs:[]},t.prototype.renderFgSegs=function(e,t,n,o,i,a,s){var l=this.context,u=this.props.eventSelection,c=this.state.framePositions,d=1===this.props.cells.length,p=i||a||s,f=[];if(c)for(var h=0,v=t;h<v.length;h++){var g=v[h],m=g.seg,y=m.eventRange.instance.instanceId,E=y+":"+e,S=g.isVisible&&!o[y],b=g.isAbsolute,D="",C="";b&&(l.isRtl?(C=0,D=c.lefts[m.lastCol]-c.lefts[m.firstCol]):(D=0,C=c.rights[m.firstCol]-c.rights[m.lastCol])),f.push(_o("div",{className:"fc-daygrid-event-harness"+(b?" fc-daygrid-event-harness-abs":""),key:E,ref:p?null:this.segHarnessRefs.createRef(E),style:{visibility:S?"":"hidden",marginTop:b?"":g.marginTop,top:b?g.absoluteTop:"",left:D,right:C}},il(m)?_o(sl,r({seg:m,isDragging:i,isSelected:y===u,defaultDisplayEventEnd:d},sr(m,n))):_o(al,r({seg:m,isDragging:i,isResizing:a,isDateSelecting:s,isSelected:y===u,defaultDisplayEventEnd:d},sr(m,n)))))}return f},t.prototype.renderFillSegs=function(e,t){var n=this.context.isRtl,i=this.props.todayRange,a=this.state.framePositions,s=[];if(a)for(var l=0,u=e;l<u.length;l++){var c=u[l],d=n?{right:0,left:a.lefts[c.lastCol]-a.lefts[c.firstCol]}:{left:0,right:a.rights[c.firstCol]-a.rights[c.lastCol]};s.push(_o("div",{key:ur(c.eventRange),className:"fc-daygrid-bg-harness",style:d},"bg-event"===t?_o(ds,r({seg:c},sr(c,i))):cs(t)))}return _o.apply(void 0,o([xo,{}],s))},t.prototype.updateSizing=function(e){var t=this.props,n=this.frameElRefs;if(!t.forPrint&&null!==t.clientWidth){if(e){var o=t.cells.map((function(e){return n.currentMap[e.key]}));if(o.length){var i=this.rootElRef.current;this.setState({framePositions:new So(i,o,!0,!1)})}}var a=this.state.eventInstanceHeights,s=this.queryEventInstanceHeights(),l=!0===t.dayMaxEvents||!0===t.dayMaxEventRows;this.safeSetState({eventInstanceHeights:r(r({},a),s),maxContentHeight:l?this.computeMaxContentHeight():null})}},t.prototype.queryEventInstanceHeights=function(){var e=this.segHarnessRefs.currentMap,t={};for(var n in e){var r=Math.round(e[n].getBoundingClientRect().height),o=n.split(":")[0];t[o]=Math.max(t[o]||0,r)}return t},t.prototype.computeMaxContentHeight=function(){var e=this.props.cells[0].key,t=this.cellElRefs.currentMap[e],n=this.fgElRefs.currentMap[e];return t.getBoundingClientRect().bottom-n.getBoundingClientRect().top},t.prototype.getCellEls=function(){var e=this.cellElRefs.currentMap;return this.props.cells.map((function(t){return e[t.key]}))},t}(Bo);gl.addStateEquality({eventInstanceHeights:wt});var ml=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.splitBusinessHourSegs=qt(Qs),t.splitBgEventSegs=qt(Qs),t.splitFgEventSegs=qt(Qs),t.splitDateSelectionSegs=qt(Qs),t.splitEventDrag=qt(tl),t.splitEventResize=qt(tl),t.rowRefs=new Fa,t.handleRootEl=function(e){t.rootEl=e,e?t.context.registerInteractiveComponent(t,{el:e,isHitComboAllowed:t.props.isHitComboAllowed}):t.context.unregisterInteractiveComponent(t)},t}return n(t,e),t.prototype.render=function(){var e=this,t=this.props,n=t.dateProfile,r=t.dayMaxEventRows,o=t.dayMaxEvents,i=t.expandRows,a=t.cells.length,s=this.splitBusinessHourSegs(t.businessHourSegs,a),l=this.splitBgEventSegs(t.bgEventSegs,a),u=this.splitFgEventSegs(t.fgEventSegs,a),c=this.splitDateSelectionSegs(t.dateSelectionSegs,a),d=this.splitEventDrag(t.eventDrag,a),p=this.splitEventResize(t.eventResize,a),f=!0===o||!0===r;return f&&!i&&(f=!1,r=null,o=null),_o("div",{className:["fc-daygrid-body",f?"fc-daygrid-body-balanced":"fc-daygrid-body-unbalanced",i?"":"fc-daygrid-body-natural"].join(" "),ref:this.handleRootEl,style:{width:t.clientWidth,minWidth:t.tableMinWidth}},_o(Ca,{unit:"day"},(function(f,h){return _o(xo,null,_o("table",{role:"presentation",className:"fc-scrollgrid-sync-table",style:{width:t.clientWidth,minWidth:t.tableMinWidth,height:i?t.clientHeight:""}},t.colGroupNode,_o("tbody",{role:"presentation"},t.cells.map((function(i,f){return _o(gl,{ref:e.rowRefs.createRef(f),key:i.length?i[0].date.toISOString():f,showDayNumbers:a>1,showWeekNumbers:t.showWeekNumbers,todayRange:h,dateProfile:n,cells:i,renderIntro:t.renderRowIntro,businessHourSegs:s[f],eventSelection:t.eventSelection,bgEventSegs:l[f].filter(yl),fgEventSegs:u[f],dateSelectionSegs:c[f],eventDrag:d[f],eventResize:p[f],dayMaxEvents:o,dayMaxEventRows:r,clientWidth:t.clientWidth,clientHeight:t.clientHeight,forPrint:t.forPrint})})))))})))},t.prototype.prepareHits=function(){this.rowPositions=new So(this.rootEl,this.rowRefs.collect().map((function(e){return e.getCellEls()[0]})),!1,!0),this.colPositions=new So(this.rootEl,this.rowRefs.currentMap[0].getCellEls(),!0,!1)},t.prototype.queryHit=function(e,t){var n=this.colPositions,o=this.rowPositions,i=n.leftToIndex(e),a=o.topToIndex(t);if(null!=a&&null!=i){var s=this.props.cells[a][i];return{dateProfile:this.props.dateProfile,dateSpan:r({range:this.getCellRange(a,i),allDay:!0},s.extraDateSpan),dayEl:this.getCellEl(a,i),rect:{left:n.lefts[i],right:n.rights[i],top:o.tops[a],bottom:o.bottoms[a]},layer:0}}return null},t.prototype.getCellEl=function(e,t){return this.rowRefs.currentMap[e].getCellEls()[t]},t.prototype.getCellRange=function(e,t){var n=this.props.cells[e][t].date;return{start:n,end:tt(n,1)}},t}(Bo);function yl(e){return e.eventRange.def.allDay}var El=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.forceDayIfListItem=!0,t}return n(t,e),t.prototype.sliceRange=function(e,t){return t.sliceRange(e)},t}(xa),Sl=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.slicer=new El,t.tableRef=ko(),t}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context;return _o(ml,r({ref:this.tableRef},this.slicer.sliceProps(e,e.dateProfile,e.nextDayThreshold,t,e.dayTableModel),{dateProfile:e.dateProfile,cells:e.dayTableModel.cells,colGroupNode:e.colGroupNode,tableMinWidth:e.tableMinWidth,renderRowIntro:e.renderRowIntro,dayMaxEvents:e.dayMaxEvents,dayMaxEventRows:e.dayMaxEventRows,showWeekNumbers:e.showWeekNumbers,expandRows:e.expandRows,headerAlignElRef:e.headerAlignElRef,clientWidth:e.clientWidth,clientHeight:e.clientHeight,forPrint:e.forPrint}))},t}(Bo),bl=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.buildDayTableModel=qt(Dl),t.headerRef=ko(),t.tableRef=ko(),t}return n(t,e),t.prototype.render=function(){var e=this,t=this.context,n=t.options,r=t.dateProfileGenerator,o=this.props,i=this.buildDayTableModel(o.dateProfile,r),a=n.dayHeaders&&_o(Ra,{ref:this.headerRef,dateProfile:o.dateProfile,dates:i.headerDates,datesRepDistinctDays:1===i.rowCnt}),s=function(t){return _o(Sl,{ref:e.tableRef,dateProfile:o.dateProfile,dayTableModel:i,businessHours:o.businessHours,dateSelection:o.dateSelection,eventStore:o.eventStore,eventUiBases:o.eventUiBases,eventSelection:o.eventSelection,eventDrag:o.eventDrag,eventResize:o.eventResize,nextDayThreshold:n.nextDayThreshold,colGroupNode:t.tableColGroupNode,tableMinWidth:t.tableMinWidth,dayMaxEvents:n.dayMaxEvents,dayMaxEventRows:n.dayMaxEventRows,showWeekNumbers:n.weekNumbers,expandRows:!o.isHeightAuto,headerAlignElRef:e.headerElRef,clientWidth:t.clientWidth,clientHeight:t.clientHeight,forPrint:o.forPrint})};return n.dayMinWidth?this.renderHScrollLayout(a,s,i.colCnt,n.dayMinWidth):this.renderSimpleLayout(a,s)},t}(Js);function Dl(e,t){var n=new Ta(e.renderRange,t);return new ka(n,/year|month|week/.test(e.currentRangeUnit))}var Cl=zo({initialView:"dayGridMonth",views:{dayGrid:{component:bl,dateProfileGeneratorClass:function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.buildRenderRange=function(t,n,r){var o,i=this.props.dateEnv,a=e.prototype.buildRenderRange.call(this,t,n,r),s=a.start,l=a.end;(/^(year|month)$/.test(n)&&(s=i.startOfWeek(s),(o=i.startOfWeek(l)).valueOf()!==l.valueOf()&&(l=et(o,1))),this.props.monthMode&&this.props.fixedWeekCount)&&(l=et(l,6-Math.ceil(rt(s,l))));return{start:s,end:l}},t}(ai)},dayGridDay:{type:"dayGrid",duration:{days:1}},dayGridWeek:{type:"dayGrid",duration:{weeks:1}},dayGridMonth:{type:"dayGrid",duration:{months:1},monthMode:!0,fixedWeekCount:!0}}}),wl=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.getKeyInfo=function(){return{allDay:{},timed:{}}},t.prototype.getKeysForDateSpan=function(e){return e.allDay?["allDay"]:["timed"]},t.prototype.getKeysForEventDef=function(e){return e.allDay?Kn(e)?["timed","allDay"]:["allDay"]:["timed"]},t}(to),Rl=ln({hour:"numeric",minute:"2-digit",omitZeroMinute:!0,meridiem:"short"});function _l(e){var t=["fc-timegrid-slot","fc-timegrid-slot-label",e.isLabeled?"fc-scrollgrid-shrink":"fc-timegrid-slot-minor"];return _o(Oo.Consumer,null,(function(n){if(!e.isLabeled)return _o("td",{className:t.join(" "),"data-time":e.isoTimeStr});var r=n.dateEnv,o=n.options,i=n.viewApi,a=null==o.slotLabelFormat?Rl:Array.isArray(o.slotLabelFormat)?ln(o.slotLabelFormat[0]):ln(o.slotLabelFormat),s={level:0,time:e.time,date:r.toDate(e.date),view:i,text:r.format(e.date,a)};return _o(Yo,{hookProps:s,classNames:o.slotLabelClassNames,content:o.slotLabelContent,defaultContent:Tl,didMount:o.slotLabelDidMount,willUnmount:o.slotLabelWillUnmount},(function(n,r,o,i){return _o("td",{ref:n,className:t.concat(r).join(" "),"data-time":e.isoTimeStr},_o("div",{className:"fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame"},_o("div",{className:"fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion",ref:o},i)))}))}))}function Tl(e){return e.text}var kl=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){return this.props.slatMetas.map((function(e){return _o("tr",{key:e.key},_o(_l,r({},e)))}))},t}(Uo),xl=ln({week:"short"}),Ml=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.allDaySplitter=new wl,t.headerElRef=ko(),t.rootElRef=ko(),t.scrollerElRef=ko(),t.state={slatCoords:null},t.handleScrollTopRequest=function(e){var n=t.scrollerElRef.current;n&&(n.scrollTop=e)},t.renderHeadAxis=function(e,n){void 0===n&&(n="");var o=t.context.options,i=t.props.dateProfile.renderRange,a=1===ot(i.start,i.end)?so(t.context,i.start,"week"):{};return o.weekNumbers&&"day"===e?_o(fs,{date:i.start,defaultFormat:xl},(function(e,t,o,i){return _o("th",{ref:e,"aria-hidden":!0,className:["fc-timegrid-axis","fc-scrollgrid-shrink"].concat(t).join(" ")},_o("div",{className:"fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid",style:{height:n}},_o("a",r({ref:o,className:"fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner"},a),i)))})):_o("th",{"aria-hidden":!0,className:"fc-timegrid-axis"},_o("div",{className:"fc-timegrid-axis-frame",style:{height:n}}))},t.renderTableRowAxis=function(e){var n=t.context,r=n.options,o=n.viewApi,i={text:r.allDayText,view:o};return _o(Yo,{hookProps:i,classNames:r.allDayClassNames,content:r.allDayContent,defaultContent:Il,didMount:r.allDayDidMount,willUnmount:r.allDayWillUnmount},(function(t,n,r,o){return _o("td",{ref:t,"aria-hidden":!0,className:["fc-timegrid-axis","fc-scrollgrid-shrink"].concat(n).join(" ")},_o("div",{className:"fc-timegrid-axis-frame fc-scrollgrid-shrink-frame"+(null==e?" fc-timegrid-axis-frame-liquid":""),style:{height:e}},_o("span",{className:"fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner",ref:r},o)))}))},t.handleSlatCoords=function(e){t.setState({slatCoords:e})},t}return n(t,e),t.prototype.renderSimpleLayout=function(e,t,n){var r=this.context,o=this.props,i=[],a=Qa(r.options);return e&&i.push({type:"header",key:"header",isSticky:a,chunk:{elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}}),t&&(i.push({type:"body",key:"all-day",chunk:{content:t}}),i.push({type:"body",key:"all-day-divider",outerContent:_o("tr",{role:"presentation",className:"fc-scrollgrid-section"},_o("td",{className:"fc-timegrid-divider "+r.theme.getClass("tableCellShaded")}))})),i.push({type:"body",key:"body",liquid:!0,expandRows:Boolean(r.options.expandRows),chunk:{scrollerElRef:this.scrollerElRef,content:n}}),_o(ti,{viewSpec:r.viewSpec,elRef:this.rootElRef},(function(e,t){return _o("div",{className:["fc-timegrid"].concat(t).join(" "),ref:e},_o(ts,{liquid:!o.isHeightAuto&&!o.forPrint,collapsibleWidth:o.forPrint,cols:[{width:"shrink"}],sections:i}))}))},t.prototype.renderHScrollLayout=function(e,t,n,r,o,i,a){var s=this,l=this.context.pluginHooks.scrollGridImpl;if(!l)throw new Error("No ScrollGrid implementation");var u=this.context,c=this.props,d=!c.forPrint&&Qa(u.options),p=!c.forPrint&&es(u.options),f=[];e&&f.push({type:"header",key:"header",isSticky:d,syncRowHeights:!0,chunks:[{key:"axis",rowContent:function(e){return _o("tr",{role:"presentation"},s.renderHeadAxis("day",e.rowSyncHeights[0]))}},{key:"cols",elRef:this.headerElRef,tableClassName:"fc-col-header",rowContent:e}]}),t&&(f.push({type:"body",key:"all-day",syncRowHeights:!0,chunks:[{key:"axis",rowContent:function(e){return _o("tr",{role:"presentation"},s.renderTableRowAxis(e.rowSyncHeights[0]))}},{key:"cols",content:t}]}),f.push({key:"all-day-divider",type:"body",outerContent:_o("tr",{role:"presentation",className:"fc-scrollgrid-section"},_o("td",{colSpan:2,className:"fc-timegrid-divider "+u.theme.getClass("tableCellShaded")}))}));var h=u.options.nowIndicator;return f.push({type:"body",key:"body",liquid:!0,expandRows:Boolean(u.options.expandRows),chunks:[{key:"axis",content:function(e){return _o("div",{className:"fc-timegrid-axis-chunk"},_o("table",{"aria-hidden":!0,style:{height:e.expandRows?e.clientHeight:""}},e.tableColGroupNode,_o("tbody",null,_o(kl,{slatMetas:i}))),_o("div",{className:"fc-timegrid-now-indicator-container"},_o(Ca,{unit:h?"minute":"day"},(function(e){var t=h&&a&&a.safeComputeTop(e);return"number"==typeof t?_o(is,{isAxis:!0,date:e},(function(e,n,r,o){return _o("div",{ref:e,className:["fc-timegrid-now-indicator-arrow"].concat(n).join(" "),style:{top:t}},o)})):null}))))}},{key:"cols",scrollerElRef:this.scrollerElRef,content:n}]}),p&&f.push({key:"footer",type:"footer",isSticky:!0,chunks:[{key:"axis",content:Ja},{key:"cols",content:Ja}]}),_o(ti,{viewSpec:u.viewSpec,elRef:this.rootElRef},(function(e,t){return _o("div",{className:["fc-timegrid"].concat(t).join(" "),ref:e},_o(l,{liquid:!c.isHeightAuto&&!c.forPrint,collapsibleWidth:!1,colGroups:[{width:"shrink",cols:[{width:"shrink"}]},{cols:[{span:r,minWidth:o}]}],sections:f}))}))},t.prototype.getAllDayMaxEventProps=function(){var e=this.context.options,t=e.dayMaxEvents,n=e.dayMaxEventRows;return!0!==t&&!0!==n||(t=void 0,n=5),{dayMaxEvents:t,dayMaxEventRows:n}},t}(Bo);function Il(e){return e.text}var Pl=function(){function e(e,t,n){this.positions=e,this.dateProfile=t,this.slotDuration=n}return e.prototype.safeComputeTop=function(e){var t=this.dateProfile;if(Zn(t.currentRange,e)){var n=lt(e),r=e.valueOf()-n.valueOf();if(r>=Ut(t.slotMinTime)&&r<Ut(t.slotMaxTime))return this.computeTimeTop(Nt(r))}return null},e.prototype.computeDateTop=function(e,t){return t||(t=lt(e)),this.computeTimeTop(Nt(e.valueOf()-t.valueOf()))},e.prototype.computeTimeTop=function(e){var t,n,r=this.positions,o=this.dateProfile,i=r.els.length,a=(e.milliseconds-Ut(o.slotMinTime))/Ut(this.slotDuration);return a=Math.max(0,a),a=Math.min(i,a),t=Math.floor(a),n=a-(t=Math.min(t,i-1)),r.tops[t]+r.getHeight(t)*n},e}(),Nl=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context,n=t.options,o=e.slatElRefs;return _o("tbody",null,e.slatMetas.map((function(i,a){var s={time:i.time,date:t.dateEnv.toDate(i.date),view:t.viewApi},l=["fc-timegrid-slot","fc-timegrid-slot-lane",i.isLabeled?"":"fc-timegrid-slot-minor"];return _o("tr",{key:i.key,ref:o.createRef(i.key)},e.axis&&_o(_l,r({},i)),_o(Yo,{hookProps:s,classNames:n.slotLaneClassNames,content:n.slotLaneContent,didMount:n.slotLaneDidMount,willUnmount:n.slotLaneWillUnmount},(function(e,t,n,r){return _o("td",{ref:e,className:l.concat(t).join(" "),"data-time":i.isoTimeStr},r)})))})))},t}(Uo),Hl=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.rootElRef=ko(),t.slatElRefs=new Fa,t}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context;return _o("div",{ref:this.rootElRef,className:"fc-timegrid-slots"},_o("table",{"aria-hidden":!0,className:t.theme.getClass("table"),style:{minWidth:e.tableMinWidth,width:e.clientWidth,height:e.minHeight}},e.tableColGroupNode,_o(Nl,{slatElRefs:this.slatElRefs,axis:e.axis,slatMetas:e.slatMetas})))},t.prototype.componentDidMount=function(){this.updateSizing()},t.prototype.componentDidUpdate=function(){this.updateSizing()},t.prototype.componentWillUnmount=function(){this.props.onCoords&&this.props.onCoords(null)},t.prototype.updateSizing=function(){var e,t=this.context,n=this.props;n.onCoords&&null!==n.clientWidth&&(this.rootElRef.current.offsetHeight&&n.onCoords(new Pl(new So(this.rootElRef.current,(e=this.slatElRefs.currentMap,n.slatMetas.map((function(t){return e[t.key]}))),!1,!0),this.props.dateProfile,t.options.slotDuration)))},t}(Uo);function Ol(e,t){var n,r=[];for(n=0;n<t;n+=1)r.push([]);if(e)for(n=0;n<e.length;n+=1)r[e[n].col].push(e[n]);return r}function Al(e,t){var n=[];if(e){for(a=0;a<t;a+=1)n[a]={affectedInstances:e.affectedInstances,isEvent:e.isEvent,segs:[]};for(var r=0,o=e.segs;r<o.length;r++){var i=o[r];n[i.col].segs.push(i)}}else for(var a=0;a<t;a+=1)n[a]=null;return n}var Ll=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.rootElRef=ko(),t}return n(t,e),t.prototype.render=function(){var e=this,t=this.props;return _o(ms,{allDayDate:null,moreCnt:t.hiddenSegs.length,allSegs:t.hiddenSegs,hiddenSegs:t.hiddenSegs,alignmentElRef:this.rootElRef,defaultContent:Ul,extraDateSpan:t.extraDateSpan,dateProfile:t.dateProfile,todayRange:t.todayRange,popoverContent:function(){return Xl(t.hiddenSegs,t)}},(function(n,r,o,i,a,s,l,u){return _o("a",{ref:function(t){Fo(n,t),Fo(e.rootElRef,t)},className:["fc-timegrid-more-link"].concat(r).join(" "),style:{top:t.top,bottom:t.bottom},onClick:a,title:s,"aria-expanded":l,"aria-controls":u},_o("div",{ref:o,className:"fc-timegrid-more-link-inner fc-sticky"},i))}))},t}(Uo);function Ul(e){return e.shortText}function Wl(e,t,n){var o=new qi;null!=t&&(o.strictOrder=t),null!=n&&(o.maxStackCnt=n);var i,a,s,l=Xi(o.addSegs(e)),u=function(e){var t=e.entriesByLevel,n=zl((function(e,t){return e+":"+t}),(function(o,i){var a=Vl(function(e,t,n){for(var r=e.levelCoords,o=e.entriesByLevel,i=o[t][n],a=r[t]+i.thickness,s=r.length,l=t;l<s&&r[l]<a;l+=1);for(;l<s;l+=1){for(var u=o[l],c=void 0,d=Qi(u,i.span.start,Yi),p=d[0]+d[1],f=p;(c=u[f])&&c.span.start<i.span.end;)f+=1;if(p<f)return{level:l,lateralStart:p,lateralEnd:f}}return null}(e,o,i),n),s=t[o][i];return[r(r({},s),{nextLevelNodes:a[0]}),s.thickness+a[1]]}));return Vl(t.length?{level:0,lateralStart:0,lateralEnd:t[0].length}:null,n)[0]}(o);return i=u,a=1,s=zl((function(e,t,n){return Zi(e)}),(function(e,t,n){var o,i=e.nextLevelNodes,l=e.thickness,u=l+n,c=l/u,d=[];if(i.length)for(var p=0,f=i;p<f.length;p++){var h=f[p];if(void 0===o)o=(v=s(h,t,u))[0],d.push(v[1]);else{var v=s(h,o,0);d.push(v[1])}}else o=a;var g=(o-t)*c;return[o-g,r(r({},e),{thickness:g,nextLevelNodes:d})]})),{segRects:function(e){var t=[],n=zl((function(e,t,n){return Zi(e)}),(function(e,n,i){var a=r(r({},e),{levelCoord:n,stackDepth:i,stackForward:0});return t.push(a),a.stackForward=o(e.nextLevelNodes,n+e.thickness,i+1)+1}));function o(e,t,r){for(var o=0,i=0,a=e;i<a.length;i++){var s=a[i];o=Math.max(n(s,t,r),o)}return o}return o(e,0,0),t}(u=i.map((function(e){return s(e,0,0)[1]}))),hiddenGroups:l}}function Vl(e,t){if(!e)return[[],0];for(var n=e.level,r=e.lateralStart,o=e.lateralEnd,i=r,a=[];i<o;)a.push(t(n,i)),i+=1;return a.sort(Fl),[a.map(Bl),a[0][1]]}function Fl(e,t){return t[1]-e[1]}function Bl(e){return e[0]}function zl(e,t){var n={};return function(){for(var r=[],o=0;o<arguments.length;o++)r[o]=arguments[o];var i=e.apply(void 0,r);return i in n?n[i]:n[i]=t.apply(void 0,r)}}function jl(e,t,n,r){void 0===n&&(n=null),void 0===r&&(r=0);var o=[];if(n)for(var i=0;i<e.length;i+=1){var a=e[i],s=n.computeDateTop(a.start,t),l=Math.max(s+(r||0),n.computeDateTop(a.end,t));o.push({start:Math.round(s),end:Math.round(l)})}return o}var Gl=ln({hour:"numeric",minute:"2-digit",meridiem:!1}),ql=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=["fc-timegrid-event","fc-v-event"];return this.props.isShort&&e.push("fc-timegrid-event-short"),_o(rs,r({},this.props,{defaultTimeFormat:Gl,extraClassNames:e}))},t}(Uo),Yl=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.props;return _o(ss,{date:e.date,dateProfile:e.dateProfile,todayRange:e.todayRange,extraHookProps:e.extraHookProps},(function(e,t){return t&&_o("div",{className:"fc-timegrid-col-misc",ref:e},t)}))},t}(Uo),Zl=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.sortEventSegs=qt(tr),t}return n(t,e),t.prototype.render=function(){var e=this,t=this.props,n=this.context,o=n.options.selectMirror,i=t.eventDrag&&t.eventDrag.segs||t.eventResize&&t.eventResize.segs||o&&t.dateSelectionSegs||[],a=t.eventDrag&&t.eventDrag.affectedInstances||t.eventResize&&t.eventResize.affectedInstances||{},s=this.sortEventSegs(t.fgEventSegs,n.options.eventOrder);return _o(us,{elRef:t.elRef,date:t.date,dateProfile:t.dateProfile,todayRange:t.todayRange,extraHookProps:t.extraHookProps},(function(n,l,u){return _o("td",r({ref:n,role:"gridcell",className:["fc-timegrid-col"].concat(l,t.extraClassNames||[]).join(" ")},u,t.extraDataAttrs),_o("div",{className:"fc-timegrid-col-frame"},_o("div",{className:"fc-timegrid-col-bg"},e.renderFillSegs(t.businessHourSegs,"non-business"),e.renderFillSegs(t.bgEventSegs,"bg-event"),e.renderFillSegs(t.dateSelectionSegs,"highlight")),_o("div",{className:"fc-timegrid-col-events"},e.renderFgSegs(s,a,!1,!1,!1)),_o("div",{className:"fc-timegrid-col-events"},e.renderFgSegs(i,{},Boolean(t.eventDrag),Boolean(t.eventResize),Boolean(o))),_o("div",{className:"fc-timegrid-now-indicator-container"},e.renderNowIndicator(t.nowIndicatorSegs)),_o(Yl,{date:t.date,dateProfile:t.dateProfile,todayRange:t.todayRange,extraHookProps:t.extraHookProps})))}))},t.prototype.renderFgSegs=function(e,t,n,r,o){var i=this.props;return i.forPrint?Xl(e,i):this.renderPositionedFgSegs(e,t,n,r,o)},t.prototype.renderPositionedFgSegs=function(e,t,n,o,i){var a=this,s=this.context.options,l=s.eventMaxStack,u=s.eventShortHeight,c=s.eventOrderStrict,d=s.eventMinHeight,p=this.props,f=p.date,h=p.slatCoords,v=p.eventSelection,g=p.todayRange,m=p.nowDate,y=n||o||i,E=function(e,t,n,r){for(var o=[],i=[],a=0;a<e.length;a+=1){var s=t[a];s?o.push({index:a,thickness:1,span:s}):i.push(e[a])}for(var l=Wl(o,n,r),u=l.segRects,c=l.hiddenGroups,d=[],p=0,f=u;p<f.length;p++){var h=f[p];d.push({seg:e[h.index],rect:h})}for(var v=0,g=i;v<g.length;v++){var m=g[v];d.push({seg:m,rect:null})}return{segPlacements:d,hiddenGroups:c}}(e,jl(e,f,h,d),c,l),S=E.segPlacements,b=E.hiddenGroups;return _o(xo,null,this.renderHiddenGroups(b,e),S.map((function(e){var s=e.seg,l=e.rect,c=s.eventRange.instance.instanceId,d=y||Boolean(!t[c]&&l),p=Kl(l&&l.span),f=!y&&l?a.computeSegHStyle(l):{left:0,right:0},h=Boolean(l)&&l.stackForward>0,E=Boolean(l)&&l.span.end-l.span.start<u;return _o("div",{className:"fc-timegrid-event-harness"+(h?" fc-timegrid-event-harness-inset":""),key:c,style:r(r({visibility:d?"":"hidden"},p),f)},_o(ql,r({seg:s,isDragging:n,isResizing:o,isDateSelecting:i,isSelected:c===v,isShort:E},sr(s,g,m))))})))},t.prototype.renderHiddenGroups=function(e,t){var n=this.props,r=n.extraDateSpan,o=n.dateProfile,i=n.todayRange,a=n.nowDate,s=n.eventSelection,l=n.eventDrag,u=n.eventResize;return _o(xo,null,e.map((function(e){var n,c,d=Kl(e.span),p=(n=e.entries,c=t,n.map((function(e){return c[e.index]})));return _o(Ll,{key:Ft(Ss(p)),hiddenSegs:p,top:d.top,bottom:d.bottom,extraDateSpan:r,dateProfile:o,todayRange:i,nowDate:a,eventSelection:s,eventDrag:l,eventResize:u})})))},t.prototype.renderFillSegs=function(e,t){var n=this.props,o=this.context,i=jl(e,n.date,n.slatCoords,o.options.eventMinHeight).map((function(o,i){var a=e[i];return _o("div",{key:ur(a.eventRange),className:"fc-timegrid-bg-harness",style:Kl(o)},"bg-event"===t?_o(ds,r({seg:a},sr(a,n.todayRange,n.nowDate))):cs(t))}));return _o(xo,null,i)},t.prototype.renderNowIndicator=function(e){var t=this.props,n=t.slatCoords,r=t.date;return n?e.map((function(e,t){return _o(is,{isAxis:!1,date:r,key:t},(function(t,o,i,a){return _o("div",{ref:t,className:["fc-timegrid-now-indicator-line"].concat(o).join(" "),style:{top:n.computeDateTop(e.start,r)}},a)}))})):null},t.prototype.computeSegHStyle=function(e){var t,n,r=this.context,o=r.isRtl,i=r.options.slotEventOverlap,a=e.levelCoord,s=e.levelCoord+e.thickness;i&&(s=Math.min(1,a+2*(s-a))),o?(t=1-s,n=a):(t=a,n=1-s);var l={zIndex:e.stackDepth+1,left:100*t+"%",right:100*n+"%"};return i&&!e.stackForward&&(l[o?"marginLeft":"marginRight"]=20),l},t}(Uo);function Xl(e,t){var n=t.todayRange,o=t.nowDate,i=t.eventSelection,a=t.eventDrag,s=t.eventResize,l=(a?a.affectedInstances:null)||(s?s.affectedInstances:null)||{};return _o(xo,null,e.map((function(e){var t=e.eventRange.instance.instanceId;return _o("div",{key:t,style:{visibility:l[t]?"hidden":""}},_o(ql,r({seg:e,isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:t===i,isShort:!1},sr(e,n,o))))})))}function Kl(e){return e?{top:e.start,bottom:-e.end}:{top:"",bottom:""}}var $l=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.splitFgEventSegs=qt(Ol),t.splitBgEventSegs=qt(Ol),t.splitBusinessHourSegs=qt(Ol),t.splitNowIndicatorSegs=qt(Ol),t.splitDateSelectionSegs=qt(Ol),t.splitEventDrag=qt(Al),t.splitEventResize=qt(Al),t.rootElRef=ko(),t.cellElRefs=new Fa,t}return n(t,e),t.prototype.render=function(){var e=this,t=this.props,n=this.context.options.nowIndicator&&t.slatCoords&&t.slatCoords.safeComputeTop(t.nowDate),r=t.cells.length,o=this.splitFgEventSegs(t.fgEventSegs,r),i=this.splitBgEventSegs(t.bgEventSegs,r),a=this.splitBusinessHourSegs(t.businessHourSegs,r),s=this.splitNowIndicatorSegs(t.nowIndicatorSegs,r),l=this.splitDateSelectionSegs(t.dateSelectionSegs,r),u=this.splitEventDrag(t.eventDrag,r),c=this.splitEventResize(t.eventResize,r);return _o("div",{className:"fc-timegrid-cols",ref:this.rootElRef},_o("table",{role:"presentation",style:{minWidth:t.tableMinWidth,width:t.clientWidth}},t.tableColGroupNode,_o("tbody",{role:"presentation"},_o("tr",{role:"row"},t.axis&&_o("td",{"aria-hidden":!0,className:"fc-timegrid-col fc-timegrid-axis"},_o("div",{className:"fc-timegrid-col-frame"},_o("div",{className:"fc-timegrid-now-indicator-container"},"number"==typeof n&&_o(is,{isAxis:!0,date:t.nowDate},(function(e,t,r,o){return _o("div",{ref:e,className:["fc-timegrid-now-indicator-arrow"].concat(t).join(" "),style:{top:n}},o)}))))),t.cells.map((function(n,r){return _o(Zl,{key:n.key,elRef:e.cellElRefs.createRef(n.key),dateProfile:t.dateProfile,date:n.date,nowDate:t.nowDate,todayRange:t.todayRange,extraHookProps:n.extraHookProps,extraDataAttrs:n.extraDataAttrs,extraClassNames:n.extraClassNames,extraDateSpan:n.extraDateSpan,fgEventSegs:o[r],bgEventSegs:i[r],businessHourSegs:a[r],nowIndicatorSegs:s[r],dateSelectionSegs:l[r],eventDrag:u[r],eventResize:c[r],slatCoords:t.slatCoords,eventSelection:t.eventSelection,forPrint:t.forPrint})}))))))},t.prototype.componentDidMount=function(){this.updateCoords()},t.prototype.componentDidUpdate=function(){this.updateCoords()},t.prototype.updateCoords=function(){var e,t=this.props;t.onColCoords&&null!==t.clientWidth&&t.onColCoords(new So(this.rootElRef.current,(e=this.cellElRefs.currentMap,t.cells.map((function(t){return e[t.key]}))),!0,!1))},t}(Uo);var Jl=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.processSlotOptions=qt(Ql),t.state={slatCoords:null},t.handleRootEl=function(e){e?t.context.registerInteractiveComponent(t,{el:e,isHitComboAllowed:t.props.isHitComboAllowed}):t.context.unregisterInteractiveComponent(t)},t.handleScrollRequest=function(e){var n=t.props.onScrollTopRequest,r=t.state.slatCoords;if(n&&r){if(e.time){var o=r.computeTimeTop(e.time);(o=Math.ceil(o))&&(o+=1),n(o)}return!0}return!1},t.handleColCoords=function(e){t.colCoords=e},t.handleSlatCoords=function(e){t.setState({slatCoords:e}),t.props.onSlatCoords&&t.props.onSlatCoords(e)},t}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.state;return _o("div",{className:"fc-timegrid-body",ref:this.handleRootEl,style:{width:e.clientWidth,minWidth:e.tableMinWidth}},_o(Hl,{axis:e.axis,dateProfile:e.dateProfile,slatMetas:e.slatMetas,clientWidth:e.clientWidth,minHeight:e.expandRows?e.clientHeight:"",tableMinWidth:e.tableMinWidth,tableColGroupNode:e.axis?e.tableColGroupNode:null,onCoords:this.handleSlatCoords}),_o($l,{cells:e.cells,axis:e.axis,dateProfile:e.dateProfile,businessHourSegs:e.businessHourSegs,bgEventSegs:e.bgEventSegs,fgEventSegs:e.fgEventSegs,dateSelectionSegs:e.dateSelectionSegs,eventSelection:e.eventSelection,eventDrag:e.eventDrag,eventResize:e.eventResize,todayRange:e.todayRange,nowDate:e.nowDate,nowIndicatorSegs:e.nowIndicatorSegs,clientWidth:e.clientWidth,tableMinWidth:e.tableMinWidth,tableColGroupNode:e.tableColGroupNode,slatCoords:t.slatCoords,onColCoords:this.handleColCoords,forPrint:e.forPrint}))},t.prototype.componentDidMount=function(){this.scrollResponder=this.context.createScrollResponder(this.handleScrollRequest)},t.prototype.componentDidUpdate=function(e){this.scrollResponder.update(e.dateProfile!==this.props.dateProfile)},t.prototype.componentWillUnmount=function(){this.scrollResponder.detach()},t.prototype.queryHit=function(e,t){var n=this.context,o=n.dateEnv,i=n.options,a=this.colCoords,s=this.props.dateProfile,l=this.state.slatCoords,u=this.processSlotOptions(this.props.slotDuration,i.snapDuration),c=u.snapDuration,d=u.snapsPerSlot,p=a.leftToIndex(e),f=l.positions.topToIndex(t);if(null!=p&&null!=f){var h=this.props.cells[p],v=l.positions.tops[f],g=l.positions.getHeight(f),m=(t-v)/g,y=f*d+Math.floor(m*d),E=this.props.cells[p].date,S=Ot(s.slotMinTime,At(c,y)),b=o.add(E,S),D=o.add(b,c);return{dateProfile:s,dateSpan:r({range:{start:b,end:D},allDay:!1},h.extraDateSpan),dayEl:a.els[p],rect:{left:a.lefts[p],right:a.rights[p],top:v,bottom:v+g},layer:0}}return null},t}(Bo);function Ql(e,t){var n=t||e,r=Wt(e,n);return null===r&&(n=e,r=1),{snapDuration:n,snapsPerSlot:r}}var eu=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.sliceRange=function(e,t){for(var n=[],r=0;r<t.length;r+=1){var o=jn(e,t[r]);o&&n.push({start:o.start,end:o.end,isStart:o.start.valueOf()===e.start.valueOf(),isEnd:o.end.valueOf()===e.end.valueOf(),col:r})}return n},t}(xa),tu=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.buildDayRanges=qt(nu),t.slicer=new eu,t.timeColsRef=ko(),t}return n(t,e),t.prototype.render=function(){var e=this,t=this.props,n=this.context,o=t.dateProfile,i=t.dayTableModel,a=n.options.nowIndicator,s=this.buildDayRanges(i,o,n.dateEnv);return _o(Ca,{unit:a?"minute":"day"},(function(l,u){return _o(Jl,r({ref:e.timeColsRef},e.slicer.sliceProps(t,o,null,n,s),{forPrint:t.forPrint,axis:t.axis,dateProfile:o,slatMetas:t.slatMetas,slotDuration:t.slotDuration,cells:i.cells[0],tableColGroupNode:t.tableColGroupNode,tableMinWidth:t.tableMinWidth,clientWidth:t.clientWidth,clientHeight:t.clientHeight,expandRows:t.expandRows,nowDate:l,nowIndicatorSegs:a&&e.slicer.sliceNowDate(l,n,s),todayRange:u,onScrollTopRequest:t.onScrollTopRequest,onSlatCoords:t.onSlatCoords}))}))},t}(Bo);function nu(e,t,n){for(var r=[],o=0,i=e.headerDates;o<i.length;o++){var a=i[o];r.push({start:n.add(a,t.slotMinTime),end:n.add(a,t.slotMaxTime)})}return r}var ru=[{hours:1},{minutes:30},{minutes:15},{seconds:30},{seconds:15}];function ou(e,t,n,r,o){for(var i=new Date(0),a=e,s=Nt(0),l=n||function(e){var t,n,r;for(t=ru.length-1;t>=0;t-=1)if(null!==(r=Wt(n=Nt(ru[t]),e))&&r>1)return n;return e}(r),u=[];Ut(a)<Ut(t);){var c=o.add(i,a),d=null!==Wt(s,l);u.push({date:c,time:a,key:c.toISOString(),isoTimeStr:zt(c),isLabeled:d}),a=Ot(a,r),s=Ot(s,r)}return u}var iu=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.buildTimeColsModel=qt(au),t.buildSlatMetas=qt(ou),t}return n(t,e),t.prototype.render=function(){var e=this,t=this.context,n=t.options,o=t.dateEnv,i=t.dateProfileGenerator,a=this.props,s=a.dateProfile,l=this.buildTimeColsModel(s,i),u=this.allDaySplitter.splitProps(a),c=this.buildSlatMetas(s.slotMinTime,s.slotMaxTime,n.slotLabelInterval,n.slotDuration,o),d=n.dayMinWidth,p=!d,f=d,h=n.dayHeaders&&_o(Ra,{dates:l.headerDates,dateProfile:s,datesRepDistinctDays:!0,renderIntro:p?this.renderHeadAxis:null}),v=!1!==n.allDaySlot&&function(t){return _o(Sl,r({},u.allDay,{dateProfile:s,dayTableModel:l,nextDayThreshold:n.nextDayThreshold,tableMinWidth:t.tableMinWidth,colGroupNode:t.tableColGroupNode,renderRowIntro:p?e.renderTableRowAxis:null,showWeekNumbers:!1,expandRows:!1,headerAlignElRef:e.headerElRef,clientWidth:t.clientWidth,clientHeight:t.clientHeight,forPrint:a.forPrint},e.getAllDayMaxEventProps()))},g=function(t){return _o(tu,r({},u.timed,{dayTableModel:l,dateProfile:s,axis:p,slotDuration:n.slotDuration,slatMetas:c,forPrint:a.forPrint,tableColGroupNode:t.tableColGroupNode,tableMinWidth:t.tableMinWidth,clientWidth:t.clientWidth,clientHeight:t.clientHeight,onSlatCoords:e.handleSlatCoords,expandRows:t.expandRows,onScrollTopRequest:e.handleScrollTopRequest}))};return f?this.renderHScrollLayout(h,v,g,l.colCnt,d,c,this.state.slatCoords):this.renderSimpleLayout(h,v,g)},t}(Ml);function au(e,t){var n=new Ta(e.renderRange,t);return new ka(n,!1)}var su=zo({initialView:"timeGridWeek",optionRefiners:{allDaySlot:Boolean},views:{timeGrid:{component:iu,usesMinMaxTime:!0,allDaySlot:!0,slotDuration:"00:30:00",slotEventOverlap:!0},timeGridDay:{type:"timeGrid",duration:{days:1}},timeGridWeek:{type:"timeGrid",duration:{weeks:1}}}}),lu=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.state={textId:xe()},t}return n(t,e),t.prototype.render=function(){var e=this.context,t=e.theme,n=e.dateEnv,o=e.options,i=e.viewApi,a=this.props,s=a.cellId,l=a.dayDate,u=a.todayRange,c=this.state.textId,d=ro(l,u),p=o.listDayFormat?n.format(l,o.listDayFormat):"",f=o.listDaySideFormat?n.format(l,o.listDaySideFormat):"",h=r({date:n.toDate(l),view:i,textId:c,text:p,sideText:f,navLinkAttrs:so(this.context,l),sideNavLinkAttrs:so(this.context,l,"day",!1)},d),v=["fc-list-day"].concat(oo(d,t));return _o(Yo,{hookProps:h,classNames:o.dayHeaderClassNames,content:o.dayHeaderContent,defaultContent:uu,didMount:o.dayHeaderDidMount,willUnmount:o.dayHeaderWillUnmount},(function(e,n,r,o){return _o("tr",{ref:e,className:v.concat(n).join(" "),"data-date":Bt(l)},_o("th",{scope:"colgroup",colSpan:3,id:s,"aria-labelledby":c},_o("div",{className:"fc-list-day-cushion "+t.getClass("tableCellShaded"),ref:r},o)))}))},t}(Uo);function uu(e){return _o(xo,null,e.text&&_o("a",r({id:e.textId,className:"fc-list-day-text"},e.navLinkAttrs),e.text),e.sideText&&_o("a",r({"aria-hidden":!0,className:"fc-list-day-side-text"},e.sideNavLinkAttrs),e.sideText))}var cu=ln({hour:"numeric",minute:"2-digit",meridiem:"short"}),du=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t.prototype.render=function(){var e=this.props,t=this.context,n=e.seg,o=e.timeHeaderId,i=e.eventHeaderId,a=e.dateHeaderId,s=t.options.eventTimeFormat||cu;return _o(ns,{seg:n,timeText:"",disableDragging:!0,disableResizing:!0,defaultContent:function(){return function(e,t){var n=cr(e,t);return _o("a",r({},n),e.eventRange.def.title)}(n,t)},isPast:e.isPast,isFuture:e.isFuture,isToday:e.isToday,isSelected:e.isSelected,isDragging:e.isDragging,isResizing:e.isResizing,isDateSelecting:e.isDateSelecting},(function(e,r,l,u,c){return _o("tr",{className:["fc-list-event",c.event.url?"fc-event-forced-url":""].concat(r).join(" "),ref:e},function(e,t,n,r,o){var i=n.options;if(!1!==i.displayEventTime){var a=e.eventRange.def,s=e.eventRange.instance,l=!1,u=void 0;if(a.allDay?l=!0:Vn(e.eventRange.range)?e.isStart?u=ar(e,t,n,null,null,s.range.start,e.end):e.isEnd?u=ar(e,t,n,null,null,e.start,s.range.end):l=!0:u=ar(e,t,n),l){var c={text:n.options.allDayText,view:n.viewApi};return _o(Yo,{hookProps:c,classNames:i.allDayClassNames,content:i.allDayContent,defaultContent:pu,didMount:i.allDayDidMount,willUnmount:i.allDayWillUnmount},(function(e,t,n,i){return _o("td",{ref:e,headers:r+" "+o,className:["fc-list-event-time"].concat(t).join(" ")},i)}))}return _o("td",{className:"fc-list-event-time"},u)}return null}(n,s,t,o,a),_o("td",{"aria-hidden":!0,className:"fc-list-event-graphic"},_o("span",{className:"fc-list-event-dot",style:{borderColor:c.borderColor||c.backgroundColor}})),_o("td",{ref:l,headers:i+" "+a,className:"fc-list-event-title"},u))}))},t}(Uo);function pu(e){return e.text}var fu=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.computeDateVars=qt(vu),t.eventStoreToSegs=qt(t._eventStoreToSegs),t.state={timeHeaderId:xe(),eventHeaderId:xe(),dateHeaderIdRoot:xe()},t.setRootEl=function(e){e?t.context.registerInteractiveComponent(t,{el:e}):t.context.unregisterInteractiveComponent(t)},t}return n(t,e),t.prototype.render=function(){var e=this,t=this.props,n=this.context,r=["fc-list",n.theme.getClass("table"),!1!==n.options.stickyHeaderDates?"fc-list-sticky":""],o=this.computeDateVars(t.dateProfile),i=o.dayDates,a=o.dayRanges,s=this.eventStoreToSegs(t.eventStore,t.eventUiBases,a);return _o(ti,{viewSpec:n.viewSpec,elRef:this.setRootEl},(function(n,o){return _o("div",{ref:n,className:r.concat(o).join(" ")},_o(Va,{liquid:!t.isHeightAuto,overflowX:t.isHeightAuto?"visible":"hidden",overflowY:t.isHeightAuto?"visible":"auto"},s.length>0?e.renderSegList(s,i):e.renderEmptyMessage()))}))},t.prototype.renderEmptyMessage=function(){var e=this.context,t=e.options,n=e.viewApi,r={text:t.noEventsText,view:n};return _o(Yo,{hookProps:r,classNames:t.noEventsClassNames,content:t.noEventsContent,defaultContent:hu,didMount:t.noEventsDidMount,willUnmount:t.noEventsWillUnmount},(function(e,t,n,r){return _o("div",{className:["fc-list-empty"].concat(t).join(" "),ref:e},_o("div",{className:"fc-list-empty-cushion",ref:n},r))}))},t.prototype.renderSegList=function(e,t){var n=this.context,o=n.theme,i=n.options,a=this.state,s=a.timeHeaderId,l=a.eventHeaderId,u=a.dateHeaderIdRoot,c=function(e){var t,n,r=[];for(t=0;t<e.length;t+=1)(r[(n=e[t]).dayIndex]||(r[n.dayIndex]=[])).push(n);return r}(e);return _o(Ca,{unit:"day"},(function(e,n){for(var a=[],d=0;d<c.length;d+=1){var p=c[d];if(p){var f=Bt(t[d]),h=u+"-"+f;a.push(_o(lu,{key:f,cellId:h,dayDate:t[d],todayRange:n}));for(var v=0,g=p=tr(p,i.eventOrder);v<g.length;v++){var m=g[v];a.push(_o(du,r({key:f+":"+m.eventRange.instance.instanceId,seg:m,isDragging:!1,isResizing:!1,isDateSelecting:!1,isSelected:!1,timeHeaderId:s,eventHeaderId:l,dateHeaderId:h},sr(m,n,e))))}}}return _o("table",{className:"fc-list-table "+o.getClass("table")},_o("thead",null,_o("tr",null,_o("th",{scope:"col",id:s},i.timeHint),_o("th",{scope:"col","aria-hidden":!0}),_o("th",{scope:"col",id:l},i.eventHint))),_o("tbody",null,a))}))},t.prototype._eventStoreToSegs=function(e,t,n){return this.eventRangesToSegs(Xn(e,t,this.props.dateProfile.activeRange,this.context.options.nextDayThreshold).fg,n)},t.prototype.eventRangesToSegs=function(e,t){for(var n=[],r=0,o=e;r<o.length;r++){var i=o[r];n.push.apply(n,this.eventRangeToSegs(i,t))}return n},t.prototype.eventRangeToSegs=function(e,t){var n,r,o,i=this.context.dateEnv,a=this.context.options.nextDayThreshold,s=e.range,l=e.def.allDay,u=[];for(n=0;n<t.length;n+=1)if((r=jn(s,t[n]))&&(o={component:this,eventRange:e,start:r.start,end:r.end,isStart:e.isStart&&r.start.valueOf()===s.start.valueOf(),isEnd:e.isEnd&&r.end.valueOf()===s.end.valueOf(),dayIndex:n},u.push(o),!o.isEnd&&!l&&n+1<t.length&&s.end<i.add(t[n+1].start,a))){o.end=s.end,o.isEnd=!0;break}return u},t}(Bo);function hu(e){return e.text}function vu(e){for(var t=lt(e.renderRange.start),n=e.renderRange.end,r=[],o=[];t<n;)r.push(t),o.push({start:t,end:tt(t,1)}),t=tt(t,1);return{dayDates:r,dayRanges:o}}function gu(e){return!1===e?null:ln(e)}var mu=zo({optionRefiners:{listDayFormat:gu,listDaySideFormat:gu,noEventsClassNames:yn,noEventsContent:yn,noEventsDidMount:yn,noEventsWillUnmount:yn},views:{list:{component:fu,buttonTextKey:"list",listDayFormat:{month:"long",day:"numeric",year:"numeric"}},listDay:{type:"list",duration:{days:1},listDayFormat:{weekday:"long"}},listWeek:{type:"list",duration:{weeks:1},listDayFormat:{weekday:"long"},listDaySideFormat:{month:"long",day:"numeric",year:"numeric"}},listMonth:{type:"list",duration:{month:1},listDaySideFormat:{weekday:"long"}},listYear:{type:"list",duration:{year:1},listDaySideFormat:{weekday:"long"}}}}),yu=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t}(wo);yu.prototype.classes={root:"fc-theme-bootstrap",table:"table-bordered",tableCellShaded:"table-active",buttonGroup:"btn-group",button:"btn btn-primary",buttonActive:"active",popover:"popover",popoverHeader:"popover-header",popoverContent:"popover-body"},yu.prototype.baseIconClass="fa",yu.prototype.iconClasses={close:"fa-times",prev:"fa-chevron-left",next:"fa-chevron-right",prevYear:"fa-angle-double-left",nextYear:"fa-angle-double-right"},yu.prototype.rtlIconClasses={prev:"fa-chevron-right",next:"fa-chevron-left",prevYear:"fa-angle-double-right",nextYear:"fa-angle-double-left"},yu.prototype.iconOverrideOption="bootstrapFontAwesome",yu.prototype.iconOverrideCustomButtonOption="bootstrapFontAwesome",yu.prototype.iconOverridePrefix="fa-";var Eu=zo({themeClasses:{bootstrap:yu}}),Su=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return n(t,e),t}(wo);Su.prototype.classes={root:"fc-theme-bootstrap5",tableCellShaded:"fc-theme-bootstrap5-shaded",buttonGroup:"btn-group",button:"btn btn-primary",buttonActive:"active",popover:"popover",popoverHeader:"popover-header",popoverContent:"popover-body"},Su.prototype.baseIconClass="bi",Su.prototype.iconClasses={close:"bi-x-lg",prev:"bi-chevron-left",next:"bi-chevron-right",prevYear:"bi-chevron-double-left",nextYear:"bi-chevron-double-right"},Su.prototype.rtlIconClasses={prev:"bi-chevron-right",next:"bi-chevron-left",prevYear:"bi-chevron-double-right",nextYear:"bi-chevron-double-left"},Su.prototype.iconOverrideOption="buttonIcons",Su.prototype.iconOverrideCustomButtonOption="icon",Su.prototype.iconOverridePrefix="bi-";var bu=zo({themeClasses:{bootstrap5:Su}}),Du="https://www.googleapis.com/calendar/v3/calendars";var Cu=zo({eventSourceDefs:[{parseMeta:function(e){var t=e.googleCalendarId;return!t&&e.url&&(t=function(e){var t;if(/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(e))return e;if((t=/^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(e))||(t=/^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(e)))return decodeURIComponent(t[1]);return null}(e.url)),t?{googleCalendarId:t,googleCalendarApiKey:e.googleCalendarApiKey,googleCalendarApiBase:e.googleCalendarApiBase,extraParams:e.extraParams}:null},fetch:function(e,t,n){var o=e.context,i=o.dateEnv,a=o.options,s=e.eventSource.meta,l=s.googleCalendarApiKey||a.googleCalendarApiKey;if(l){var u=function(e){var t=e.googleCalendarApiBase;t||(t=Du);return t+"/"+encodeURIComponent(e.googleCalendarId)+"/events"}(s),c=s.extraParams,d="function"==typeof c?c():c,p=function(e,t,n,o){var i,a,s;o.canComputeOffset?(a=o.formatIso(e.start),s=o.formatIso(e.end)):(a=tt(e.start,-1).toISOString(),s=tt(e.end,1).toISOString());i=r(r({},n||{}),{key:t,timeMin:a,timeMax:s,singleEvents:!0,maxResults:9999}),"local"!==o.timeZone&&(i.timeZone=o.timeZone);return i}(e.range,l,d,i);_i("GET",u,p,(function(e,r){var o,i;e.error?n({message:"Google Calendar API: "+e.error.message,errors:e.error.errors,xhr:r}):t({rawEvents:(o=e.items,i=p.timeZone,o.map((function(e){return function(e,t){var n=e.htmlLink||null;n&&t&&(n=function(e,t){return e.replace(/(\?.*?)?(#|$)/,(function(e,n,r){return(n?n+"&":"?")+t+r}))}(n,"ctz="+t));return{id:e.id,title:e.summary,start:e.start.dateTime||e.start.date,end:e.end.dateTime||e.end.date,url:n,location:e.location,description:e.description,attachments:e.attachments||[],extendedProps:(e.extendedProperties||{}).shared||{}}}(e,i)}))),xhr:r})}),(function(e,t){n({message:e,xhr:t})}))}else n({message:"Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/"})}}],optionRefiners:{googleCalendarApiKey:String},eventSourceRefiners:{googleCalendarApiKey:String,googleCalendarId:String,googleCalendarApiBase:String,extraParams:yn}});return xi.push($s,Cl,su,mu,Eu,bu,Cu),e.BASE_OPTION_DEFAULTS=cn,e.BASE_OPTION_REFINERS=un,e.BaseComponent=Uo,e.BgEvent=ds,e.BootstrapTheme=yu,e.Calendar=Cs,e.CalendarApi=kr,e.CalendarContent=fa,e.CalendarDataManager=Ni,e.CalendarDataProvider=ji,e.CalendarRoot=ga,e.Component=Ro,e.ContentHook=Xo,e.CustomContentRenderContext=Zo,e.DateComponent=Bo,e.DateEnv=Lr,e.DateProfileGenerator=ai,e.DayCellContent=ss,e.DayCellRoot=us,e.DayGridView=bl,e.DayHeader=Ra,e.DaySeriesModel=Ta,e.DayTable=Sl,e.DayTableModel=ka,e.DayTableSlicer=El,e.DayTimeCols=tu,e.DayTimeColsSlicer=eu,e.DayTimeColsView=iu,e.DelayedRunner=Mi,e.Draggable=Zs,e.ElementDragging=oa,e.ElementScrollController=Do,e.Emitter=Eo,e.EventApi=xr,e.EventRoot=ns,e.EventSourceApi=ye,e.FeaturefulElementDragging=Os,e.Fragment=xo,e.Interaction=ea,e.ListView=fu,e.MoreLinkRoot=ms,e.MountHook=$o,e.NamedTimeZoneImpl=Gi,e.NowIndicatorRoot=is,e.NowTimer=Ca,e.PointerDragging=Ts,e.PositionCache=So,e.RefMap=Fa,e.RenderHook=Yo,e.ScrollController=bo,e.ScrollResponder=Ho,e.Scroller=Va,e.SegHierarchy=qi,e.SimpleScrollGrid=ts,e.Slicer=xa,e.Splitter=to,e.StandardEvent=rs,e.Table=ml,e.TableDateCell=Sa,e.TableDowCell=Da,e.TableView=Js,e.Theme=wo,e.ThirdPartyDraggable=Ks,e.TimeCols=Jl,e.TimeColsSlatsCoords=Pl,e.TimeColsView=Ml,e.ViewApi=Cr,e.ViewContextType=Oo,e.ViewRoot=ti,e.WeekNumberRoot=fs,e.WindowScrollController=Co,e.addDays=tt,e.addDurations=Ot,e.addMs=nt,e.addWeeks=et,e.allowContextMenu=ze,e.allowSelection=Fe,e.applyMutationToEventStore=Sr,e.applyStyle=we,e.applyStyleProp=Re,e.asCleanDays=function(e){return e.years||e.months||e.milliseconds?0:e.days},e.asRoughMinutes=function(e){return Ut(e)/6e4},e.asRoughMs=Ut,e.asRoughSeconds=function(e){return Ut(e)/1e3},e.binarySearch=Qi,e.buildClassNameNormalizer=Jo,e.buildDayRanges=nu,e.buildDayTableModel=Dl,e.buildEntryKey=Zi,e.buildEventApis=Ir,e.buildEventRangeKey=ur,e.buildHashFromArray=function(e,t){for(var n={},r=0;r<e.length;r+=1){var o=t(e[r],r);n[o[0]]=o[1]}return n},e.buildIsoString=Ft,e.buildNavLinkAttrs=so,e.buildSegCompareObj=nr,e.buildSegTimeText=ar,e.buildSlatMetas=ou,e.buildTimeColsModel=au,e.collectFromHash=kt,e.combineEventUis=xn,e.compareByFieldSpec=qe,e.compareByFieldSpecs=Ge,e.compareNumbers=Ke,e.compareObjs=_t,e.computeEarliestSegStart=Ss,e.computeEdges=ho,e.computeFallbackHeaderFormat=ma,e.computeHeightAndMargins=function(e){return e.getBoundingClientRect().height+function(e){var t=window.getComputedStyle(e);return parseInt(t.marginTop,10)+parseInt(t.marginBottom,10)}(e)},e.computeInnerRect=vo,e.computeRect=go,e.computeSegDraggable=rr,e.computeSegEndResizable=ir,e.computeSegStartResizable=or,e.computeShrinkWidth=Ba,e.computeSmallestCellWidth=Je,e.computeVisibleDayRange=Wn,e.config=ia,e.constrainPoint=Kr,e.createAriaClickAttrs=He,e.createContext=Mo,e.createDuration=Nt,e.createElement=_o,e.createEmptyEventStore=Dn,e.createEventInstance=mt,e.createEventUi=kn,e.createFormatter=ln,e.createPlugin=zo,e.createPortal=Io,e.createRef=ko,e.diffDates=Fn,e.diffDayAndTime=it,e.diffDays=ot,e.diffPoints=Jr,e.diffWeeks=rt,e.diffWholeDays=st,e.diffWholeWeeks=at,e.disableCursor=Ue,e.elementClosest=Se,e.elementMatches=be,e.enableCursor=We,e.eventTupleToStore=Sn,e.filterEventStoreDefs=wn,e.filterHash=St,e.findDirectChildren=function(e,t){for(var n=e instanceof HTMLElement?[e]:e,r=[],o=0;o<n.length;o+=1)for(var i=n[o].children,a=0;a<i.length;a+=1){var s=i[a];t&&!be(s,t)||r.push(s)}return r},e.findElements=De,e.flexibleCompare=Ye,e.flushSync=Po,e.formatDate=function(e,t){void 0===t&&(t={});var n=jr(t),r=ln(t),o=n.createMarkerMeta(e);return o?n.format(o.marker,r,{forcedTzo:o.forcedTzo}):""},e.formatDayString=Bt,e.formatIsoTimeString=zt,e.formatRange=function(e,t,n){var r=jr("object"==typeof n&&n?n:{}),o=ln(n),i=r.createMarkerMeta(e),a=r.createMarkerMeta(t);return i&&a?r.formatRange(i.marker,a.marker,o,{forcedStartTzo:i.forcedTzo,forcedEndTzo:a.forcedTzo,isEndExclusive:n.isEndExclusive,defaultSeparator:cn.defaultRangeSeparator}):""},e.getAllowYScrolling=ja,e.getCanVGrowWithinCell=Qr,e.getClippingParents=mo,e.getDateMeta=ro,e.getDayClassNames=oo,e.getDefaultEventEnd=Er,e.getElRoot=Te,e.getElSeg=Jn,e.getEntrySpanEnd=Yi,e.getEventClassNames=lr,e.getEventTargetViaRoot=_e,e.getIsRtlScrollbarOnLeft=co,e.getRectCenter=$r,e.getRelevantEvents=bn,e.getScrollGridClassNames=Ka,e.getScrollbarWidths=po,e.getSectionClassNames=$a,e.getSectionHasLiquidHeight=za,e.getSegAnchorAttrs=cr,e.getSegMeta=sr,e.getSlotClassNames=function(e,t){var n=["fc-slot","fc-slot-"+Qe[e.dow]];return e.isDisabled?n.push("fc-slot-disabled"):(e.isToday&&(n.push("fc-slot-today"),n.push(t.getClass("today"))),e.isPast&&n.push("fc-slot-past"),e.isFuture&&n.push("fc-slot-future")),n},e.getStickyFooterScrollbar=es,e.getStickyHeaderDates=Qa,e.getUnequalProps=Rt,e.getUniqueDomId=xe,e.globalLocales=Ur,e.globalPlugins=xi,e.greatestDurationDenominator=Vt,e.groupIntersectingEntries=Xi,e.guid=Le,e.hasBgRendering=Kn,e.hasShrinkWidth=Xa,e.identity=yn,e.interactionSettingsStore=ra,e.interactionSettingsToStore=na,e.intersectRanges=jn,e.intersectRects=Xr,e.intersectSpans=$i,e.isArraysEqual=Gt,e.isColPropsEqual=qa,e.isDateSelectionValid=Pa,e.isDateSpansEqual=fr,e.isInt=$e,e.isInteractionValid=Ia,e.isMultiDayRange=Vn,e.isPropsEqual=wt,e.isPropsValid=Ha,e.isValidDate=vt,e.joinSpans=Ki,e.listenBySelector=Ie,e.mapHash=bt,e.memoize=qt,e.memoizeArraylike=function(e,t,n){var r=this,o=[],i=[];return function(a){for(var s=o.length,l=a.length,u=0;u<s;u+=1)if(a[u]){if(!Gt(o[u],a[u])){n&&n(i[u]);var c=e.apply(r,a[u]);t&&t(c,i[u])||(i[u]=c)}}else n&&n(i[u]);for(;u<l;u+=1)i[u]=e.apply(r,a[u]);return o=a,i.splice(l),i}},e.memoizeHashlike=function(e,t,n){var r=this,o={},i={};return function(a){var s={};for(var l in a)if(i[l])if(Gt(o[l],a[l]))s[l]=i[l];else{n&&n(i[l]);var u=e.apply(r,a[l]);s[l]=t&&t(u,i[l])?i[l]:u}else s[l]=e.apply(r,a[l]);return o=a,i=s,s}},e.memoizeObjArg=Yt,e.mergeEventStores=Cn,e.multiplyDuration=At,e.padStart=Ze,e.parseBusinessHours=Yr,e.parseClassNames=Rn,e.parseDragMeta=sa,e.parseEventDef=Ln,e.parseFieldSpecs=je,e.parseMarker=Ar,e.pointInsideRect=Zr,e.preventContextMenu=Be,e.preventDefault=Me,e.preventSelection=Ve,e.rangeContainsMarker=Zn,e.rangeContainsRange=Yn,e.rangesEqual=Gn,e.rangesIntersect=qn,e.refineEventDef=On,e.refineProps=mn,e.removeElement=Ee,e.removeExact=function(e,t){for(var n=0,r=0;r<e.length;)e[r]===t?(e.splice(r,1),n+=1):r+=1;return n},e.render=To,e.renderChunkContent=Ga,e.renderFill=cs,e.renderMicroColGroup=Ya,e.renderScrollShim=Ja,e.requestJson=_i,e.sanitizeShrinkWidth=Za,e.setElSeg=$n,e.setRef=Fo,e.sliceEventStore=Xn,e.sliceEvents=function(e,t){return Xn(e.eventStore,e.eventUiBases,e.dateProfile.activeRange,t?e.nextDayThreshold:null).fg},e.sortEventSegs=tr,e.startOfDay=lt,e.translateRect=function(e,t,n){return{left:e.left+t,right:e.right+t,top:e.top+n,bottom:e.bottom+n}},e.triggerDateSelect=mr,e.unmountComponentAtNode=No,e.unpromisify=yo,e.version="5.11.3",e.whenTransitionDone=Ne,e.wholeDivideDurations=Wt,Object.defineProperty(e,"__esModule",{value:!0}),e}({});
\ No newline at end of file