懒羊羊
2023-08-30 1ac2bc1590406d9babec036e154d8d08f34a6aa1
提交 | 用户 | 时间
1ac2bc 1 /*!
2 FullCalendar Core Package v4.3.1
3 Docs & License: https://fullcalendar.io/
4 (c) 2019 Adam Shaw
5 */
6
7 (function (global, factory) {
8     typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
9     typeof define === 'function' && define.amd ? define(['exports'], factory) :
10     (global = global || self, factory(global.FullCalendar = {}));
11 }(this, function (exports) { 'use strict';
12
13     // Creating
14     // ----------------------------------------------------------------------------------------------------------------
15     var elementPropHash = {
16         className: true,
17         colSpan: true,
18         rowSpan: true
19     };
20     var containerTagHash = {
21         '<tr': 'tbody',
22         '<td': 'tr'
23     };
24     function createElement(tagName, attrs, content) {
25         var el = document.createElement(tagName);
26         if (attrs) {
27             for (var attrName in attrs) {
28                 if (attrName === 'style') {
29                     applyStyle(el, attrs[attrName]);
30                 }
31                 else if (elementPropHash[attrName]) {
32                     el[attrName] = attrs[attrName];
33                 }
34                 else {
35                     el.setAttribute(attrName, attrs[attrName]);
36                 }
37             }
38         }
39         if (typeof content === 'string') {
40             el.innerHTML = content; // shortcut. no need to process HTML in any way
41         }
42         else if (content != null) {
43             appendToElement(el, content);
44         }
45         return el;
46     }
47     function htmlToElement(html) {
48         html = html.trim();
49         var container = document.createElement(computeContainerTag(html));
50         container.innerHTML = html;
51         return container.firstChild;
52     }
53     function htmlToElements(html) {
54         return Array.prototype.slice.call(htmlToNodeList(html));
55     }
56     function htmlToNodeList(html) {
57         html = html.trim();
58         var container = document.createElement(computeContainerTag(html));
59         container.innerHTML = html;
60         return container.childNodes;
61     }
62     // assumes html already trimmed and tag names are lowercase
63     function computeContainerTag(html) {
64         return containerTagHash[html.substr(0, 3) // faster than using regex
65         ] || 'div';
66     }
67     function appendToElement(el, content) {
68         var childNodes = normalizeContent(content);
69         for (var i = 0; i < childNodes.length; i++) {
70             el.appendChild(childNodes[i]);
71         }
72     }
73     function prependToElement(parent, content) {
74         var newEls = normalizeContent(content);
75         var afterEl = parent.firstChild || null; // if no firstChild, will append to end, but that's okay, b/c there were no children
76         for (var i = 0; i < newEls.length; i++) {
77             parent.insertBefore(newEls[i], afterEl);
78         }
79     }
80     function insertAfterElement(refEl, content) {
81         var newEls = normalizeContent(content);
82         var afterEl = refEl.nextSibling || null;
83         for (var i = 0; i < newEls.length; i++) {
84             refEl.parentNode.insertBefore(newEls[i], afterEl);
85         }
86     }
87     function normalizeContent(content) {
88         var els;
89         if (typeof content === 'string') {
90             els = htmlToElements(content);
91         }
92         else if (content instanceof Node) {
93             els = [content];
94         }
95         else { // Node[] or NodeList
96             els = Array.prototype.slice.call(content);
97         }
98         return els;
99     }
100     function removeElement(el) {
101         if (el.parentNode) {
102             el.parentNode.removeChild(el);
103         }
104     }
105     // Querying
106     // ----------------------------------------------------------------------------------------------------------------
107     // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
108     var matchesMethod = Element.prototype.matches ||
109         Element.prototype.matchesSelector ||
110         Element.prototype.msMatchesSelector;
111     var closestMethod = Element.prototype.closest || function (selector) {
112         // polyfill
113         var el = this;
114         if (!document.documentElement.contains(el)) {
115             return null;
116         }
117         do {
118             if (elementMatches(el, selector)) {
119                 return el;
120             }
121             el = el.parentElement || el.parentNode;
122         } while (el !== null && el.nodeType === 1);
123         return null;
124     };
125     function elementClosest(el, selector) {
126         return closestMethod.call(el, selector);
127     }
128     function elementMatches(el, selector) {
129         return matchesMethod.call(el, selector);
130     }
131     // accepts multiple subject els
132     // returns a real array. good for methods like forEach
133     function findElements(container, selector) {
134         var containers = container instanceof HTMLElement ? [container] : container;
135         var allMatches = [];
136         for (var i = 0; i < containers.length; i++) {
137             var matches = containers[i].querySelectorAll(selector);
138             for (var j = 0; j < matches.length; j++) {
139                 allMatches.push(matches[j]);
140             }
141         }
142         return allMatches;
143     }
144     // accepts multiple subject els
145     // only queries direct child elements
146     function findChildren(parent, selector) {
147         var parents = parent instanceof HTMLElement ? [parent] : parent;
148         var allMatches = [];
149         for (var i = 0; i < parents.length; i++) {
150             var childNodes = parents[i].children; // only ever elements
151             for (var j = 0; j < childNodes.length; j++) {
152                 var childNode = childNodes[j];
153                 if (!selector || elementMatches(childNode, selector)) {
154                     allMatches.push(childNode);
155                 }
156             }
157         }
158         return allMatches;
159     }
160     // Attributes
161     // ----------------------------------------------------------------------------------------------------------------
162     function forceClassName(el, className, bool) {
163         if (bool) {
164             el.classList.add(className);
165         }
166         else {
167             el.classList.remove(className);
168         }
169     }
170     // Style
171     // ----------------------------------------------------------------------------------------------------------------
172     var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;
173     function applyStyle(el, props) {
174         for (var propName in props) {
175             applyStyleProp(el, propName, props[propName]);
176         }
177     }
178     function applyStyleProp(el, name, val) {
179         if (val == null) {
180             el.style[name] = '';
181         }
182         else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
183             el.style[name] = val + 'px';
184         }
185         else {
186             el.style[name] = val;
187         }
188     }
189
190     function pointInsideRect(point, rect) {
191         return point.left >= rect.left &&
192             point.left < rect.right &&
193             point.top >= rect.top &&
194             point.top < rect.bottom;
195     }
196     // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
197     function intersectRects(rect1, rect2) {
198         var res = {
199             left: Math.max(rect1.left, rect2.left),
200             right: Math.min(rect1.right, rect2.right),
201             top: Math.max(rect1.top, rect2.top),
202             bottom: Math.min(rect1.bottom, rect2.bottom)
203         };
204         if (res.left < res.right && res.top < res.bottom) {
205             return res;
206         }
207         return false;
208     }
209     function translateRect(rect, deltaX, deltaY) {
210         return {
211             left: rect.left + deltaX,
212             right: rect.right + deltaX,
213             top: rect.top + deltaY,
214             bottom: rect.bottom + deltaY
215         };
216     }
217     // Returns a new point that will have been moved to reside within the given rectangle
218     function constrainPoint(point, rect) {
219         return {
220             left: Math.min(Math.max(point.left, rect.left), rect.right),
221             top: Math.min(Math.max(point.top, rect.top), rect.bottom)
222         };
223     }
224     // Returns a point that is the center of the given rectangle
225     function getRectCenter(rect) {
226         return {
227             left: (rect.left + rect.right) / 2,
228             top: (rect.top + rect.bottom) / 2
229         };
230     }
231     // Subtracts point2's coordinates from point1's coordinates, returning a delta
232     function diffPoints(point1, point2) {
233         return {
234             left: point1.left - point2.left,
235             top: point1.top - point2.top
236         };
237     }
238
239     // Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side
240     var isRtlScrollbarOnLeft = null;
241     function getIsRtlScrollbarOnLeft() {
242         if (isRtlScrollbarOnLeft === null) {
243             isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();
244         }
245         return isRtlScrollbarOnLeft;
246     }
247     function computeIsRtlScrollbarOnLeft() {
248         var outerEl = createElement('div', {
249             style: {
250                 position: 'absolute',
251                 top: -1000,
252                 left: 0,
253                 border: 0,
254                 padding: 0,
255                 overflow: 'scroll',
256                 direction: 'rtl'
257             }
258         }, '<div></div>');
259         document.body.appendChild(outerEl);
260         var innerEl = outerEl.firstChild;
261         var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;
262         removeElement(outerEl);
263         return res;
264     }
265     // The scrollbar width computations in computeEdges are sometimes flawed when it comes to
266     // retina displays, rounding, and IE11. Massage them into a usable value.
267     function sanitizeScrollbarWidth(width) {
268         width = Math.max(0, width); // no negatives
269         width = Math.round(width);
270         return width;
271     }
272
273     function computeEdges(el, getPadding) {
274         if (getPadding === void 0) { getPadding = false; }
275         var computedStyle = window.getComputedStyle(el);
276         var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
277         var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
278         var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
279         var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
280         // must use offset(Width|Height) because compatible with client(Width|Height)
281         var scrollbarLeftRight = sanitizeScrollbarWidth(el.offsetWidth - el.clientWidth - borderLeft - borderRight);
282         var scrollbarBottom = sanitizeScrollbarWidth(el.offsetHeight - el.clientHeight - borderTop - borderBottom);
283         var res = {
284             borderLeft: borderLeft,
285             borderRight: borderRight,
286             borderTop: borderTop,
287             borderBottom: borderBottom,
288             scrollbarBottom: scrollbarBottom,
289             scrollbarLeft: 0,
290             scrollbarRight: 0
291         };
292         if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side?
293             res.scrollbarLeft = scrollbarLeftRight;
294         }
295         else {
296             res.scrollbarRight = scrollbarLeftRight;
297         }
298         if (getPadding) {
299             res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
300             res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
301             res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
302             res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
303         }
304         return res;
305     }
306     function computeInnerRect(el, goWithinPadding) {
307         if (goWithinPadding === void 0) { goWithinPadding = false; }
308         var outerRect = computeRect(el);
309         var edges = computeEdges(el, goWithinPadding);
310         var res = {
311             left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
312             right: outerRect.right - edges.borderRight - edges.scrollbarRight,
313             top: outerRect.top + edges.borderTop,
314             bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom
315         };
316         if (goWithinPadding) {
317             res.left += edges.paddingLeft;
318             res.right -= edges.paddingRight;
319             res.top += edges.paddingTop;
320             res.bottom -= edges.paddingBottom;
321         }
322         return res;
323     }
324     function computeRect(el) {
325         var rect = el.getBoundingClientRect();
326         return {
327             left: rect.left + window.pageXOffset,
328             top: rect.top + window.pageYOffset,
329             right: rect.right + window.pageXOffset,
330             bottom: rect.bottom + window.pageYOffset
331         };
332     }
333     function computeViewportRect() {
334         return {
335             left: window.pageXOffset,
336             right: window.pageXOffset + document.documentElement.clientWidth,
337             top: window.pageYOffset,
338             bottom: window.pageYOffset + document.documentElement.clientHeight
339         };
340     }
341     function computeHeightAndMargins(el) {
342         return el.getBoundingClientRect().height + computeVMargins(el);
343     }
344     function computeVMargins(el) {
345         var computed = window.getComputedStyle(el);
346         return parseInt(computed.marginTop, 10) +
347             parseInt(computed.marginBottom, 10);
348     }
349     // does not return window
350     function getClippingParents(el) {
351         var parents = [];
352         while (el instanceof HTMLElement) { // will stop when gets to document or null
353             var computedStyle = window.getComputedStyle(el);
354             if (computedStyle.position === 'fixed') {
355                 break;
356             }
357             if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
358                 parents.push(el);
359             }
360             el = el.parentNode;
361         }
362         return parents;
363     }
364     function computeClippingRect(el) {
365         return getClippingParents(el)
366             .map(function (el) {
367             return computeInnerRect(el);
368         })
369             .concat(computeViewportRect())
370             .reduce(function (rect0, rect1) {
371             return intersectRects(rect0, rect1) || rect1; // should always intersect
372         });
373     }
374
375     // Stops a mouse/touch event from doing it's native browser action
376     function preventDefault(ev) {
377         ev.preventDefault();
378     }
379     // Event Delegation
380     // ----------------------------------------------------------------------------------------------------------------
381     function listenBySelector(container, eventType, selector, handler) {
382         function realHandler(ev) {
383             var matchedChild = elementClosest(ev.target, selector);
384             if (matchedChild) {
385                 handler.call(matchedChild, ev, matchedChild);
386             }
387         }
388         container.addEventListener(eventType, realHandler);
389         return function () {
390             container.removeEventListener(eventType, realHandler);
391         };
392     }
393     function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
394         var currentMatchedChild;
395         return listenBySelector(container, 'mouseover', selector, function (ev, matchedChild) {
396             if (matchedChild !== currentMatchedChild) {
397                 currentMatchedChild = matchedChild;
398                 onMouseEnter(ev, matchedChild);
399                 var realOnMouseLeave_1 = function (ev) {
400                     currentMatchedChild = null;
401                     onMouseLeave(ev, matchedChild);
402                     matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1);
403                 };
404                 // listen to the next mouseleave, and then unattach
405                 matchedChild.addEventListener('mouseleave', realOnMouseLeave_1);
406             }
407         });
408     }
409     // Animation
410     // ----------------------------------------------------------------------------------------------------------------
411     var transitionEventNames = [
412         'webkitTransitionEnd',
413         'otransitionend',
414         'oTransitionEnd',
415         'msTransitionEnd',
416         'transitionend'
417     ];
418     // triggered only when the next single subsequent transition finishes
419     function whenTransitionDone(el, callback) {
420         var realCallback = function (ev) {
421             callback(ev);
422             transitionEventNames.forEach(function (eventName) {
423                 el.removeEventListener(eventName, realCallback);
424             });
425         };
426         transitionEventNames.forEach(function (eventName) {
427             el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes
428         });
429     }
430
431     var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
432     // Adding
433     function addWeeks(m, n) {
434         var a = dateToUtcArray(m);
435         a[2] += n * 7;
436         return arrayToUtcDate(a);
437     }
438     function addDays(m, n) {
439         var a = dateToUtcArray(m);
440         a[2] += n;
441         return arrayToUtcDate(a);
442     }
443     function addMs(m, n) {
444         var a = dateToUtcArray(m);
445         a[6] += n;
446         return arrayToUtcDate(a);
447     }
448     // Diffing (all return floats)
449     function diffWeeks(m0, m1) {
450         return diffDays(m0, m1) / 7;
451     }
452     function diffDays(m0, m1) {
453         return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
454     }
455     function diffHours(m0, m1) {
456         return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
457     }
458     function diffMinutes(m0, m1) {
459         return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
460     }
461     function diffSeconds(m0, m1) {
462         return (m1.valueOf() - m0.valueOf()) / 1000;
463     }
464     function diffDayAndTime(m0, m1) {
465         var m0day = startOfDay(m0);
466         var m1day = startOfDay(m1);
467         return {
468             years: 0,
469             months: 0,
470             days: Math.round(diffDays(m0day, m1day)),
471             milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf())
472         };
473     }
474     // Diffing Whole Units
475     function diffWholeWeeks(m0, m1) {
476         var d = diffWholeDays(m0, m1);
477         if (d !== null && d % 7 === 0) {
478             return d / 7;
479         }
480         return null;
481     }
482     function diffWholeDays(m0, m1) {
483         if (timeAsMs(m0) === timeAsMs(m1)) {
484             return Math.round(diffDays(m0, m1));
485         }
486         return null;
487     }
488     // Start-Of
489     function startOfDay(m) {
490         return arrayToUtcDate([
491             m.getUTCFullYear(),
492             m.getUTCMonth(),
493             m.getUTCDate()
494         ]);
495     }
496     function startOfHour(m) {
497         return arrayToUtcDate([
498             m.getUTCFullYear(),
499             m.getUTCMonth(),
500             m.getUTCDate(),
501             m.getUTCHours()
502         ]);
503     }
504     function startOfMinute(m) {
505         return arrayToUtcDate([
506             m.getUTCFullYear(),
507             m.getUTCMonth(),
508             m.getUTCDate(),
509             m.getUTCHours(),
510             m.getUTCMinutes()
511         ]);
512     }
513     function startOfSecond(m) {
514         return arrayToUtcDate([
515             m.getUTCFullYear(),
516             m.getUTCMonth(),
517             m.getUTCDate(),
518             m.getUTCHours(),
519             m.getUTCMinutes(),
520             m.getUTCSeconds()
521         ]);
522     }
523     // Week Computation
524     function weekOfYear(marker, dow, doy) {
525         var y = marker.getUTCFullYear();
526         var w = weekOfGivenYear(marker, y, dow, doy);
527         if (w < 1) {
528             return weekOfGivenYear(marker, y - 1, dow, doy);
529         }
530         var nextW = weekOfGivenYear(marker, y + 1, dow, doy);
531         if (nextW >= 1) {
532             return Math.min(w, nextW);
533         }
534         return w;
535     }
536     function weekOfGivenYear(marker, year, dow, doy) {
537         var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
538         var dayStart = startOfDay(marker);
539         var days = Math.round(diffDays(firstWeekStart, dayStart));
540         return Math.floor(days / 7) + 1; // zero-indexed
541     }
542     // start-of-first-week - start-of-year
543     function firstWeekOffset(year, dow, doy) {
544         // first-week day -- which january is always in the first week (4 for iso, 1 for other)
545         var fwd = 7 + dow - doy;
546         // first-week day local weekday -- which local weekday is fwd
547         var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
548         return -fwdlw + fwd - 1;
549     }
550     // Array Conversion
551     function dateToLocalArray(date) {
552         return [
553             date.getFullYear(),
554             date.getMonth(),
555             date.getDate(),
556             date.getHours(),
557             date.getMinutes(),
558             date.getSeconds(),
559             date.getMilliseconds()
560         ];
561     }
562     function arrayToLocalDate(a) {
563         return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month
564         a[3] || 0, a[4] || 0, a[5] || 0);
565     }
566     function dateToUtcArray(date) {
567         return [
568             date.getUTCFullYear(),
569             date.getUTCMonth(),
570             date.getUTCDate(),
571             date.getUTCHours(),
572             date.getUTCMinutes(),
573             date.getUTCSeconds(),
574             date.getUTCMilliseconds()
575         ];
576     }
577     function arrayToUtcDate(a) {
578         // according to web standards (and Safari), a month index is required.
579         // massage if only given a year.
580         if (a.length === 1) {
581             a = a.concat([0]);
582         }
583         return new Date(Date.UTC.apply(Date, a));
584     }
585     // Other Utils
586     function isValidDate(m) {
587         return !isNaN(m.valueOf());
588     }
589     function timeAsMs(m) {
590         return m.getUTCHours() * 1000 * 60 * 60 +
591             m.getUTCMinutes() * 1000 * 60 +
592             m.getUTCSeconds() * 1000 +
593             m.getUTCMilliseconds();
594     }
595
596     var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
597     var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
598     // Parsing and Creation
599     function createDuration(input, unit) {
600         var _a;
601         if (typeof input === 'string') {
602             return parseString(input);
603         }
604         else if (typeof input === 'object' && input) { // non-null object
605             return normalizeObject(input);
606         }
607         else if (typeof input === 'number') {
608             return normalizeObject((_a = {}, _a[unit || 'milliseconds'] = input, _a));
609         }
610         else {
611             return null;
612         }
613     }
614     function parseString(s) {
615         var m = PARSE_RE.exec(s);
616         if (m) {
617             var sign = m[1] ? -1 : 1;
618             return {
619                 years: 0,
620                 months: 0,
621                 days: sign * (m[2] ? parseInt(m[2], 10) : 0),
622                 milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours
623                     (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes
624                     (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds
625                     (m[6] ? parseInt(m[6], 10) : 0) // ms
626                 )
627             };
628         }
629         return null;
630     }
631     function normalizeObject(obj) {
632         return {
633             years: obj.years || obj.year || 0,
634             months: obj.months || obj.month || 0,
635             days: (obj.days || obj.day || 0) +
636                 getWeeksFromInput(obj) * 7,
637             milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours
638                 (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes
639                 (obj.seconds || obj.second || 0) * 1000 + // seconds
640                 (obj.milliseconds || obj.millisecond || obj.ms || 0) // ms
641         };
642     }
643     function getWeeksFromInput(obj) {
644         return obj.weeks || obj.week || 0;
645     }
646     // Equality
647     function durationsEqual(d0, d1) {
648         return d0.years === d1.years &&
649             d0.months === d1.months &&
650             d0.days === d1.days &&
651             d0.milliseconds === d1.milliseconds;
652     }
653     function isSingleDay(dur) {
654         return dur.years === 0 && dur.months === 0 && dur.days === 1 && dur.milliseconds === 0;
655     }
656     // Simple Math
657     function addDurations(d0, d1) {
658         return {
659             years: d0.years + d1.years,
660             months: d0.months + d1.months,
661             days: d0.days + d1.days,
662             milliseconds: d0.milliseconds + d1.milliseconds
663         };
664     }
665     function subtractDurations(d1, d0) {
666         return {
667             years: d1.years - d0.years,
668             months: d1.months - d0.months,
669             days: d1.days - d0.days,
670             milliseconds: d1.milliseconds - d0.milliseconds
671         };
672     }
673     function multiplyDuration(d, n) {
674         return {
675             years: d.years * n,
676             months: d.months * n,
677             days: d.days * n,
678             milliseconds: d.milliseconds * n
679         };
680     }
681     // Conversions
682     // "Rough" because they are based on average-case Gregorian months/years
683     function asRoughYears(dur) {
684         return asRoughDays(dur) / 365;
685     }
686     function asRoughMonths(dur) {
687         return asRoughDays(dur) / 30;
688     }
689     function asRoughDays(dur) {
690         return asRoughMs(dur) / 864e5;
691     }
692     function asRoughMinutes(dur) {
693         return asRoughMs(dur) / (1000 * 60);
694     }
695     function asRoughSeconds(dur) {
696         return asRoughMs(dur) / 1000;
697     }
698     function asRoughMs(dur) {
699         return dur.years * (365 * 864e5) +
700             dur.months * (30 * 864e5) +
701             dur.days * 864e5 +
702             dur.milliseconds;
703     }
704     // Advanced Math
705     function wholeDivideDurations(numerator, denominator) {
706         var res = null;
707         for (var i = 0; i < INTERNAL_UNITS.length; i++) {
708             var unit = INTERNAL_UNITS[i];
709             if (denominator[unit]) {
710                 var localRes = numerator[unit] / denominator[unit];
711                 if (!isInt(localRes) || (res !== null && res !== localRes)) {
712                     return null;
713                 }
714                 res = localRes;
715             }
716             else if (numerator[unit]) {
717                 // needs to divide by something but can't!
718                 return null;
719             }
720         }
721         return res;
722     }
723     function greatestDurationDenominator(dur, dontReturnWeeks) {
724         var ms = dur.milliseconds;
725         if (ms) {
726             if (ms % 1000 !== 0) {
727                 return { unit: 'millisecond', value: ms };
728             }
729             if (ms % (1000 * 60) !== 0) {
730                 return { unit: 'second', value: ms / 1000 };
731             }
732             if (ms % (1000 * 60 * 60) !== 0) {
733                 return { unit: 'minute', value: ms / (1000 * 60) };
734             }
735             if (ms) {
736                 return { unit: 'hour', value: ms / (1000 * 60 * 60) };
737             }
738         }
739         if (dur.days) {
740             if (!dontReturnWeeks && dur.days % 7 === 0) {
741                 return { unit: 'week', value: dur.days / 7 };
742             }
743             return { unit: 'day', value: dur.days };
744         }
745         if (dur.months) {
746             return { unit: 'month', value: dur.months };
747         }
748         if (dur.years) {
749             return { unit: 'year', value: dur.years };
750         }
751         return { unit: 'millisecond', value: 0 };
752     }
753
754     /* FullCalendar-specific DOM Utilities
755     ----------------------------------------------------------------------------------------------------------------------*/
756     // Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left
757     // and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.
758     function compensateScroll(rowEl, scrollbarWidths) {
759         if (scrollbarWidths.left) {
760             applyStyle(rowEl, {
761                 borderLeftWidth: 1,
762                 marginLeft: scrollbarWidths.left - 1
763             });
764         }
765         if (scrollbarWidths.right) {
766             applyStyle(rowEl, {
767                 borderRightWidth: 1,
768                 marginRight: scrollbarWidths.right - 1
769             });
770         }
771     }
772     // Undoes compensateScroll and restores all borders/margins
773     function uncompensateScroll(rowEl) {
774         applyStyle(rowEl, {
775             marginLeft: '',
776             marginRight: '',
777             borderLeftWidth: '',
778             borderRightWidth: ''
779         });
780     }
781     // Make the mouse cursor express that an event is not allowed in the current area
782     function disableCursor() {
783         document.body.classList.add('fc-not-allowed');
784     }
785     // Returns the mouse cursor to its original look
786     function enableCursor() {
787         document.body.classList.remove('fc-not-allowed');
788     }
789     // Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.
790     // By default, all elements that are shorter than the recommended height are expanded uniformly, not considering
791     // any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and
792     // reduces the available height.
793     function distributeHeight(els, availableHeight, shouldRedistribute) {
794         // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,
795         // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.
796         var minOffset1 = Math.floor(availableHeight / els.length); // for non-last element
797         var minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE*
798         var flexEls = []; // elements that are allowed to expand. array of DOM nodes
799         var flexOffsets = []; // amount of vertical space it takes up
800         var flexHeights = []; // actual css height
801         var usedHeight = 0;
802         undistributeHeight(els); // give all elements their natural height
803         // find elements that are below the recommended height (expandable).
804         // important to query for heights in a single first pass (to avoid reflow oscillation).
805         els.forEach(function (el, i) {
806             var minOffset = i === els.length - 1 ? minOffset2 : minOffset1;
807             var naturalHeight = el.getBoundingClientRect().height;
808             var naturalOffset = naturalHeight + computeVMargins(el);
809             if (naturalOffset < minOffset) {
810                 flexEls.push(el);
811                 flexOffsets.push(naturalOffset);
812                 flexHeights.push(naturalHeight);
813             }
814             else {
815                 // this element stretches past recommended height (non-expandable). mark the space as occupied.
816                 usedHeight += naturalOffset;
817             }
818         });
819         // readjust the recommended height to only consider the height available to non-maxed-out rows.
820         if (shouldRedistribute) {
821             availableHeight -= usedHeight;
822             minOffset1 = Math.floor(availableHeight / flexEls.length);
823             minOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE*
824         }
825         // assign heights to all expandable elements
826         flexEls.forEach(function (el, i) {
827             var minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1;
828             var naturalOffset = flexOffsets[i];
829             var naturalHeight = flexHeights[i];
830             var newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding
831             if (naturalOffset < minOffset) { // we check this again because redistribution might have changed things
832                 el.style.height = newHeight + 'px';
833             }
834         });
835     }
836     // Undoes distrubuteHeight, restoring all els to their natural height
837     function undistributeHeight(els) {
838         els.forEach(function (el) {
839             el.style.height = '';
840         });
841     }
842     // Given `els`, a set of <td> cells, find the cell with the largest natural width and set the widths of all the
843     // cells to be that width.
844     // PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline
845     function matchCellWidths(els) {
846         var maxInnerWidth = 0;
847         els.forEach(function (el) {
848             var innerEl = el.firstChild; // hopefully an element
849             if (innerEl instanceof HTMLElement) {
850                 var innerWidth_1 = innerEl.getBoundingClientRect().width;
851                 if (innerWidth_1 > maxInnerWidth) {
852                     maxInnerWidth = innerWidth_1;
853                 }
854             }
855         });
856         maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance
857         els.forEach(function (el) {
858             el.style.width = maxInnerWidth + 'px';
859         });
860         return maxInnerWidth;
861     }
862     // Given one element that resides inside another,
863     // Subtracts the height of the inner element from the outer element.
864     function subtractInnerElHeight(outerEl, innerEl) {
865         // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
866         var reflowStyleProps = {
867             position: 'relative',
868             left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll
869         };
870         applyStyle(outerEl, reflowStyleProps);
871         applyStyle(innerEl, reflowStyleProps);
872         var diff = // grab the dimensions
873          outerEl.getBoundingClientRect().height -
874             innerEl.getBoundingClientRect().height;
875         // undo hack
876         var resetStyleProps = { position: '', left: '' };
877         applyStyle(outerEl, resetStyleProps);
878         applyStyle(innerEl, resetStyleProps);
879         return diff;
880     }
881     /* Selection
882     ----------------------------------------------------------------------------------------------------------------------*/
883     function preventSelection(el) {
884         el.classList.add('fc-unselectable');
885         el.addEventListener('selectstart', preventDefault);
886     }
887     function allowSelection(el) {
888         el.classList.remove('fc-unselectable');
889         el.removeEventListener('selectstart', preventDefault);
890     }
891     /* Context Menu
892     ----------------------------------------------------------------------------------------------------------------------*/
893     function preventContextMenu(el) {
894         el.addEventListener('contextmenu', preventDefault);
895     }
896     function allowContextMenu(el) {
897         el.removeEventListener('contextmenu', preventDefault);
898     }
899     /* Object Ordering by Field
900     ----------------------------------------------------------------------------------------------------------------------*/
901     function parseFieldSpecs(input) {
902         var specs = [];
903         var tokens = [];
904         var i;
905         var token;
906         if (typeof input === 'string') {
907             tokens = input.split(/\s*,\s*/);
908         }
909         else if (typeof input === 'function') {
910             tokens = [input];
911         }
912         else if (Array.isArray(input)) {
913             tokens = input;
914         }
915         for (i = 0; i < tokens.length; i++) {
916             token = tokens[i];
917             if (typeof token === 'string') {
918                 specs.push(token.charAt(0) === '-' ?
919                     { field: token.substring(1), order: -1 } :
920                     { field: token, order: 1 });
921             }
922             else if (typeof token === 'function') {
923                 specs.push({ func: token });
924             }
925         }
926         return specs;
927     }
928     function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
929         var i;
930         var cmp;
931         for (i = 0; i < fieldSpecs.length; i++) {
932             cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
933             if (cmp) {
934                 return cmp;
935             }
936         }
937         return 0;
938     }
939     function compareByFieldSpec(obj0, obj1, fieldSpec) {
940         if (fieldSpec.func) {
941             return fieldSpec.func(obj0, obj1);
942         }
943         return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])
944             * (fieldSpec.order || 1);
945     }
946     function flexibleCompare(a, b) {
947         if (!a && !b) {
948             return 0;
949         }
950         if (b == null) {
951             return -1;
952         }
953         if (a == null) {
954             return 1;
955         }
956         if (typeof a === 'string' || typeof b === 'string') {
957             return String(a).localeCompare(String(b));
958         }
959         return a - b;
960     }
961     /* String Utilities
962     ----------------------------------------------------------------------------------------------------------------------*/
963     function capitaliseFirstLetter(str) {
964         return str.charAt(0).toUpperCase() + str.slice(1);
965     }
966     function padStart(val, len) {
967         var s = String(val);
968         return '000'.substr(0, len - s.length) + s;
969     }
970     /* Number Utilities
971     ----------------------------------------------------------------------------------------------------------------------*/
972     function compareNumbers(a, b) {
973         return a - b;
974     }
975     function isInt(n) {
976         return n % 1 === 0;
977     }
978     /* Weird Utilities
979     ----------------------------------------------------------------------------------------------------------------------*/
980     function applyAll(functions, thisObj, args) {
981         if (typeof functions === 'function') { // supplied a single function
982             functions = [functions];
983         }
984         if (functions) {
985             var i = void 0;
986             var ret = void 0;
987             for (i = 0; i < functions.length; i++) {
988                 ret = functions[i].apply(thisObj, args) || ret;
989             }
990             return ret;
991         }
992     }
993     function firstDefined() {
994         var args = [];
995         for (var _i = 0; _i < arguments.length; _i++) {
996             args[_i] = arguments[_i];
997         }
998         for (var i = 0; i < args.length; i++) {
999             if (args[i] !== undefined) {
1000                 return args[i];
1001             }
1002         }
1003     }
1004     // Returns a function, that, as long as it continues to be invoked, will not
1005     // be triggered. The function will be called after it stops being called for
1006     // N milliseconds. If `immediate` is passed, trigger the function on the
1007     // leading edge, instead of the trailing.
1008     // https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714
1009     function debounce(func, wait) {
1010         var timeout;
1011         var args;
1012         var context;
1013         var timestamp;
1014         var result;
1015         var later = function () {
1016             var last = new Date().valueOf() - timestamp;
1017             if (last < wait) {
1018                 timeout = setTimeout(later, wait - last);
1019             }
1020             else {
1021                 timeout = null;
1022                 result = func.apply(context, args);
1023                 context = args = null;
1024             }
1025         };
1026         return function () {
1027             context = this;
1028             args = arguments;
1029             timestamp = new Date().valueOf();
1030             if (!timeout) {
1031                 timeout = setTimeout(later, wait);
1032             }
1033             return result;
1034         };
1035     }
1036     // Number and Boolean are only types that defaults or not computed for
1037     // TODO: write more comments
1038     function refineProps(rawProps, processors, defaults, leftoverProps) {
1039         if (defaults === void 0) { defaults = {}; }
1040         var refined = {};
1041         for (var key in processors) {
1042             var processor = processors[key];
1043             if (rawProps[key] !== undefined) {
1044                 // found
1045                 if (processor === Function) {
1046                     refined[key] = typeof rawProps[key] === 'function' ? rawProps[key] : null;
1047                 }
1048                 else if (processor) { // a refining function?
1049                     refined[key] = processor(rawProps[key]);
1050                 }
1051                 else {
1052                     refined[key] = rawProps[key];
1053                 }
1054             }
1055             else if (defaults[key] !== undefined) {
1056                 // there's an explicit default
1057                 refined[key] = defaults[key];
1058             }
1059             else {
1060                 // must compute a default
1061                 if (processor === String) {
1062                     refined[key] = ''; // empty string is default for String
1063                 }
1064                 else if (!processor || processor === Number || processor === Boolean || processor === Function) {
1065                     refined[key] = null; // assign null for other non-custom processor funcs
1066                 }
1067                 else {
1068                     refined[key] = processor(null); // run the custom processor func
1069                 }
1070             }
1071         }
1072         if (leftoverProps) {
1073             for (var key in rawProps) {
1074                 if (processors[key] === undefined) {
1075                     leftoverProps[key] = rawProps[key];
1076                 }
1077             }
1078         }
1079         return refined;
1080     }
1081     /* Date stuff that doesn't belong in datelib core
1082     ----------------------------------------------------------------------------------------------------------------------*/
1083     // given a timed range, computes an all-day range that has the same exact duration,
1084     // but whose start time is aligned with the start of the day.
1085     function computeAlignedDayRange(timedRange) {
1086         var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
1087         var start = startOfDay(timedRange.start);
1088         var end = addDays(start, dayCnt);
1089         return { start: start, end: end };
1090     }
1091     // given a timed range, computes an all-day range based on how for the end date bleeds into the next day
1092     // TODO: give nextDayThreshold a default arg
1093     function computeVisibleDayRange(timedRange, nextDayThreshold) {
1094         if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); }
1095         var startDay = null;
1096         var endDay = null;
1097         if (timedRange.end) {
1098             endDay = startOfDay(timedRange.end);
1099             var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`
1100             // If the end time is actually inclusively part of the next day and is equal to or
1101             // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
1102             // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
1103             if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
1104                 endDay = addDays(endDay, 1);
1105             }
1106         }
1107         if (timedRange.start) {
1108             startDay = startOfDay(timedRange.start); // the beginning of the day the range starts
1109             // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
1110             if (endDay && endDay <= startDay) {
1111                 endDay = addDays(startDay, 1);
1112             }
1113         }
1114         return { start: startDay, end: endDay };
1115     }
1116     // spans from one day into another?
1117     function isMultiDayRange(range) {
1118         var visibleRange = computeVisibleDayRange(range);
1119         return diffDays(visibleRange.start, visibleRange.end) > 1;
1120     }
1121     function diffDates(date0, date1, dateEnv, largeUnit) {
1122         if (largeUnit === 'year') {
1123             return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
1124         }
1125         else if (largeUnit === 'month') {
1126             return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
1127         }
1128         else {
1129             return diffDayAndTime(date0, date1); // returns a duration
1130         }
1131     }
1132
1133     /*! *****************************************************************************
1134     Copyright (c) Microsoft Corporation. All rights reserved.
1135     Licensed under the Apache License, Version 2.0 (the "License"); you may not use
1136     this file except in compliance with the License. You may obtain a copy of the
1137     License at http://www.apache.org/licenses/LICENSE-2.0
1138
1139     THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1140     KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
1141     WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
1142     MERCHANTABLITY OR NON-INFRINGEMENT.
1143
1144     See the Apache Version 2.0 License for specific language governing permissions
1145     and limitations under the License.
1146     ***************************************************************************** */
1147     /* global Reflect, Promise */
1148
1149     var extendStatics = function(d, b) {
1150         extendStatics = Object.setPrototypeOf ||
1151             ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
1152             function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
1153         return extendStatics(d, b);
1154     };
1155
1156     function __extends(d, b) {
1157         extendStatics(d, b);
1158         function __() { this.constructor = d; }
1159         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1160     }
1161
1162     var __assign = function() {
1163         __assign = Object.assign || function __assign(t) {
1164             for (var s, i = 1, n = arguments.length; i < n; i++) {
1165                 s = arguments[i];
1166                 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
1167             }
1168             return t;
1169         };
1170         return __assign.apply(this, arguments);
1171     };
1172
1173     function parseRecurring(eventInput, allDayDefault, dateEnv, recurringTypes, leftovers) {
1174         for (var i = 0; i < recurringTypes.length; i++) {
1175             var localLeftovers = {};
1176             var parsed = recurringTypes[i].parse(eventInput, localLeftovers, dateEnv);
1177             if (parsed) {
1178                 var allDay = localLeftovers.allDay;
1179                 delete localLeftovers.allDay; // remove from leftovers
1180                 if (allDay == null) {
1181                     allDay = allDayDefault;
1182                     if (allDay == null) {
1183                         allDay = parsed.allDayGuess;
1184                         if (allDay == null) {
1185                             allDay = false;
1186                         }
1187                     }
1188                 }
1189                 __assign(leftovers, localLeftovers);
1190                 return {
1191                     allDay: allDay,
1192                     duration: parsed.duration,
1193                     typeData: parsed.typeData,
1194                     typeId: i
1195                 };
1196             }
1197         }
1198         return null;
1199     }
1200     /*
1201     Event MUST have a recurringDef
1202     */
1203     function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) {
1204         var typeDef = recurringTypes[eventDef.recurringDef.typeId];
1205         var markers = typeDef.expand(eventDef.recurringDef.typeData, {
1206             start: dateEnv.subtract(framingRange.start, duration),
1207             end: framingRange.end
1208         }, dateEnv);
1209         // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to
1210         if (eventDef.allDay) {
1211             markers = markers.map(startOfDay);
1212         }
1213         return markers;
1214     }
1215
1216     var hasOwnProperty = Object.prototype.hasOwnProperty;
1217     // Merges an array of objects into a single object.
1218     // The second argument allows for an array of property names who's object values will be merged together.
1219     function mergeProps(propObjs, complexProps) {
1220         var dest = {};
1221         var i;
1222         var name;
1223         var complexObjs;
1224         var j;
1225         var val;
1226         var props;
1227         if (complexProps) {
1228             for (i = 0; i < complexProps.length; i++) {
1229                 name = complexProps[i];
1230                 complexObjs = [];
1231                 // collect the trailing object values, stopping when a non-object is discovered
1232                 for (j = propObjs.length - 1; j >= 0; j--) {
1233                     val = propObjs[j][name];
1234                     if (typeof val === 'object' && val) { // non-null object
1235                         complexObjs.unshift(val);
1236                     }
1237                     else if (val !== undefined) {
1238                         dest[name] = val; // if there were no objects, this value will be used
1239                         break;
1240                     }
1241                 }
1242                 // if the trailing values were objects, use the merged value
1243                 if (complexObjs.length) {
1244                     dest[name] = mergeProps(complexObjs);
1245                 }
1246             }
1247         }
1248         // copy values into the destination, going from last to first
1249         for (i = propObjs.length - 1; i >= 0; i--) {
1250             props = propObjs[i];
1251             for (name in props) {
1252                 if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign
1253                     dest[name] = props[name];
1254                 }
1255             }
1256         }
1257         return dest;
1258     }
1259     function filterHash(hash, func) {
1260         var filtered = {};
1261         for (var key in hash) {
1262             if (func(hash[key], key)) {
1263                 filtered[key] = hash[key];
1264             }
1265         }
1266         return filtered;
1267     }
1268     function mapHash(hash, func) {
1269         var newHash = {};
1270         for (var key in hash) {
1271             newHash[key] = func(hash[key], key);
1272         }
1273         return newHash;
1274     }
1275     function arrayToHash(a) {
1276         var hash = {};
1277         for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
1278             var item = a_1[_i];
1279             hash[item] = true;
1280         }
1281         return hash;
1282     }
1283     function hashValuesToArray(obj) {
1284         var a = [];
1285         for (var key in obj) {
1286             a.push(obj[key]);
1287         }
1288         return a;
1289     }
1290     function isPropsEqual(obj0, obj1) {
1291         for (var key in obj0) {
1292             if (hasOwnProperty.call(obj0, key)) {
1293                 if (!(key in obj1)) {
1294                     return false;
1295                 }
1296             }
1297         }
1298         for (var key in obj1) {
1299             if (hasOwnProperty.call(obj1, key)) {
1300                 if (obj0[key] !== obj1[key]) {
1301                     return false;
1302                 }
1303             }
1304         }
1305         return true;
1306     }
1307
1308     function parseEvents(rawEvents, sourceId, calendar, allowOpenRange) {
1309         var eventStore = createEmptyEventStore();
1310         for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
1311             var rawEvent = rawEvents_1[_i];
1312             var tuple = parseEvent(rawEvent, sourceId, calendar, allowOpenRange);
1313             if (tuple) {
1314                 eventTupleToStore(tuple, eventStore);
1315             }
1316         }
1317         return eventStore;
1318     }
1319     function eventTupleToStore(tuple, eventStore) {
1320         if (eventStore === void 0) { eventStore = createEmptyEventStore(); }
1321         eventStore.defs[tuple.def.defId] = tuple.def;
1322         if (tuple.instance) {
1323             eventStore.instances[tuple.instance.instanceId] = tuple.instance;
1324         }
1325         return eventStore;
1326     }
1327     function expandRecurring(eventStore, framingRange, calendar) {
1328         var dateEnv = calendar.dateEnv;
1329         var defs = eventStore.defs, instances = eventStore.instances;
1330         // remove existing recurring instances
1331         instances = filterHash(instances, function (instance) {
1332             return !defs[instance.defId].recurringDef;
1333         });
1334         for (var defId in defs) {
1335             var def = defs[defId];
1336             if (def.recurringDef) {
1337                 var duration = def.recurringDef.duration;
1338                 if (!duration) {
1339                     duration = def.allDay ?
1340                         calendar.defaultAllDayEventDuration :
1341                         calendar.defaultTimedEventDuration;
1342                 }
1343                 var starts = expandRecurringRanges(def, duration, framingRange, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes);
1344                 for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) {
1345                     var start = starts_1[_i];
1346                     var instance = createEventInstance(defId, {
1347                         start: start,
1348                         end: dateEnv.add(start, duration)
1349                     });
1350                     instances[instance.instanceId] = instance;
1351                 }
1352             }
1353         }
1354         return { defs: defs, instances: instances };
1355     }
1356     // retrieves events that have the same groupId as the instance specified by `instanceId`
1357     // or they are the same as the instance.
1358     // why might instanceId not be in the store? an event from another calendar?
1359     function getRelevantEvents(eventStore, instanceId) {
1360         var instance = eventStore.instances[instanceId];
1361         if (instance) {
1362             var def_1 = eventStore.defs[instance.defId];
1363             // get events/instances with same group
1364             var newStore = filterEventStoreDefs(eventStore, function (lookDef) {
1365                 return isEventDefsGrouped(def_1, lookDef);
1366             });
1367             // add the original
1368             // TODO: wish we could use eventTupleToStore or something like it
1369             newStore.defs[def_1.defId] = def_1;
1370             newStore.instances[instance.instanceId] = instance;
1371             return newStore;
1372         }
1373         return createEmptyEventStore();
1374     }
1375     function isEventDefsGrouped(def0, def1) {
1376         return Boolean(def0.groupId && def0.groupId === def1.groupId);
1377     }
1378     function transformRawEvents(rawEvents, eventSource, calendar) {
1379         var calEachTransform = calendar.opt('eventDataTransform');
1380         var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
1381         if (sourceEachTransform) {
1382             rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
1383         }
1384         if (calEachTransform) {
1385             rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
1386         }
1387         return rawEvents;
1388     }
1389     function transformEachRawEvent(rawEvents, func) {
1390         var refinedEvents;
1391         if (!func) {
1392             refinedEvents = rawEvents;
1393         }
1394         else {
1395             refinedEvents = [];
1396             for (var _i = 0, rawEvents_2 = rawEvents; _i < rawEvents_2.length; _i++) {
1397                 var rawEvent = rawEvents_2[_i];
1398                 var refinedEvent = func(rawEvent);
1399                 if (refinedEvent) {
1400                     refinedEvents.push(refinedEvent);
1401                 }
1402                 else if (refinedEvent == null) {
1403                     refinedEvents.push(rawEvent);
1404                 } // if a different falsy value, do nothing
1405             }
1406         }
1407         return refinedEvents;
1408     }
1409     function createEmptyEventStore() {
1410         return { defs: {}, instances: {} };
1411     }
1412     function mergeEventStores(store0, store1) {
1413         return {
1414             defs: __assign({}, store0.defs, store1.defs),
1415             instances: __assign({}, store0.instances, store1.instances)
1416         };
1417     }
1418     function filterEventStoreDefs(eventStore, filterFunc) {
1419         var defs = filterHash(eventStore.defs, filterFunc);
1420         var instances = filterHash(eventStore.instances, function (instance) {
1421             return defs[instance.defId]; // still exists?
1422         });
1423         return { defs: defs, instances: instances };
1424     }
1425
1426     function parseRange(input, dateEnv) {
1427         var start = null;
1428         var end = null;
1429         if (input.start) {
1430             start = dateEnv.createMarker(input.start);
1431         }
1432         if (input.end) {
1433             end = dateEnv.createMarker(input.end);
1434         }
1435         if (!start && !end) {
1436             return null;
1437         }
1438         if (start && end && end < start) {
1439             return null;
1440         }
1441         return { start: start, end: end };
1442     }
1443     // SIDE-EFFECT: will mutate ranges.
1444     // Will return a new array result.
1445     function invertRanges(ranges, constraintRange) {
1446         var invertedRanges = [];
1447         var start = constraintRange.start; // the end of the previous range. the start of the new range
1448         var i;
1449         var dateRange;
1450         // ranges need to be in order. required for our date-walking algorithm
1451         ranges.sort(compareRanges);
1452         for (i = 0; i < ranges.length; i++) {
1453             dateRange = ranges[i];
1454             // add the span of time before the event (if there is any)
1455             if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)
1456                 invertedRanges.push({ start: start, end: dateRange.start });
1457             }
1458             if (dateRange.end > start) {
1459                 start = dateRange.end;
1460             }
1461         }
1462         // add the span of time after the last event (if there is any)
1463         if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)
1464             invertedRanges.push({ start: start, end: constraintRange.end });
1465         }
1466         return invertedRanges;
1467     }
1468     function compareRanges(range0, range1) {
1469         return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
1470     }
1471     function intersectRanges(range0, range1) {
1472         var start = range0.start;
1473         var end = range0.end;
1474         var newRange = null;
1475         if (range1.start !== null) {
1476             if (start === null) {
1477                 start = range1.start;
1478             }
1479             else {
1480                 start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
1481             }
1482         }
1483         if (range1.end != null) {
1484             if (end === null) {
1485                 end = range1.end;
1486             }
1487             else {
1488                 end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
1489             }
1490         }
1491         if (start === null || end === null || start < end) {
1492             newRange = { start: start, end: end };
1493         }
1494         return newRange;
1495     }
1496     function rangesEqual(range0, range1) {
1497         return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
1498             (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
1499     }
1500     function rangesIntersect(range0, range1) {
1501         return (range0.end === null || range1.start === null || range0.end > range1.start) &&
1502             (range0.start === null || range1.end === null || range0.start < range1.end);
1503     }
1504     function rangeContainsRange(outerRange, innerRange) {
1505         return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
1506             (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
1507     }
1508     function rangeContainsMarker(range, date) {
1509         return (range.start === null || date >= range.start) &&
1510             (range.end === null || date < range.end);
1511     }
1512     // If the given date is not within the given range, move it inside.
1513     // (If it's past the end, make it one millisecond before the end).
1514     function constrainMarkerToRange(date, range) {
1515         if (range.start != null && date < range.start) {
1516             return range.start;
1517         }
1518         if (range.end != null && date >= range.end) {
1519             return new Date(range.end.valueOf() - 1);
1520         }
1521         return date;
1522     }
1523
1524     function removeExact(array, exactVal) {
1525         var removeCnt = 0;
1526         var i = 0;
1527         while (i < array.length) {
1528             if (array[i] === exactVal) {
1529                 array.splice(i, 1);
1530                 removeCnt++;
1531             }
1532             else {
1533                 i++;
1534             }
1535         }
1536         return removeCnt;
1537     }
1538     function isArraysEqual(a0, a1) {
1539         var len = a0.length;
1540         var i;
1541         if (len !== a1.length) { // not array? or not same length?
1542             return false;
1543         }
1544         for (i = 0; i < len; i++) {
1545             if (a0[i] !== a1[i]) {
1546                 return false;
1547             }
1548         }
1549         return true;
1550     }
1551
1552     function memoize(workerFunc) {
1553         var args;
1554         var res;
1555         return function () {
1556             if (!args || !isArraysEqual(args, arguments)) {
1557                 args = arguments;
1558                 res = workerFunc.apply(this, arguments);
1559             }
1560             return res;
1561         };
1562     }
1563     /*
1564     always executes the workerFunc, but if the result is equal to the previous result,
1565     return the previous result instead.
1566     */
1567     function memoizeOutput(workerFunc, equalityFunc) {
1568         var cachedRes = null;
1569         return function () {
1570             var newRes = workerFunc.apply(this, arguments);
1571             if (cachedRes === null || !(cachedRes === newRes || equalityFunc(cachedRes, newRes))) {
1572                 cachedRes = newRes;
1573             }
1574             return cachedRes;
1575         };
1576     }
1577
1578     var EXTENDED_SETTINGS_AND_SEVERITIES = {
1579         week: 3,
1580         separator: 0,
1581         omitZeroMinute: 0,
1582         meridiem: 0,
1583         omitCommas: 0
1584     };
1585     var STANDARD_DATE_PROP_SEVERITIES = {
1586         timeZoneName: 7,
1587         era: 6,
1588         year: 5,
1589         month: 4,
1590         day: 2,
1591         weekday: 2,
1592         hour: 1,
1593         minute: 1,
1594         second: 1
1595     };
1596     var MERIDIEM_RE = /\s*([ap])\.?m\.?/i; // eats up leading spaces too
1597     var COMMA_RE = /,/g; // we need re for globalness
1598     var MULTI_SPACE_RE = /\s+/g;
1599     var LTR_RE = /\u200e/g; // control character
1600     var UTC_RE = /UTC|GMT/;
1601     var NativeFormatter = /** @class */ (function () {
1602         function NativeFormatter(formatSettings) {
1603             var standardDateProps = {};
1604             var extendedSettings = {};
1605             var severity = 0;
1606             for (var name_1 in formatSettings) {
1607                 if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) {
1608                     extendedSettings[name_1] = formatSettings[name_1];
1609                     severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity);
1610                 }
1611                 else {
1612                     standardDateProps[name_1] = formatSettings[name_1];
1613                     if (name_1 in STANDARD_DATE_PROP_SEVERITIES) {
1614                         severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity);
1615                     }
1616                 }
1617             }
1618             this.standardDateProps = standardDateProps;
1619             this.extendedSettings = extendedSettings;
1620             this.severity = severity;
1621             this.buildFormattingFunc = memoize(buildFormattingFunc);
1622         }
1623         NativeFormatter.prototype.format = function (date, context) {
1624             return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
1625         };
1626         NativeFormatter.prototype.formatRange = function (start, end, context) {
1627             var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings;
1628             var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
1629             if (!diffSeverity) {
1630                 return this.format(start, context);
1631             }
1632             var biggestUnitForPartial = diffSeverity;
1633             if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time
1634                 (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&
1635                 (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&
1636                 (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
1637                 biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time
1638             }
1639             var full0 = this.format(start, context);
1640             var full1 = this.format(end, context);
1641             if (full0 === full1) {
1642                 return full0;
1643             }
1644             var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial);
1645             var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
1646             var partial0 = partialFormattingFunc(start);
1647             var partial1 = partialFormattingFunc(end);
1648             var insertion = findCommonInsertion(full0, partial0, full1, partial1);
1649             var separator = extendedSettings.separator || '';
1650             if (insertion) {
1651                 return insertion.before + partial0 + separator + partial1 + insertion.after;
1652             }
1653             return full0 + separator + full1;
1654         };
1655         NativeFormatter.prototype.getLargestUnit = function () {
1656             switch (this.severity) {
1657                 case 7:
1658                 case 6:
1659                 case 5:
1660                     return 'year';
1661                 case 4:
1662                     return 'month';
1663                 case 3:
1664                     return 'week';
1665                 default:
1666                     return 'day';
1667             }
1668         };
1669         return NativeFormatter;
1670     }());
1671     function buildFormattingFunc(standardDateProps, extendedSettings, context) {
1672         var standardDatePropCnt = Object.keys(standardDateProps).length;
1673         if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
1674             return function (date) {
1675                 return formatTimeZoneOffset(date.timeZoneOffset);
1676             };
1677         }
1678         if (standardDatePropCnt === 0 && extendedSettings.week) {
1679             return function (date) {
1680                 return formatWeekNumber(context.computeWeekNumber(date.marker), context.weekLabel, context.locale, extendedSettings.week);
1681             };
1682         }
1683         return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
1684     }
1685     function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
1686         standardDateProps = __assign({}, standardDateProps); // copy
1687         extendedSettings = __assign({}, extendedSettings); // copy
1688         sanitizeSettings(standardDateProps, extendedSettings);
1689         standardDateProps.timeZone = 'UTC'; // we leverage the only guaranteed timeZone for our UTC markers
1690         var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
1691         var zeroFormat; // needed?
1692         if (extendedSettings.omitZeroMinute) {
1693             var zeroProps = __assign({}, standardDateProps);
1694             delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings
1695             zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
1696         }
1697         return function (date) {
1698             var marker = date.marker;
1699             var format;
1700             if (zeroFormat && !marker.getUTCMinutes()) {
1701                 format = zeroFormat;
1702             }
1703             else {
1704                 format = normalFormat;
1705             }
1706             var s = format.format(marker);
1707             return postProcess(s, date, standardDateProps, extendedSettings, context);
1708         };
1709     }
1710     function sanitizeSettings(standardDateProps, extendedSettings) {
1711         // deal with a browser inconsistency where formatting the timezone
1712         // requires that the hour/minute be present.
1713         if (standardDateProps.timeZoneName) {
1714             if (!standardDateProps.hour) {
1715                 standardDateProps.hour = '2-digit';
1716             }
1717             if (!standardDateProps.minute) {
1718                 standardDateProps.minute = '2-digit';
1719             }
1720         }
1721         // only support short timezone names
1722         if (standardDateProps.timeZoneName === 'long') {
1723             standardDateProps.timeZoneName = 'short';
1724         }
1725         // if requesting to display seconds, MUST display minutes
1726         if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
1727             delete extendedSettings.omitZeroMinute;
1728         }
1729     }
1730     function postProcess(s, date, standardDateProps, extendedSettings, context) {
1731         s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes
1732         if (standardDateProps.timeZoneName === 'short') {
1733             s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?
1734                 'UTC' : // important to normalize for IE, which does "GMT"
1735                 formatTimeZoneOffset(date.timeZoneOffset));
1736         }
1737         if (extendedSettings.omitCommas) {
1738             s = s.replace(COMMA_RE, '').trim();
1739         }
1740         if (extendedSettings.omitZeroMinute) {
1741             s = s.replace(':00', ''); // zeroFormat doesn't always achieve this
1742         }
1743         // ^ do anything that might create adjacent spaces before this point,
1744         // because MERIDIEM_RE likes to eat up loading spaces
1745         if (extendedSettings.meridiem === false) {
1746             s = s.replace(MERIDIEM_RE, '').trim();
1747         }
1748         else if (extendedSettings.meridiem === 'narrow') { // a/p
1749             s = s.replace(MERIDIEM_RE, function (m0, m1) {
1750                 return m1.toLocaleLowerCase();
1751             });
1752         }
1753         else if (extendedSettings.meridiem === 'short') { // am/pm
1754             s = s.replace(MERIDIEM_RE, function (m0, m1) {
1755                 return m1.toLocaleLowerCase() + 'm';
1756             });
1757         }
1758         else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase
1759             s = s.replace(MERIDIEM_RE, function (m0) {
1760                 return m0.toLocaleLowerCase();
1761             });
1762         }
1763         s = s.replace(MULTI_SPACE_RE, ' ');
1764         s = s.trim();
1765         return s;
1766     }
1767     function injectTzoStr(s, tzoStr) {
1768         var replaced = false;
1769         s = s.replace(UTC_RE, function () {
1770             replaced = true;
1771             return tzoStr;
1772         });
1773         // IE11 doesn't include UTC/GMT in the original string, so append to end
1774         if (!replaced) {
1775             s += ' ' + tzoStr;
1776         }
1777         return s;
1778     }
1779     function formatWeekNumber(num, weekLabel, locale, display) {
1780         var parts = [];
1781         if (display === 'narrow') {
1782             parts.push(weekLabel);
1783         }
1784         else if (display === 'short') {
1785             parts.push(weekLabel, ' ');
1786         }
1787         // otherwise, considered 'numeric'
1788         parts.push(locale.simpleNumberFormat.format(num));
1789         if (locale.options.isRtl) { // TODO: use control characters instead?
1790             parts.reverse();
1791         }
1792         return parts.join('');
1793     }
1794     // Range Formatting Utils
1795     // 0 = exactly the same
1796     // 1 = different by time
1797     // and bigger
1798     function computeMarkerDiffSeverity(d0, d1, ca) {
1799         if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
1800             return 5;
1801         }
1802         if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
1803             return 4;
1804         }
1805         if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
1806             return 2;
1807         }
1808         if (timeAsMs(d0) !== timeAsMs(d1)) {
1809             return 1;
1810         }
1811         return 0;
1812     }
1813     function computePartialFormattingOptions(options, biggestUnit) {
1814         var partialOptions = {};
1815         for (var name_2 in options) {
1816             if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)
1817                 STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) {
1818                 partialOptions[name_2] = options[name_2];
1819             }
1820         }
1821         return partialOptions;
1822     }
1823     function findCommonInsertion(full0, partial0, full1, partial1) {
1824         var i0 = 0;
1825         while (i0 < full0.length) {
1826             var found0 = full0.indexOf(partial0, i0);
1827             if (found0 === -1) {
1828                 break;
1829             }
1830             var before0 = full0.substr(0, found0);
1831             i0 = found0 + partial0.length;
1832             var after0 = full0.substr(i0);
1833             var i1 = 0;
1834             while (i1 < full1.length) {
1835                 var found1 = full1.indexOf(partial1, i1);
1836                 if (found1 === -1) {
1837                     break;
1838                 }
1839                 var before1 = full1.substr(0, found1);
1840                 i1 = found1 + partial1.length;
1841                 var after1 = full1.substr(i1);
1842                 if (before0 === before1 && after0 === after1) {
1843                     return {
1844                         before: before0,
1845                         after: after0
1846                     };
1847                 }
1848             }
1849         }
1850         return null;
1851     }
1852
1853     /*
1854     TODO: fix the terminology of "formatter" vs "formatting func"
1855     */
1856     /*
1857     At the time of instantiation, this object does not know which cmd-formatting system it will use.
1858     It receives this at the time of formatting, as a setting.
1859     */
1860     var CmdFormatter = /** @class */ (function () {
1861         function CmdFormatter(cmdStr, separator) {
1862             this.cmdStr = cmdStr;
1863             this.separator = separator;
1864         }
1865         CmdFormatter.prototype.format = function (date, context) {
1866             return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, this.separator));
1867         };
1868         CmdFormatter.prototype.formatRange = function (start, end, context) {
1869             return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, this.separator));
1870         };
1871         return CmdFormatter;
1872     }());
1873
1874     var FuncFormatter = /** @class */ (function () {
1875         function FuncFormatter(func) {
1876             this.func = func;
1877         }
1878         FuncFormatter.prototype.format = function (date, context) {
1879             return this.func(createVerboseFormattingArg(date, null, context));
1880         };
1881         FuncFormatter.prototype.formatRange = function (start, end, context) {
1882             return this.func(createVerboseFormattingArg(start, end, context));
1883         };
1884         return FuncFormatter;
1885     }());
1886
1887     // Formatter Object Creation
1888     function createFormatter(input, defaultSeparator) {
1889         if (typeof input === 'object' && input) { // non-null object
1890             if (typeof defaultSeparator === 'string') {
1891                 input = __assign({ separator: defaultSeparator }, input);
1892             }
1893             return new NativeFormatter(input);
1894         }
1895         else if (typeof input === 'string') {
1896             return new CmdFormatter(input, defaultSeparator);
1897         }
1898         else if (typeof input === 'function') {
1899             return new FuncFormatter(input);
1900         }
1901     }
1902     // String Utils
1903     // timeZoneOffset is in minutes
1904     function buildIsoString(marker, timeZoneOffset, stripZeroTime) {
1905         if (stripZeroTime === void 0) { stripZeroTime = false; }
1906         var s = marker.toISOString();
1907         s = s.replace('.000', '');
1908         if (stripZeroTime) {
1909             s = s.replace('T00:00:00Z', '');
1910         }
1911         if (s.length > 10) { // time part wasn't stripped, can add timezone info
1912             if (timeZoneOffset == null) {
1913                 s = s.replace('Z', '');
1914             }
1915             else if (timeZoneOffset !== 0) {
1916                 s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
1917             }
1918             // otherwise, its UTC-0 and we want to keep the Z
1919         }
1920         return s;
1921     }
1922     function formatIsoTimeString(marker) {
1923         return padStart(marker.getUTCHours(), 2) + ':' +
1924             padStart(marker.getUTCMinutes(), 2) + ':' +
1925             padStart(marker.getUTCSeconds(), 2);
1926     }
1927     function formatTimeZoneOffset(minutes, doIso) {
1928         if (doIso === void 0) { doIso = false; }
1929         var sign = minutes < 0 ? '-' : '+';
1930         var abs = Math.abs(minutes);
1931         var hours = Math.floor(abs / 60);
1932         var mins = Math.round(abs % 60);
1933         if (doIso) {
1934             return sign + padStart(hours, 2) + ':' + padStart(mins, 2);
1935         }
1936         else {
1937             return 'GMT' + sign + hours + (mins ? ':' + padStart(mins, 2) : '');
1938         }
1939     }
1940     // Arg Utils
1941     function createVerboseFormattingArg(start, end, context, separator) {
1942         var startInfo = expandZonedMarker(start, context.calendarSystem);
1943         var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
1944         return {
1945             date: startInfo,
1946             start: startInfo,
1947             end: endInfo,
1948             timeZone: context.timeZone,
1949             localeCodes: context.locale.codes,
1950             separator: separator
1951         };
1952     }
1953     function expandZonedMarker(dateInfo, calendarSystem) {
1954         var a = calendarSystem.markerToArray(dateInfo.marker);
1955         return {
1956             marker: dateInfo.marker,
1957             timeZoneOffset: dateInfo.timeZoneOffset,
1958             array: a,
1959             year: a[0],
1960             month: a[1],
1961             day: a[2],
1962             hour: a[3],
1963             minute: a[4],
1964             second: a[5],
1965             millisecond: a[6]
1966         };
1967     }
1968
1969     var EventSourceApi = /** @class */ (function () {
1970         function EventSourceApi(calendar, internalEventSource) {
1971             this.calendar = calendar;
1972             this.internalEventSource = internalEventSource;
1973         }
1974         EventSourceApi.prototype.remove = function () {
1975             this.calendar.dispatch({
1976                 type: 'REMOVE_EVENT_SOURCE',
1977                 sourceId: this.internalEventSource.sourceId
1978             });
1979         };
1980         EventSourceApi.prototype.refetch = function () {
1981             this.calendar.dispatch({
1982                 type: 'FETCH_EVENT_SOURCES',
1983                 sourceIds: [this.internalEventSource.sourceId]
1984             });
1985         };
1986         Object.defineProperty(EventSourceApi.prototype, "id", {
1987             get: function () {
1988                 return this.internalEventSource.publicId;
1989             },
1990             enumerable: true,
1991             configurable: true
1992         });
1993         Object.defineProperty(EventSourceApi.prototype, "url", {
1994             // only relevant to json-feed event sources
1995             get: function () {
1996                 return this.internalEventSource.meta.url;
1997             },
1998             enumerable: true,
1999             configurable: true
2000         });
2001         return EventSourceApi;
2002     }());
2003
2004     var EventApi = /** @class */ (function () {
2005         function EventApi(calendar, def, instance) {
2006             this._calendar = calendar;
2007             this._def = def;
2008             this._instance = instance || null;
2009         }
2010         /*
2011         TODO: make event struct more responsible for this
2012         */
2013         EventApi.prototype.setProp = function (name, val) {
2014             var _a, _b;
2015             if (name in DATE_PROPS) ;
2016             else if (name in NON_DATE_PROPS) {
2017                 if (typeof NON_DATE_PROPS[name] === 'function') {
2018                     val = NON_DATE_PROPS[name](val);
2019                 }
2020                 this.mutate({
2021                     standardProps: (_a = {}, _a[name] = val, _a)
2022                 });
2023             }
2024             else if (name in UNSCOPED_EVENT_UI_PROPS) {
2025                 var ui = void 0;
2026                 if (typeof UNSCOPED_EVENT_UI_PROPS[name] === 'function') {
2027                     val = UNSCOPED_EVENT_UI_PROPS[name](val);
2028                 }
2029                 if (name === 'color') {
2030                     ui = { backgroundColor: val, borderColor: val };
2031                 }
2032                 else if (name === 'editable') {
2033                     ui = { startEditable: val, durationEditable: val };
2034                 }
2035                 else {
2036                     ui = (_b = {}, _b[name] = val, _b);
2037                 }
2038                 this.mutate({
2039                     standardProps: { ui: ui }
2040                 });
2041             }
2042         };
2043         EventApi.prototype.setExtendedProp = function (name, val) {
2044             var _a;
2045             this.mutate({
2046                 extendedProps: (_a = {}, _a[name] = val, _a)
2047             });
2048         };
2049         EventApi.prototype.setStart = function (startInput, options) {
2050             if (options === void 0) { options = {}; }
2051             var dateEnv = this._calendar.dateEnv;
2052             var start = dateEnv.createMarker(startInput);
2053             if (start && this._instance) { // TODO: warning if parsed bad
2054                 var instanceRange = this._instance.range;
2055                 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?
2056                 if (options.maintainDuration) {
2057                     this.mutate({ datesDelta: startDelta });
2058                 }
2059                 else {
2060                     this.mutate({ startDelta: startDelta });
2061                 }
2062             }
2063         };
2064         EventApi.prototype.setEnd = function (endInput, options) {
2065             if (options === void 0) { options = {}; }
2066             var dateEnv = this._calendar.dateEnv;
2067             var end;
2068             if (endInput != null) {
2069                 end = dateEnv.createMarker(endInput);
2070                 if (!end) {
2071                     return; // TODO: warning if parsed bad
2072                 }
2073             }
2074             if (this._instance) {
2075                 if (end) {
2076                     var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
2077                     this.mutate({ endDelta: endDelta });
2078                 }
2079                 else {
2080                     this.mutate({ standardProps: { hasEnd: false } });
2081                 }
2082             }
2083         };
2084         EventApi.prototype.setDates = function (startInput, endInput, options) {
2085             if (options === void 0) { options = {}; }
2086             var dateEnv = this._calendar.dateEnv;
2087             var standardProps = { allDay: options.allDay };
2088             var start = dateEnv.createMarker(startInput);
2089             var end;
2090             if (!start) {
2091                 return; // TODO: warning if parsed bad
2092             }
2093             if (endInput != null) {
2094                 end = dateEnv.createMarker(endInput);
2095                 if (!end) { // TODO: warning if parsed bad
2096                     return;
2097                 }
2098             }
2099             if (this._instance) {
2100                 var instanceRange = this._instance.range;
2101                 // when computing the diff for an event being converted to all-day,
2102                 // compute diff off of the all-day values the way event-mutation does.
2103                 if (options.allDay === true) {
2104                     instanceRange = computeAlignedDayRange(instanceRange);
2105                 }
2106                 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
2107                 if (end) {
2108                     var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
2109                     if (durationsEqual(startDelta, endDelta)) {
2110                         this.mutate({ datesDelta: startDelta, standardProps: standardProps });
2111                     }
2112                     else {
2113                         this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps });
2114                     }
2115                 }
2116                 else { // means "clear the end"
2117                     standardProps.hasEnd = false;
2118                     this.mutate({ datesDelta: startDelta, standardProps: standardProps });
2119                 }
2120             }
2121         };
2122         EventApi.prototype.moveStart = function (deltaInput) {
2123             var delta = createDuration(deltaInput);
2124             if (delta) { // TODO: warning if parsed bad
2125                 this.mutate({ startDelta: delta });
2126             }
2127         };
2128         EventApi.prototype.moveEnd = function (deltaInput) {
2129             var delta = createDuration(deltaInput);
2130             if (delta) { // TODO: warning if parsed bad
2131                 this.mutate({ endDelta: delta });
2132             }
2133         };
2134         EventApi.prototype.moveDates = function (deltaInput) {
2135             var delta = createDuration(deltaInput);
2136             if (delta) { // TODO: warning if parsed bad
2137                 this.mutate({ datesDelta: delta });
2138             }
2139         };
2140         EventApi.prototype.setAllDay = function (allDay, options) {
2141             if (options === void 0) { options = {}; }
2142             var standardProps = { allDay: allDay };
2143             var maintainDuration = options.maintainDuration;
2144             if (maintainDuration == null) {
2145                 maintainDuration = this._calendar.opt('allDayMaintainDuration');
2146             }
2147             if (this._def.allDay !== allDay) {
2148                 standardProps.hasEnd = maintainDuration;
2149             }
2150             this.mutate({ standardProps: standardProps });
2151         };
2152         EventApi.prototype.formatRange = function (formatInput) {
2153             var dateEnv = this._calendar.dateEnv;
2154             var instance = this._instance;
2155             var formatter = createFormatter(formatInput, this._calendar.opt('defaultRangeSeparator'));
2156             if (this._def.hasEnd) {
2157                 return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
2158                     forcedStartTzo: instance.forcedStartTzo,
2159                     forcedEndTzo: instance.forcedEndTzo
2160                 });
2161             }
2162             else {
2163                 return dateEnv.format(instance.range.start, formatter, {
2164                     forcedTzo: instance.forcedStartTzo
2165                 });
2166             }
2167         };
2168         EventApi.prototype.mutate = function (mutation) {
2169             var def = this._def;
2170             var instance = this._instance;
2171             if (instance) {
2172                 this._calendar.dispatch({
2173                     type: 'MUTATE_EVENTS',
2174                     instanceId: instance.instanceId,
2175                     mutation: mutation,
2176                     fromApi: true
2177                 });
2178                 var eventStore = this._calendar.state.eventStore;
2179                 this._def = eventStore.defs[def.defId];
2180                 this._instance = eventStore.instances[instance.instanceId];
2181             }
2182         };
2183         EventApi.prototype.remove = function () {
2184             this._calendar.dispatch({
2185                 type: 'REMOVE_EVENT_DEF',
2186                 defId: this._def.defId
2187             });
2188         };
2189         Object.defineProperty(EventApi.prototype, "source", {
2190             get: function () {
2191                 var sourceId = this._def.sourceId;
2192                 if (sourceId) {
2193                     return new EventSourceApi(this._calendar, this._calendar.state.eventSources[sourceId]);
2194                 }
2195                 return null;
2196             },
2197             enumerable: true,
2198             configurable: true
2199         });
2200         Object.defineProperty(EventApi.prototype, "start", {
2201             get: function () {
2202                 return this._instance ?
2203                     this._calendar.dateEnv.toDate(this._instance.range.start) :
2204                     null;
2205             },
2206             enumerable: true,
2207             configurable: true
2208         });
2209         Object.defineProperty(EventApi.prototype, "end", {
2210             get: function () {
2211                 return (this._instance && this._def.hasEnd) ?
2212                     this._calendar.dateEnv.toDate(this._instance.range.end) :
2213                     null;
2214             },
2215             enumerable: true,
2216             configurable: true
2217         });
2218         Object.defineProperty(EventApi.prototype, "id", {
2219             // computable props that all access the def
2220             // TODO: find a TypeScript-compatible way to do this at scale
2221             get: function () { return this._def.publicId; },
2222             enumerable: true,
2223             configurable: true
2224         });
2225         Object.defineProperty(EventApi.prototype, "groupId", {
2226             get: function () { return this._def.groupId; },
2227             enumerable: true,
2228             configurable: true
2229         });
2230         Object.defineProperty(EventApi.prototype, "allDay", {
2231             get: function () { return this._def.allDay; },
2232             enumerable: true,
2233             configurable: true
2234         });
2235         Object.defineProperty(EventApi.prototype, "title", {
2236             get: function () { return this._def.title; },
2237             enumerable: true,
2238             configurable: true
2239         });
2240         Object.defineProperty(EventApi.prototype, "url", {
2241             get: function () { return this._def.url; },
2242             enumerable: true,
2243             configurable: true
2244         });
2245         Object.defineProperty(EventApi.prototype, "rendering", {
2246             get: function () { return this._def.rendering; },
2247             enumerable: true,
2248             configurable: true
2249         });
2250         Object.defineProperty(EventApi.prototype, "startEditable", {
2251             get: function () { return this._def.ui.startEditable; },
2252             enumerable: true,
2253             configurable: true
2254         });
2255         Object.defineProperty(EventApi.prototype, "durationEditable", {
2256             get: function () { return this._def.ui.durationEditable; },
2257             enumerable: true,
2258             configurable: true
2259         });
2260         Object.defineProperty(EventApi.prototype, "constraint", {
2261             get: function () { return this._def.ui.constraints[0] || null; },
2262             enumerable: true,
2263             configurable: true
2264         });
2265         Object.defineProperty(EventApi.prototype, "overlap", {
2266             get: function () { return this._def.ui.overlap; },
2267             enumerable: true,
2268             configurable: true
2269         });
2270         Object.defineProperty(EventApi.prototype, "allow", {
2271             get: function () { return this._def.ui.allows[0] || null; },
2272             enumerable: true,
2273             configurable: true
2274         });
2275         Object.defineProperty(EventApi.prototype, "backgroundColor", {
2276             get: function () { return this._def.ui.backgroundColor; },
2277             enumerable: true,
2278             configurable: true
2279         });
2280         Object.defineProperty(EventApi.prototype, "borderColor", {
2281             get: function () { return this._def.ui.borderColor; },
2282             enumerable: true,
2283             configurable: true
2284         });
2285         Object.defineProperty(EventApi.prototype, "textColor", {
2286             get: function () { return this._def.ui.textColor; },
2287             enumerable: true,
2288             configurable: true
2289         });
2290         Object.defineProperty(EventApi.prototype, "classNames", {
2291             // NOTE: user can't modify these because Object.freeze was called in event-def parsing
2292             get: function () { return this._def.ui.classNames; },
2293             enumerable: true,
2294             configurable: true
2295         });
2296         Object.defineProperty(EventApi.prototype, "extendedProps", {
2297             get: function () { return this._def.extendedProps; },
2298             enumerable: true,
2299             configurable: true
2300         });
2301         return EventApi;
2302     }());
2303
2304     /*
2305     Specifying nextDayThreshold signals that all-day ranges should be sliced.
2306     */
2307     function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
2308         var inverseBgByGroupId = {};
2309         var inverseBgByDefId = {};
2310         var defByGroupId = {};
2311         var bgRanges = [];
2312         var fgRanges = [];
2313         var eventUis = compileEventUis(eventStore.defs, eventUiBases);
2314         for (var defId in eventStore.defs) {
2315             var def = eventStore.defs[defId];
2316             if (def.rendering === 'inverse-background') {
2317                 if (def.groupId) {
2318                     inverseBgByGroupId[def.groupId] = [];
2319                     if (!defByGroupId[def.groupId]) {
2320                         defByGroupId[def.groupId] = def;
2321                     }
2322                 }
2323                 else {
2324                     inverseBgByDefId[defId] = [];
2325                 }
2326             }
2327         }
2328         for (var instanceId in eventStore.instances) {
2329             var instance = eventStore.instances[instanceId];
2330             var def = eventStore.defs[instance.defId];
2331             var ui = eventUis[def.defId];
2332             var origRange = instance.range;
2333             var normalRange = (!def.allDay && nextDayThreshold) ?
2334                 computeVisibleDayRange(origRange, nextDayThreshold) :
2335                 origRange;
2336             var slicedRange = intersectRanges(normalRange, framingRange);
2337             if (slicedRange) {
2338                 if (def.rendering === 'inverse-background') {
2339                     if (def.groupId) {
2340                         inverseBgByGroupId[def.groupId].push(slicedRange);
2341                     }
2342                     else {
2343                         inverseBgByDefId[instance.defId].push(slicedRange);
2344                     }
2345                 }
2346                 else {
2347                     (def.rendering === 'background' ? bgRanges : fgRanges).push({
2348                         def: def,
2349                         ui: ui,
2350                         instance: instance,
2351                         range: slicedRange,
2352                         isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
2353                         isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf()
2354                     });
2355                 }
2356             }
2357         }
2358         for (var groupId in inverseBgByGroupId) { // BY GROUP
2359             var ranges = inverseBgByGroupId[groupId];
2360             var invertedRanges = invertRanges(ranges, framingRange);
2361             for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) {
2362                 var invertedRange = invertedRanges_1[_i];
2363                 var def = defByGroupId[groupId];
2364                 var ui = eventUis[def.defId];
2365                 bgRanges.push({
2366                     def: def,
2367                     ui: ui,
2368                     instance: null,
2369                     range: invertedRange,
2370                     isStart: false,
2371                     isEnd: false
2372                 });
2373             }
2374         }
2375         for (var defId in inverseBgByDefId) {
2376             var ranges = inverseBgByDefId[defId];
2377             var invertedRanges = invertRanges(ranges, framingRange);
2378             for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) {
2379                 var invertedRange = invertedRanges_2[_a];
2380                 bgRanges.push({
2381                     def: eventStore.defs[defId],
2382                     ui: eventUis[defId],
2383                     instance: null,
2384                     range: invertedRange,
2385                     isStart: false,
2386                     isEnd: false
2387                 });
2388             }
2389         }
2390         return { bg: bgRanges, fg: fgRanges };
2391     }
2392     function hasBgRendering(def) {
2393         return def.rendering === 'background' || def.rendering === 'inverse-background';
2394     }
2395     function filterSegsViaEls(view, segs, isMirror) {
2396         if (view.hasPublicHandlers('eventRender')) {
2397             segs = segs.filter(function (seg) {
2398                 var custom = view.publiclyTrigger('eventRender', [
2399                     {
2400                         event: new EventApi(view.calendar, seg.eventRange.def, seg.eventRange.instance),
2401                         isMirror: isMirror,
2402                         isStart: seg.isStart,
2403                         isEnd: seg.isEnd,
2404                         // TODO: include seg.range once all components consistently generate it
2405                         el: seg.el,
2406                         view: view
2407                     }
2408                 ]);
2409                 if (custom === false) { // means don't render at all
2410                     return false;
2411                 }
2412                 else if (custom && custom !== true) {
2413                     seg.el = custom;
2414                 }
2415                 return true;
2416             });
2417         }
2418         for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
2419             var seg = segs_1[_i];
2420             setElSeg(seg.el, seg);
2421         }
2422         return segs;
2423     }
2424     function setElSeg(el, seg) {
2425         el.fcSeg = seg;
2426     }
2427     function getElSeg(el) {
2428         return el.fcSeg || null;
2429     }
2430     // event ui computation
2431     function compileEventUis(eventDefs, eventUiBases) {
2432         return mapHash(eventDefs, function (eventDef) {
2433             return compileEventUi(eventDef, eventUiBases);
2434         });
2435     }
2436     function compileEventUi(eventDef, eventUiBases) {
2437         var uis = [];
2438         if (eventUiBases['']) {
2439             uis.push(eventUiBases['']);
2440         }
2441         if (eventUiBases[eventDef.defId]) {
2442             uis.push(eventUiBases[eventDef.defId]);
2443         }
2444         uis.push(eventDef.ui);
2445         return combineEventUis(uis);
2446     }
2447
2448     // applies the mutation to ALL defs/instances within the event store
2449     function applyMutationToEventStore(eventStore, eventConfigBase, mutation, calendar) {
2450         var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
2451         var dest = createEmptyEventStore();
2452         for (var defId in eventStore.defs) {
2453             var def = eventStore.defs[defId];
2454             dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, calendar.pluginSystem.hooks.eventDefMutationAppliers, calendar);
2455         }
2456         for (var instanceId in eventStore.instances) {
2457             var instance = eventStore.instances[instanceId];
2458             var def = dest.defs[instance.defId]; // important to grab the newly modified def
2459             dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, calendar);
2460         }
2461         return dest;
2462     }
2463     function applyMutationToEventDef(eventDef, eventConfig, mutation, appliers, calendar) {
2464         var standardProps = mutation.standardProps || {};
2465         // if hasEnd has not been specified, guess a good value based on deltas.
2466         // if duration will change, there's no way the default duration will persist,
2467         // and thus, we need to mark the event as having a real end
2468         if (standardProps.hasEnd == null &&
2469             eventConfig.durationEditable &&
2470             (mutation.startDelta || mutation.endDelta)) {
2471             standardProps.hasEnd = true; // TODO: is this mutation okay?
2472         }
2473         var copy = __assign({}, eventDef, standardProps, { ui: __assign({}, eventDef.ui, standardProps.ui) });
2474         if (mutation.extendedProps) {
2475             copy.extendedProps = __assign({}, copy.extendedProps, mutation.extendedProps);
2476         }
2477         for (var _i = 0, appliers_1 = appliers; _i < appliers_1.length; _i++) {
2478             var applier = appliers_1[_i];
2479             applier(copy, mutation, calendar);
2480         }
2481         if (!copy.hasEnd && calendar.opt('forceEventDuration')) {
2482             copy.hasEnd = true;
2483         }
2484         return copy;
2485     }
2486     function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
2487     eventConfig, mutation, calendar) {
2488         var dateEnv = calendar.dateEnv;
2489         var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
2490         var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
2491         var copy = __assign({}, eventInstance);
2492         if (forceAllDay) {
2493             copy.range = computeAlignedDayRange(copy.range);
2494         }
2495         if (mutation.datesDelta && eventConfig.startEditable) {
2496             copy.range = {
2497                 start: dateEnv.add(copy.range.start, mutation.datesDelta),
2498                 end: dateEnv.add(copy.range.end, mutation.datesDelta)
2499             };
2500         }
2501         if (mutation.startDelta && eventConfig.durationEditable) {
2502             copy.range = {
2503                 start: dateEnv.add(copy.range.start, mutation.startDelta),
2504                 end: copy.range.end
2505             };
2506         }
2507         if (mutation.endDelta && eventConfig.durationEditable) {
2508             copy.range = {
2509                 start: copy.range.start,
2510                 end: dateEnv.add(copy.range.end, mutation.endDelta)
2511             };
2512         }
2513         if (clearEnd) {
2514             copy.range = {
2515                 start: copy.range.start,
2516                 end: calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start)
2517             };
2518         }
2519         // in case event was all-day but the supplied deltas were not
2520         // better util for this?
2521         if (eventDef.allDay) {
2522             copy.range = {
2523                 start: startOfDay(copy.range.start),
2524                 end: startOfDay(copy.range.end)
2525             };
2526         }
2527         // handle invalid durations
2528         if (copy.range.end < copy.range.start) {
2529             copy.range.end = calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start);
2530         }
2531         return copy;
2532     }
2533
2534     function reduceEventStore (eventStore, action, eventSources, dateProfile, calendar) {
2535         switch (action.type) {
2536             case 'RECEIVE_EVENTS': // raw
2537                 return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, calendar);
2538             case 'ADD_EVENTS': // already parsed, but not expanded
2539                 return addEvent(eventStore, action.eventStore, // new ones
2540                 dateProfile ? dateProfile.activeRange : null, calendar);
2541             case 'MERGE_EVENTS': // already parsed and expanded
2542                 return mergeEventStores(eventStore, action.eventStore);
2543             case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
2544             case 'NEXT':
2545             case 'SET_DATE':
2546             case 'SET_VIEW_TYPE':
2547                 if (dateProfile) {
2548                     return expandRecurring(eventStore, dateProfile.activeRange, calendar);
2549                 }
2550                 else {
2551                     return eventStore;
2552                 }
2553             case 'CHANGE_TIMEZONE':
2554                 return rezoneDates(eventStore, action.oldDateEnv, calendar.dateEnv);
2555             case 'MUTATE_EVENTS':
2556                 return applyMutationToRelated(eventStore, action.instanceId, action.mutation, action.fromApi, calendar);
2557             case 'REMOVE_EVENT_INSTANCES':
2558                 return excludeInstances(eventStore, action.instances);
2559             case 'REMOVE_EVENT_DEF':
2560                 return filterEventStoreDefs(eventStore, function (eventDef) {
2561                     return eventDef.defId !== action.defId;
2562                 });
2563             case 'REMOVE_EVENT_SOURCE':
2564                 return excludeEventsBySourceId(eventStore, action.sourceId);
2565             case 'REMOVE_ALL_EVENT_SOURCES':
2566                 return filterEventStoreDefs(eventStore, function (eventDef) {
2567                     return !eventDef.sourceId; // only keep events with no source id
2568                 });
2569             case 'REMOVE_ALL_EVENTS':
2570                 return createEmptyEventStore();
2571             case 'RESET_EVENTS':
2572                 return {
2573                     defs: eventStore.defs,
2574                     instances: eventStore.instances
2575                 };
2576             default:
2577                 return eventStore;
2578         }
2579     }
2580     function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, calendar) {
2581         if (eventSource && // not already removed
2582             fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
2583         ) {
2584             var subset = parseEvents(transformRawEvents(rawEvents, eventSource, calendar), eventSource.sourceId, calendar);
2585             if (fetchRange) {
2586                 subset = expandRecurring(subset, fetchRange, calendar);
2587             }
2588             return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
2589         }
2590         return eventStore;
2591     }
2592     function addEvent(eventStore, subset, expandRange, calendar) {
2593         if (expandRange) {
2594             subset = expandRecurring(subset, expandRange, calendar);
2595         }
2596         return mergeEventStores(eventStore, subset);
2597     }
2598     function rezoneDates(eventStore, oldDateEnv, newDateEnv) {
2599         var defs = eventStore.defs;
2600         var instances = mapHash(eventStore.instances, function (instance) {
2601             var def = defs[instance.defId];
2602             if (def.allDay || def.recurringDef) {
2603                 return instance; // isn't dependent on timezone
2604             }
2605             else {
2606                 return __assign({}, instance, { range: {
2607                         start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
2608                         end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo))
2609                     }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
2610             }
2611         });
2612         return { defs: defs, instances: instances };
2613     }
2614     function applyMutationToRelated(eventStore, instanceId, mutation, fromApi, calendar) {
2615         var relevant = getRelevantEvents(eventStore, instanceId);
2616         var eventConfigBase = fromApi ?
2617             { '': {
2618                     startEditable: true,
2619                     durationEditable: true,
2620                     constraints: [],
2621                     overlap: null,
2622                     allows: [],
2623                     backgroundColor: '',
2624                     borderColor: '',
2625                     textColor: '',
2626                     classNames: []
2627                 } } :
2628             calendar.eventUiBases;
2629         relevant = applyMutationToEventStore(relevant, eventConfigBase, mutation, calendar);
2630         return mergeEventStores(eventStore, relevant);
2631     }
2632     function excludeEventsBySourceId(eventStore, sourceId) {
2633         return filterEventStoreDefs(eventStore, function (eventDef) {
2634             return eventDef.sourceId !== sourceId;
2635         });
2636     }
2637     // QUESTION: why not just return instances? do a general object-property-exclusion util
2638     function excludeInstances(eventStore, removals) {
2639         return {
2640             defs: eventStore.defs,
2641             instances: filterHash(eventStore.instances, function (instance) {
2642                 return !removals[instance.instanceId];
2643             })
2644         };
2645     }
2646
2647     // high-level segmenting-aware tester functions
2648     // ------------------------------------------------------------------------------------------------------------------------
2649     function isInteractionValid(interaction, calendar) {
2650         return isNewPropsValid({ eventDrag: interaction }, calendar); // HACK: the eventDrag props is used for ALL interactions
2651     }
2652     function isDateSelectionValid(dateSelection, calendar) {
2653         return isNewPropsValid({ dateSelection: dateSelection }, calendar);
2654     }
2655     function isNewPropsValid(newProps, calendar) {
2656         var view = calendar.view;
2657         var props = __assign({ businessHours: view ? view.props.businessHours : createEmptyEventStore(), dateSelection: '', eventStore: calendar.state.eventStore, eventUiBases: calendar.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
2658         return (calendar.pluginSystem.hooks.isPropsValid || isPropsValid)(props, calendar);
2659     }
2660     function isPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2661         if (dateSpanMeta === void 0) { dateSpanMeta = {}; }
2662         if (state.eventDrag && !isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
2663             return false;
2664         }
2665         if (state.dateSelection && !isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
2666             return false;
2667         }
2668         return true;
2669     }
2670     // Moving Event Validation
2671     // ------------------------------------------------------------------------------------------------------------------------
2672     function isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2673         var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
2674         var subjectEventStore = interaction.mutatedEvents;
2675         var subjectDefs = subjectEventStore.defs;
2676         var subjectInstances = subjectEventStore.instances;
2677         var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
2678             state.eventUiBases :
2679             { '': calendar.selectionConfig } // if not a real event, validate as a selection
2680         );
2681         if (filterConfig) {
2682             subjectConfigs = mapHash(subjectConfigs, filterConfig);
2683         }
2684         var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); // exclude the subject events. TODO: exclude defs too?
2685         var otherDefs = otherEventStore.defs;
2686         var otherInstances = otherEventStore.instances;
2687         var otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
2688         for (var subjectInstanceId in subjectInstances) {
2689             var subjectInstance = subjectInstances[subjectInstanceId];
2690             var subjectRange = subjectInstance.range;
2691             var subjectConfig = subjectConfigs[subjectInstance.defId];
2692             var subjectDef = subjectDefs[subjectInstance.defId];
2693             // constraint
2694             if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, calendar)) {
2695                 return false;
2696             }
2697             // overlap
2698             var overlapFunc = calendar.opt('eventOverlap');
2699             if (typeof overlapFunc !== 'function') {
2700                 overlapFunc = null;
2701             }
2702             for (var otherInstanceId in otherInstances) {
2703                 var otherInstance = otherInstances[otherInstanceId];
2704                 // intersect! evaluate
2705                 if (rangesIntersect(subjectRange, otherInstance.range)) {
2706                     var otherOverlap = otherConfigs[otherInstance.defId].overlap;
2707                     // consider the other event's overlap. only do this if the subject event is a "real" event
2708                     if (otherOverlap === false && interaction.isEvent) {
2709                         return false;
2710                     }
2711                     if (subjectConfig.overlap === false) {
2712                         return false;
2713                     }
2714                     if (overlapFunc && !overlapFunc(new EventApi(calendar, otherDefs[otherInstance.defId], otherInstance), // still event
2715                     new EventApi(calendar, subjectDef, subjectInstance) // moving event
2716                     )) {
2717                         return false;
2718                     }
2719                 }
2720             }
2721             // allow (a function)
2722             var calendarEventStore = calendar.state.eventStore; // need global-to-calendar, not local to component (splittable)state
2723             for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) {
2724                 var subjectAllow = _a[_i];
2725                 var subjectDateSpan = __assign({}, dateSpanMeta, { range: subjectInstance.range, allDay: subjectDef.allDay });
2726                 var origDef = calendarEventStore.defs[subjectDef.defId];
2727                 var origInstance = calendarEventStore.instances[subjectInstanceId];
2728                 var eventApi = void 0;
2729                 if (origDef) { // was previously in the calendar
2730                     eventApi = new EventApi(calendar, origDef, origInstance);
2731                 }
2732                 else { // was an external event
2733                     eventApi = new EventApi(calendar, subjectDef); // no instance, because had no dates
2734                 }
2735                 if (!subjectAllow(calendar.buildDateSpanApi(subjectDateSpan), eventApi)) {
2736                     return false;
2737                 }
2738             }
2739         }
2740         return true;
2741     }
2742     // Date Selection Validation
2743     // ------------------------------------------------------------------------------------------------------------------------
2744     function isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2745         var relevantEventStore = state.eventStore;
2746         var relevantDefs = relevantEventStore.defs;
2747         var relevantInstances = relevantEventStore.instances;
2748         var selection = state.dateSelection;
2749         var selectionRange = selection.range;
2750         var selectionConfig = calendar.selectionConfig;
2751         if (filterConfig) {
2752             selectionConfig = filterConfig(selectionConfig);
2753         }
2754         // constraint
2755         if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, calendar)) {
2756             return false;
2757         }
2758         // overlap
2759         var overlapFunc = calendar.opt('selectOverlap');
2760         if (typeof overlapFunc !== 'function') {
2761             overlapFunc = null;
2762         }
2763         for (var relevantInstanceId in relevantInstances) {
2764             var relevantInstance = relevantInstances[relevantInstanceId];
2765             // intersect! evaluate
2766             if (rangesIntersect(selectionRange, relevantInstance.range)) {
2767                 if (selectionConfig.overlap === false) {
2768                     return false;
2769                 }
2770                 if (overlapFunc && !overlapFunc(new EventApi(calendar, relevantDefs[relevantInstance.defId], relevantInstance))) {
2771                     return false;
2772                 }
2773             }
2774         }
2775         // allow (a function)
2776         for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) {
2777             var selectionAllow = _a[_i];
2778             var fullDateSpan = __assign({}, dateSpanMeta, selection);
2779             if (!selectionAllow(calendar.buildDateSpanApi(fullDateSpan), null)) {
2780                 return false;
2781             }
2782         }
2783         return true;
2784     }
2785     // Constraint Utils
2786     // ------------------------------------------------------------------------------------------------------------------------
2787     function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, calendar) {
2788         for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
2789             var constraint = constraints_1[_i];
2790             if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, calendar), subjectRange)) {
2791                 return false;
2792             }
2793         }
2794         return true;
2795     }
2796     function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
2797     otherEventStore, // for if constraint is an even group ID
2798     businessHoursUnexpanded, // for if constraint is 'businessHours'
2799     calendar // for expanding businesshours
2800     ) {
2801         if (constraint === 'businessHours') {
2802             return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, calendar));
2803         }
2804         else if (typeof constraint === 'string') { // an group ID
2805             return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) {
2806                 return eventDef.groupId === constraint;
2807             }));
2808         }
2809         else if (typeof constraint === 'object' && constraint) { // non-null object
2810             return eventStoreToRanges(expandRecurring(constraint, subjectRange, calendar));
2811         }
2812         return []; // if it's false
2813     }
2814     // TODO: move to event-store file?
2815     function eventStoreToRanges(eventStore) {
2816         var instances = eventStore.instances;
2817         var ranges = [];
2818         for (var instanceId in instances) {
2819             ranges.push(instances[instanceId].range);
2820         }
2821         return ranges;
2822     }
2823     // TODO: move to geom file?
2824     function anyRangesContainRange(outerRanges, innerRange) {
2825         for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) {
2826             var outerRange = outerRanges_1[_i];
2827             if (rangeContainsRange(outerRange, innerRange)) {
2828                 return true;
2829             }
2830         }
2831         return false;
2832     }
2833     // Parsing
2834     // ------------------------------------------------------------------------------------------------------------------------
2835     function normalizeConstraint(input, calendar) {
2836         if (Array.isArray(input)) {
2837             return parseEvents(input, '', calendar, true); // allowOpenRange=true
2838         }
2839         else if (typeof input === 'object' && input) { // non-null object
2840             return parseEvents([input], '', calendar, true); // allowOpenRange=true
2841         }
2842         else if (input != null) {
2843             return String(input);
2844         }
2845         else {
2846             return null;
2847         }
2848     }
2849
2850     function htmlEscape(s) {
2851         return (s + '').replace(/&/g, '&amp;')
2852             .replace(/</g, '&lt;')
2853             .replace(/>/g, '&gt;')
2854             .replace(/'/g, '&#039;')
2855             .replace(/"/g, '&quot;')
2856             .replace(/\n/g, '<br />');
2857     }
2858     // Given a hash of CSS properties, returns a string of CSS.
2859     // Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.
2860     function cssToStr(cssProps) {
2861         var statements = [];
2862         for (var name_1 in cssProps) {
2863             var val = cssProps[name_1];
2864             if (val != null && val !== '') {
2865                 statements.push(name_1 + ':' + val);
2866             }
2867         }
2868         return statements.join(';');
2869     }
2870     // Given an object hash of HTML attribute names to values,
2871     // generates a string that can be injected between < > in HTML
2872     function attrsToStr(attrs) {
2873         var parts = [];
2874         for (var name_2 in attrs) {
2875             var val = attrs[name_2];
2876             if (val != null) {
2877                 parts.push(name_2 + '="' + htmlEscape(val) + '"');
2878             }
2879         }
2880         return parts.join(' ');
2881     }
2882     function parseClassName(raw) {
2883         if (Array.isArray(raw)) {
2884             return raw;
2885         }
2886         else if (typeof raw === 'string') {
2887             return raw.split(/\s+/);
2888         }
2889         else {
2890             return [];
2891         }
2892     }
2893
2894     var UNSCOPED_EVENT_UI_PROPS = {
2895         editable: Boolean,
2896         startEditable: Boolean,
2897         durationEditable: Boolean,
2898         constraint: null,
2899         overlap: null,
2900         allow: null,
2901         className: parseClassName,
2902         classNames: parseClassName,
2903         color: String,
2904         backgroundColor: String,
2905         borderColor: String,
2906         textColor: String
2907     };
2908     function processUnscopedUiProps(rawProps, calendar, leftovers) {
2909         var props = refineProps(rawProps, UNSCOPED_EVENT_UI_PROPS, {}, leftovers);
2910         var constraint = normalizeConstraint(props.constraint, calendar);
2911         return {
2912             startEditable: props.startEditable != null ? props.startEditable : props.editable,
2913             durationEditable: props.durationEditable != null ? props.durationEditable : props.editable,
2914             constraints: constraint != null ? [constraint] : [],
2915             overlap: props.overlap,
2916             allows: props.allow != null ? [props.allow] : [],
2917             backgroundColor: props.backgroundColor || props.color,
2918             borderColor: props.borderColor || props.color,
2919             textColor: props.textColor,
2920             classNames: props.classNames.concat(props.className)
2921         };
2922     }
2923     function processScopedUiProps(prefix, rawScoped, calendar, leftovers) {
2924         var rawUnscoped = {};
2925         var wasFound = {};
2926         for (var key in UNSCOPED_EVENT_UI_PROPS) {
2927             var scopedKey = prefix + capitaliseFirstLetter(key);
2928             rawUnscoped[key] = rawScoped[scopedKey];
2929             wasFound[scopedKey] = true;
2930         }
2931         if (prefix === 'event') {
2932             rawUnscoped.editable = rawScoped.editable; // special case. there is no 'eventEditable', just 'editable'
2933         }
2934         if (leftovers) {
2935             for (var key in rawScoped) {
2936                 if (!wasFound[key]) {
2937                     leftovers[key] = rawScoped[key];
2938                 }
2939             }
2940         }
2941         return processUnscopedUiProps(rawUnscoped, calendar);
2942     }
2943     var EMPTY_EVENT_UI = {
2944         startEditable: null,
2945         durationEditable: null,
2946         constraints: [],
2947         overlap: null,
2948         allows: [],
2949         backgroundColor: '',
2950         borderColor: '',
2951         textColor: '',
2952         classNames: []
2953     };
2954     // prevent against problems with <2 args!
2955     function combineEventUis(uis) {
2956         return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
2957     }
2958     function combineTwoEventUis(item0, item1) {
2959         return {
2960             startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
2961             durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
2962             constraints: item0.constraints.concat(item1.constraints),
2963             overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
2964             allows: item0.allows.concat(item1.allows),
2965             backgroundColor: item1.backgroundColor || item0.backgroundColor,
2966             borderColor: item1.borderColor || item0.borderColor,
2967             textColor: item1.textColor || item0.textColor,
2968             classNames: item0.classNames.concat(item1.classNames)
2969         };
2970     }
2971
2972     var NON_DATE_PROPS = {
2973         id: String,
2974         groupId: String,
2975         title: String,
2976         url: String,
2977         rendering: String,
2978         extendedProps: null
2979     };
2980     var DATE_PROPS = {
2981         start: null,
2982         date: null,
2983         end: null,
2984         allDay: null
2985     };
2986     var uid = 0;
2987     function parseEvent(raw, sourceId, calendar, allowOpenRange) {
2988         var allDayDefault = computeIsAllDayDefault(sourceId, calendar);
2989         var leftovers0 = {};
2990         var recurringRes = parseRecurring(raw, // raw, but with single-event stuff stripped out
2991         allDayDefault, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes, leftovers0 // will populate with non-recurring props
2992         );
2993         if (recurringRes) {
2994             var def = parseEventDef(leftovers0, sourceId, recurringRes.allDay, Boolean(recurringRes.duration), calendar);
2995             def.recurringDef = {
2996                 typeId: recurringRes.typeId,
2997                 typeData: recurringRes.typeData,
2998                 duration: recurringRes.duration
2999             };
3000             return { def: def, instance: null };
3001         }
3002         else {
3003             var leftovers1 = {};
3004             var singleRes = parseSingle(raw, allDayDefault, calendar, leftovers1, allowOpenRange);
3005             if (singleRes) {
3006                 var def = parseEventDef(leftovers1, sourceId, singleRes.allDay, singleRes.hasEnd, calendar);
3007                 var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
3008                 return { def: def, instance: instance };
3009             }
3010         }
3011         return null;
3012     }
3013     /*
3014     Will NOT populate extendedProps with the leftover properties.
3015     Will NOT populate date-related props.
3016     The EventNonDateInput has been normalized (id => publicId, etc).
3017     */
3018     function parseEventDef(raw, sourceId, allDay, hasEnd, calendar) {
3019         var leftovers = {};
3020         var def = pluckNonDateProps(raw, calendar, leftovers);
3021         def.defId = String(uid++);
3022         def.sourceId = sourceId;
3023         def.allDay = allDay;
3024         def.hasEnd = hasEnd;
3025         for (var _i = 0, _a = calendar.pluginSystem.hooks.eventDefParsers; _i < _a.length; _i++) {
3026             var eventDefParser = _a[_i];
3027             var newLeftovers = {};
3028             eventDefParser(def, leftovers, newLeftovers);
3029             leftovers = newLeftovers;
3030         }
3031         def.extendedProps = __assign(leftovers, def.extendedProps || {});
3032         // help out EventApi from having user modify props
3033         Object.freeze(def.ui.classNames);
3034         Object.freeze(def.extendedProps);
3035         return def;
3036     }
3037     function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
3038         return {
3039             instanceId: String(uid++),
3040             defId: defId,
3041             range: range,
3042             forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
3043             forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo
3044         };
3045     }
3046     function parseSingle(raw, allDayDefault, calendar, leftovers, allowOpenRange) {
3047         var props = pluckDateProps(raw, leftovers);
3048         var allDay = props.allDay;
3049         var startMeta;
3050         var startMarker = null;
3051         var hasEnd = false;
3052         var endMeta;
3053         var endMarker = null;
3054         startMeta = calendar.dateEnv.createMarkerMeta(props.start);
3055         if (startMeta) {
3056             startMarker = startMeta.marker;
3057         }
3058         else if (!allowOpenRange) {
3059             return null;
3060         }
3061         if (props.end != null) {
3062             endMeta = calendar.dateEnv.createMarkerMeta(props.end);
3063         }
3064         if (allDay == null) {
3065             if (allDayDefault != null) {
3066                 allDay = allDayDefault;
3067             }
3068             else {
3069                 // fall back to the date props LAST
3070                 allDay = (!startMeta || startMeta.isTimeUnspecified) &&
3071                     (!endMeta || endMeta.isTimeUnspecified);
3072             }
3073         }
3074         if (allDay && startMarker) {
3075             startMarker = startOfDay(startMarker);
3076         }
3077         if (endMeta) {
3078             endMarker = endMeta.marker;
3079             if (allDay) {
3080                 endMarker = startOfDay(endMarker);
3081             }
3082             if (startMarker && endMarker <= startMarker) {
3083                 endMarker = null;
3084             }
3085         }
3086         if (endMarker) {
3087             hasEnd = true;
3088         }
3089         else if (!allowOpenRange) {
3090             hasEnd = calendar.opt('forceEventDuration') || false;
3091             endMarker = calendar.dateEnv.add(startMarker, allDay ?
3092                 calendar.defaultAllDayEventDuration :
3093                 calendar.defaultTimedEventDuration);
3094         }
3095         return {
3096             allDay: allDay,
3097             hasEnd: hasEnd,
3098             range: { start: startMarker, end: endMarker },
3099             forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
3100             forcedEndTzo: endMeta ? endMeta.forcedTzo : null
3101         };
3102     }
3103     function pluckDateProps(raw, leftovers) {
3104         var props = refineProps(raw, DATE_PROPS, {}, leftovers);
3105         props.start = (props.start !== null) ? props.start : props.date;
3106         delete props.date;
3107         return props;
3108     }
3109     function pluckNonDateProps(raw, calendar, leftovers) {
3110         var preLeftovers = {};
3111         var props = refineProps(raw, NON_DATE_PROPS, {}, preLeftovers);
3112         var ui = processUnscopedUiProps(preLeftovers, calendar, leftovers);
3113         props.publicId = props.id;
3114         delete props.id;
3115         props.ui = ui;
3116         return props;
3117     }
3118     function computeIsAllDayDefault(sourceId, calendar) {
3119         var res = null;
3120         if (sourceId) {
3121             var source = calendar.state.eventSources[sourceId];
3122             res = source.allDayDefault;
3123         }
3124         if (res == null) {
3125             res = calendar.opt('allDayDefault');
3126         }
3127         return res;
3128     }
3129
3130     var DEF_DEFAULTS = {
3131         startTime: '09:00',
3132         endTime: '17:00',
3133         daysOfWeek: [1, 2, 3, 4, 5],
3134         rendering: 'inverse-background',
3135         classNames: 'fc-nonbusiness',
3136         groupId: '_businessHours' // so multiple defs get grouped
3137     };
3138     /*
3139     TODO: pass around as EventDefHash!!!
3140     */
3141     function parseBusinessHours(input, calendar) {
3142         return parseEvents(refineInputs(input), '', calendar);
3143     }
3144     function refineInputs(input) {
3145         var rawDefs;
3146         if (input === true) {
3147             rawDefs = [{}]; // will get DEF_DEFAULTS verbatim
3148         }
3149         else if (Array.isArray(input)) {
3150             // if specifying an array, every sub-definition NEEDS a day-of-week
3151             rawDefs = input.filter(function (rawDef) {
3152                 return rawDef.daysOfWeek;
3153             });
3154         }
3155         else if (typeof input === 'object' && input) { // non-null object
3156             rawDefs = [input];
3157         }
3158         else { // is probably false
3159             rawDefs = [];
3160         }
3161         rawDefs = rawDefs.map(function (rawDef) {
3162             return __assign({}, DEF_DEFAULTS, rawDef);
3163         });
3164         return rawDefs;
3165     }
3166
3167     function memoizeRendering(renderFunc, unrenderFunc, dependencies) {
3168         if (dependencies === void 0) { dependencies = []; }
3169         var dependents = [];
3170         var thisContext;
3171         var prevArgs;
3172         function unrender() {
3173             if (prevArgs) {
3174                 for (var _i = 0, dependents_1 = dependents; _i < dependents_1.length; _i++) {
3175                     var dependent = dependents_1[_i];
3176                     dependent.unrender();
3177                 }
3178                 if (unrenderFunc) {
3179                     unrenderFunc.apply(thisContext, prevArgs);
3180                 }
3181                 prevArgs = null;
3182             }
3183         }
3184         function res() {
3185             if (!prevArgs || !isArraysEqual(prevArgs, arguments)) {
3186                 unrender();
3187                 thisContext = this;
3188                 prevArgs = arguments;
3189                 renderFunc.apply(this, arguments);
3190             }
3191         }
3192         res.dependents = dependents;
3193         res.unrender = unrender;
3194         for (var _i = 0, dependencies_1 = dependencies; _i < dependencies_1.length; _i++) {
3195             var dependency = dependencies_1[_i];
3196             dependency.dependents.push(res);
3197         }
3198         return res;
3199     }
3200
3201     var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
3202     var Splitter = /** @class */ (function () {
3203         function Splitter() {
3204             this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
3205             this.splitDateSelection = memoize(this._splitDateSpan);
3206             this.splitEventStore = memoize(this._splitEventStore);
3207             this.splitIndividualUi = memoize(this._splitIndividualUi);
3208             this.splitEventDrag = memoize(this._splitInteraction);
3209             this.splitEventResize = memoize(this._splitInteraction);
3210             this.eventUiBuilders = {}; // TODO: typescript protection
3211         }
3212         Splitter.prototype.splitProps = function (props) {
3213             var _this = this;
3214             var keyInfos = this.getKeyInfo(props);
3215             var defKeys = this.getKeysForEventDefs(props.eventStore);
3216             var dateSelections = this.splitDateSelection(props.dateSelection);
3217             var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
3218             var eventStores = this.splitEventStore(props.eventStore, defKeys);
3219             var eventDrags = this.splitEventDrag(props.eventDrag);
3220             var eventResizes = this.splitEventResize(props.eventResize);
3221             var splitProps = {};
3222             this.eventUiBuilders = mapHash(keyInfos, function (info, key) {
3223                 return _this.eventUiBuilders[key] || memoize(buildEventUiForKey);
3224             });
3225             for (var key in keyInfos) {
3226                 var keyInfo = keyInfos[key];
3227                 var eventStore = eventStores[key] || EMPTY_EVENT_STORE;
3228                 var buildEventUi = this.eventUiBuilders[key];
3229                 splitProps[key] = {
3230                     businessHours: keyInfo.businessHours || props.businessHours,
3231                     dateSelection: dateSelections[key] || null,
3232                     eventStore: eventStore,
3233                     eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
3234                     eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
3235                     eventDrag: eventDrags[key] || null,
3236                     eventResize: eventResizes[key] || null
3237                 };
3238             }
3239             return splitProps;
3240         };
3241         Splitter.prototype._splitDateSpan = function (dateSpan) {
3242             var dateSpans = {};
3243             if (dateSpan) {
3244                 var keys = this.getKeysForDateSpan(dateSpan);
3245                 for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
3246                     var key = keys_1[_i];
3247                     dateSpans[key] = dateSpan;
3248                 }
3249             }
3250             return dateSpans;
3251         };
3252         Splitter.prototype._getKeysForEventDefs = function (eventStore) {
3253             var _this = this;
3254             return mapHash(eventStore.defs, function (eventDef) {
3255                 return _this.getKeysForEventDef(eventDef);
3256             });
3257         };
3258         Splitter.prototype._splitEventStore = function (eventStore, defKeys) {
3259             var defs = eventStore.defs, instances = eventStore.instances;
3260             var splitStores = {};
3261             for (var defId in defs) {
3262                 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
3263                     var key = _a[_i];
3264                     if (!splitStores[key]) {
3265                         splitStores[key] = createEmptyEventStore();
3266                     }
3267                     splitStores[key].defs[defId] = defs[defId];
3268                 }
3269             }
3270             for (var instanceId in instances) {
3271                 var instance = instances[instanceId];
3272                 for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) {
3273                     var key = _c[_b];
3274                     if (splitStores[key]) { // must have already been created
3275                         splitStores[key].instances[instanceId] = instance;
3276                     }
3277                 }
3278             }
3279             return splitStores;
3280         };
3281         Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) {
3282             var splitHashes = {};
3283             for (var defId in eventUiBases) {
3284                 if (defId) { // not the '' key
3285                     for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
3286                         var key = _a[_i];
3287                         if (!splitHashes[key]) {
3288                             splitHashes[key] = {};
3289                         }
3290                         splitHashes[key][defId] = eventUiBases[defId];
3291                     }
3292                 }
3293             }
3294             return splitHashes;
3295         };
3296         Splitter.prototype._splitInteraction = function (interaction) {
3297             var splitStates = {};
3298             if (interaction) {
3299                 var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents) // can't use cached. might be events from other calendar
3300                 );
3301                 // can't rely on defKeys because event data is mutated
3302                 var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
3303                 var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
3304                 var populate = function (key) {
3305                     if (!splitStates[key]) {
3306                         splitStates[key] = {
3307                             affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE,
3308                             mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE,
3309                             isEvent: interaction.isEvent,
3310                             origSeg: interaction.origSeg
3311                         };
3312                     }
3313                 };
3314                 for (var key in affectedStores_1) {
3315                     populate(key);
3316                 }
3317                 for (var key in mutatedStores_1) {
3318                     populate(key);
3319                 }
3320             }
3321             return splitStates;
3322         };
3323         return Splitter;
3324     }());
3325     function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
3326         var baseParts = [];
3327         if (allUi) {
3328             baseParts.push(allUi);
3329         }
3330         if (eventUiForKey) {
3331             baseParts.push(eventUiForKey);
3332         }
3333         var stuff = {
3334             '': combineEventUis(baseParts)
3335         };
3336         if (individualUi) {
3337             __assign(stuff, individualUi);
3338         }
3339         return stuff;
3340     }
3341
3342     // Generates HTML for an anchor to another view into the calendar.
3343     // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings.
3344     // `gotoOptions` can either be a DateMarker, or an object with the form:
3345     // { date, type, forceOff }
3346     // `type` is a view-type like "day" or "week". default value is "day".
3347     // `attrs` and `innerHtml` are use to generate the rest of the HTML tag.
3348     function buildGotoAnchorHtml(component, gotoOptions, attrs, innerHtml) {
3349         var dateEnv = component.dateEnv;
3350         var date;
3351         var type;
3352         var forceOff;
3353         var finalOptions;
3354         if (gotoOptions instanceof Date) {
3355             date = gotoOptions; // a single date-like input
3356         }
3357         else {
3358             date = gotoOptions.date;
3359             type = gotoOptions.type;
3360             forceOff = gotoOptions.forceOff;
3361         }
3362         finalOptions = {
3363             date: dateEnv.formatIso(date, { omitTime: true }),
3364             type: type || 'day'
3365         };
3366         if (typeof attrs === 'string') {
3367             innerHtml = attrs;
3368             attrs = null;
3369         }
3370         attrs = attrs ? ' ' + attrsToStr(attrs) : ''; // will have a leading space
3371         innerHtml = innerHtml || '';
3372         if (!forceOff && component.opt('navLinks')) {
3373             return '<a' + attrs +
3374                 ' data-goto="' + htmlEscape(JSON.stringify(finalOptions)) + '">' +
3375                 innerHtml +
3376                 '</a>';
3377         }
3378         else {
3379             return '<span' + attrs + '>' +
3380                 innerHtml +
3381                 '</span>';
3382         }
3383     }
3384     function getAllDayHtml(component) {
3385         return component.opt('allDayHtml') || htmlEscape(component.opt('allDayText'));
3386     }
3387     // Computes HTML classNames for a single-day element
3388     function getDayClasses(date, dateProfile, context, noThemeHighlight) {
3389         var calendar = context.calendar, view = context.view, theme = context.theme, dateEnv = context.dateEnv;
3390         var classes = [];
3391         var todayStart;
3392         var todayEnd;
3393         if (!rangeContainsMarker(dateProfile.activeRange, date)) {
3394             classes.push('fc-disabled-day');
3395         }
3396         else {
3397             classes.push('fc-' + DAY_IDS[date.getUTCDay()]);
3398             if (view.opt('monthMode') &&
3399                 dateEnv.getMonth(date) !== dateEnv.getMonth(dateProfile.currentRange.start)) {
3400                 classes.push('fc-other-month');
3401             }
3402             todayStart = startOfDay(calendar.getNow());
3403             todayEnd = addDays(todayStart, 1);
3404             if (date < todayStart) {
3405                 classes.push('fc-past');
3406             }
3407             else if (date >= todayEnd) {
3408                 classes.push('fc-future');
3409             }
3410             else {
3411                 classes.push('fc-today');
3412                 if (noThemeHighlight !== true) {
3413                     classes.push(theme.getClass('today'));
3414                 }
3415             }
3416         }
3417         return classes;
3418     }
3419
3420     // given a function that resolves a result asynchronously.
3421     // the function can either call passed-in success and failure callbacks,
3422     // or it can return a promise.
3423     // if you need to pass additional params to func, bind them first.
3424     function unpromisify(func, success, failure) {
3425         // guard against success/failure callbacks being called more than once
3426         // and guard against a promise AND callback being used together.
3427         var isResolved = false;
3428         var wrappedSuccess = function () {
3429             if (!isResolved) {
3430                 isResolved = true;
3431                 success.apply(this, arguments);
3432             }
3433         };
3434         var wrappedFailure = function () {
3435             if (!isResolved) {
3436                 isResolved = true;
3437                 if (failure) {
3438                     failure.apply(this, arguments);
3439                 }
3440             }
3441         };
3442         var res = func(wrappedSuccess, wrappedFailure);
3443         if (res && typeof res.then === 'function') {
3444             res.then(wrappedSuccess, wrappedFailure);
3445         }
3446     }
3447
3448     var Mixin = /** @class */ (function () {
3449         function Mixin() {
3450         }
3451         // mix into a CLASS
3452         Mixin.mixInto = function (destClass) {
3453             this.mixIntoObj(destClass.prototype);
3454         };
3455         // mix into ANY object
3456         Mixin.mixIntoObj = function (destObj) {
3457             var _this = this;
3458             Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
3459                 if (!destObj[name]) { // if destination doesn't already define it
3460                     destObj[name] = _this.prototype[name];
3461                 }
3462             });
3463         };
3464         /*
3465         will override existing methods
3466         TODO: remove! not used anymore
3467         */
3468         Mixin.mixOver = function (destClass) {
3469             var _this = this;
3470             Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
3471                 destClass.prototype[name] = _this.prototype[name];
3472             });
3473         };
3474         return Mixin;
3475     }());
3476
3477     /*
3478     USAGE:
3479       import { default as EmitterMixin, EmitterInterface } from './EmitterMixin'
3480     in class:
3481       on: EmitterInterface['on']
3482       one: EmitterInterface['one']
3483       off: EmitterInterface['off']
3484       trigger: EmitterInterface['trigger']
3485       triggerWith: EmitterInterface['triggerWith']
3486       hasHandlers: EmitterInterface['hasHandlers']
3487     after class:
3488       EmitterMixin.mixInto(TheClass)
3489     */
3490     var EmitterMixin = /** @class */ (function (_super) {
3491         __extends(EmitterMixin, _super);
3492         function EmitterMixin() {
3493             return _super !== null && _super.apply(this, arguments) || this;
3494         }
3495         EmitterMixin.prototype.on = function (type, handler) {
3496             addToHash(this._handlers || (this._handlers = {}), type, handler);
3497             return this; // for chaining
3498         };
3499         // todo: add comments
3500         EmitterMixin.prototype.one = function (type, handler) {
3501             addToHash(this._oneHandlers || (this._oneHandlers = {}), type, handler);
3502             return this; // for chaining
3503         };
3504         EmitterMixin.prototype.off = function (type, handler) {
3505             if (this._handlers) {
3506                 removeFromHash(this._handlers, type, handler);
3507             }
3508             if (this._oneHandlers) {
3509                 removeFromHash(this._oneHandlers, type, handler);
3510             }
3511             return this; // for chaining
3512         };
3513         EmitterMixin.prototype.trigger = function (type) {
3514             var args = [];
3515             for (var _i = 1; _i < arguments.length; _i++) {
3516                 args[_i - 1] = arguments[_i];
3517             }
3518             this.triggerWith(type, this, args);
3519             return this; // for chaining
3520         };
3521         EmitterMixin.prototype.triggerWith = function (type, context, args) {
3522             if (this._handlers) {
3523                 applyAll(this._handlers[type], context, args);
3524             }
3525             if (this._oneHandlers) {
3526                 applyAll(this._oneHandlers[type], context, args);
3527                 delete this._oneHandlers[type]; // will never fire again
3528             }
3529             return this; // for chaining
3530         };
3531         EmitterMixin.prototype.hasHandlers = function (type) {
3532             return (this._handlers && this._handlers[type] && this._handlers[type].length) ||
3533                 (this._oneHandlers && this._oneHandlers[type] && this._oneHandlers[type].length);
3534         };
3535         return EmitterMixin;
3536     }(Mixin));
3537     function addToHash(hash, type, handler) {
3538         (hash[type] || (hash[type] = []))
3539             .push(handler);
3540     }
3541     function removeFromHash(hash, type, handler) {
3542         if (handler) {
3543             if (hash[type]) {
3544                 hash[type] = hash[type].filter(function (func) {
3545                     return func !== handler;
3546                 });
3547             }
3548         }
3549         else {
3550             delete hash[type]; // remove all handler funcs for this type
3551         }
3552     }
3553
3554     /*
3555     Records offset information for a set of elements, relative to an origin element.
3556     Can record the left/right OR the top/bottom OR both.
3557     Provides methods for querying the cache by position.
3558     */
3559     var PositionCache = /** @class */ (function () {
3560         function PositionCache(originEl, els, isHorizontal, isVertical) {
3561             this.originEl = originEl;
3562             this.els = els;
3563             this.isHorizontal = isHorizontal;
3564             this.isVertical = isVertical;
3565         }
3566         // Queries the els for coordinates and stores them.
3567         // Call this method before using and of the get* methods below.
3568         PositionCache.prototype.build = function () {
3569             var originEl = this.originEl;
3570             var originClientRect = this.originClientRect =
3571                 originEl.getBoundingClientRect(); // relative to viewport top-left
3572             if (this.isHorizontal) {
3573                 this.buildElHorizontals(originClientRect.left);
3574             }
3575             if (this.isVertical) {
3576                 this.buildElVerticals(originClientRect.top);
3577             }
3578         };
3579         // Populates the left/right internal coordinate arrays
3580         PositionCache.prototype.buildElHorizontals = function (originClientLeft) {
3581             var lefts = [];
3582             var rights = [];
3583             for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
3584                 var el = _a[_i];
3585                 var rect = el.getBoundingClientRect();
3586                 lefts.push(rect.left - originClientLeft);
3587                 rights.push(rect.right - originClientLeft);
3588             }
3589             this.lefts = lefts;
3590             this.rights = rights;
3591         };
3592         // Populates the top/bottom internal coordinate arrays
3593         PositionCache.prototype.buildElVerticals = function (originClientTop) {
3594             var tops = [];
3595             var bottoms = [];
3596             for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
3597                 var el = _a[_i];
3598                 var rect = el.getBoundingClientRect();
3599                 tops.push(rect.top - originClientTop);
3600                 bottoms.push(rect.bottom - originClientTop);
3601             }
3602             this.tops = tops;
3603             this.bottoms = bottoms;
3604         };
3605         // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
3606         // If no intersection is made, returns undefined.
3607         PositionCache.prototype.leftToIndex = function (leftPosition) {
3608             var lefts = this.lefts;
3609             var rights = this.rights;
3610             var len = lefts.length;
3611             var i;
3612             for (i = 0; i < len; i++) {
3613                 if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
3614                     return i;
3615                 }
3616             }
3617         };
3618         // Given a top offset (from document top), returns the index of the el that it vertically intersects.
3619         // If no intersection is made, returns undefined.
3620         PositionCache.prototype.topToIndex = function (topPosition) {
3621             var tops = this.tops;
3622             var bottoms = this.bottoms;
3623             var len = tops.length;
3624             var i;
3625             for (i = 0; i < len; i++) {
3626                 if (topPosition >= tops[i] && topPosition < bottoms[i]) {
3627                     return i;
3628                 }
3629             }
3630         };
3631         // Gets the width of the element at the given index
3632         PositionCache.prototype.getWidth = function (leftIndex) {
3633             return this.rights[leftIndex] - this.lefts[leftIndex];
3634         };
3635         // Gets the height of the element at the given index
3636         PositionCache.prototype.getHeight = function (topIndex) {
3637             return this.bottoms[topIndex] - this.tops[topIndex];
3638         };
3639         return PositionCache;
3640     }());
3641
3642     /*
3643     An object for getting/setting scroll-related information for an element.
3644     Internally, this is done very differently for window versus DOM element,
3645     so this object serves as a common interface.
3646     */
3647     var ScrollController = /** @class */ (function () {
3648         function ScrollController() {
3649         }
3650         ScrollController.prototype.getMaxScrollTop = function () {
3651             return this.getScrollHeight() - this.getClientHeight();
3652         };
3653         ScrollController.prototype.getMaxScrollLeft = function () {
3654             return this.getScrollWidth() - this.getClientWidth();
3655         };
3656         ScrollController.prototype.canScrollVertically = function () {
3657             return this.getMaxScrollTop() > 0;
3658         };
3659         ScrollController.prototype.canScrollHorizontally = function () {
3660             return this.getMaxScrollLeft() > 0;
3661         };
3662         ScrollController.prototype.canScrollUp = function () {
3663             return this.getScrollTop() > 0;
3664         };
3665         ScrollController.prototype.canScrollDown = function () {
3666             return this.getScrollTop() < this.getMaxScrollTop();
3667         };
3668         ScrollController.prototype.canScrollLeft = function () {
3669             return this.getScrollLeft() > 0;
3670         };
3671         ScrollController.prototype.canScrollRight = function () {
3672             return this.getScrollLeft() < this.getMaxScrollLeft();
3673         };
3674         return ScrollController;
3675     }());
3676     var ElementScrollController = /** @class */ (function (_super) {
3677         __extends(ElementScrollController, _super);
3678         function ElementScrollController(el) {
3679             var _this = _super.call(this) || this;
3680             _this.el = el;
3681             return _this;
3682         }
3683         ElementScrollController.prototype.getScrollTop = function () {
3684             return this.el.scrollTop;
3685         };
3686         ElementScrollController.prototype.getScrollLeft = function () {
3687             return this.el.scrollLeft;
3688         };
3689         ElementScrollController.prototype.setScrollTop = function (top) {
3690             this.el.scrollTop = top;
3691         };
3692         ElementScrollController.prototype.setScrollLeft = function (left) {
3693             this.el.scrollLeft = left;
3694         };
3695         ElementScrollController.prototype.getScrollWidth = function () {
3696             return this.el.scrollWidth;
3697         };
3698         ElementScrollController.prototype.getScrollHeight = function () {
3699             return this.el.scrollHeight;
3700         };
3701         ElementScrollController.prototype.getClientHeight = function () {
3702             return this.el.clientHeight;
3703         };
3704         ElementScrollController.prototype.getClientWidth = function () {
3705             return this.el.clientWidth;
3706         };
3707         return ElementScrollController;
3708     }(ScrollController));
3709     var WindowScrollController = /** @class */ (function (_super) {
3710         __extends(WindowScrollController, _super);
3711         function WindowScrollController() {
3712             return _super !== null && _super.apply(this, arguments) || this;
3713         }
3714         WindowScrollController.prototype.getScrollTop = function () {
3715             return window.pageYOffset;
3716         };
3717         WindowScrollController.prototype.getScrollLeft = function () {
3718             return window.pageXOffset;
3719         };
3720         WindowScrollController.prototype.setScrollTop = function (n) {
3721             window.scroll(window.pageXOffset, n);
3722         };
3723         WindowScrollController.prototype.setScrollLeft = function (n) {
3724             window.scroll(n, window.pageYOffset);
3725         };
3726         WindowScrollController.prototype.getScrollWidth = function () {
3727             return document.documentElement.scrollWidth;
3728         };
3729         WindowScrollController.prototype.getScrollHeight = function () {
3730             return document.documentElement.scrollHeight;
3731         };
3732         WindowScrollController.prototype.getClientHeight = function () {
3733             return document.documentElement.clientHeight;
3734         };
3735         WindowScrollController.prototype.getClientWidth = function () {
3736             return document.documentElement.clientWidth;
3737         };
3738         return WindowScrollController;
3739     }(ScrollController));
3740
3741     /*
3742     Embodies a div that has potential scrollbars
3743     */
3744     var ScrollComponent = /** @class */ (function (_super) {
3745         __extends(ScrollComponent, _super);
3746         function ScrollComponent(overflowX, overflowY) {
3747             var _this = _super.call(this, createElement('div', {
3748                 className: 'fc-scroller'
3749             })) || this;
3750             _this.overflowX = overflowX;
3751             _this.overflowY = overflowY;
3752             _this.applyOverflow();
3753             return _this;
3754         }
3755         // sets to natural height, unlocks overflow
3756         ScrollComponent.prototype.clear = function () {
3757             this.setHeight('auto');
3758             this.applyOverflow();
3759         };
3760         ScrollComponent.prototype.destroy = function () {
3761             removeElement(this.el);
3762         };
3763         // Overflow
3764         // -----------------------------------------------------------------------------------------------------------------
3765         ScrollComponent.prototype.applyOverflow = function () {
3766             applyStyle(this.el, {
3767                 overflowX: this.overflowX,
3768                 overflowY: this.overflowY
3769             });
3770         };
3771         // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
3772         // Useful for preserving scrollbar widths regardless of future resizes.
3773         // Can pass in scrollbarWidths for optimization.
3774         ScrollComponent.prototype.lockOverflow = function (scrollbarWidths) {
3775             var overflowX = this.overflowX;
3776             var overflowY = this.overflowY;
3777             scrollbarWidths = scrollbarWidths || this.getScrollbarWidths();
3778             if (overflowX === 'auto') {
3779                 overflowX = (scrollbarWidths.bottom || // horizontal scrollbars?
3780                     this.canScrollHorizontally() // OR scrolling pane with massless scrollbars?
3781                 ) ? 'scroll' : 'hidden';
3782             }
3783             if (overflowY === 'auto') {
3784                 overflowY = (scrollbarWidths.left || scrollbarWidths.right || // horizontal scrollbars?
3785                     this.canScrollVertically() // OR scrolling pane with massless scrollbars?
3786                 ) ? 'scroll' : 'hidden';
3787             }
3788             applyStyle(this.el, { overflowX: overflowX, overflowY: overflowY });
3789         };
3790         ScrollComponent.prototype.setHeight = function (height) {
3791             applyStyleProp(this.el, 'height', height);
3792         };
3793         ScrollComponent.prototype.getScrollbarWidths = function () {
3794             var edges = computeEdges(this.el);
3795             return {
3796                 left: edges.scrollbarLeft,
3797                 right: edges.scrollbarRight,
3798                 bottom: edges.scrollbarBottom
3799             };
3800         };
3801         return ScrollComponent;
3802     }(ElementScrollController));
3803
3804     var Theme = /** @class */ (function () {
3805         function Theme(calendarOptions) {
3806             this.calendarOptions = calendarOptions;
3807             this.processIconOverride();
3808         }
3809         Theme.prototype.processIconOverride = function () {
3810             if (this.iconOverrideOption) {
3811                 this.setIconOverride(this.calendarOptions[this.iconOverrideOption]);
3812             }
3813         };
3814         Theme.prototype.setIconOverride = function (iconOverrideHash) {
3815             var iconClassesCopy;
3816             var buttonName;
3817             if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object
3818                 iconClassesCopy = __assign({}, this.iconClasses);
3819                 for (buttonName in iconOverrideHash) {
3820                     iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
3821                 }
3822                 this.iconClasses = iconClassesCopy;
3823             }
3824             else if (iconOverrideHash === false) {
3825                 this.iconClasses = {};
3826             }
3827         };
3828         Theme.prototype.applyIconOverridePrefix = function (className) {
3829             var prefix = this.iconOverridePrefix;
3830             if (prefix && className.indexOf(prefix) !== 0) { // if not already present
3831                 className = prefix + className;
3832             }
3833             return className;
3834         };
3835         Theme.prototype.getClass = function (key) {
3836             return this.classes[key] || '';
3837         };
3838         Theme.prototype.getIconClass = function (buttonName) {
3839             var className = this.iconClasses[buttonName];
3840             if (className) {
3841                 return this.baseIconClass + ' ' + className;
3842             }
3843             return '';
3844         };
3845         Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
3846             var className;
3847             if (this.iconOverrideCustomButtonOption) {
3848                 className = customButtonProps[this.iconOverrideCustomButtonOption];
3849                 if (className) {
3850                     return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className);
3851                 }
3852             }
3853             return '';
3854         };
3855         return Theme;
3856     }());
3857     Theme.prototype.classes = {};
3858     Theme.prototype.iconClasses = {};
3859     Theme.prototype.baseIconClass = '';
3860     Theme.prototype.iconOverridePrefix = '';
3861
3862     var guid = 0;
3863     var Component = /** @class */ (function () {
3864         function Component(context, isView) {
3865             // HACK to populate view at top of component instantiation call chain
3866             if (isView) {
3867                 context.view = this;
3868             }
3869             this.uid = String(guid++);
3870             this.context = context;
3871             this.dateEnv = context.dateEnv;
3872             this.theme = context.theme;
3873             this.view = context.view;
3874             this.calendar = context.calendar;
3875             this.isRtl = this.opt('dir') === 'rtl';
3876         }
3877         Component.addEqualityFuncs = function (newFuncs) {
3878             this.prototype.equalityFuncs = __assign({}, this.prototype.equalityFuncs, newFuncs);
3879         };
3880         Component.prototype.opt = function (name) {
3881             return this.context.options[name];
3882         };
3883         Component.prototype.receiveProps = function (props) {
3884             var _a = recycleProps(this.props || {}, props, this.equalityFuncs), anyChanges = _a.anyChanges, comboProps = _a.comboProps;
3885             this.props = comboProps;
3886             if (anyChanges) {
3887                 this.render(comboProps);
3888             }
3889         };
3890         Component.prototype.render = function (props) {
3891         };
3892         // after destroy is called, this component won't ever be used again
3893         Component.prototype.destroy = function () {
3894         };
3895         return Component;
3896     }());
3897     Component.prototype.equalityFuncs = {};
3898     /*
3899     Reuses old values when equal. If anything is unequal, returns newProps as-is.
3900     Great for PureComponent, but won't be feasible with React, so just eliminate and use React's DOM diffing.
3901     */
3902     function recycleProps(oldProps, newProps, equalityFuncs) {
3903         var comboProps = {}; // some old, some new
3904         var anyChanges = false;
3905         for (var key in newProps) {
3906             if (key in oldProps && (oldProps[key] === newProps[key] ||
3907                 (equalityFuncs[key] && equalityFuncs[key](oldProps[key], newProps[key])))) {
3908                 // equal to old? use old prop
3909                 comboProps[key] = oldProps[key];
3910             }
3911             else {
3912                 comboProps[key] = newProps[key];
3913                 anyChanges = true;
3914             }
3915         }
3916         for (var key in oldProps) {
3917             if (!(key in newProps)) {
3918                 anyChanges = true;
3919                 break;
3920             }
3921         }
3922         return { anyChanges: anyChanges, comboProps: comboProps };
3923     }
3924
3925     /*
3926     PURPOSES:
3927     - hook up to fg, fill, and mirror renderers
3928     - interface for dragging and hits
3929     */
3930     var DateComponent = /** @class */ (function (_super) {
3931         __extends(DateComponent, _super);
3932         function DateComponent(context, el, isView) {
3933             var _this = _super.call(this, context, isView) || this;
3934             _this.el = el;
3935             return _this;
3936         }
3937         DateComponent.prototype.destroy = function () {
3938             _super.prototype.destroy.call(this);
3939             removeElement(this.el);
3940         };
3941         // TODO: WHAT ABOUT (sourceSeg && sourceSeg.component.doesDragMirror)
3942         //
3943         // Event Drag-n-Drop Rendering (for both events and external elements)
3944         // ---------------------------------------------------------------------------------------------------------------
3945         /*
3946         renderEventDragSegs(state: EventSegUiInteractionState) {
3947           if (state) {
3948             let { isEvent, segs, sourceSeg } = state
3949       
3950             if (this.eventRenderer) {
3951               this.eventRenderer.hideByHash(state.affectedInstances)
3952             }
3953       
3954             // if the user is dragging something that is considered an event with real event data,
3955             // and this component likes to do drag mirrors OR the component where the seg came from
3956             // likes to do drag mirrors, then render a drag mirror.
3957             if (isEvent && (this.doesDragMirror || sourceSeg && sourceSeg.component.doesDragMirror)) {
3958               if (this.mirrorRenderer) {
3959                 this.mirrorRenderer.renderSegs(segs, { isDragging: true, sourceSeg })
3960               }
3961             }
3962       
3963             // if it would be impossible to render a drag mirror OR this component likes to render
3964             // highlights, then render a highlight.
3965             if (!isEvent || this.doesDragHighlight) {
3966               if (this.fillRenderer) {
3967                 this.fillRenderer.renderSegs('highlight', segs)
3968               }
3969             }
3970           }
3971         }
3972         */
3973         // Hit System
3974         // -----------------------------------------------------------------------------------------------------------------
3975         DateComponent.prototype.buildPositionCaches = function () {
3976         };
3977         DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
3978             return null; // this should be abstract
3979         };
3980         // Validation
3981         // -----------------------------------------------------------------------------------------------------------------
3982         DateComponent.prototype.isInteractionValid = function (interaction) {
3983             var calendar = this.calendar;
3984             var dateProfile = this.props.dateProfile; // HACK
3985             var instances = interaction.mutatedEvents.instances;
3986             if (dateProfile) { // HACK for DayTile
3987                 for (var instanceId in instances) {
3988                     if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
3989                         return false;
3990                     }
3991                 }
3992             }
3993             return isInteractionValid(interaction, calendar);
3994         };
3995         DateComponent.prototype.isDateSelectionValid = function (selection) {
3996             var dateProfile = this.props.dateProfile; // HACK
3997             if (dateProfile && // HACK for DayTile
3998                 !rangeContainsRange(dateProfile.validRange, selection.range)) {
3999                 return false;
4000             }
4001             return isDateSelectionValid(selection, this.calendar);
4002         };
4003         // Triggering
4004         // -----------------------------------------------------------------------------------------------------------------
4005         // TODO: move to Calendar
4006         DateComponent.prototype.publiclyTrigger = function (name, args) {
4007             var calendar = this.calendar;
4008             return calendar.publiclyTrigger(name, args);
4009         };
4010         DateComponent.prototype.publiclyTriggerAfterSizing = function (name, args) {
4011             var calendar = this.calendar;
4012             return calendar.publiclyTriggerAfterSizing(name, args);
4013         };
4014         DateComponent.prototype.hasPublicHandlers = function (name) {
4015             var calendar = this.calendar;
4016             return calendar.hasPublicHandlers(name);
4017         };
4018         DateComponent.prototype.triggerRenderedSegs = function (segs, isMirrors) {
4019             var calendar = this.calendar;
4020             if (this.hasPublicHandlers('eventPositioned')) {
4021                 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
4022                     var seg = segs_1[_i];
4023                     this.publiclyTriggerAfterSizing('eventPositioned', [
4024                         {
4025                             event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
4026                             isMirror: isMirrors,
4027                             isStart: seg.isStart,
4028                             isEnd: seg.isEnd,
4029                             el: seg.el,
4030                             view: this // safe to cast because this method is only called on context.view
4031                         }
4032                     ]);
4033                 }
4034             }
4035             if (!calendar.state.loadingLevel) { // avoid initial empty state while pending
4036                 calendar.afterSizingTriggers._eventsPositioned = [null]; // fire once
4037             }
4038         };
4039         DateComponent.prototype.triggerWillRemoveSegs = function (segs, isMirrors) {
4040             var calendar = this.calendar;
4041             for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
4042                 var seg = segs_2[_i];
4043                 calendar.trigger('eventElRemove', seg.el);
4044             }
4045             if (this.hasPublicHandlers('eventDestroy')) {
4046                 for (var _a = 0, segs_3 = segs; _a < segs_3.length; _a++) {
4047                     var seg = segs_3[_a];
4048                     this.publiclyTrigger('eventDestroy', [
4049                         {
4050                             event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
4051                             isMirror: isMirrors,
4052                             el: seg.el,
4053                             view: this // safe to cast because this method is only called on context.view
4054                         }
4055                     ]);
4056                 }
4057             }
4058         };
4059         // Pointer Interaction Utils
4060         // -----------------------------------------------------------------------------------------------------------------
4061         DateComponent.prototype.isValidSegDownEl = function (el) {
4062             return !this.props.eventDrag && // HACK
4063                 !this.props.eventResize && // HACK
4064                 !elementClosest(el, '.fc-mirror') &&
4065                 (this.isPopover() || !this.isInPopover(el));
4066             // ^above line ensures we don't detect a seg interaction within a nested component.
4067             // it's a HACK because it only supports a popover as the nested component.
4068         };
4069         DateComponent.prototype.isValidDateDownEl = function (el) {
4070             var segEl = elementClosest(el, this.fgSegSelector);
4071             return (!segEl || segEl.classList.contains('fc-mirror')) &&
4072                 !elementClosest(el, '.fc-more') && // a "more.." link
4073                 !elementClosest(el, 'a[data-goto]') && // a clickable nav link
4074                 !this.isInPopover(el);
4075         };
4076         DateComponent.prototype.isPopover = function () {
4077             return this.el.classList.contains('fc-popover');
4078         };
4079         DateComponent.prototype.isInPopover = function (el) {
4080             return Boolean(elementClosest(el, '.fc-popover'));
4081         };
4082         return DateComponent;
4083     }(Component));
4084     DateComponent.prototype.fgSegSelector = '.fc-event-container > *';
4085     DateComponent.prototype.bgSegSelector = '.fc-bgevent:not(.fc-nonbusiness)';
4086
4087     var uid$1 = 0;
4088     function createPlugin(input) {
4089         return {
4090             id: String(uid$1++),
4091             deps: input.deps || [],
4092             reducers: input.reducers || [],
4093             eventDefParsers: input.eventDefParsers || [],
4094             isDraggableTransformers: input.isDraggableTransformers || [],
4095             eventDragMutationMassagers: input.eventDragMutationMassagers || [],
4096             eventDefMutationAppliers: input.eventDefMutationAppliers || [],
4097             dateSelectionTransformers: input.dateSelectionTransformers || [],
4098             datePointTransforms: input.datePointTransforms || [],
4099             dateSpanTransforms: input.dateSpanTransforms || [],
4100             views: input.views || {},
4101             viewPropsTransformers: input.viewPropsTransformers || [],
4102             isPropsValid: input.isPropsValid || null,
4103             externalDefTransforms: input.externalDefTransforms || [],
4104             eventResizeJoinTransforms: input.eventResizeJoinTransforms || [],
4105             viewContainerModifiers: input.viewContainerModifiers || [],
4106             eventDropTransformers: input.eventDropTransformers || [],
4107             componentInteractions: input.componentInteractions || [],
4108             calendarInteractions: input.calendarInteractions || [],
4109             themeClasses: input.themeClasses || {},
4110             eventSourceDefs: input.eventSourceDefs || [],
4111             cmdFormatter: input.cmdFormatter,
4112             recurringTypes: input.recurringTypes || [],
4113             namedTimeZonedImpl: input.namedTimeZonedImpl,
4114             defaultView: input.defaultView || '',
4115             elementDraggingImpl: input.elementDraggingImpl,
4116             optionChangeHandlers: input.optionChangeHandlers || {}
4117         };
4118     }
4119     var PluginSystem = /** @class */ (function () {
4120         function PluginSystem() {
4121             this.hooks = {
4122                 reducers: [],
4123                 eventDefParsers: [],
4124                 isDraggableTransformers: [],
4125                 eventDragMutationMassagers: [],
4126                 eventDefMutationAppliers: [],
4127                 dateSelectionTransformers: [],
4128                 datePointTransforms: [],
4129                 dateSpanTransforms: [],
4130                 views: {},
4131                 viewPropsTransformers: [],
4132                 isPropsValid: null,
4133                 externalDefTransforms: [],
4134                 eventResizeJoinTransforms: [],
4135                 viewContainerModifiers: [],
4136                 eventDropTransformers: [],
4137                 componentInteractions: [],
4138                 calendarInteractions: [],
4139                 themeClasses: {},
4140                 eventSourceDefs: [],
4141                 cmdFormatter: null,
4142                 recurringTypes: [],
4143                 namedTimeZonedImpl: null,
4144                 defaultView: '',
4145                 elementDraggingImpl: null,
4146                 optionChangeHandlers: {}
4147             };
4148             this.addedHash = {};
4149         }
4150         PluginSystem.prototype.add = function (plugin) {
4151             if (!this.addedHash[plugin.id]) {
4152                 this.addedHash[plugin.id] = true;
4153                 for (var _i = 0, _a = plugin.deps; _i < _a.length; _i++) {
4154                     var dep = _a[_i];
4155                     this.add(dep);
4156                 }
4157                 this.hooks = combineHooks(this.hooks, plugin);
4158             }
4159         };
4160         return PluginSystem;
4161     }());
4162     function combineHooks(hooks0, hooks1) {
4163         return {
4164             reducers: hooks0.reducers.concat(hooks1.reducers),
4165             eventDefParsers: hooks0.eventDefParsers.concat(hooks1.eventDefParsers),
4166             isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),
4167             eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
4168             eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
4169             dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
4170             datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
4171             dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
4172             views: __assign({}, hooks0.views, hooks1.views),
4173             viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
4174             isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
4175             externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
4176             eventResizeJoinTransforms: hooks0.eventResizeJoinTransforms.concat(hooks1.eventResizeJoinTransforms),
4177             viewContainerModifiers: hooks0.viewContainerModifiers.concat(hooks1.viewContainerModifiers),
4178             eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
4179             calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
4180             componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
4181             themeClasses: __assign({}, hooks0.themeClasses, hooks1.themeClasses),
4182             eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
4183             cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
4184             recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
4185             namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
4186             defaultView: hooks0.defaultView || hooks1.defaultView,
4187             elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
4188             optionChangeHandlers: __assign({}, hooks0.optionChangeHandlers, hooks1.optionChangeHandlers)
4189         };
4190     }
4191
4192     var eventSourceDef = {
4193         ignoreRange: true,
4194         parseMeta: function (raw) {
4195             if (Array.isArray(raw)) { // short form
4196                 return raw;
4197             }
4198             else if (Array.isArray(raw.events)) {
4199                 return raw.events;
4200             }
4201             return null;
4202         },
4203         fetch: function (arg, success) {
4204             success({
4205                 rawEvents: arg.eventSource.meta
4206             });
4207         }
4208     };
4209     var ArrayEventSourcePlugin = createPlugin({
4210         eventSourceDefs: [eventSourceDef]
4211     });
4212
4213     var eventSourceDef$1 = {
4214         parseMeta: function (raw) {
4215             if (typeof raw === 'function') { // short form
4216                 return raw;
4217             }
4218             else if (typeof raw.events === 'function') {
4219                 return raw.events;
4220             }
4221             return null;
4222         },
4223         fetch: function (arg, success, failure) {
4224             var dateEnv = arg.calendar.dateEnv;
4225             var func = arg.eventSource.meta;
4226             unpromisify(func.bind(null, {
4227                 start: dateEnv.toDate(arg.range.start),
4228                 end: dateEnv.toDate(arg.range.end),
4229                 startStr: dateEnv.formatIso(arg.range.start),
4230                 endStr: dateEnv.formatIso(arg.range.end),
4231                 timeZone: dateEnv.timeZone
4232             }), function (rawEvents) {
4233                 success({ rawEvents: rawEvents }); // needs an object response
4234             }, failure // send errorObj directly to failure callback
4235             );
4236         }
4237     };
4238     var FuncEventSourcePlugin = createPlugin({
4239         eventSourceDefs: [eventSourceDef$1]
4240     });
4241
4242     function requestJson(method, url, params, successCallback, failureCallback) {
4243         method = method.toUpperCase();
4244         var body = null;
4245         if (method === 'GET') {
4246             url = injectQueryStringParams(url, params);
4247         }
4248         else {
4249             body = encodeParams(params);
4250         }
4251         var xhr = new XMLHttpRequest();
4252         xhr.open(method, url, true);
4253         if (method !== 'GET') {
4254             xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
4255         }
4256         xhr.onload = function () {
4257             if (xhr.status >= 200 && xhr.status < 400) {
4258                 try {
4259                     var res = JSON.parse(xhr.responseText);
4260                     successCallback(res, xhr);
4261                 }
4262                 catch (err) {
4263                     failureCallback('Failure parsing JSON', xhr);
4264                 }
4265             }
4266             else {
4267                 failureCallback('Request failed', xhr);
4268             }
4269         };
4270         xhr.onerror = function () {
4271             failureCallback('Request failed', xhr);
4272         };
4273         xhr.send(body);
4274     }
4275     function injectQueryStringParams(url, params) {
4276         return url +
4277             (url.indexOf('?') === -1 ? '?' : '&') +
4278             encodeParams(params);
4279     }
4280     function encodeParams(params) {
4281         var parts = [];
4282         for (var key in params) {
4283             parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
4284         }
4285         return parts.join('&');
4286     }
4287
4288     var eventSourceDef$2 = {
4289         parseMeta: function (raw) {
4290             if (typeof raw === 'string') { // short form
4291                 raw = { url: raw };
4292             }
4293             else if (!raw || typeof raw !== 'object' || !raw.url) {
4294                 return null;
4295             }
4296             return {
4297                 url: raw.url,
4298                 method: (raw.method || 'GET').toUpperCase(),
4299                 extraParams: raw.extraParams,
4300                 startParam: raw.startParam,
4301                 endParam: raw.endParam,
4302                 timeZoneParam: raw.timeZoneParam
4303             };
4304         },
4305         fetch: function (arg, success, failure) {
4306             var meta = arg.eventSource.meta;
4307             var requestParams = buildRequestParams(meta, arg.range, arg.calendar);
4308             requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) {
4309                 success({ rawEvents: rawEvents, xhr: xhr });
4310             }, function (errorMessage, xhr) {
4311                 failure({ message: errorMessage, xhr: xhr });
4312             });
4313         }
4314     };
4315     var JsonFeedEventSourcePlugin = createPlugin({
4316         eventSourceDefs: [eventSourceDef$2]
4317     });
4318     function buildRequestParams(meta, range, calendar) {
4319         var dateEnv = calendar.dateEnv;
4320         var startParam;
4321         var endParam;
4322         var timeZoneParam;
4323         var customRequestParams;
4324         var params = {};
4325         startParam = meta.startParam;
4326         if (startParam == null) {
4327             startParam = calendar.opt('startParam');
4328         }
4329         endParam = meta.endParam;
4330         if (endParam == null) {
4331             endParam = calendar.opt('endParam');
4332         }
4333         timeZoneParam = meta.timeZoneParam;
4334         if (timeZoneParam == null) {
4335             timeZoneParam = calendar.opt('timeZoneParam');
4336         }
4337         // retrieve any outbound GET/POST data from the options
4338         if (typeof meta.extraParams === 'function') {
4339             // supplied as a function that returns a key/value object
4340             customRequestParams = meta.extraParams();
4341         }
4342         else {
4343             // probably supplied as a straight key/value object
4344             customRequestParams = meta.extraParams || {};
4345         }
4346         __assign(params, customRequestParams);
4347         params[startParam] = dateEnv.formatIso(range.start);
4348         params[endParam] = dateEnv.formatIso(range.end);
4349         if (dateEnv.timeZone !== 'local') {
4350             params[timeZoneParam] = dateEnv.timeZone;
4351         }
4352         return params;
4353     }
4354
4355     var recurring = {
4356         parse: function (rawEvent, leftoverProps, dateEnv) {
4357             var createMarker = dateEnv.createMarker.bind(dateEnv);
4358             var processors = {
4359                 daysOfWeek: null,
4360                 startTime: createDuration,
4361                 endTime: createDuration,
4362                 startRecur: createMarker,
4363                 endRecur: createMarker
4364             };
4365             var props = refineProps(rawEvent, processors, {}, leftoverProps);
4366             var anyValid = false;
4367             for (var propName in props) {
4368                 if (props[propName] != null) {
4369                     anyValid = true;
4370                     break;
4371                 }
4372             }
4373             if (anyValid) {
4374                 var duration = null;
4375                 if ('duration' in leftoverProps) {
4376                     duration = createDuration(leftoverProps.duration);
4377                     delete leftoverProps.duration;
4378                 }
4379                 if (!duration && props.startTime && props.endTime) {
4380                     duration = subtractDurations(props.endTime, props.startTime);
4381                 }
4382                 return {
4383                     allDayGuess: Boolean(!props.startTime && !props.endTime),
4384                     duration: duration,
4385                     typeData: props // doesn't need endTime anymore but oh well
4386                 };
4387             }
4388             return null;
4389         },
4390         expand: function (typeData, framingRange, dateEnv) {
4391             var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
4392             if (clippedFramingRange) {
4393                 return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
4394             }
4395             else {
4396                 return [];
4397             }
4398         }
4399     };
4400     var SimpleRecurrencePlugin = createPlugin({
4401         recurringTypes: [recurring]
4402     });
4403     function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
4404         var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
4405         var dayMarker = startOfDay(framingRange.start);
4406         var endMarker = framingRange.end;
4407         var instanceStarts = [];
4408         while (dayMarker < endMarker) {
4409             var instanceStart 
4410             // if everyday, or this particular day-of-week
4411             = void 0;
4412             // if everyday, or this particular day-of-week
4413             if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
4414                 if (startTime) {
4415                     instanceStart = dateEnv.add(dayMarker, startTime);
4416                 }
4417                 else {
4418                     instanceStart = dayMarker;
4419                 }
4420                 instanceStarts.push(instanceStart);
4421             }
4422             dayMarker = addDays(dayMarker, 1);
4423         }
4424         return instanceStarts;
4425     }
4426
4427     var DefaultOptionChangeHandlers = createPlugin({
4428         optionChangeHandlers: {
4429             events: function (events, calendar, deepEqual) {
4430                 handleEventSources([events], calendar, deepEqual);
4431             },
4432             eventSources: handleEventSources,
4433             plugins: handlePlugins
4434         }
4435     });
4436     function handleEventSources(inputs, calendar, deepEqual) {
4437         var unfoundSources = hashValuesToArray(calendar.state.eventSources);
4438         var newInputs = [];
4439         for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
4440             var input = inputs_1[_i];
4441             var inputFound = false;
4442             for (var i = 0; i < unfoundSources.length; i++) {
4443                 if (deepEqual(unfoundSources[i]._raw, input)) {
4444                     unfoundSources.splice(i, 1); // delete
4445                     inputFound = true;
4446                     break;
4447                 }
4448             }
4449             if (!inputFound) {
4450                 newInputs.push(input);
4451             }
4452         }
4453         for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) {
4454             var unfoundSource = unfoundSources_1[_a];
4455             calendar.dispatch({
4456                 type: 'REMOVE_EVENT_SOURCE',
4457                 sourceId: unfoundSource.sourceId
4458             });
4459         }
4460         for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) {
4461             var newInput = newInputs_1[_b];
4462             calendar.addEventSource(newInput);
4463         }
4464     }
4465     // shortcoming: won't remove plugins
4466     function handlePlugins(inputs, calendar) {
4467         calendar.addPluginInputs(inputs); // will gracefully handle duplicates
4468     }
4469
4470     var config = {}; // TODO: make these options
4471     var globalDefaults = {
4472         defaultRangeSeparator: ' - ',
4473         titleRangeSeparator: ' \u2013 ',
4474         defaultTimedEventDuration: '01:00:00',
4475         defaultAllDayEventDuration: { day: 1 },
4476         forceEventDuration: false,
4477         nextDayThreshold: '00:00:00',
4478         // display
4479         columnHeader: true,
4480         defaultView: '',
4481         aspectRatio: 1.35,
4482         header: {
4483             left: 'title',
4484             center: '',
4485             right: 'today prev,next'
4486         },
4487         weekends: true,
4488         weekNumbers: false,
4489         weekNumberCalculation: 'local',
4490         editable: false,
4491         // nowIndicator: false,
4492         scrollTime: '06:00:00',
4493         minTime: '00:00:00',
4494         maxTime: '24:00:00',
4495         showNonCurrentDates: true,
4496         // event ajax
4497         lazyFetching: true,
4498         startParam: 'start',
4499         endParam: 'end',
4500         timeZoneParam: 'timeZone',
4501         timeZone: 'local',
4502         // allDayDefault: undefined,
4503         // locale
4504         locales: [],
4505         locale: '',
4506         // dir: will get this from the default locale
4507         // buttonIcons: null,
4508         // allows setting a min-height to the event segment to prevent short events overlapping each other
4509         timeGridEventMinHeight: 0,
4510         themeSystem: 'standard',
4511         // eventResizableFromStart: false,
4512         dragRevertDuration: 500,
4513         dragScroll: true,
4514         allDayMaintainDuration: false,
4515         // selectable: false,
4516         unselectAuto: true,
4517         // selectMinDistance: 0,
4518         dropAccept: '*',
4519         eventOrder: 'start,-duration,allDay,title',
4520         // ^ if start tie, longer events go before shorter. final tie-breaker is title text
4521         // rerenderDelay: null,
4522         eventLimit: false,
4523         eventLimitClick: 'popover',
4524         dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
4525         handleWindowResize: true,
4526         windowResizeDelay: 100,
4527         longPressDelay: 1000,
4528         eventDragMinDistance: 5 // only applies to mouse
4529     };
4530     var rtlDefaults = {
4531         header: {
4532             left: 'next,prev today',
4533             center: '',
4534             right: 'title'
4535         },
4536         buttonIcons: {
4537             // TODO: make RTL support the responibility of the theme
4538             prev: 'fc-icon-chevron-right',
4539             next: 'fc-icon-chevron-left',
4540             prevYear: 'fc-icon-chevrons-right',
4541             nextYear: 'fc-icon-chevrons-left'
4542         }
4543     };
4544     var complexOptions = [
4545         'header',
4546         'footer',
4547         'buttonText',
4548         'buttonIcons'
4549     ];
4550     // Merges an array of option objects into a single object
4551     function mergeOptions(optionObjs) {
4552         return mergeProps(optionObjs, complexOptions);
4553     }
4554     // TODO: move this stuff to a "plugin"-related file...
4555     var INTERNAL_PLUGINS = [
4556         ArrayEventSourcePlugin,
4557         FuncEventSourcePlugin,
4558         JsonFeedEventSourcePlugin,
4559         SimpleRecurrencePlugin,
4560         DefaultOptionChangeHandlers
4561     ];
4562     function refinePluginDefs(pluginInputs) {
4563         var plugins = [];
4564         for (var _i = 0, pluginInputs_1 = pluginInputs; _i < pluginInputs_1.length; _i++) {
4565             var pluginInput = pluginInputs_1[_i];
4566             if (typeof pluginInput === 'string') {
4567                 var globalName = 'FullCalendar' + capitaliseFirstLetter(pluginInput);
4568                 if (!window[globalName]) {
4569                     console.warn('Plugin file not loaded for ' + pluginInput);
4570                 }
4571                 else {
4572                     plugins.push(window[globalName].default); // is an ES6 module
4573                 }
4574             }
4575             else {
4576                 plugins.push(pluginInput);
4577             }
4578         }
4579         return INTERNAL_PLUGINS.concat(plugins);
4580     }
4581
4582     var RAW_EN_LOCALE = {
4583         code: 'en',
4584         week: {
4585             dow: 0,
4586             doy: 4 // 4 days need to be within the year to be considered the first week
4587         },
4588         dir: 'ltr',
4589         buttonText: {
4590             prev: 'prev',
4591             next: 'next',
4592             prevYear: 'prev year',
4593             nextYear: 'next year',
4594             year: 'year',
4595             today: 'today',
4596             month: 'month',
4597             week: 'week',
4598             day: 'day',
4599             list: 'list'
4600         },
4601         weekLabel: 'W',
4602         allDayText: 'all-day',
4603         eventLimitText: 'more',
4604         noEventsMessage: 'No events to display'
4605     };
4606     function parseRawLocales(explicitRawLocales) {
4607         var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
4608         var globalArray = window['FullCalendarLocalesAll'] || []; // from locales-all.js
4609         var globalObject = window['FullCalendarLocales'] || {}; // from locales/*.js. keys are meaningless
4610         var allRawLocales = globalArray.concat(// globalArray is low prio
4611         hashValuesToArray(globalObject), // medium prio
4612         explicitRawLocales // highest prio
4613         );
4614         var rawLocaleMap = {
4615             en: RAW_EN_LOCALE // necessary?
4616         };
4617         for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) {
4618             var rawLocale = allRawLocales_1[_i];
4619             rawLocaleMap[rawLocale.code] = rawLocale;
4620         }
4621         return {
4622             map: rawLocaleMap,
4623             defaultCode: defaultCode
4624         };
4625     }
4626     function buildLocale(inputSingular, available) {
4627         if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
4628             return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
4629         }
4630         else {
4631             return queryLocale(inputSingular, available);
4632         }
4633     }
4634     function queryLocale(codeArg, available) {
4635         var codes = [].concat(codeArg || []); // will convert to array
4636         var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
4637         return parseLocale(codeArg, codes, raw);
4638     }
4639     function queryRawLocale(codes, available) {
4640         for (var i = 0; i < codes.length; i++) {
4641             var parts = codes[i].toLocaleLowerCase().split('-');
4642             for (var j = parts.length; j > 0; j--) {
4643                 var simpleId = parts.slice(0, j).join('-');
4644                 if (available[simpleId]) {
4645                     return available[simpleId];
4646                 }
4647             }
4648         }
4649         return null;
4650     }
4651     function parseLocale(codeArg, codes, raw) {
4652         var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']);
4653         delete merged.code; // don't want this part of the options
4654         var week = merged.week;
4655         delete merged.week;
4656         return {
4657             codeArg: codeArg,
4658             codes: codes,
4659             week: week,
4660             simpleNumberFormat: new Intl.NumberFormat(codeArg),
4661             options: merged
4662         };
4663     }
4664
4665     var OptionsManager = /** @class */ (function () {
4666         function OptionsManager(overrides) {
4667             this.overrides = __assign({}, overrides); // make a copy
4668             this.dynamicOverrides = {};
4669             this.compute();
4670         }
4671         OptionsManager.prototype.mutate = function (updates, removals, isDynamic) {
4672             var overrideHash = isDynamic ? this.dynamicOverrides : this.overrides;
4673             __assign(overrideHash, updates);
4674             for (var _i = 0, removals_1 = removals; _i < removals_1.length; _i++) {
4675                 var propName = removals_1[_i];
4676                 delete overrideHash[propName];
4677             }
4678             this.compute();
4679         };
4680         // Computes the flattened options hash for the calendar and assigns to `this.options`.
4681         // Assumes this.overrides and this.dynamicOverrides have already been initialized.
4682         OptionsManager.prototype.compute = function () {
4683             // TODO: not a very efficient system
4684             var locales = firstDefined(// explicit locale option given?
4685             this.dynamicOverrides.locales, this.overrides.locales, globalDefaults.locales);
4686             var locale = firstDefined(// explicit locales option given?
4687             this.dynamicOverrides.locale, this.overrides.locale, globalDefaults.locale);
4688             var available = parseRawLocales(locales);
4689             var localeDefaults = buildLocale(locale || available.defaultCode, available.map).options;
4690             var dir = firstDefined(// based on options computed so far, is direction RTL?
4691             this.dynamicOverrides.dir, this.overrides.dir, localeDefaults.dir);
4692             var dirDefaults = dir === 'rtl' ? rtlDefaults : {};
4693             this.dirDefaults = dirDefaults;
4694             this.localeDefaults = localeDefaults;
4695             this.computed = mergeOptions([
4696                 globalDefaults,
4697                 dirDefaults,
4698                 localeDefaults,
4699                 this.overrides,
4700                 this.dynamicOverrides
4701             ]);
4702         };
4703         return OptionsManager;
4704     }());
4705
4706     var calendarSystemClassMap = {};
4707     function registerCalendarSystem(name, theClass) {
4708         calendarSystemClassMap[name] = theClass;
4709     }
4710     function createCalendarSystem(name) {
4711         return new calendarSystemClassMap[name]();
4712     }
4713     var GregorianCalendarSystem = /** @class */ (function () {
4714         function GregorianCalendarSystem() {
4715         }
4716         GregorianCalendarSystem.prototype.getMarkerYear = function (d) {
4717             return d.getUTCFullYear();
4718         };
4719         GregorianCalendarSystem.prototype.getMarkerMonth = function (d) {
4720             return d.getUTCMonth();
4721         };
4722         GregorianCalendarSystem.prototype.getMarkerDay = function (d) {
4723             return d.getUTCDate();
4724         };
4725         GregorianCalendarSystem.prototype.arrayToMarker = function (arr) {
4726             return arrayToUtcDate(arr);
4727         };
4728         GregorianCalendarSystem.prototype.markerToArray = function (marker) {
4729             return dateToUtcArray(marker);
4730         };
4731         return GregorianCalendarSystem;
4732     }());
4733     registerCalendarSystem('gregory', GregorianCalendarSystem);
4734
4735     var ISO_RE = /^\s*(\d{4})(-(\d{2})(-(\d{2})([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
4736     function parse(str) {
4737         var m = ISO_RE.exec(str);
4738         if (m) {
4739             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));
4740             if (isValidDate(marker)) {
4741                 var timeZoneOffset = null;
4742                 if (m[13]) {
4743                     timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
4744                         Number(m[18] || 0));
4745                 }
4746                 return {
4747                     marker: marker,
4748                     isTimeUnspecified: !m[6],
4749                     timeZoneOffset: timeZoneOffset
4750                 };
4751             }
4752         }
4753         return null;
4754     }
4755
4756     var DateEnv = /** @class */ (function () {
4757         function DateEnv(settings) {
4758             var timeZone = this.timeZone = settings.timeZone;
4759             var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
4760             if (settings.namedTimeZoneImpl && isNamedTimeZone) {
4761                 this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
4762             }
4763             this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
4764             this.calendarSystem = createCalendarSystem(settings.calendarSystem);
4765             this.locale = settings.locale;
4766             this.weekDow = settings.locale.week.dow;
4767             this.weekDoy = settings.locale.week.doy;
4768             if (settings.weekNumberCalculation === 'ISO') {
4769                 this.weekDow = 1;
4770                 this.weekDoy = 4;
4771             }
4772             if (typeof settings.firstDay === 'number') {
4773                 this.weekDow = settings.firstDay;
4774             }
4775             if (typeof settings.weekNumberCalculation === 'function') {
4776                 this.weekNumberFunc = settings.weekNumberCalculation;
4777             }
4778             this.weekLabel = settings.weekLabel != null ? settings.weekLabel : settings.locale.options.weekLabel;
4779             this.cmdFormatter = settings.cmdFormatter;
4780         }
4781         // Creating / Parsing
4782         DateEnv.prototype.createMarker = function (input) {
4783             var meta = this.createMarkerMeta(input);
4784             if (meta === null) {
4785                 return null;
4786             }
4787             return meta.marker;
4788         };
4789         DateEnv.prototype.createNowMarker = function () {
4790             if (this.canComputeOffset) {
4791                 return this.timestampToMarker(new Date().valueOf());
4792             }
4793             else {
4794                 // if we can't compute the current date val for a timezone,
4795                 // better to give the current local date vals than UTC
4796                 return arrayToUtcDate(dateToLocalArray(new Date()));
4797             }
4798         };
4799         DateEnv.prototype.createMarkerMeta = function (input) {
4800             if (typeof input === 'string') {
4801                 return this.parse(input);
4802             }
4803             var marker = null;
4804             if (typeof input === 'number') {
4805                 marker = this.timestampToMarker(input);
4806             }
4807             else if (input instanceof Date) {
4808                 input = input.valueOf();
4809                 if (!isNaN(input)) {
4810                     marker = this.timestampToMarker(input);
4811                 }
4812             }
4813             else if (Array.isArray(input)) {
4814                 marker = arrayToUtcDate(input);
4815             }
4816             if (marker === null || !isValidDate(marker)) {
4817                 return null;
4818             }
4819             return { marker: marker, isTimeUnspecified: false, forcedTzo: null };
4820         };
4821         DateEnv.prototype.parse = function (s) {
4822             var parts = parse(s);
4823             if (parts === null) {
4824                 return null;
4825             }
4826             var marker = parts.marker;
4827             var forcedTzo = null;
4828             if (parts.timeZoneOffset !== null) {
4829                 if (this.canComputeOffset) {
4830                     marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
4831                 }
4832                 else {
4833                     forcedTzo = parts.timeZoneOffset;
4834                 }
4835             }
4836             return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo };
4837         };
4838         // Accessors
4839         DateEnv.prototype.getYear = function (marker) {
4840             return this.calendarSystem.getMarkerYear(marker);
4841         };
4842         DateEnv.prototype.getMonth = function (marker) {
4843             return this.calendarSystem.getMarkerMonth(marker);
4844         };
4845         // Adding / Subtracting
4846         DateEnv.prototype.add = function (marker, dur) {
4847             var a = this.calendarSystem.markerToArray(marker);
4848             a[0] += dur.years;
4849             a[1] += dur.months;
4850             a[2] += dur.days;
4851             a[6] += dur.milliseconds;
4852             return this.calendarSystem.arrayToMarker(a);
4853         };
4854         DateEnv.prototype.subtract = function (marker, dur) {
4855             var a = this.calendarSystem.markerToArray(marker);
4856             a[0] -= dur.years;
4857             a[1] -= dur.months;
4858             a[2] -= dur.days;
4859             a[6] -= dur.milliseconds;
4860             return this.calendarSystem.arrayToMarker(a);
4861         };
4862         DateEnv.prototype.addYears = function (marker, n) {
4863             var a = this.calendarSystem.markerToArray(marker);
4864             a[0] += n;
4865             return this.calendarSystem.arrayToMarker(a);
4866         };
4867         DateEnv.prototype.addMonths = function (marker, n) {
4868             var a = this.calendarSystem.markerToArray(marker);
4869             a[1] += n;
4870             return this.calendarSystem.arrayToMarker(a);
4871         };
4872         // Diffing Whole Units
4873         DateEnv.prototype.diffWholeYears = function (m0, m1) {
4874             var calendarSystem = this.calendarSystem;
4875             if (timeAsMs(m0) === timeAsMs(m1) &&
4876                 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
4877                 calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
4878                 return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
4879             }
4880             return null;
4881         };
4882         DateEnv.prototype.diffWholeMonths = function (m0, m1) {
4883             var calendarSystem = this.calendarSystem;
4884             if (timeAsMs(m0) === timeAsMs(m1) &&
4885                 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
4886                 return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
4887                     (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
4888             }
4889             return null;
4890         };
4891         // Range / Duration
4892         DateEnv.prototype.greatestWholeUnit = function (m0, m1) {
4893             var n = this.diffWholeYears(m0, m1);
4894             if (n !== null) {
4895                 return { unit: 'year', value: n };
4896             }
4897             n = this.diffWholeMonths(m0, m1);
4898             if (n !== null) {
4899                 return { unit: 'month', value: n };
4900             }
4901             n = diffWholeWeeks(m0, m1);
4902             if (n !== null) {
4903                 return { unit: 'week', value: n };
4904             }
4905             n = diffWholeDays(m0, m1);
4906             if (n !== null) {
4907                 return { unit: 'day', value: n };
4908             }
4909             n = diffHours(m0, m1);
4910             if (isInt(n)) {
4911                 return { unit: 'hour', value: n };
4912             }
4913             n = diffMinutes(m0, m1);
4914             if (isInt(n)) {
4915                 return { unit: 'minute', value: n };
4916             }
4917             n = diffSeconds(m0, m1);
4918             if (isInt(n)) {
4919                 return { unit: 'second', value: n };
4920             }
4921             return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
4922         };
4923         DateEnv.prototype.countDurationsBetween = function (m0, m1, d) {
4924             // TODO: can use greatestWholeUnit
4925             var diff;
4926             if (d.years) {
4927                 diff = this.diffWholeYears(m0, m1);
4928                 if (diff !== null) {
4929                     return diff / asRoughYears(d);
4930                 }
4931             }
4932             if (d.months) {
4933                 diff = this.diffWholeMonths(m0, m1);
4934                 if (diff !== null) {
4935                     return diff / asRoughMonths(d);
4936                 }
4937             }
4938             if (d.days) {
4939                 diff = diffWholeDays(m0, m1);
4940                 if (diff !== null) {
4941                     return diff / asRoughDays(d);
4942                 }
4943             }
4944             return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
4945         };
4946         // Start-Of
4947         DateEnv.prototype.startOf = function (m, unit) {
4948             if (unit === 'year') {
4949                 return this.startOfYear(m);
4950             }
4951             else if (unit === 'month') {
4952                 return this.startOfMonth(m);
4953             }
4954             else if (unit === 'week') {
4955                 return this.startOfWeek(m);
4956             }
4957             else if (unit === 'day') {
4958                 return startOfDay(m);
4959             }
4960             else if (unit === 'hour') {
4961                 return startOfHour(m);
4962             }
4963             else if (unit === 'minute') {
4964                 return startOfMinute(m);
4965             }
4966             else if (unit === 'second') {
4967                 return startOfSecond(m);
4968             }
4969         };
4970         DateEnv.prototype.startOfYear = function (m) {
4971             return this.calendarSystem.arrayToMarker([
4972                 this.calendarSystem.getMarkerYear(m)
4973             ]);
4974         };
4975         DateEnv.prototype.startOfMonth = function (m) {
4976             return this.calendarSystem.arrayToMarker([
4977                 this.calendarSystem.getMarkerYear(m),
4978                 this.calendarSystem.getMarkerMonth(m)
4979             ]);
4980         };
4981         DateEnv.prototype.startOfWeek = function (m) {
4982             return this.calendarSystem.arrayToMarker([
4983                 this.calendarSystem.getMarkerYear(m),
4984                 this.calendarSystem.getMarkerMonth(m),
4985                 m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7)
4986             ]);
4987         };
4988         // Week Number
4989         DateEnv.prototype.computeWeekNumber = function (marker) {
4990             if (this.weekNumberFunc) {
4991                 return this.weekNumberFunc(this.toDate(marker));
4992             }
4993             else {
4994                 return weekOfYear(marker, this.weekDow, this.weekDoy);
4995             }
4996         };
4997         // TODO: choke on timeZoneName: long
4998         DateEnv.prototype.format = function (marker, formatter, dateOptions) {
4999             if (dateOptions === void 0) { dateOptions = {}; }
5000             return formatter.format({
5001                 marker: marker,
5002                 timeZoneOffset: dateOptions.forcedTzo != null ?
5003                     dateOptions.forcedTzo :
5004                     this.offsetForMarker(marker)
5005             }, this);
5006         };
5007         DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) {
5008             if (dateOptions === void 0) { dateOptions = {}; }
5009             if (dateOptions.isEndExclusive) {
5010                 end = addMs(end, -1);
5011             }
5012             return formatter.formatRange({
5013                 marker: start,
5014                 timeZoneOffset: dateOptions.forcedStartTzo != null ?
5015                     dateOptions.forcedStartTzo :
5016                     this.offsetForMarker(start)
5017             }, {
5018                 marker: end,
5019                 timeZoneOffset: dateOptions.forcedEndTzo != null ?
5020                     dateOptions.forcedEndTzo :
5021                     this.offsetForMarker(end)
5022             }, this);
5023         };
5024         DateEnv.prototype.formatIso = function (marker, extraOptions) {
5025             if (extraOptions === void 0) { extraOptions = {}; }
5026             var timeZoneOffset = null;
5027             if (!extraOptions.omitTimeZoneOffset) {
5028                 if (extraOptions.forcedTzo != null) {
5029                     timeZoneOffset = extraOptions.forcedTzo;
5030                 }
5031                 else {
5032                     timeZoneOffset = this.offsetForMarker(marker);
5033                 }
5034             }
5035             return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
5036         };
5037         // TimeZone
5038         DateEnv.prototype.timestampToMarker = function (ms) {
5039             if (this.timeZone === 'local') {
5040                 return arrayToUtcDate(dateToLocalArray(new Date(ms)));
5041             }
5042             else if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
5043                 return new Date(ms);
5044             }
5045             else {
5046                 return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
5047             }
5048         };
5049         DateEnv.prototype.offsetForMarker = function (m) {
5050             if (this.timeZone === 'local') {
5051                 return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
5052             }
5053             else if (this.timeZone === 'UTC') {
5054                 return 0;
5055             }
5056             else if (this.namedTimeZoneImpl) {
5057                 return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
5058             }
5059             return null;
5060         };
5061         // Conversion
5062         DateEnv.prototype.toDate = function (m, forcedTzo) {
5063             if (this.timeZone === 'local') {
5064                 return arrayToLocalDate(dateToUtcArray(m));
5065             }
5066             else if (this.timeZone === 'UTC') {
5067                 return new Date(m.valueOf()); // make sure it's a copy
5068             }
5069             else if (!this.namedTimeZoneImpl) {
5070                 return new Date(m.valueOf() - (forcedTzo || 0));
5071             }
5072             else {
5073                 return new Date(m.valueOf() -
5074                     this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60 // convert minutes -> ms
5075                 );
5076             }
5077         };
5078         return DateEnv;
5079     }());
5080
5081     var SIMPLE_SOURCE_PROPS = {
5082         id: String,
5083         allDayDefault: Boolean,
5084         eventDataTransform: Function,
5085         success: Function,
5086         failure: Function
5087     };
5088     var uid$2 = 0;
5089     function doesSourceNeedRange(eventSource, calendar) {
5090         var defs = calendar.pluginSystem.hooks.eventSourceDefs;
5091         return !defs[eventSource.sourceDefId].ignoreRange;
5092     }
5093     function parseEventSource(raw, calendar) {
5094         var defs = calendar.pluginSystem.hooks.eventSourceDefs;
5095         for (var i = defs.length - 1; i >= 0; i--) { // later-added plugins take precedence
5096             var def = defs[i];
5097             var meta = def.parseMeta(raw);
5098             if (meta) {
5099                 var res = parseEventSourceProps(typeof raw === 'object' ? raw : {}, meta, i, calendar);
5100                 res._raw = raw;
5101                 return res;
5102             }
5103         }
5104         return null;
5105     }
5106     function parseEventSourceProps(raw, meta, sourceDefId, calendar) {
5107         var leftovers0 = {};
5108         var props = refineProps(raw, SIMPLE_SOURCE_PROPS, {}, leftovers0);
5109         var leftovers1 = {};
5110         var ui = processUnscopedUiProps(leftovers0, calendar, leftovers1);
5111         props.isFetching = false;
5112         props.latestFetchId = '';
5113         props.fetchRange = null;
5114         props.publicId = String(raw.id || '');
5115         props.sourceId = String(uid$2++);
5116         props.sourceDefId = sourceDefId;
5117         props.meta = meta;
5118         props.ui = ui;
5119         props.extendedProps = leftovers1;
5120         return props;
5121     }
5122
5123     function reduceEventSources (eventSources, action, dateProfile, calendar) {
5124         switch (action.type) {
5125             case 'ADD_EVENT_SOURCES': // already parsed
5126                 return addSources(eventSources, action.sources, dateProfile ? dateProfile.activeRange : null, calendar);
5127             case 'REMOVE_EVENT_SOURCE':
5128                 return removeSource(eventSources, action.sourceId);
5129             case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
5130             case 'NEXT':
5131             case 'SET_DATE':
5132             case 'SET_VIEW_TYPE':
5133                 if (dateProfile) {
5134                     return fetchDirtySources(eventSources, dateProfile.activeRange, calendar);
5135                 }
5136                 else {
5137                     return eventSources;
5138                 }
5139             case 'FETCH_EVENT_SOURCES':
5140             case 'CHANGE_TIMEZONE':
5141                 return fetchSourcesByIds(eventSources, action.sourceIds ?
5142                     arrayToHash(action.sourceIds) :
5143                     excludeStaticSources(eventSources, calendar), dateProfile ? dateProfile.activeRange : null, calendar);
5144             case 'RECEIVE_EVENTS':
5145             case 'RECEIVE_EVENT_ERROR':
5146                 return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
5147             case 'REMOVE_ALL_EVENT_SOURCES':
5148                 return {};
5149             default:
5150                 return eventSources;
5151         }
5152     }
5153     var uid$3 = 0;
5154     function addSources(eventSourceHash, sources, fetchRange, calendar) {
5155         var hash = {};
5156         for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
5157             var source = sources_1[_i];
5158             hash[source.sourceId] = source;
5159         }
5160         if (fetchRange) {
5161             hash = fetchDirtySources(hash, fetchRange, calendar);
5162         }
5163         return __assign({}, eventSourceHash, hash);
5164     }
5165     function removeSource(eventSourceHash, sourceId) {
5166         return filterHash(eventSourceHash, function (eventSource) {
5167             return eventSource.sourceId !== sourceId;
5168         });
5169     }
5170     function fetchDirtySources(sourceHash, fetchRange, calendar) {
5171         return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) {
5172             return isSourceDirty(eventSource, fetchRange, calendar);
5173         }), fetchRange, calendar);
5174     }
5175     function isSourceDirty(eventSource, fetchRange, calendar) {
5176         if (!doesSourceNeedRange(eventSource, calendar)) {
5177             return !eventSource.latestFetchId;
5178         }
5179         else {
5180             return !calendar.opt('lazyFetching') ||
5181                 !eventSource.fetchRange ||
5182                 fetchRange.start < eventSource.fetchRange.start ||
5183                 fetchRange.end > eventSource.fetchRange.end;
5184         }
5185     }
5186     function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, calendar) {
5187         var nextSources = {};
5188         for (var sourceId in prevSources) {
5189             var source = prevSources[sourceId];
5190             if (sourceIdHash[sourceId]) {
5191                 nextSources[sourceId] = fetchSource(source, fetchRange, calendar);
5192             }
5193             else {
5194                 nextSources[sourceId] = source;
5195             }
5196         }
5197         return nextSources;
5198     }
5199     function fetchSource(eventSource, fetchRange, calendar) {
5200         var sourceDef = calendar.pluginSystem.hooks.eventSourceDefs[eventSource.sourceDefId];
5201         var fetchId = String(uid$3++);
5202         sourceDef.fetch({
5203             eventSource: eventSource,
5204             calendar: calendar,
5205             range: fetchRange
5206         }, function (res) {
5207             var rawEvents = res.rawEvents;
5208             var calSuccess = calendar.opt('eventSourceSuccess');
5209             var calSuccessRes;
5210             var sourceSuccessRes;
5211             if (eventSource.success) {
5212                 sourceSuccessRes = eventSource.success(rawEvents, res.xhr);
5213             }
5214             if (calSuccess) {
5215                 calSuccessRes = calSuccess(rawEvents, res.xhr);
5216             }
5217             rawEvents = sourceSuccessRes || calSuccessRes || rawEvents;
5218             calendar.dispatch({
5219                 type: 'RECEIVE_EVENTS',
5220                 sourceId: eventSource.sourceId,
5221                 fetchId: fetchId,
5222                 fetchRange: fetchRange,
5223                 rawEvents: rawEvents
5224             });
5225         }, function (error) {
5226             var callFailure = calendar.opt('eventSourceFailure');
5227             console.warn(error.message, error);
5228             if (eventSource.failure) {
5229                 eventSource.failure(error);
5230             }
5231             if (callFailure) {
5232                 callFailure(error);
5233             }
5234             calendar.dispatch({
5235                 type: 'RECEIVE_EVENT_ERROR',
5236                 sourceId: eventSource.sourceId,
5237                 fetchId: fetchId,
5238                 fetchRange: fetchRange,
5239                 error: error
5240             });
5241         });
5242         return __assign({}, eventSource, { isFetching: true, latestFetchId: fetchId });
5243     }
5244     function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
5245         var _a;
5246         var eventSource = sourceHash[sourceId];
5247         if (eventSource && // not already removed
5248             fetchId === eventSource.latestFetchId) {
5249             return __assign({}, sourceHash, (_a = {}, _a[sourceId] = __assign({}, eventSource, { isFetching: false, fetchRange: fetchRange }), _a));
5250         }
5251         return sourceHash;
5252     }
5253     function excludeStaticSources(eventSources, calendar) {
5254         return filterHash(eventSources, function (eventSource) {
5255             return doesSourceNeedRange(eventSource, calendar);
5256         });
5257     }
5258
5259     var DateProfileGenerator = /** @class */ (function () {
5260         function DateProfileGenerator(viewSpec, calendar) {
5261             this.viewSpec = viewSpec;
5262             this.options = viewSpec.options;
5263             this.dateEnv = calendar.dateEnv;
5264             this.calendar = calendar;
5265             this.initHiddenDays();
5266         }
5267         /* Date Range Computation
5268         ------------------------------------------------------------------------------------------------------------------*/
5269         // Builds a structure with info about what the dates/ranges will be for the "prev" view.
5270         DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate) {
5271             var dateEnv = this.dateEnv;
5272             var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5273             currentDateProfile.dateIncrement);
5274             return this.build(prevDate, -1);
5275         };
5276         // Builds a structure with info about what the dates/ranges will be for the "next" view.
5277         DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate) {
5278             var dateEnv = this.dateEnv;
5279             var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5280             currentDateProfile.dateIncrement);
5281             return this.build(nextDate, 1);
5282         };
5283         // Builds a structure holding dates/ranges for rendering around the given date.
5284         // Optional direction param indicates whether the date is being incremented/decremented
5285         // from its previous value. decremented = -1, incremented = 1 (default).
5286         DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) {
5287             if (forceToValid === void 0) { forceToValid = false; }
5288             var validRange;
5289             var minTime = null;
5290             var maxTime = null;
5291             var currentInfo;
5292             var isRangeAllDay;
5293             var renderRange;
5294             var activeRange;
5295             var isValid;
5296             validRange = this.buildValidRange();
5297             validRange = this.trimHiddenDays(validRange);
5298             if (forceToValid) {
5299                 currentDate = constrainMarkerToRange(currentDate, validRange);
5300             }
5301             currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
5302             isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
5303             renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
5304             renderRange = this.trimHiddenDays(renderRange);
5305             activeRange = renderRange;
5306             if (!this.options.showNonCurrentDates) {
5307                 activeRange = intersectRanges(activeRange, currentInfo.range);
5308             }
5309             minTime = createDuration(this.options.minTime);
5310             maxTime = createDuration(this.options.maxTime);
5311             activeRange = this.adjustActiveRange(activeRange, minTime, maxTime);
5312             activeRange = intersectRanges(activeRange, validRange); // might return null
5313             // it's invalid if the originally requested date is not contained,
5314             // or if the range is completely outside of the valid range.
5315             isValid = rangesIntersect(currentInfo.range, validRange);
5316             return {
5317                 // constraint for where prev/next operations can go and where events can be dragged/resized to.
5318                 // an object with optional start and end properties.
5319                 validRange: validRange,
5320                 // range the view is formally responsible for.
5321                 // for example, a month view might have 1st-31st, excluding padded dates
5322                 currentRange: currentInfo.range,
5323                 // name of largest unit being displayed, like "month" or "week"
5324                 currentRangeUnit: currentInfo.unit,
5325                 isRangeAllDay: isRangeAllDay,
5326                 // dates that display events and accept drag-n-drop
5327                 // will be `null` if no dates accept events
5328                 activeRange: activeRange,
5329                 // date range with a rendered skeleton
5330                 // includes not-active days that need some sort of DOM
5331                 renderRange: renderRange,
5332                 // Duration object that denotes the first visible time of any given day
5333                 minTime: minTime,
5334                 // Duration object that denotes the exclusive visible end time of any given day
5335                 maxTime: maxTime,
5336                 isValid: isValid,
5337                 // how far the current date will move for a prev/next operation
5338                 dateIncrement: this.buildDateIncrement(currentInfo.duration)
5339                 // pass a fallback (might be null) ^
5340             };
5341         };
5342         // Builds an object with optional start/end properties.
5343         // Indicates the minimum/maximum dates to display.
5344         // not responsible for trimming hidden days.
5345         DateProfileGenerator.prototype.buildValidRange = function () {
5346             return this.getRangeOption('validRange', this.calendar.getNow()) ||
5347                 { start: null, end: null }; // completely open-ended
5348         };
5349         // Builds a structure with info about the "current" range, the range that is
5350         // highlighted as being the current month for example.
5351         // See build() for a description of `direction`.
5352         // Guaranteed to have `range` and `unit` properties. `duration` is optional.
5353         DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
5354             var _a = this, viewSpec = _a.viewSpec, dateEnv = _a.dateEnv;
5355             var duration = null;
5356             var unit = null;
5357             var range = null;
5358             var dayCount;
5359             if (viewSpec.duration) {
5360                 duration = viewSpec.duration;
5361                 unit = viewSpec.durationUnit;
5362                 range = this.buildRangeFromDuration(date, direction, duration, unit);
5363             }
5364             else if ((dayCount = this.options.dayCount)) {
5365                 unit = 'day';
5366                 range = this.buildRangeFromDayCount(date, direction, dayCount);
5367             }
5368             else if ((range = this.buildCustomVisibleRange(date))) {
5369                 unit = dateEnv.greatestWholeUnit(range.start, range.end).unit;
5370             }
5371             else {
5372                 duration = this.getFallbackDuration();
5373                 unit = greatestDurationDenominator(duration).unit;
5374                 range = this.buildRangeFromDuration(date, direction, duration, unit);
5375             }
5376             return { duration: duration, unit: unit, range: range };
5377         };
5378         DateProfileGenerator.prototype.getFallbackDuration = function () {
5379             return createDuration({ day: 1 });
5380         };
5381         // Returns a new activeRange to have time values (un-ambiguate)
5382         // minTime or maxTime causes the range to expand.
5383         DateProfileGenerator.prototype.adjustActiveRange = function (range, minTime, maxTime) {
5384             var dateEnv = this.dateEnv;
5385             var start = range.start;
5386             var end = range.end;
5387             if (this.viewSpec.class.prototype.usesMinMaxTime) {
5388                 // expand active range if minTime is negative (why not when positive?)
5389                 if (asRoughDays(minTime) < 0) {
5390                     start = startOfDay(start); // necessary?
5391                     start = dateEnv.add(start, minTime);
5392                 }
5393                 // expand active range if maxTime is beyond one day (why not when positive?)
5394                 if (asRoughDays(maxTime) > 1) {
5395                     end = startOfDay(end); // necessary?
5396                     end = addDays(end, -1);
5397                     end = dateEnv.add(end, maxTime);
5398                 }
5399             }
5400             return { start: start, end: end };
5401         };
5402         // Builds the "current" range when it is specified as an explicit duration.
5403         // `unit` is the already-computed greatestDurationDenominator unit of duration.
5404         DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
5405             var dateEnv = this.dateEnv;
5406             var alignment = this.options.dateAlignment;
5407             var dateIncrementInput;
5408             var dateIncrementDuration;
5409             var start;
5410             var end;
5411             var res;
5412             // compute what the alignment should be
5413             if (!alignment) {
5414                 dateIncrementInput = this.options.dateIncrement;
5415                 if (dateIncrementInput) {
5416                     dateIncrementDuration = createDuration(dateIncrementInput);
5417                     // use the smaller of the two units
5418                     if (asRoughMs(dateIncrementDuration) < asRoughMs(duration)) {
5419                         alignment = greatestDurationDenominator(dateIncrementDuration, !getWeeksFromInput(dateIncrementInput)).unit;
5420                     }
5421                     else {
5422                         alignment = unit;
5423                     }
5424                 }
5425                 else {
5426                     alignment = unit;
5427                 }
5428             }
5429             // if the view displays a single day or smaller
5430             if (asRoughDays(duration) <= 1) {
5431                 if (this.isHiddenDay(start)) {
5432                     start = this.skipHiddenDays(start, direction);
5433                     start = startOfDay(start);
5434                 }
5435             }
5436             function computeRes() {
5437                 start = dateEnv.startOf(date, alignment);
5438                 end = dateEnv.add(start, duration);
5439                 res = { start: start, end: end };
5440             }
5441             computeRes();
5442             // if range is completely enveloped by hidden days, go past the hidden days
5443             if (!this.trimHiddenDays(res)) {
5444                 date = this.skipHiddenDays(date, direction);
5445                 computeRes();
5446             }
5447             return res;
5448         };
5449         // Builds the "current" range when a dayCount is specified.
5450         DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
5451             var dateEnv = this.dateEnv;
5452             var customAlignment = this.options.dateAlignment;
5453             var runningCount = 0;
5454             var start = date;
5455             var end;
5456             if (customAlignment) {
5457                 start = dateEnv.startOf(start, customAlignment);
5458             }
5459             start = startOfDay(start);
5460             start = this.skipHiddenDays(start, direction);
5461             end = start;
5462             do {
5463                 end = addDays(end, 1);
5464                 if (!this.isHiddenDay(end)) {
5465                     runningCount++;
5466                 }
5467             } while (runningCount < dayCount);
5468             return { start: start, end: end };
5469         };
5470         // Builds a normalized range object for the "visible" range,
5471         // which is a way to define the currentRange and activeRange at the same time.
5472         DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
5473             var dateEnv = this.dateEnv;
5474             var visibleRange = this.getRangeOption('visibleRange', dateEnv.toDate(date));
5475             if (visibleRange && (visibleRange.start == null || visibleRange.end == null)) {
5476                 return null;
5477             }
5478             return visibleRange;
5479         };
5480         // Computes the range that will represent the element/cells for *rendering*,
5481         // but which may have voided days/times.
5482         // not responsible for trimming hidden days.
5483         DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
5484             return currentRange;
5485         };
5486         // Compute the duration value that should be added/substracted to the current date
5487         // when a prev/next operation happens.
5488         DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
5489             var dateIncrementInput = this.options.dateIncrement;
5490             var customAlignment;
5491             if (dateIncrementInput) {
5492                 return createDuration(dateIncrementInput);
5493             }
5494             else if ((customAlignment = this.options.dateAlignment)) {
5495                 return createDuration(1, customAlignment);
5496             }
5497             else if (fallback) {
5498                 return fallback;
5499             }
5500             else {
5501                 return createDuration({ days: 1 });
5502             }
5503         };
5504         // Arguments after name will be forwarded to a hypothetical function value
5505         // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects.
5506         // Always clone your objects if you fear mutation.
5507         DateProfileGenerator.prototype.getRangeOption = function (name) {
5508             var otherArgs = [];
5509             for (var _i = 1; _i < arguments.length; _i++) {
5510                 otherArgs[_i - 1] = arguments[_i];
5511             }
5512             var val = this.options[name];
5513             if (typeof val === 'function') {
5514                 val = val.apply(null, otherArgs);
5515             }
5516             if (val) {
5517                 val = parseRange(val, this.dateEnv);
5518             }
5519             if (val) {
5520                 val = computeVisibleDayRange(val);
5521             }
5522             return val;
5523         };
5524         /* Hidden Days
5525         ------------------------------------------------------------------------------------------------------------------*/
5526         // Initializes internal variables related to calculating hidden days-of-week
5527         DateProfileGenerator.prototype.initHiddenDays = function () {
5528             var hiddenDays = this.options.hiddenDays || []; // array of day-of-week indices that are hidden
5529             var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
5530             var dayCnt = 0;
5531             var i;
5532             if (this.options.weekends === false) {
5533                 hiddenDays.push(0, 6); // 0=sunday, 6=saturday
5534             }
5535             for (i = 0; i < 7; i++) {
5536                 if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
5537                     dayCnt++;
5538                 }
5539             }
5540             if (!dayCnt) {
5541                 throw new Error('invalid hiddenDays'); // all days were hidden? bad.
5542             }
5543             this.isHiddenDayHash = isHiddenDayHash;
5544         };
5545         // Remove days from the beginning and end of the range that are computed as hidden.
5546         // If the whole range is trimmed off, returns null
5547         DateProfileGenerator.prototype.trimHiddenDays = function (range) {
5548             var start = range.start;
5549             var end = range.end;
5550             if (start) {
5551                 start = this.skipHiddenDays(start);
5552             }
5553             if (end) {
5554                 end = this.skipHiddenDays(end, -1, true);
5555             }
5556             if (start == null || end == null || start < end) {
5557                 return { start: start, end: end };
5558             }
5559             return null;
5560         };
5561         // Is the current day hidden?
5562         // `day` is a day-of-week index (0-6), or a Date (used for UTC)
5563         DateProfileGenerator.prototype.isHiddenDay = function (day) {
5564             if (day instanceof Date) {
5565                 day = day.getUTCDay();
5566             }
5567             return this.isHiddenDayHash[day];
5568         };
5569         // Incrementing the current day until it is no longer a hidden day, returning a copy.
5570         // DOES NOT CONSIDER validRange!
5571         // If the initial value of `date` is not a hidden day, don't do anything.
5572         // Pass `isExclusive` as `true` if you are dealing with an end date.
5573         // `inc` defaults to `1` (increment one day forward each time)
5574         DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) {
5575             if (inc === void 0) { inc = 1; }
5576             if (isExclusive === void 0) { isExclusive = false; }
5577             while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
5578                 date = addDays(date, inc);
5579             }
5580             return date;
5581         };
5582         return DateProfileGenerator;
5583     }());
5584     // TODO: find a way to avoid comparing DateProfiles. it's tedious
5585     function isDateProfilesEqual(p0, p1) {
5586         return rangesEqual(p0.validRange, p1.validRange) &&
5587             rangesEqual(p0.activeRange, p1.activeRange) &&
5588             rangesEqual(p0.renderRange, p1.renderRange) &&
5589             durationsEqual(p0.minTime, p1.minTime) &&
5590             durationsEqual(p0.maxTime, p1.maxTime);
5591         /*
5592         TODO: compare more?
5593           currentRange: DateRange
5594           currentRangeUnit: string
5595           isRangeAllDay: boolean
5596           isValid: boolean
5597           dateIncrement: Duration
5598         */
5599     }
5600
5601     function reduce (state, action, calendar) {
5602         var viewType = reduceViewType(state.viewType, action);
5603         var dateProfile = reduceDateProfile(state.dateProfile, action, state.currentDate, viewType, calendar);
5604         var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendar);
5605         var nextState = __assign({}, state, { viewType: viewType,
5606             dateProfile: dateProfile, currentDate: reduceCurrentDate(state.currentDate, action, dateProfile), eventSources: eventSources, eventStore: reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendar), dateSelection: reduceDateSelection(state.dateSelection, action, calendar), eventSelection: reduceSelectedEvent(state.eventSelection, action), eventDrag: reduceEventDrag(state.eventDrag, action, eventSources, calendar), eventResize: reduceEventResize(state.eventResize, action, eventSources, calendar), eventSourceLoadingLevel: computeLoadingLevel(eventSources), loadingLevel: computeLoadingLevel(eventSources) });
5607         for (var _i = 0, _a = calendar.pluginSystem.hooks.reducers; _i < _a.length; _i++) {
5608             var reducerFunc = _a[_i];
5609             nextState = reducerFunc(nextState, action, calendar);
5610         }
5611         // console.log(action.type, nextState)
5612         return nextState;
5613     }
5614     function reduceViewType(currentViewType, action) {
5615         switch (action.type) {
5616             case 'SET_VIEW_TYPE':
5617                 return action.viewType;
5618             default:
5619                 return currentViewType;
5620         }
5621     }
5622     function reduceDateProfile(currentDateProfile, action, currentDate, viewType, calendar) {
5623         var newDateProfile;
5624         switch (action.type) {
5625             case 'PREV':
5626                 newDateProfile = calendar.dateProfileGenerators[viewType].buildPrev(currentDateProfile, currentDate);
5627                 break;
5628             case 'NEXT':
5629                 newDateProfile = calendar.dateProfileGenerators[viewType].buildNext(currentDateProfile, currentDate);
5630                 break;
5631             case 'SET_DATE':
5632                 if (!currentDateProfile.activeRange ||
5633                     !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker)) {
5634                     newDateProfile = calendar.dateProfileGenerators[viewType].build(action.dateMarker, undefined, true // forceToValid
5635                     );
5636                 }
5637                 break;
5638             case 'SET_VIEW_TYPE':
5639                 var generator = calendar.dateProfileGenerators[viewType];
5640                 if (!generator) {
5641                     throw new Error(viewType ?
5642                         'The FullCalendar view "' + viewType + '" does not exist. Make sure your plugins are loaded correctly.' :
5643                         'No available FullCalendar view plugins.');
5644                 }
5645                 newDateProfile = generator.build(action.dateMarker || currentDate, undefined, true // forceToValid
5646                 );
5647                 break;
5648         }
5649         if (newDateProfile &&
5650             newDateProfile.isValid &&
5651             !(currentDateProfile && isDateProfilesEqual(currentDateProfile, newDateProfile))) {
5652             return newDateProfile;
5653         }
5654         else {
5655             return currentDateProfile;
5656         }
5657     }
5658     function reduceCurrentDate(currentDate, action, dateProfile) {
5659         switch (action.type) {
5660             case 'PREV':
5661             case 'NEXT':
5662                 if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) {
5663                     return dateProfile.currentRange.start;
5664                 }
5665                 else {
5666                     return currentDate;
5667                 }
5668             case 'SET_DATE':
5669             case 'SET_VIEW_TYPE':
5670                 var newDate = action.dateMarker || currentDate;
5671                 if (dateProfile.activeRange && !rangeContainsMarker(dateProfile.activeRange, newDate)) {
5672                     return dateProfile.currentRange.start;
5673                 }
5674                 else {
5675                     return newDate;
5676                 }
5677             default:
5678                 return currentDate;
5679         }
5680     }
5681     function reduceDateSelection(currentSelection, action, calendar) {
5682         switch (action.type) {
5683             case 'SELECT_DATES':
5684                 return action.selection;
5685             case 'UNSELECT_DATES':
5686                 return null;
5687             default:
5688                 return currentSelection;
5689         }
5690     }
5691     function reduceSelectedEvent(currentInstanceId, action) {
5692         switch (action.type) {
5693             case 'SELECT_EVENT':
5694                 return action.eventInstanceId;
5695             case 'UNSELECT_EVENT':
5696                 return '';
5697             default:
5698                 return currentInstanceId;
5699         }
5700     }
5701     function reduceEventDrag(currentDrag, action, sources, calendar) {
5702         switch (action.type) {
5703             case 'SET_EVENT_DRAG':
5704                 var newDrag = action.state;
5705                 return {
5706                     affectedEvents: newDrag.affectedEvents,
5707                     mutatedEvents: newDrag.mutatedEvents,
5708                     isEvent: newDrag.isEvent,
5709                     origSeg: newDrag.origSeg
5710                 };
5711             case 'UNSET_EVENT_DRAG':
5712                 return null;
5713             default:
5714                 return currentDrag;
5715         }
5716     }
5717     function reduceEventResize(currentResize, action, sources, calendar) {
5718         switch (action.type) {
5719             case 'SET_EVENT_RESIZE':
5720                 var newResize = action.state;
5721                 return {
5722                     affectedEvents: newResize.affectedEvents,
5723                     mutatedEvents: newResize.mutatedEvents,
5724                     isEvent: newResize.isEvent,
5725                     origSeg: newResize.origSeg
5726                 };
5727             case 'UNSET_EVENT_RESIZE':
5728                 return null;
5729             default:
5730                 return currentResize;
5731         }
5732     }
5733     function computeLoadingLevel(eventSources) {
5734         var cnt = 0;
5735         for (var sourceId in eventSources) {
5736             if (eventSources[sourceId].isFetching) {
5737                 cnt++;
5738             }
5739         }
5740         return cnt;
5741     }
5742
5743     var STANDARD_PROPS = {
5744         start: null,
5745         end: null,
5746         allDay: Boolean
5747     };
5748     function parseDateSpan(raw, dateEnv, defaultDuration) {
5749         var span = parseOpenDateSpan(raw, dateEnv);
5750         var range = span.range;
5751         if (!range.start) {
5752             return null;
5753         }
5754         if (!range.end) {
5755             if (defaultDuration == null) {
5756                 return null;
5757             }
5758             else {
5759                 range.end = dateEnv.add(range.start, defaultDuration);
5760             }
5761         }
5762         return span;
5763     }
5764     /*
5765     TODO: somehow combine with parseRange?
5766     Will return null if the start/end props were present but parsed invalidly.
5767     */
5768     function parseOpenDateSpan(raw, dateEnv) {
5769         var leftovers = {};
5770         var standardProps = refineProps(raw, STANDARD_PROPS, {}, leftovers);
5771         var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
5772         var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
5773         var allDay = standardProps.allDay;
5774         if (allDay == null) {
5775             allDay = (startMeta && startMeta.isTimeUnspecified) &&
5776                 (!endMeta || endMeta.isTimeUnspecified);
5777         }
5778         // use this leftover object as the selection object
5779         leftovers.range = {
5780             start: startMeta ? startMeta.marker : null,
5781             end: endMeta ? endMeta.marker : null
5782         };
5783         leftovers.allDay = allDay;
5784         return leftovers;
5785     }
5786     function isDateSpansEqual(span0, span1) {
5787         return rangesEqual(span0.range, span1.range) &&
5788             span0.allDay === span1.allDay &&
5789             isSpanPropsEqual(span0, span1);
5790     }
5791     // the NON-DATE-RELATED props
5792     function isSpanPropsEqual(span0, span1) {
5793         for (var propName in span1) {
5794             if (propName !== 'range' && propName !== 'allDay') {
5795                 if (span0[propName] !== span1[propName]) {
5796                     return false;
5797                 }
5798             }
5799         }
5800         // are there any props that span0 has that span1 DOESN'T have?
5801         // both have range/allDay, so no need to special-case.
5802         for (var propName in span0) {
5803             if (!(propName in span1)) {
5804                 return false;
5805             }
5806         }
5807         return true;
5808     }
5809     function buildDateSpanApi(span, dateEnv) {
5810         return {
5811             start: dateEnv.toDate(span.range.start),
5812             end: dateEnv.toDate(span.range.end),
5813             startStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
5814             endStr: dateEnv.formatIso(span.range.end, { omitTime: span.allDay }),
5815             allDay: span.allDay
5816         };
5817     }
5818     function buildDatePointApi(span, dateEnv) {
5819         return {
5820             date: dateEnv.toDate(span.range.start),
5821             dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
5822             allDay: span.allDay
5823         };
5824     }
5825     function fabricateEventRange(dateSpan, eventUiBases, calendar) {
5826         var def = parseEventDef({ editable: false }, '', // sourceId
5827         dateSpan.allDay, true, // hasEnd
5828         calendar);
5829         return {
5830             def: def,
5831             ui: compileEventUi(def, eventUiBases),
5832             instance: createEventInstance(def.defId, dateSpan.range),
5833             range: dateSpan.range,
5834             isStart: true,
5835             isEnd: true
5836         };
5837     }
5838
5839     function compileViewDefs(defaultConfigs, overrideConfigs) {
5840         var hash = {};
5841         var viewType;
5842         for (viewType in defaultConfigs) {
5843             ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5844         }
5845         for (viewType in overrideConfigs) {
5846             ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5847         }
5848         return hash;
5849     }
5850     function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5851         if (hash[viewType]) {
5852             return hash[viewType];
5853         }
5854         var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5855         if (viewDef) {
5856             hash[viewType] = viewDef;
5857         }
5858         return viewDef;
5859     }
5860     function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5861         var defaultConfig = defaultConfigs[viewType];
5862         var overrideConfig = overrideConfigs[viewType];
5863         var queryProp = function (name) {
5864             return (defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
5865                 ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null);
5866         };
5867         var theClass = queryProp('class');
5868         var superType = queryProp('superType');
5869         if (!superType && theClass) {
5870             superType =
5871                 findViewNameBySubclass(theClass, overrideConfigs) ||
5872                     findViewNameBySubclass(theClass, defaultConfigs);
5873         }
5874         var superDef = null;
5875         if (superType) {
5876             if (superType === viewType) {
5877                 throw new Error('Can\'t have a custom view type that references itself');
5878             }
5879             superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);
5880         }
5881         if (!theClass && superDef) {
5882             theClass = superDef.class;
5883         }
5884         if (!theClass) {
5885             return null; // don't throw a warning, might be settings for a single-unit view
5886         }
5887         return {
5888             type: viewType,
5889             class: theClass,
5890             defaults: __assign({}, (superDef ? superDef.defaults : {}), (defaultConfig ? defaultConfig.options : {})),
5891             overrides: __assign({}, (superDef ? superDef.overrides : {}), (overrideConfig ? overrideConfig.options : {}))
5892         };
5893     }
5894     function findViewNameBySubclass(viewSubclass, configs) {
5895         var superProto = Object.getPrototypeOf(viewSubclass.prototype);
5896         for (var viewType in configs) {
5897             var parsed = configs[viewType];
5898             // need DIRECT subclass, so instanceof won't do it
5899             if (parsed.class && parsed.class.prototype === superProto) {
5900                 return viewType;
5901             }
5902         }
5903         return '';
5904     }
5905
5906     function parseViewConfigs(inputs) {
5907         return mapHash(inputs, parseViewConfig);
5908     }
5909     var VIEW_DEF_PROPS = {
5910         type: String,
5911         class: null
5912     };
5913     function parseViewConfig(input) {
5914         if (typeof input === 'function') {
5915             input = { class: input };
5916         }
5917         var options = {};
5918         var props = refineProps(input, VIEW_DEF_PROPS, {}, options);
5919         return {
5920             superType: props.type,
5921             class: props.class,
5922             options: options
5923         };
5924     }
5925
5926     function buildViewSpecs(defaultInputs, optionsManager) {
5927         var defaultConfigs = parseViewConfigs(defaultInputs);
5928         var overrideConfigs = parseViewConfigs(optionsManager.overrides.views);
5929         var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
5930         return mapHash(viewDefs, function (viewDef) {
5931             return buildViewSpec(viewDef, overrideConfigs, optionsManager);
5932         });
5933     }
5934     function buildViewSpec(viewDef, overrideConfigs, optionsManager) {
5935         var durationInput = viewDef.overrides.duration ||
5936             viewDef.defaults.duration ||
5937             optionsManager.dynamicOverrides.duration ||
5938             optionsManager.overrides.duration;
5939         var duration = null;
5940         var durationUnit = '';
5941         var singleUnit = '';
5942         var singleUnitOverrides = {};
5943         if (durationInput) {
5944             duration = createDuration(durationInput);
5945             if (duration) { // valid?
5946                 var denom = greatestDurationDenominator(duration, !getWeeksFromInput(durationInput));
5947                 durationUnit = denom.unit;
5948                 if (denom.value === 1) {
5949                     singleUnit = durationUnit;
5950                     singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].options : {};
5951                 }
5952             }
5953         }
5954         var queryButtonText = function (options) {
5955             var buttonTextMap = options.buttonText || {};
5956             var buttonTextKey = viewDef.defaults.buttonTextKey;
5957             if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
5958                 return buttonTextMap[buttonTextKey];
5959             }
5960             if (buttonTextMap[viewDef.type] != null) {
5961                 return buttonTextMap[viewDef.type];
5962             }
5963             if (buttonTextMap[singleUnit] != null) {
5964                 return buttonTextMap[singleUnit];
5965             }
5966         };
5967         return {
5968             type: viewDef.type,
5969             class: viewDef.class,
5970             duration: duration,
5971             durationUnit: durationUnit,
5972             singleUnit: singleUnit,
5973             options: __assign({}, globalDefaults, viewDef.defaults, optionsManager.dirDefaults, optionsManager.localeDefaults, optionsManager.overrides, singleUnitOverrides, viewDef.overrides, optionsManager.dynamicOverrides),
5974             buttonTextOverride: queryButtonText(optionsManager.dynamicOverrides) ||
5975                 queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence
5976                 viewDef.overrides.buttonText,
5977             buttonTextDefault: queryButtonText(optionsManager.localeDefaults) ||
5978                 queryButtonText(optionsManager.dirDefaults) ||
5979                 viewDef.defaults.buttonText ||
5980                 queryButtonText(globalDefaults) ||
5981                 viewDef.type // fall back to given view name
5982         };
5983     }
5984
5985     var Toolbar = /** @class */ (function (_super) {
5986         __extends(Toolbar, _super);
5987         function Toolbar(context, extraClassName) {
5988             var _this = _super.call(this, context) || this;
5989             _this._renderLayout = memoizeRendering(_this.renderLayout, _this.unrenderLayout);
5990             _this._updateTitle = memoizeRendering(_this.updateTitle, null, [_this._renderLayout]);
5991             _this._updateActiveButton = memoizeRendering(_this.updateActiveButton, null, [_this._renderLayout]);
5992             _this._updateToday = memoizeRendering(_this.updateToday, null, [_this._renderLayout]);
5993             _this._updatePrev = memoizeRendering(_this.updatePrev, null, [_this._renderLayout]);
5994             _this._updateNext = memoizeRendering(_this.updateNext, null, [_this._renderLayout]);
5995             _this.el = createElement('div', { className: 'fc-toolbar ' + extraClassName });
5996             return _this;
5997         }
5998         Toolbar.prototype.destroy = function () {
5999             _super.prototype.destroy.call(this);
6000             this._renderLayout.unrender(); // should unrender everything else
6001             removeElement(this.el);
6002         };
6003         Toolbar.prototype.render = function (props) {
6004             this._renderLayout(props.layout);
6005             this._updateTitle(props.title);
6006             this._updateActiveButton(props.activeButton);
6007             this._updateToday(props.isTodayEnabled);
6008             this._updatePrev(props.isPrevEnabled);
6009             this._updateNext(props.isNextEnabled);
6010         };
6011         Toolbar.prototype.renderLayout = function (layout) {
6012             var el = this.el;
6013             this.viewsWithButtons = [];
6014             appendToElement(el, this.renderSection('left', layout.left));
6015             appendToElement(el, this.renderSection('center', layout.center));
6016             appendToElement(el, this.renderSection('right', layout.right));
6017         };
6018         Toolbar.prototype.unrenderLayout = function () {
6019             this.el.innerHTML = '';
6020         };
6021         Toolbar.prototype.renderSection = function (position, buttonStr) {
6022             var _this = this;
6023             var _a = this, theme = _a.theme, calendar = _a.calendar;
6024             var optionsManager = calendar.optionsManager;
6025             var viewSpecs = calendar.viewSpecs;
6026             var sectionEl = createElement('div', { className: 'fc-' + position });
6027             var calendarCustomButtons = optionsManager.computed.customButtons || {};
6028             var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {};
6029             var calendarButtonText = optionsManager.computed.buttonText || {};
6030             if (buttonStr) {
6031                 buttonStr.split(' ').forEach(function (buttonGroupStr, i) {
6032                     var groupChildren = [];
6033                     var isOnlyButtons = true;
6034                     var groupEl;
6035                     buttonGroupStr.split(',').forEach(function (buttonName, j) {
6036                         var customButtonProps;
6037                         var viewSpec;
6038                         var buttonClick;
6039                         var buttonIcon; // only one of these will be set
6040                         var buttonText; // "
6041                         var buttonInnerHtml;
6042                         var buttonClasses;
6043                         var buttonEl;
6044                         var buttonAriaAttr;
6045                         if (buttonName === 'title') {
6046                             groupChildren.push(htmlToElement('<h2>&nbsp;</h2>')); // we always want it to take up height
6047                             isOnlyButtons = false;
6048                         }
6049                         else {
6050                             if ((customButtonProps = calendarCustomButtons[buttonName])) {
6051                                 buttonClick = function (ev) {
6052                                     if (customButtonProps.click) {
6053                                         customButtonProps.click.call(buttonEl, ev);
6054                                     }
6055                                 };
6056                                 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
6057                                     (buttonIcon = theme.getIconClass(buttonName)) ||
6058                                     (buttonText = customButtonProps.text);
6059                             }
6060                             else if ((viewSpec = viewSpecs[buttonName])) {
6061                                 _this.viewsWithButtons.push(buttonName);
6062                                 buttonClick = function () {
6063                                     calendar.changeView(buttonName);
6064                                 };
6065                                 (buttonText = viewSpec.buttonTextOverride) ||
6066                                     (buttonIcon = theme.getIconClass(buttonName)) ||
6067                                     (buttonText = viewSpec.buttonTextDefault);
6068                             }
6069                             else if (calendar[buttonName]) { // a calendar method
6070                                 buttonClick = function () {
6071                                     calendar[buttonName]();
6072                                 };
6073                                 (buttonText = calendarButtonTextOverrides[buttonName]) ||
6074                                     (buttonIcon = theme.getIconClass(buttonName)) ||
6075                                     (buttonText = calendarButtonText[buttonName]);
6076                                 //            ^ everything else is considered default
6077                             }
6078                             if (buttonClick) {
6079                                 buttonClasses = [
6080                                     'fc-' + buttonName + '-button',
6081                                     theme.getClass('button')
6082                                 ];
6083                                 if (buttonText) {
6084                                     buttonInnerHtml = htmlEscape(buttonText);
6085                                     buttonAriaAttr = '';
6086                                 }
6087                                 else if (buttonIcon) {
6088                                     buttonInnerHtml = "<span class='" + buttonIcon + "'></span>";
6089                                     buttonAriaAttr = ' aria-label="' + buttonName + '"';
6090                                 }
6091                                 buttonEl = htmlToElement(// type="button" so that it doesn't submit a form
6092                                 '<button type="button" class="' + buttonClasses.join(' ') + '"' +
6093                                     buttonAriaAttr +
6094                                     '>' + buttonInnerHtml + '</button>');
6095                                 buttonEl.addEventListener('click', buttonClick);
6096                                 groupChildren.push(buttonEl);
6097                             }
6098                         }
6099                     });
6100                     if (groupChildren.length > 1) {
6101                         groupEl = document.createElement('div');
6102                         var buttonGroupClassName = theme.getClass('buttonGroup');
6103                         if (isOnlyButtons && buttonGroupClassName) {
6104                             groupEl.classList.add(buttonGroupClassName);
6105                         }
6106                         appendToElement(groupEl, groupChildren);
6107                         sectionEl.appendChild(groupEl);
6108                     }
6109                     else {
6110                         appendToElement(sectionEl, groupChildren); // 1 or 0 children
6111                     }
6112                 });
6113             }
6114             return sectionEl;
6115         };
6116         Toolbar.prototype.updateToday = function (isTodayEnabled) {
6117             this.toggleButtonEnabled('today', isTodayEnabled);
6118         };
6119         Toolbar.prototype.updatePrev = function (isPrevEnabled) {
6120             this.toggleButtonEnabled('prev', isPrevEnabled);
6121         };
6122         Toolbar.prototype.updateNext = function (isNextEnabled) {
6123             this.toggleButtonEnabled('next', isNextEnabled);
6124         };
6125         Toolbar.prototype.updateTitle = function (text) {
6126             findElements(this.el, 'h2').forEach(function (titleEl) {
6127                 titleEl.innerText = text;
6128             });
6129         };
6130         Toolbar.prototype.updateActiveButton = function (buttonName) {
6131             var className = this.theme.getClass('buttonActive');
6132             findElements(this.el, 'button').forEach(function (buttonEl) {
6133                 if (buttonName && buttonEl.classList.contains('fc-' + buttonName + '-button')) {
6134                     buttonEl.classList.add(className);
6135                 }
6136                 else {
6137                     buttonEl.classList.remove(className);
6138                 }
6139             });
6140         };
6141         Toolbar.prototype.toggleButtonEnabled = function (buttonName, bool) {
6142             findElements(this.el, '.fc-' + buttonName + '-button').forEach(function (buttonEl) {
6143                 buttonEl.disabled = !bool;
6144             });
6145         };
6146         return Toolbar;
6147     }(Component));
6148
6149     var CalendarComponent = /** @class */ (function (_super) {
6150         __extends(CalendarComponent, _super);
6151         function CalendarComponent(context, el) {
6152             var _this = _super.call(this, context) || this;
6153             _this._renderToolbars = memoizeRendering(_this.renderToolbars);
6154             _this.buildViewPropTransformers = memoize(buildViewPropTransformers);
6155             _this.el = el;
6156             prependToElement(el, _this.contentEl = createElement('div', { className: 'fc-view-container' }));
6157             var calendar = _this.calendar;
6158             for (var _i = 0, _a = calendar.pluginSystem.hooks.viewContainerModifiers; _i < _a.length; _i++) {
6159                 var modifyViewContainer = _a[_i];
6160                 modifyViewContainer(_this.contentEl, calendar);
6161             }
6162             _this.toggleElClassNames(true);
6163             _this.computeTitle = memoize(computeTitle);
6164             _this.parseBusinessHours = memoize(function (input) {
6165                 return parseBusinessHours(input, _this.calendar);
6166             });
6167             return _this;
6168         }
6169         CalendarComponent.prototype.destroy = function () {
6170             if (this.header) {
6171                 this.header.destroy();
6172             }
6173             if (this.footer) {
6174                 this.footer.destroy();
6175             }
6176             if (this.view) {
6177                 this.view.destroy();
6178             }
6179             removeElement(this.contentEl);
6180             this.toggleElClassNames(false);
6181             _super.prototype.destroy.call(this);
6182         };
6183         CalendarComponent.prototype.toggleElClassNames = function (bool) {
6184             var classList = this.el.classList;
6185             var dirClassName = 'fc-' + this.opt('dir');
6186             var themeClassName = this.theme.getClass('widget');
6187             if (bool) {
6188                 classList.add('fc');
6189                 classList.add(dirClassName);
6190                 classList.add(themeClassName);
6191             }
6192             else {
6193                 classList.remove('fc');
6194                 classList.remove(dirClassName);
6195                 classList.remove(themeClassName);
6196             }
6197         };
6198         CalendarComponent.prototype.render = function (props) {
6199             this.freezeHeight();
6200             var title = this.computeTitle(props.dateProfile, props.viewSpec.options);
6201             this._renderToolbars(props.viewSpec, props.dateProfile, props.currentDate, props.dateProfileGenerator, title);
6202             this.renderView(props, title);
6203             this.updateSize();
6204             this.thawHeight();
6205         };
6206         CalendarComponent.prototype.renderToolbars = function (viewSpec, dateProfile, currentDate, dateProfileGenerator, title) {
6207             var headerLayout = this.opt('header');
6208             var footerLayout = this.opt('footer');
6209             var now = this.calendar.getNow();
6210             var todayInfo = dateProfileGenerator.build(now);
6211             var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate);
6212             var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate);
6213             var toolbarProps = {
6214                 title: title,
6215                 activeButton: viewSpec.type,
6216                 isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now),
6217                 isPrevEnabled: prevInfo.isValid,
6218                 isNextEnabled: nextInfo.isValid
6219             };
6220             if (headerLayout) {
6221                 if (!this.header) {
6222                     this.header = new Toolbar(this.context, 'fc-header-toolbar');
6223                     prependToElement(this.el, this.header.el);
6224                 }
6225                 this.header.receiveProps(__assign({ layout: headerLayout }, toolbarProps));
6226             }
6227             else if (this.header) {
6228                 this.header.destroy();
6229                 this.header = null;
6230             }
6231             if (footerLayout) {
6232                 if (!this.footer) {
6233                     this.footer = new Toolbar(this.context, 'fc-footer-toolbar');
6234                     appendToElement(this.el, this.footer.el);
6235                 }
6236                 this.footer.receiveProps(__assign({ layout: footerLayout }, toolbarProps));
6237             }
6238             else if (this.footer) {
6239                 this.footer.destroy();
6240                 this.footer = null;
6241             }
6242         };
6243         CalendarComponent.prototype.renderView = function (props, title) {
6244             var view = this.view;
6245             var viewSpec = props.viewSpec, dateProfileGenerator = props.dateProfileGenerator;
6246             if (!view || view.viewSpec !== viewSpec) {
6247                 if (view) {
6248                     view.destroy();
6249                 }
6250                 view = this.view = new viewSpec['class']({
6251                     calendar: this.calendar,
6252                     view: null,
6253                     dateEnv: this.dateEnv,
6254                     theme: this.theme,
6255                     options: viewSpec.options
6256                 }, viewSpec, dateProfileGenerator, this.contentEl);
6257             }
6258             else {
6259                 view.addScroll(view.queryScroll());
6260             }
6261             view.title = title; // for the API
6262             var viewProps = {
6263                 dateProfile: props.dateProfile,
6264                 businessHours: this.parseBusinessHours(viewSpec.options.businessHours),
6265                 eventStore: props.eventStore,
6266                 eventUiBases: props.eventUiBases,
6267                 dateSelection: props.dateSelection,
6268                 eventSelection: props.eventSelection,
6269                 eventDrag: props.eventDrag,
6270                 eventResize: props.eventResize
6271             };
6272             var transformers = this.buildViewPropTransformers(this.calendar.pluginSystem.hooks.viewPropsTransformers);
6273             for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
6274                 var transformer = transformers_1[_i];
6275                 __assign(viewProps, transformer.transform(viewProps, viewSpec, props, view));
6276             }
6277             view.receiveProps(viewProps);
6278         };
6279         // Sizing
6280         // -----------------------------------------------------------------------------------------------------------------
6281         CalendarComponent.prototype.updateSize = function (isResize) {
6282             if (isResize === void 0) { isResize = false; }
6283             var view = this.view;
6284             if (isResize) {
6285                 view.addScroll(view.queryScroll());
6286             }
6287             if (isResize || this.isHeightAuto == null) {
6288                 this.computeHeightVars();
6289             }
6290             view.updateSize(isResize, this.viewHeight, this.isHeightAuto);
6291             view.updateNowIndicator(); // we need to guarantee this will run after updateSize
6292             view.popScroll(isResize);
6293         };
6294         CalendarComponent.prototype.computeHeightVars = function () {
6295             var calendar = this.calendar; // yuck. need to handle dynamic options
6296             var heightInput = calendar.opt('height');
6297             var contentHeightInput = calendar.opt('contentHeight');
6298             this.isHeightAuto = heightInput === 'auto' || contentHeightInput === 'auto';
6299             if (typeof contentHeightInput === 'number') { // exists and not 'auto'
6300                 this.viewHeight = contentHeightInput;
6301             }
6302             else if (typeof contentHeightInput === 'function') { // exists and is a function
6303                 this.viewHeight = contentHeightInput();
6304             }
6305             else if (typeof heightInput === 'number') { // exists and not 'auto'
6306                 this.viewHeight = heightInput - this.queryToolbarsHeight();
6307             }
6308             else if (typeof heightInput === 'function') { // exists and is a function
6309                 this.viewHeight = heightInput() - this.queryToolbarsHeight();
6310             }
6311             else if (heightInput === 'parent') { // set to height of parent element
6312                 var parentEl = this.el.parentNode;
6313                 this.viewHeight = parentEl.getBoundingClientRect().height - this.queryToolbarsHeight();
6314             }
6315             else {
6316                 this.viewHeight = Math.round(this.contentEl.getBoundingClientRect().width /
6317                     Math.max(calendar.opt('aspectRatio'), .5));
6318             }
6319         };
6320         CalendarComponent.prototype.queryToolbarsHeight = function () {
6321             var height = 0;
6322             if (this.header) {
6323                 height += computeHeightAndMargins(this.header.el);
6324             }
6325             if (this.footer) {
6326                 height += computeHeightAndMargins(this.footer.el);
6327             }
6328             return height;
6329         };
6330         // Height "Freezing"
6331         // -----------------------------------------------------------------------------------------------------------------
6332         CalendarComponent.prototype.freezeHeight = function () {
6333             applyStyle(this.el, {
6334                 height: this.el.getBoundingClientRect().height,
6335                 overflow: 'hidden'
6336             });
6337         };
6338         CalendarComponent.prototype.thawHeight = function () {
6339             applyStyle(this.el, {
6340                 height: '',
6341                 overflow: ''
6342             });
6343         };
6344         return CalendarComponent;
6345     }(Component));
6346     // Title and Date Formatting
6347     // -----------------------------------------------------------------------------------------------------------------
6348     // Computes what the title at the top of the calendar should be for this view
6349     function computeTitle(dateProfile, viewOptions) {
6350         var range;
6351         // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
6352         if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
6353             range = dateProfile.currentRange;
6354         }
6355         else { // for day units or smaller, use the actual day range
6356             range = dateProfile.activeRange;
6357         }
6358         return this.dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || computeTitleFormat(dateProfile), viewOptions.titleRangeSeparator), { isEndExclusive: dateProfile.isRangeAllDay });
6359     }
6360     // Generates the format string that should be used to generate the title for the current date range.
6361     // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
6362     function computeTitleFormat(dateProfile) {
6363         var currentRangeUnit = dateProfile.currentRangeUnit;
6364         if (currentRangeUnit === 'year') {
6365             return { year: 'numeric' };
6366         }
6367         else if (currentRangeUnit === 'month') {
6368             return { year: 'numeric', month: 'long' }; // like "September 2014"
6369         }
6370         else {
6371             var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
6372             if (days !== null && days > 1) {
6373                 // multi-day range. shorter, like "Sep 9 - 10 2014"
6374                 return { year: 'numeric', month: 'short', day: 'numeric' };
6375             }
6376             else {
6377                 // one day. longer, like "September 9 2014"
6378                 return { year: 'numeric', month: 'long', day: 'numeric' };
6379             }
6380         }
6381     }
6382     // Plugin
6383     // -----------------------------------------------------------------------------------------------------------------
6384     function buildViewPropTransformers(theClasses) {
6385         return theClasses.map(function (theClass) {
6386             return new theClass();
6387         });
6388     }
6389
6390     var Interaction = /** @class */ (function () {
6391         function Interaction(settings) {
6392             this.component = settings.component;
6393         }
6394         Interaction.prototype.destroy = function () {
6395         };
6396         return Interaction;
6397     }());
6398     function parseInteractionSettings(component, input) {
6399         return {
6400             component: component,
6401             el: input.el,
6402             useEventCenter: input.useEventCenter != null ? input.useEventCenter : true
6403         };
6404     }
6405     function interactionSettingsToStore(settings) {
6406         var _a;
6407         return _a = {},
6408             _a[settings.component.uid] = settings,
6409             _a;
6410     }
6411     // global state
6412     var interactionSettingsStore = {};
6413
6414     /*
6415     Detects when the user clicks on an event within a DateComponent
6416     */
6417     var EventClicking = /** @class */ (function (_super) {
6418         __extends(EventClicking, _super);
6419         function EventClicking(settings) {
6420             var _this = _super.call(this, settings) || this;
6421             _this.handleSegClick = function (ev, segEl) {
6422                 var component = _this.component;
6423                 var seg = getElSeg(segEl);
6424                 if (seg && // might be the <div> surrounding the more link
6425                     component.isValidSegDownEl(ev.target)) {
6426                     // our way to simulate a link click for elements that can't be <a> tags
6427                     // grab before trigger fired in case trigger trashes DOM thru rerendering
6428                     var hasUrlContainer = elementClosest(ev.target, '.fc-has-url');
6429                     var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
6430                     component.publiclyTrigger('eventClick', [
6431                         {
6432                             el: segEl,
6433                             event: new EventApi(component.calendar, seg.eventRange.def, seg.eventRange.instance),
6434                             jsEvent: ev,
6435                             view: component.view
6436                         }
6437                     ]);
6438                     if (url && !ev.defaultPrevented) {
6439                         window.location.href = url;
6440                     }
6441                 }
6442             };
6443             var component = settings.component;
6444             _this.destroy = listenBySelector(component.el, 'click', component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegClick);
6445             return _this;
6446         }
6447         return EventClicking;
6448     }(Interaction));
6449
6450     /*
6451     Triggers events and adds/removes core classNames when the user's pointer
6452     enters/leaves event-elements of a component.
6453     */
6454     var EventHovering = /** @class */ (function (_super) {
6455         __extends(EventHovering, _super);
6456         function EventHovering(settings) {
6457             var _this = _super.call(this, settings) || this;
6458             // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
6459             _this.handleEventElRemove = function (el) {
6460                 if (el === _this.currentSegEl) {
6461                     _this.handleSegLeave(null, _this.currentSegEl);
6462                 }
6463             };
6464             _this.handleSegEnter = function (ev, segEl) {
6465                 if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
6466                     segEl.classList.add('fc-allow-mouse-resize');
6467                     _this.currentSegEl = segEl;
6468                     _this.triggerEvent('eventMouseEnter', ev, segEl);
6469                 }
6470             };
6471             _this.handleSegLeave = function (ev, segEl) {
6472                 if (_this.currentSegEl) {
6473                     segEl.classList.remove('fc-allow-mouse-resize');
6474                     _this.currentSegEl = null;
6475                     _this.triggerEvent('eventMouseLeave', ev, segEl);
6476                 }
6477             };
6478             var component = settings.component;
6479             _this.removeHoverListeners = listenToHoverBySelector(component.el, component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegEnter, _this.handleSegLeave);
6480             component.calendar.on('eventElRemove', _this.handleEventElRemove);
6481             return _this;
6482         }
6483         EventHovering.prototype.destroy = function () {
6484             this.removeHoverListeners();
6485             this.component.calendar.off('eventElRemove', this.handleEventElRemove);
6486         };
6487         EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) {
6488             var component = this.component;
6489             var seg = getElSeg(segEl);
6490             if (!ev || component.isValidSegDownEl(ev.target)) {
6491                 component.publiclyTrigger(publicEvName, [
6492                     {
6493                         el: segEl,
6494                         event: new EventApi(this.component.calendar, seg.eventRange.def, seg.eventRange.instance),
6495                         jsEvent: ev,
6496                         view: component.view
6497                     }
6498                 ]);
6499             }
6500         };
6501         return EventHovering;
6502     }(Interaction));
6503
6504     var StandardTheme = /** @class */ (function (_super) {
6505         __extends(StandardTheme, _super);
6506         function StandardTheme() {
6507             return _super !== null && _super.apply(this, arguments) || this;
6508         }
6509         return StandardTheme;
6510     }(Theme));
6511     StandardTheme.prototype.classes = {
6512         widget: 'fc-unthemed',
6513         widgetHeader: 'fc-widget-header',
6514         widgetContent: 'fc-widget-content',
6515         buttonGroup: 'fc-button-group',
6516         button: 'fc-button fc-button-primary',
6517         buttonActive: 'fc-button-active',
6518         popoverHeader: 'fc-widget-header',
6519         popoverContent: 'fc-widget-content',
6520         // day grid
6521         headerRow: 'fc-widget-header',
6522         dayRow: 'fc-widget-content',
6523         // list view
6524         listView: 'fc-widget-content'
6525     };
6526     StandardTheme.prototype.baseIconClass = 'fc-icon';
6527     StandardTheme.prototype.iconClasses = {
6528         close: 'fc-icon-x',
6529         prev: 'fc-icon-chevron-left',
6530         next: 'fc-icon-chevron-right',
6531         prevYear: 'fc-icon-chevrons-left',
6532         nextYear: 'fc-icon-chevrons-right'
6533     };
6534     StandardTheme.prototype.iconOverrideOption = 'buttonIcons';
6535     StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
6536     StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
6537
6538     var Calendar = /** @class */ (function () {
6539         function Calendar(el, overrides) {
6540             var _this = this;
6541             this.parseRawLocales = memoize(parseRawLocales);
6542             this.buildLocale = memoize(buildLocale);
6543             this.buildDateEnv = memoize(buildDateEnv);
6544             this.buildTheme = memoize(buildTheme);
6545             this.buildEventUiSingleBase = memoize(this._buildEventUiSingleBase);
6546             this.buildSelectionConfig = memoize(this._buildSelectionConfig);
6547             this.buildEventUiBySource = memoizeOutput(buildEventUiBySource, isPropsEqual);
6548             this.buildEventUiBases = memoize(buildEventUiBases);
6549             this.interactionsStore = {};
6550             this.actionQueue = [];
6551             this.isReducing = false;
6552             // isDisplaying: boolean = false // installed in DOM? accepting renders?
6553             this.needsRerender = false; // needs a render?
6554             this.needsFullRerender = false;
6555             this.isRendering = false; // currently in the executeRender function?
6556             this.renderingPauseDepth = 0;
6557             this.buildDelayedRerender = memoize(buildDelayedRerender);
6558             this.afterSizingTriggers = {};
6559             this.isViewUpdated = false;
6560             this.isDatesUpdated = false;
6561             this.isEventsUpdated = false;
6562             this.el = el;
6563             this.optionsManager = new OptionsManager(overrides || {});
6564             this.pluginSystem = new PluginSystem();
6565             // only do once. don't do in handleOptions. because can't remove plugins
6566             this.addPluginInputs(this.optionsManager.computed.plugins || []);
6567             this.handleOptions(this.optionsManager.computed);
6568             this.publiclyTrigger('_init'); // for tests
6569             this.hydrate();
6570             this.calendarInteractions = this.pluginSystem.hooks.calendarInteractions
6571                 .map(function (calendarInteractionClass) {
6572                 return new calendarInteractionClass(_this);
6573             });
6574         }
6575         Calendar.prototype.addPluginInputs = function (pluginInputs) {
6576             var pluginDefs = refinePluginDefs(pluginInputs);
6577             for (var _i = 0, pluginDefs_1 = pluginDefs; _i < pluginDefs_1.length; _i++) {
6578                 var pluginDef = pluginDefs_1[_i];
6579                 this.pluginSystem.add(pluginDef);
6580             }
6581         };
6582         Object.defineProperty(Calendar.prototype, "view", {
6583             // public API
6584             get: function () {
6585                 return this.component ? this.component.view : null;
6586             },
6587             enumerable: true,
6588             configurable: true
6589         });
6590         // Public API for rendering
6591         // -----------------------------------------------------------------------------------------------------------------
6592         Calendar.prototype.render = function () {
6593             if (!this.component) {
6594                 this.renderableEventStore = createEmptyEventStore();
6595                 this.bindHandlers();
6596                 this.executeRender();
6597             }
6598             else {
6599                 this.requestRerender(true);
6600             }
6601         };
6602         Calendar.prototype.destroy = function () {
6603             if (this.component) {
6604                 this.unbindHandlers();
6605                 this.component.destroy(); // don't null-out. in case API needs access
6606                 this.component = null; // umm ???
6607                 for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) {
6608                     var interaction = _a[_i];
6609                     interaction.destroy();
6610                 }
6611                 this.publiclyTrigger('_destroyed');
6612             }
6613         };
6614         // Handlers
6615         // -----------------------------------------------------------------------------------------------------------------
6616         Calendar.prototype.bindHandlers = function () {
6617             var _this = this;
6618             // event delegation for nav links
6619             this.removeNavLinkListener = listenBySelector(this.el, 'click', 'a[data-goto]', function (ev, anchorEl) {
6620                 var gotoOptions = anchorEl.getAttribute('data-goto');
6621                 gotoOptions = gotoOptions ? JSON.parse(gotoOptions) : {};
6622                 var dateEnv = _this.dateEnv;
6623                 var dateMarker = dateEnv.createMarker(gotoOptions.date);
6624                 var viewType = gotoOptions.type;
6625                 // property like "navLinkDayClick". might be a string or a function
6626                 var customAction = _this.viewOpt('navLink' + capitaliseFirstLetter(viewType) + 'Click');
6627                 if (typeof customAction === 'function') {
6628                     customAction(dateEnv.toDate(dateMarker), ev);
6629                 }
6630                 else {
6631                     if (typeof customAction === 'string') {
6632                         viewType = customAction;
6633                     }
6634                     _this.zoomTo(dateMarker, viewType);
6635                 }
6636             });
6637             if (this.opt('handleWindowResize')) {
6638                 window.addEventListener('resize', this.windowResizeProxy = debounce(// prevents rapid calls
6639                 this.windowResize.bind(this), this.opt('windowResizeDelay')));
6640             }
6641         };
6642         Calendar.prototype.unbindHandlers = function () {
6643             this.removeNavLinkListener();
6644             if (this.windowResizeProxy) {
6645                 window.removeEventListener('resize', this.windowResizeProxy);
6646                 this.windowResizeProxy = null;
6647             }
6648         };
6649         // Dispatcher
6650         // -----------------------------------------------------------------------------------------------------------------
6651         Calendar.prototype.hydrate = function () {
6652             var _this = this;
6653             this.state = this.buildInitialState();
6654             var rawSources = this.opt('eventSources') || [];
6655             var singleRawSource = this.opt('events');
6656             var sources = []; // parsed
6657             if (singleRawSource) {
6658                 rawSources.unshift(singleRawSource);
6659             }
6660             for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) {
6661                 var rawSource = rawSources_1[_i];
6662                 var source = parseEventSource(rawSource, this);
6663                 if (source) {
6664                     sources.push(source);
6665                 }
6666             }
6667             this.batchRendering(function () {
6668                 _this.dispatch({ type: 'INIT' }); // pass in sources here?
6669                 _this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: sources });
6670                 _this.dispatch({
6671                     type: 'SET_VIEW_TYPE',
6672                     viewType: _this.opt('defaultView') || _this.pluginSystem.hooks.defaultView
6673                 });
6674             });
6675         };
6676         Calendar.prototype.buildInitialState = function () {
6677             return {
6678                 viewType: null,
6679                 loadingLevel: 0,
6680                 eventSourceLoadingLevel: 0,
6681                 currentDate: this.getInitialDate(),
6682                 dateProfile: null,
6683                 eventSources: {},
6684                 eventStore: createEmptyEventStore(),
6685                 dateSelection: null,
6686                 eventSelection: '',
6687                 eventDrag: null,
6688                 eventResize: null
6689             };
6690         };
6691         Calendar.prototype.dispatch = function (action) {
6692             this.actionQueue.push(action);
6693             if (!this.isReducing) {
6694                 this.isReducing = true;
6695                 var oldState = this.state;
6696                 while (this.actionQueue.length) {
6697                     this.state = this.reduce(this.state, this.actionQueue.shift(), this);
6698                 }
6699                 var newState = this.state;
6700                 this.isReducing = false;
6701                 if (!oldState.loadingLevel && newState.loadingLevel) {
6702                     this.publiclyTrigger('loading', [true]);
6703                 }
6704                 else if (oldState.loadingLevel && !newState.loadingLevel) {
6705                     this.publiclyTrigger('loading', [false]);
6706                 }
6707                 var view = this.component && this.component.view;
6708                 if (oldState.eventStore !== newState.eventStore || this.needsFullRerender) {
6709                     if (oldState.eventStore) {
6710                         this.isEventsUpdated = true;
6711                     }
6712                 }
6713                 if (oldState.dateProfile !== newState.dateProfile || this.needsFullRerender) {
6714                     if (oldState.dateProfile && view) { // why would view be null!?
6715                         this.publiclyTrigger('datesDestroy', [
6716                             {
6717                                 view: view,
6718                                 el: view.el
6719                             }
6720                         ]);
6721                     }
6722                     this.isDatesUpdated = true;
6723                 }
6724                 if (oldState.viewType !== newState.viewType || this.needsFullRerender) {
6725                     if (oldState.viewType && view) { // why would view be null!?
6726                         this.publiclyTrigger('viewSkeletonDestroy', [
6727                             {
6728                                 view: view,
6729                                 el: view.el
6730                             }
6731                         ]);
6732                     }
6733                     this.isViewUpdated = true;
6734                 }
6735                 this.requestRerender();
6736             }
6737         };
6738         Calendar.prototype.reduce = function (state, action, calendar) {
6739             return reduce(state, action, calendar);
6740         };
6741         // Render Queue
6742         // -----------------------------------------------------------------------------------------------------------------
6743         Calendar.prototype.requestRerender = function (needsFull) {
6744             if (needsFull === void 0) { needsFull = false; }
6745             this.needsRerender = true;
6746             this.needsFullRerender = this.needsFullRerender || needsFull;
6747             this.delayedRerender(); // will call a debounced-version of tryRerender
6748         };
6749         Calendar.prototype.tryRerender = function () {
6750             if (this.component && // must be accepting renders
6751                 this.needsRerender && // indicates that a rerender was requested
6752                 !this.renderingPauseDepth && // not paused
6753                 !this.isRendering // not currently in the render loop
6754             ) {
6755                 this.executeRender();
6756             }
6757         };
6758         Calendar.prototype.batchRendering = function (func) {
6759             this.renderingPauseDepth++;
6760             func();
6761             this.renderingPauseDepth--;
6762             if (this.needsRerender) {
6763                 this.requestRerender();
6764             }
6765         };
6766         // Rendering
6767         // -----------------------------------------------------------------------------------------------------------------
6768         Calendar.prototype.executeRender = function () {
6769             var needsFullRerender = this.needsFullRerender; // save before clearing
6770             // clear these BEFORE the render so that new values will accumulate during render
6771             this.needsRerender = false;
6772             this.needsFullRerender = false;
6773             this.isRendering = true;
6774             this.renderComponent(needsFullRerender);
6775             this.isRendering = false;
6776             // received a rerender request while rendering
6777             if (this.needsRerender) {
6778                 this.delayedRerender();
6779             }
6780         };
6781         /*
6782         don't call this directly. use executeRender instead
6783         */
6784         Calendar.prototype.renderComponent = function (needsFull) {
6785             var _a = this, state = _a.state, component = _a.component;
6786             var viewType = state.viewType;
6787             var viewSpec = this.viewSpecs[viewType];
6788             var savedScroll = (needsFull && component) ? component.view.queryScroll() : null;
6789             if (!viewSpec) {
6790                 throw new Error("View type \"" + viewType + "\" is not valid");
6791             }
6792             // if event sources are still loading and progressive rendering hasn't been enabled,
6793             // keep rendering the last fully loaded set of events
6794             var renderableEventStore = this.renderableEventStore =
6795                 (state.eventSourceLoadingLevel && !this.opt('progressiveEventRendering')) ?
6796                     this.renderableEventStore :
6797                     state.eventStore;
6798             var eventUiSingleBase = this.buildEventUiSingleBase(viewSpec.options);
6799             var eventUiBySource = this.buildEventUiBySource(state.eventSources);
6800             var eventUiBases = this.eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
6801             if (needsFull || !component) {
6802                 if (component) {
6803                     component.freezeHeight(); // next component will unfreeze it
6804                     component.destroy();
6805                 }
6806                 component = this.component = new CalendarComponent({
6807                     calendar: this,
6808                     view: null,
6809                     dateEnv: this.dateEnv,
6810                     theme: this.theme,
6811                     options: this.optionsManager.computed
6812                 }, this.el);
6813                 this.isViewUpdated = true;
6814                 this.isDatesUpdated = true;
6815                 this.isEventsUpdated = true;
6816             }
6817             component.receiveProps(__assign({}, state, { viewSpec: viewSpec, dateProfile: state.dateProfile, dateProfileGenerator: this.dateProfileGenerators[viewType], eventStore: renderableEventStore, eventUiBases: eventUiBases, dateSelection: state.dateSelection, eventSelection: state.eventSelection, eventDrag: state.eventDrag, eventResize: state.eventResize }));
6818             if (savedScroll) {
6819                 component.view.applyScroll(savedScroll, false);
6820             }
6821             if (this.isViewUpdated) {
6822                 this.isViewUpdated = false;
6823                 this.publiclyTrigger('viewSkeletonRender', [
6824                     {
6825                         view: component.view,
6826                         el: component.view.el
6827                     }
6828                 ]);
6829             }
6830             if (this.isDatesUpdated) {
6831                 this.isDatesUpdated = false;
6832                 this.publiclyTrigger('datesRender', [
6833                     {
6834                         view: component.view,
6835                         el: component.view.el
6836                     }
6837                 ]);
6838             }
6839             if (this.isEventsUpdated) {
6840                 this.isEventsUpdated = false;
6841             }
6842             this.releaseAfterSizingTriggers();
6843         };
6844         // Options
6845         // -----------------------------------------------------------------------------------------------------------------
6846         Calendar.prototype.setOption = function (name, val) {
6847             var _a;
6848             this.mutateOptions((_a = {}, _a[name] = val, _a), [], true);
6849         };
6850         Calendar.prototype.getOption = function (name) {
6851             return this.optionsManager.computed[name];
6852         };
6853         Calendar.prototype.opt = function (name) {
6854             return this.optionsManager.computed[name];
6855         };
6856         Calendar.prototype.viewOpt = function (name) {
6857             return this.viewOpts()[name];
6858         };
6859         Calendar.prototype.viewOpts = function () {
6860             return this.viewSpecs[this.state.viewType].options;
6861         };
6862         /*
6863         handles option changes (like a diff)
6864         */
6865         Calendar.prototype.mutateOptions = function (updates, removals, isDynamic, deepEqual) {
6866             var _this = this;
6867             var changeHandlers = this.pluginSystem.hooks.optionChangeHandlers;
6868             var normalUpdates = {};
6869             var specialUpdates = {};
6870             var oldDateEnv = this.dateEnv; // do this before handleOptions
6871             var isTimeZoneDirty = false;
6872             var isSizeDirty = false;
6873             var anyDifficultOptions = Boolean(removals.length);
6874             for (var name_1 in updates) {
6875                 if (changeHandlers[name_1]) {
6876                     specialUpdates[name_1] = updates[name_1];
6877                 }
6878                 else {
6879                     normalUpdates[name_1] = updates[name_1];
6880                 }
6881             }
6882             for (var name_2 in normalUpdates) {
6883                 if (/^(height|contentHeight|aspectRatio)$/.test(name_2)) {
6884                     isSizeDirty = true;
6885                 }
6886                 else if (/^(defaultDate|defaultView)$/.test(name_2)) ;
6887                 else {
6888                     anyDifficultOptions = true;
6889                     if (name_2 === 'timeZone') {
6890                         isTimeZoneDirty = true;
6891                     }
6892                 }
6893             }
6894             this.optionsManager.mutate(normalUpdates, removals, isDynamic);
6895             if (anyDifficultOptions) {
6896                 this.handleOptions(this.optionsManager.computed);
6897                 this.needsFullRerender = true;
6898             }
6899             this.batchRendering(function () {
6900                 if (anyDifficultOptions) {
6901                     if (isTimeZoneDirty) {
6902                         _this.dispatch({
6903                             type: 'CHANGE_TIMEZONE',
6904                             oldDateEnv: oldDateEnv
6905                         });
6906                     }
6907                     /* HACK
6908                     has the same effect as calling this.requestRerender(true)
6909                     but recomputes the state's dateProfile
6910                     */
6911                     _this.dispatch({
6912                         type: 'SET_VIEW_TYPE',
6913                         viewType: _this.state.viewType
6914                     });
6915                 }
6916                 else if (isSizeDirty) {
6917                     _this.updateSize();
6918                 }
6919                 // special updates
6920                 if (deepEqual) {
6921                     for (var name_3 in specialUpdates) {
6922                         changeHandlers[name_3](specialUpdates[name_3], _this, deepEqual);
6923                     }
6924                 }
6925             });
6926         };
6927         /*
6928         rebuilds things based off of a complete set of refined options
6929         */
6930         Calendar.prototype.handleOptions = function (options) {
6931             var _this = this;
6932             var pluginHooks = this.pluginSystem.hooks;
6933             this.defaultAllDayEventDuration = createDuration(options.defaultAllDayEventDuration);
6934             this.defaultTimedEventDuration = createDuration(options.defaultTimedEventDuration);
6935             this.delayedRerender = this.buildDelayedRerender(options.rerenderDelay);
6936             this.theme = this.buildTheme(options);
6937             var available = this.parseRawLocales(options.locales);
6938             this.availableRawLocales = available.map;
6939             var locale = this.buildLocale(options.locale || available.defaultCode, available.map);
6940             this.dateEnv = this.buildDateEnv(locale, options.timeZone, pluginHooks.namedTimeZonedImpl, options.firstDay, options.weekNumberCalculation, options.weekLabel, pluginHooks.cmdFormatter);
6941             this.selectionConfig = this.buildSelectionConfig(options); // needs dateEnv. do after :(
6942             // ineffecient to do every time?
6943             this.viewSpecs = buildViewSpecs(pluginHooks.views, this.optionsManager);
6944             // ineffecient to do every time?
6945             this.dateProfileGenerators = mapHash(this.viewSpecs, function (viewSpec) {
6946                 return new viewSpec.class.prototype.dateProfileGeneratorClass(viewSpec, _this);
6947             });
6948         };
6949         Calendar.prototype.getAvailableLocaleCodes = function () {
6950             return Object.keys(this.availableRawLocales);
6951         };
6952         Calendar.prototype._buildSelectionConfig = function (rawOpts) {
6953             return processScopedUiProps('select', rawOpts, this);
6954         };
6955         Calendar.prototype._buildEventUiSingleBase = function (rawOpts) {
6956             if (rawOpts.editable) { // so 'editable' affected events
6957                 rawOpts = __assign({}, rawOpts, { eventEditable: true });
6958             }
6959             return processScopedUiProps('event', rawOpts, this);
6960         };
6961         // Trigger
6962         // -----------------------------------------------------------------------------------------------------------------
6963         Calendar.prototype.hasPublicHandlers = function (name) {
6964             return this.hasHandlers(name) ||
6965                 this.opt(name); // handler specified in options
6966         };
6967         Calendar.prototype.publiclyTrigger = function (name, args) {
6968             var optHandler = this.opt(name);
6969             this.triggerWith(name, this, args);
6970             if (optHandler) {
6971                 return optHandler.apply(this, args);
6972             }
6973         };
6974         Calendar.prototype.publiclyTriggerAfterSizing = function (name, args) {
6975             var afterSizingTriggers = this.afterSizingTriggers;
6976             (afterSizingTriggers[name] || (afterSizingTriggers[name] = [])).push(args);
6977         };
6978         Calendar.prototype.releaseAfterSizingTriggers = function () {
6979             var afterSizingTriggers = this.afterSizingTriggers;
6980             for (var name_4 in afterSizingTriggers) {
6981                 for (var _i = 0, _a = afterSizingTriggers[name_4]; _i < _a.length; _i++) {
6982                     var args = _a[_i];
6983                     this.publiclyTrigger(name_4, args);
6984                 }
6985             }
6986             this.afterSizingTriggers = {};
6987         };
6988         // View
6989         // -----------------------------------------------------------------------------------------------------------------
6990         // Returns a boolean about whether the view is okay to instantiate at some point
6991         Calendar.prototype.isValidViewType = function (viewType) {
6992             return Boolean(this.viewSpecs[viewType]);
6993         };
6994         Calendar.prototype.changeView = function (viewType, dateOrRange) {
6995             var dateMarker = null;
6996             if (dateOrRange) {
6997                 if (dateOrRange.start && dateOrRange.end) { // a range
6998                     this.optionsManager.mutate({ visibleRange: dateOrRange }, []); // will not rerender
6999                     this.handleOptions(this.optionsManager.computed); // ...but yuck
7000                 }
7001                 else { // a date
7002                     dateMarker = this.dateEnv.createMarker(dateOrRange); // just like gotoDate
7003                 }
7004             }
7005             this.unselect();
7006             this.dispatch({
7007                 type: 'SET_VIEW_TYPE',
7008                 viewType: viewType,
7009                 dateMarker: dateMarker
7010             });
7011         };
7012         // Forces navigation to a view for the given date.
7013         // `viewType` can be a specific view name or a generic one like "week" or "day".
7014         // needs to change
7015         Calendar.prototype.zoomTo = function (dateMarker, viewType) {
7016             var spec;
7017             viewType = viewType || 'day'; // day is default zoom
7018             spec = this.viewSpecs[viewType] ||
7019                 this.getUnitViewSpec(viewType);
7020             this.unselect();
7021             if (spec) {
7022                 this.dispatch({
7023                     type: 'SET_VIEW_TYPE',
7024                     viewType: spec.type,
7025                     dateMarker: dateMarker
7026                 });
7027             }
7028             else {
7029                 this.dispatch({
7030                     type: 'SET_DATE',
7031                     dateMarker: dateMarker
7032                 });
7033             }
7034         };
7035         // Given a duration singular unit, like "week" or "day", finds a matching view spec.
7036         // Preference is given to views that have corresponding buttons.
7037         Calendar.prototype.getUnitViewSpec = function (unit) {
7038             var component = this.component;
7039             var viewTypes = [];
7040             var i;
7041             var spec;
7042             // put views that have buttons first. there will be duplicates, but oh
7043             if (component.header) {
7044                 viewTypes.push.apply(viewTypes, component.header.viewsWithButtons);
7045             }
7046             if (component.footer) {
7047                 viewTypes.push.apply(viewTypes, component.footer.viewsWithButtons);
7048             }
7049             for (var viewType in this.viewSpecs) {
7050                 viewTypes.push(viewType);
7051             }
7052             for (i = 0; i < viewTypes.length; i++) {
7053                 spec = this.viewSpecs[viewTypes[i]];
7054                 if (spec) {
7055                     if (spec.singleUnit === unit) {
7056                         return spec;
7057                     }
7058                 }
7059             }
7060         };
7061         // Current Date
7062         // -----------------------------------------------------------------------------------------------------------------
7063         Calendar.prototype.getInitialDate = function () {
7064             var defaultDateInput = this.opt('defaultDate');
7065             // compute the initial ambig-timezone date
7066             if (defaultDateInput != null) {
7067                 return this.dateEnv.createMarker(defaultDateInput);
7068             }
7069             else {
7070                 return this.getNow(); // getNow already returns unzoned
7071             }
7072         };
7073         Calendar.prototype.prev = function () {
7074             this.unselect();
7075             this.dispatch({ type: 'PREV' });
7076         };
7077         Calendar.prototype.next = function () {
7078             this.unselect();
7079             this.dispatch({ type: 'NEXT' });
7080         };
7081         Calendar.prototype.prevYear = function () {
7082             this.unselect();
7083             this.dispatch({
7084                 type: 'SET_DATE',
7085                 dateMarker: this.dateEnv.addYears(this.state.currentDate, -1)
7086             });
7087         };
7088         Calendar.prototype.nextYear = function () {
7089             this.unselect();
7090             this.dispatch({
7091                 type: 'SET_DATE',
7092                 dateMarker: this.dateEnv.addYears(this.state.currentDate, 1)
7093             });
7094         };
7095         Calendar.prototype.today = function () {
7096             this.unselect();
7097             this.dispatch({
7098                 type: 'SET_DATE',
7099                 dateMarker: this.getNow()
7100             });
7101         };
7102         Calendar.prototype.gotoDate = function (zonedDateInput) {
7103             this.unselect();
7104             this.dispatch({
7105                 type: 'SET_DATE',
7106                 dateMarker: this.dateEnv.createMarker(zonedDateInput)
7107             });
7108         };
7109         Calendar.prototype.incrementDate = function (deltaInput) {
7110             var delta = createDuration(deltaInput);
7111             if (delta) { // else, warn about invalid input?
7112                 this.unselect();
7113                 this.dispatch({
7114                     type: 'SET_DATE',
7115                     dateMarker: this.dateEnv.add(this.state.currentDate, delta)
7116                 });
7117             }
7118         };
7119         // for external API
7120         Calendar.prototype.getDate = function () {
7121             return this.dateEnv.toDate(this.state.currentDate);
7122         };
7123         // Date Formatting Utils
7124         // -----------------------------------------------------------------------------------------------------------------
7125         Calendar.prototype.formatDate = function (d, formatter) {
7126             var dateEnv = this.dateEnv;
7127             return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
7128         };
7129         // `settings` is for formatter AND isEndExclusive
7130         Calendar.prototype.formatRange = function (d0, d1, settings) {
7131             var dateEnv = this.dateEnv;
7132             return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings, this.opt('defaultRangeSeparator')), settings);
7133         };
7134         Calendar.prototype.formatIso = function (d, omitTime) {
7135             var dateEnv = this.dateEnv;
7136             return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime });
7137         };
7138         // Sizing
7139         // -----------------------------------------------------------------------------------------------------------------
7140         Calendar.prototype.windowResize = function (ev) {
7141             if (!this.isHandlingWindowResize &&
7142                 this.component && // why?
7143                 ev.target === window // not a jqui resize event
7144             ) {
7145                 this.isHandlingWindowResize = true;
7146                 this.updateSize();
7147                 this.publiclyTrigger('windowResize', [this.view]);
7148                 this.isHandlingWindowResize = false;
7149             }
7150         };
7151         Calendar.prototype.updateSize = function () {
7152             if (this.component) { // when?
7153                 this.component.updateSize(true);
7154             }
7155         };
7156         // Component Registration
7157         // -----------------------------------------------------------------------------------------------------------------
7158         Calendar.prototype.registerInteractiveComponent = function (component, settingsInput) {
7159             var settings = parseInteractionSettings(component, settingsInput);
7160             var DEFAULT_INTERACTIONS = [
7161                 EventClicking,
7162                 EventHovering
7163             ];
7164             var interactionClasses = DEFAULT_INTERACTIONS.concat(this.pluginSystem.hooks.componentInteractions);
7165             var interactions = interactionClasses.map(function (interactionClass) {
7166                 return new interactionClass(settings);
7167             });
7168             this.interactionsStore[component.uid] = interactions;
7169             interactionSettingsStore[component.uid] = settings;
7170         };
7171         Calendar.prototype.unregisterInteractiveComponent = function (component) {
7172             for (var _i = 0, _a = this.interactionsStore[component.uid]; _i < _a.length; _i++) {
7173                 var listener = _a[_i];
7174                 listener.destroy();
7175             }
7176             delete this.interactionsStore[component.uid];
7177             delete interactionSettingsStore[component.uid];
7178         };
7179         // Date Selection / Event Selection / DayClick
7180         // -----------------------------------------------------------------------------------------------------------------
7181         // this public method receives start/end dates in any format, with any timezone
7182         // NOTE: args were changed from v3
7183         Calendar.prototype.select = function (dateOrObj, endDate) {
7184             var selectionInput;
7185             if (endDate == null) {
7186                 if (dateOrObj.start != null) {
7187                     selectionInput = dateOrObj;
7188                 }
7189                 else {
7190                     selectionInput = {
7191                         start: dateOrObj,
7192                         end: null
7193                     };
7194                 }
7195             }
7196             else {
7197                 selectionInput = {
7198                     start: dateOrObj,
7199                     end: endDate
7200                 };
7201             }
7202             var selection = parseDateSpan(selectionInput, this.dateEnv, createDuration({ days: 1 }) // TODO: cache this?
7203             );
7204             if (selection) { // throw parse error otherwise?
7205                 this.dispatch({ type: 'SELECT_DATES', selection: selection });
7206                 this.triggerDateSelect(selection);
7207             }
7208         };
7209         // public method
7210         Calendar.prototype.unselect = function (pev) {
7211             if (this.state.dateSelection) {
7212                 this.dispatch({ type: 'UNSELECT_DATES' });
7213                 this.triggerDateUnselect(pev);
7214             }
7215         };
7216         Calendar.prototype.triggerDateSelect = function (selection, pev) {
7217             var arg = __assign({}, this.buildDateSpanApi(selection), { jsEvent: pev ? pev.origEvent : null, view: this.view });
7218             this.publiclyTrigger('select', [arg]);
7219         };
7220         Calendar.prototype.triggerDateUnselect = function (pev) {
7221             this.publiclyTrigger('unselect', [
7222                 {
7223                     jsEvent: pev ? pev.origEvent : null,
7224                     view: this.view
7225                 }
7226             ]);
7227         };
7228         // TODO: receive pev?
7229         Calendar.prototype.triggerDateClick = function (dateSpan, dayEl, view, ev) {
7230             var arg = __assign({}, this.buildDatePointApi(dateSpan), { dayEl: dayEl, jsEvent: ev, // Is this always a mouse event? See #4655
7231                 view: view });
7232             this.publiclyTrigger('dateClick', [arg]);
7233         };
7234         Calendar.prototype.buildDatePointApi = function (dateSpan) {
7235             var props = {};
7236             for (var _i = 0, _a = this.pluginSystem.hooks.datePointTransforms; _i < _a.length; _i++) {
7237                 var transform = _a[_i];
7238                 __assign(props, transform(dateSpan, this));
7239             }
7240             __assign(props, buildDatePointApi(dateSpan, this.dateEnv));
7241             return props;
7242         };
7243         Calendar.prototype.buildDateSpanApi = function (dateSpan) {
7244             var props = {};
7245             for (var _i = 0, _a = this.pluginSystem.hooks.dateSpanTransforms; _i < _a.length; _i++) {
7246                 var transform = _a[_i];
7247                 __assign(props, transform(dateSpan, this));
7248             }
7249             __assign(props, buildDateSpanApi(dateSpan, this.dateEnv));
7250             return props;
7251         };
7252         // Date Utils
7253         // -----------------------------------------------------------------------------------------------------------------
7254         // Returns a DateMarker for the current date, as defined by the client's computer or from the `now` option
7255         Calendar.prototype.getNow = function () {
7256             var now = this.opt('now');
7257             if (typeof now === 'function') {
7258                 now = now();
7259             }
7260             if (now == null) {
7261                 return this.dateEnv.createNowMarker();
7262             }
7263             return this.dateEnv.createMarker(now);
7264         };
7265         // Event-Date Utilities
7266         // -----------------------------------------------------------------------------------------------------------------
7267         // Given an event's allDay status and start date, return what its fallback end date should be.
7268         // TODO: rename to computeDefaultEventEnd
7269         Calendar.prototype.getDefaultEventEnd = function (allDay, marker) {
7270             var end = marker;
7271             if (allDay) {
7272                 end = startOfDay(end);
7273                 end = this.dateEnv.add(end, this.defaultAllDayEventDuration);
7274             }
7275             else {
7276                 end = this.dateEnv.add(end, this.defaultTimedEventDuration);
7277             }
7278             return end;
7279         };
7280         // Public Events API
7281         // -----------------------------------------------------------------------------------------------------------------
7282         Calendar.prototype.addEvent = function (eventInput, sourceInput) {
7283             if (eventInput instanceof EventApi) {
7284                 var def = eventInput._def;
7285                 var instance = eventInput._instance;
7286                 // not already present? don't want to add an old snapshot
7287                 if (!this.state.eventStore.defs[def.defId]) {
7288                     this.dispatch({
7289                         type: 'ADD_EVENTS',
7290                         eventStore: eventTupleToStore({ def: def, instance: instance }) // TODO: better util for two args?
7291                     });
7292                 }
7293                 return eventInput;
7294             }
7295             var sourceId;
7296             if (sourceInput instanceof EventSourceApi) {
7297                 sourceId = sourceInput.internalEventSource.sourceId;
7298             }
7299             else if (sourceInput != null) {
7300                 var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
7301                 if (!sourceApi) {
7302                     console.warn('Could not find an event source with ID "' + sourceInput + '"'); // TODO: test
7303                     return null;
7304                 }
7305                 else {
7306                     sourceId = sourceApi.internalEventSource.sourceId;
7307                 }
7308             }
7309             var tuple = parseEvent(eventInput, sourceId, this);
7310             if (tuple) {
7311                 this.dispatch({
7312                     type: 'ADD_EVENTS',
7313                     eventStore: eventTupleToStore(tuple)
7314                 });
7315                 return new EventApi(this, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
7316             }
7317             return null;
7318         };
7319         // TODO: optimize
7320         Calendar.prototype.getEventById = function (id) {
7321             var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
7322             id = String(id);
7323             for (var defId in defs) {
7324                 var def = defs[defId];
7325                 if (def.publicId === id) {
7326                     if (def.recurringDef) {
7327                         return new EventApi(this, def, null);
7328                     }
7329                     else {
7330                         for (var instanceId in instances) {
7331                             var instance = instances[instanceId];
7332                             if (instance.defId === def.defId) {
7333                                 return new EventApi(this, def, instance);
7334                             }
7335                         }
7336                     }
7337                 }
7338             }
7339             return null;
7340         };
7341         Calendar.prototype.getEvents = function () {
7342             var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
7343             var eventApis = [];
7344             for (var id in instances) {
7345                 var instance = instances[id];
7346                 var def = defs[instance.defId];
7347                 eventApis.push(new EventApi(this, def, instance));
7348             }
7349             return eventApis;
7350         };
7351         Calendar.prototype.removeAllEvents = function () {
7352             this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
7353         };
7354         Calendar.prototype.rerenderEvents = function () {
7355             this.dispatch({ type: 'RESET_EVENTS' });
7356         };
7357         // Public Event Sources API
7358         // -----------------------------------------------------------------------------------------------------------------
7359         Calendar.prototype.getEventSources = function () {
7360             var sourceHash = this.state.eventSources;
7361             var sourceApis = [];
7362             for (var internalId in sourceHash) {
7363                 sourceApis.push(new EventSourceApi(this, sourceHash[internalId]));
7364             }
7365             return sourceApis;
7366         };
7367         Calendar.prototype.getEventSourceById = function (id) {
7368             var sourceHash = this.state.eventSources;
7369             id = String(id);
7370             for (var sourceId in sourceHash) {
7371                 if (sourceHash[sourceId].publicId === id) {
7372                     return new EventSourceApi(this, sourceHash[sourceId]);
7373                 }
7374             }
7375             return null;
7376         };
7377         Calendar.prototype.addEventSource = function (sourceInput) {
7378             if (sourceInput instanceof EventSourceApi) {
7379                 // not already present? don't want to add an old snapshot
7380                 if (!this.state.eventSources[sourceInput.internalEventSource.sourceId]) {
7381                     this.dispatch({
7382                         type: 'ADD_EVENT_SOURCES',
7383                         sources: [sourceInput.internalEventSource]
7384                     });
7385                 }
7386                 return sourceInput;
7387             }
7388             var eventSource = parseEventSource(sourceInput, this);
7389             if (eventSource) { // TODO: error otherwise?
7390                 this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
7391                 return new EventSourceApi(this, eventSource);
7392             }
7393             return null;
7394         };
7395         Calendar.prototype.removeAllEventSources = function () {
7396             this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
7397         };
7398         Calendar.prototype.refetchEvents = function () {
7399             this.dispatch({ type: 'FETCH_EVENT_SOURCES' });
7400         };
7401         // Scroll
7402         // -----------------------------------------------------------------------------------------------------------------
7403         Calendar.prototype.scrollToTime = function (timeInput) {
7404             var duration = createDuration(timeInput);
7405             if (duration) {
7406                 this.component.view.scrollToDuration(duration);
7407             }
7408         };
7409         return Calendar;
7410     }());
7411     EmitterMixin.mixInto(Calendar);
7412     // for memoizers
7413     // -----------------------------------------------------------------------------------------------------------------
7414     function buildDateEnv(locale, timeZone, namedTimeZoneImpl, firstDay, weekNumberCalculation, weekLabel, cmdFormatter) {
7415         return new DateEnv({
7416             calendarSystem: 'gregory',
7417             timeZone: timeZone,
7418             namedTimeZoneImpl: namedTimeZoneImpl,
7419             locale: locale,
7420             weekNumberCalculation: weekNumberCalculation,
7421             firstDay: firstDay,
7422             weekLabel: weekLabel,
7423             cmdFormatter: cmdFormatter
7424         });
7425     }
7426     function buildTheme(calendarOptions) {
7427         var themeClass = this.pluginSystem.hooks.themeClasses[calendarOptions.themeSystem] || StandardTheme;
7428         return new themeClass(calendarOptions);
7429     }
7430     function buildDelayedRerender(wait) {
7431         var func = this.tryRerender.bind(this);
7432         if (wait != null) {
7433             func = debounce(func, wait);
7434         }
7435         return func;
7436     }
7437     function buildEventUiBySource(eventSources) {
7438         return mapHash(eventSources, function (eventSource) {
7439             return eventSource.ui;
7440         });
7441     }
7442     function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
7443         var eventUiBases = { '': eventUiSingleBase };
7444         for (var defId in eventDefs) {
7445             var def = eventDefs[defId];
7446             if (def.sourceId && eventUiBySource[def.sourceId]) {
7447                 eventUiBases[defId] = eventUiBySource[def.sourceId];
7448             }
7449         }
7450         return eventUiBases;
7451     }
7452
7453     var View = /** @class */ (function (_super) {
7454         __extends(View, _super);
7455         function View(context, viewSpec, dateProfileGenerator, parentEl) {
7456             var _this = _super.call(this, context, createElement('div', { className: 'fc-view fc-' + viewSpec.type + '-view' }), true // isView (HACK)
7457             ) || this;
7458             _this.renderDatesMem = memoizeRendering(_this.renderDatesWrap, _this.unrenderDatesWrap);
7459             _this.renderBusinessHoursMem = memoizeRendering(_this.renderBusinessHours, _this.unrenderBusinessHours, [_this.renderDatesMem]);
7460             _this.renderDateSelectionMem = memoizeRendering(_this.renderDateSelectionWrap, _this.unrenderDateSelectionWrap, [_this.renderDatesMem]);
7461             _this.renderEventsMem = memoizeRendering(_this.renderEvents, _this.unrenderEvents, [_this.renderDatesMem]);
7462             _this.renderEventSelectionMem = memoizeRendering(_this.renderEventSelectionWrap, _this.unrenderEventSelectionWrap, [_this.renderEventsMem]);
7463             _this.renderEventDragMem = memoizeRendering(_this.renderEventDragWrap, _this.unrenderEventDragWrap, [_this.renderDatesMem]);
7464             _this.renderEventResizeMem = memoizeRendering(_this.renderEventResizeWrap, _this.unrenderEventResizeWrap, [_this.renderDatesMem]);
7465             _this.viewSpec = viewSpec;
7466             _this.dateProfileGenerator = dateProfileGenerator;
7467             _this.type = viewSpec.type;
7468             _this.eventOrderSpecs = parseFieldSpecs(_this.opt('eventOrder'));
7469             _this.nextDayThreshold = createDuration(_this.opt('nextDayThreshold'));
7470             parentEl.appendChild(_this.el);
7471             _this.initialize();
7472             return _this;
7473         }
7474         View.prototype.initialize = function () {
7475         };
7476         Object.defineProperty(View.prototype, "activeStart", {
7477             // Date Setting/Unsetting
7478             // -----------------------------------------------------------------------------------------------------------------
7479             get: function () {
7480                 return this.dateEnv.toDate(this.props.dateProfile.activeRange.start);
7481             },
7482             enumerable: true,
7483             configurable: true
7484         });
7485         Object.defineProperty(View.prototype, "activeEnd", {
7486             get: function () {
7487                 return this.dateEnv.toDate(this.props.dateProfile.activeRange.end);
7488             },
7489             enumerable: true,
7490             configurable: true
7491         });
7492         Object.defineProperty(View.prototype, "currentStart", {
7493             get: function () {
7494                 return this.dateEnv.toDate(this.props.dateProfile.currentRange.start);
7495             },
7496             enumerable: true,
7497             configurable: true
7498         });
7499         Object.defineProperty(View.prototype, "currentEnd", {
7500             get: function () {
7501                 return this.dateEnv.toDate(this.props.dateProfile.currentRange.end);
7502             },
7503             enumerable: true,
7504             configurable: true
7505         });
7506         // General Rendering
7507         // -----------------------------------------------------------------------------------------------------------------
7508         View.prototype.render = function (props) {
7509             this.renderDatesMem(props.dateProfile);
7510             this.renderBusinessHoursMem(props.businessHours);
7511             this.renderDateSelectionMem(props.dateSelection);
7512             this.renderEventsMem(props.eventStore);
7513             this.renderEventSelectionMem(props.eventSelection);
7514             this.renderEventDragMem(props.eventDrag);
7515             this.renderEventResizeMem(props.eventResize);
7516         };
7517         View.prototype.destroy = function () {
7518             _super.prototype.destroy.call(this);
7519             this.renderDatesMem.unrender(); // should unrender everything else
7520         };
7521         // Sizing
7522         // -----------------------------------------------------------------------------------------------------------------
7523         View.prototype.updateSize = function (isResize, viewHeight, isAuto) {
7524             var calendar = this.calendar;
7525             if (isResize || // HACKS...
7526                 calendar.isViewUpdated ||
7527                 calendar.isDatesUpdated ||
7528                 calendar.isEventsUpdated) {
7529                 // sort of the catch-all sizing
7530                 // anything that might cause dimension changes
7531                 this.updateBaseSize(isResize, viewHeight, isAuto);
7532             }
7533         };
7534         View.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
7535         };
7536         // Date Rendering
7537         // -----------------------------------------------------------------------------------------------------------------
7538         View.prototype.renderDatesWrap = function (dateProfile) {
7539             this.renderDates(dateProfile);
7540             this.addScroll({
7541                 duration: createDuration(this.opt('scrollTime'))
7542             });
7543             this.startNowIndicator(dateProfile); // shouldn't render yet because updateSize will be called soon
7544         };
7545         View.prototype.unrenderDatesWrap = function () {
7546             this.stopNowIndicator();
7547             this.unrenderDates();
7548         };
7549         View.prototype.renderDates = function (dateProfile) { };
7550         View.prototype.unrenderDates = function () { };
7551         // Business Hours
7552         // -----------------------------------------------------------------------------------------------------------------
7553         View.prototype.renderBusinessHours = function (businessHours) { };
7554         View.prototype.unrenderBusinessHours = function () { };
7555         // Date Selection
7556         // -----------------------------------------------------------------------------------------------------------------
7557         View.prototype.renderDateSelectionWrap = function (selection) {
7558             if (selection) {
7559                 this.renderDateSelection(selection);
7560             }
7561         };
7562         View.prototype.unrenderDateSelectionWrap = function (selection) {
7563             if (selection) {
7564                 this.unrenderDateSelection(selection);
7565             }
7566         };
7567         View.prototype.renderDateSelection = function (selection) { };
7568         View.prototype.unrenderDateSelection = function (selection) { };
7569         // Event Rendering
7570         // -----------------------------------------------------------------------------------------------------------------
7571         View.prototype.renderEvents = function (eventStore) { };
7572         View.prototype.unrenderEvents = function () { };
7573         // util for subclasses
7574         View.prototype.sliceEvents = function (eventStore, allDay) {
7575             var props = this.props;
7576             return sliceEventStore(eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? this.nextDayThreshold : null).fg;
7577         };
7578         View.prototype.computeEventDraggable = function (eventDef, eventUi) {
7579             var transformers = this.calendar.pluginSystem.hooks.isDraggableTransformers;
7580             var val = eventUi.startEditable;
7581             for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
7582                 var transformer = transformers_1[_i];
7583                 val = transformer(val, eventDef, eventUi, this);
7584             }
7585             return val;
7586         };
7587         View.prototype.computeEventStartResizable = function (eventDef, eventUi) {
7588             return eventUi.durationEditable && this.opt('eventResizableFromStart');
7589         };
7590         View.prototype.computeEventEndResizable = function (eventDef, eventUi) {
7591             return eventUi.durationEditable;
7592         };
7593         // Event Selection
7594         // -----------------------------------------------------------------------------------------------------------------
7595         View.prototype.renderEventSelectionWrap = function (instanceId) {
7596             if (instanceId) {
7597                 this.renderEventSelection(instanceId);
7598             }
7599         };
7600         View.prototype.unrenderEventSelectionWrap = function (instanceId) {
7601             if (instanceId) {
7602                 this.unrenderEventSelection(instanceId);
7603             }
7604         };
7605         View.prototype.renderEventSelection = function (instanceId) { };
7606         View.prototype.unrenderEventSelection = function (instanceId) { };
7607         // Event Drag
7608         // -----------------------------------------------------------------------------------------------------------------
7609         View.prototype.renderEventDragWrap = function (state) {
7610             if (state) {
7611                 this.renderEventDrag(state);
7612             }
7613         };
7614         View.prototype.unrenderEventDragWrap = function (state) {
7615             if (state) {
7616                 this.unrenderEventDrag(state);
7617             }
7618         };
7619         View.prototype.renderEventDrag = function (state) { };
7620         View.prototype.unrenderEventDrag = function (state) { };
7621         // Event Resize
7622         // -----------------------------------------------------------------------------------------------------------------
7623         View.prototype.renderEventResizeWrap = function (state) {
7624             if (state) {
7625                 this.renderEventResize(state);
7626             }
7627         };
7628         View.prototype.unrenderEventResizeWrap = function (state) {
7629             if (state) {
7630                 this.unrenderEventResize(state);
7631             }
7632         };
7633         View.prototype.renderEventResize = function (state) { };
7634         View.prototype.unrenderEventResize = function (state) { };
7635         /* Now Indicator
7636         ------------------------------------------------------------------------------------------------------------------*/
7637         // Immediately render the current time indicator and begins re-rendering it at an interval,
7638         // which is defined by this.getNowIndicatorUnit().
7639         // TODO: somehow do this for the current whole day's background too
7640         View.prototype.startNowIndicator = function (dateProfile) {
7641             var _this = this;
7642             var dateEnv = this.dateEnv;
7643             var unit;
7644             var update;
7645             var delay; // ms wait value
7646             if (this.opt('nowIndicator')) {
7647                 unit = this.getNowIndicatorUnit(dateProfile);
7648                 if (unit) {
7649                     update = this.updateNowIndicator.bind(this);
7650                     this.initialNowDate = this.calendar.getNow();
7651                     this.initialNowQueriedMs = new Date().valueOf();
7652                     // wait until the beginning of the next interval
7653                     delay = dateEnv.add(dateEnv.startOf(this.initialNowDate, unit), createDuration(1, unit)).valueOf() - this.initialNowDate.valueOf();
7654                     // TODO: maybe always use setTimeout, waiting until start of next unit
7655                     this.nowIndicatorTimeoutID = setTimeout(function () {
7656                         _this.nowIndicatorTimeoutID = null;
7657                         update();
7658                         if (unit === 'second') {
7659                             delay = 1000; // every second
7660                         }
7661                         else {
7662                             delay = 1000 * 60; // otherwise, every minute
7663                         }
7664                         _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval
7665                     }, delay);
7666                 }
7667                 // rendering will be initiated in updateSize
7668             }
7669         };
7670         // rerenders the now indicator, computing the new current time from the amount of time that has passed
7671         // since the initial getNow call.
7672         View.prototype.updateNowIndicator = function () {
7673             if (this.props.dateProfile && // a way to determine if dates were rendered yet
7674                 this.initialNowDate // activated before?
7675             ) {
7676                 this.unrenderNowIndicator(); // won't unrender if unnecessary
7677                 this.renderNowIndicator(addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs));
7678                 this.isNowIndicatorRendered = true;
7679             }
7680         };
7681         // Immediately unrenders the view's current time indicator and stops any re-rendering timers.
7682         // Won't cause side effects if indicator isn't rendered.
7683         View.prototype.stopNowIndicator = function () {
7684             if (this.isNowIndicatorRendered) {
7685                 if (this.nowIndicatorTimeoutID) {
7686                     clearTimeout(this.nowIndicatorTimeoutID);
7687                     this.nowIndicatorTimeoutID = null;
7688                 }
7689                 if (this.nowIndicatorIntervalID) {
7690                     clearInterval(this.nowIndicatorIntervalID);
7691                     this.nowIndicatorIntervalID = null;
7692                 }
7693                 this.unrenderNowIndicator();
7694                 this.isNowIndicatorRendered = false;
7695             }
7696         };
7697         View.prototype.getNowIndicatorUnit = function (dateProfile) {
7698             // subclasses should implement
7699         };
7700         // Renders a current time indicator at the given datetime
7701         View.prototype.renderNowIndicator = function (date) {
7702             // SUBCLASSES MUST PASS TO CHILDREN!
7703         };
7704         // Undoes the rendering actions from renderNowIndicator
7705         View.prototype.unrenderNowIndicator = function () {
7706             // SUBCLASSES MUST PASS TO CHILDREN!
7707         };
7708         /* Scroller
7709         ------------------------------------------------------------------------------------------------------------------*/
7710         View.prototype.addScroll = function (scroll) {
7711             var queuedScroll = this.queuedScroll || (this.queuedScroll = {});
7712             __assign(queuedScroll, scroll);
7713         };
7714         View.prototype.popScroll = function (isResize) {
7715             this.applyQueuedScroll(isResize);
7716             this.queuedScroll = null;
7717         };
7718         View.prototype.applyQueuedScroll = function (isResize) {
7719             this.applyScroll(this.queuedScroll || {}, isResize);
7720         };
7721         View.prototype.queryScroll = function () {
7722             var scroll = {};
7723             if (this.props.dateProfile) { // dates rendered yet?
7724                 __assign(scroll, this.queryDateScroll());
7725             }
7726             return scroll;
7727         };
7728         View.prototype.applyScroll = function (scroll, isResize) {
7729             var duration = scroll.duration;
7730             if (duration != null) {
7731                 delete scroll.duration;
7732                 if (this.props.dateProfile) { // dates rendered yet?
7733                     __assign(scroll, this.computeDateScroll(duration));
7734                 }
7735             }
7736             if (this.props.dateProfile) { // dates rendered yet?
7737                 this.applyDateScroll(scroll);
7738             }
7739         };
7740         View.prototype.computeDateScroll = function (duration) {
7741             return {}; // subclasses must implement
7742         };
7743         View.prototype.queryDateScroll = function () {
7744             return {}; // subclasses must implement
7745         };
7746         View.prototype.applyDateScroll = function (scroll) {
7747             // subclasses must implement
7748         };
7749         // for API
7750         View.prototype.scrollToDuration = function (duration) {
7751             this.applyScroll({ duration: duration }, false);
7752         };
7753         return View;
7754     }(DateComponent));
7755     EmitterMixin.mixInto(View);
7756     View.prototype.usesMinMaxTime = false;
7757     View.prototype.dateProfileGeneratorClass = DateProfileGenerator;
7758
7759     var FgEventRenderer = /** @class */ (function () {
7760         function FgEventRenderer(context) {
7761             this.segs = [];
7762             this.isSizeDirty = false;
7763             this.context = context;
7764         }
7765         FgEventRenderer.prototype.renderSegs = function (segs, mirrorInfo) {
7766             this.rangeUpdated(); // called too frequently :(
7767             // render an `.el` on each seg
7768             // returns a subset of the segs. segs that were actually rendered
7769             segs = this.renderSegEls(segs, mirrorInfo);
7770             this.segs = segs;
7771             this.attachSegs(segs, mirrorInfo);
7772             this.isSizeDirty = true;
7773             this.context.view.triggerRenderedSegs(this.segs, Boolean(mirrorInfo));
7774         };
7775         FgEventRenderer.prototype.unrender = function (_segs, mirrorInfo) {
7776             this.context.view.triggerWillRemoveSegs(this.segs, Boolean(mirrorInfo));
7777             this.detachSegs(this.segs);
7778             this.segs = [];
7779         };
7780         // Updates values that rely on options and also relate to range
7781         FgEventRenderer.prototype.rangeUpdated = function () {
7782             var options = this.context.options;
7783             var displayEventTime;
7784             var displayEventEnd;
7785             this.eventTimeFormat = createFormatter(options.eventTimeFormat || this.computeEventTimeFormat(), options.defaultRangeSeparator);
7786             displayEventTime = options.displayEventTime;
7787             if (displayEventTime == null) {
7788                 displayEventTime = this.computeDisplayEventTime(); // might be based off of range
7789             }
7790             displayEventEnd = options.displayEventEnd;
7791             if (displayEventEnd == null) {
7792                 displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range
7793             }
7794             this.displayEventTime = displayEventTime;
7795             this.displayEventEnd = displayEventEnd;
7796         };
7797         // Renders and assigns an `el` property for each foreground event segment.
7798         // Only returns segments that successfully rendered.
7799         FgEventRenderer.prototype.renderSegEls = function (segs, mirrorInfo) {
7800             var html = '';
7801             var i;
7802             if (segs.length) { // don't build an empty html string
7803                 // build a large concatenation of event segment HTML
7804                 for (i = 0; i < segs.length; i++) {
7805                     html += this.renderSegHtml(segs[i], mirrorInfo);
7806                 }
7807                 // Grab individual elements from the combined HTML string. Use each as the default rendering.
7808                 // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
7809                 htmlToElements(html).forEach(function (el, i) {
7810                     var seg = segs[i];
7811                     if (el) {
7812                         seg.el = el;
7813                     }
7814                 });
7815                 segs = filterSegsViaEls(this.context.view, segs, Boolean(mirrorInfo));
7816             }
7817             return segs;
7818         };
7819         // Generic utility for generating the HTML classNames for an event segment's element
7820         FgEventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable, mirrorInfo) {
7821             var classes = [
7822                 'fc-event',
7823                 seg.isStart ? 'fc-start' : 'fc-not-start',
7824                 seg.isEnd ? 'fc-end' : 'fc-not-end'
7825             ].concat(seg.eventRange.ui.classNames);
7826             if (isDraggable) {
7827                 classes.push('fc-draggable');
7828             }
7829             if (isResizable) {
7830                 classes.push('fc-resizable');
7831             }
7832             if (mirrorInfo) {
7833                 classes.push('fc-mirror');
7834                 if (mirrorInfo.isDragging) {
7835                     classes.push('fc-dragging');
7836                 }
7837                 if (mirrorInfo.isResizing) {
7838                     classes.push('fc-resizing');
7839                 }
7840             }
7841             return classes;
7842         };
7843         // Compute the text that should be displayed on an event's element.
7844         // `range` can be the Event object itself, or something range-like, with at least a `start`.
7845         // If event times are disabled, or the event has no time, will return a blank string.
7846         // If not specified, formatter will default to the eventTimeFormat setting,
7847         // and displayEnd will default to the displayEventEnd setting.
7848         FgEventRenderer.prototype.getTimeText = function (eventRange, formatter, displayEnd) {
7849             var def = eventRange.def, instance = eventRange.instance;
7850             return this._getTimeText(instance.range.start, def.hasEnd ? instance.range.end : null, def.allDay, formatter, displayEnd, instance.forcedStartTzo, instance.forcedEndTzo);
7851         };
7852         FgEventRenderer.prototype._getTimeText = function (start, end, allDay, formatter, displayEnd, forcedStartTzo, forcedEndTzo) {
7853             var dateEnv = this.context.dateEnv;
7854             if (formatter == null) {
7855                 formatter = this.eventTimeFormat;
7856             }
7857             if (displayEnd == null) {
7858                 displayEnd = this.displayEventEnd;
7859             }
7860             if (this.displayEventTime && !allDay) {
7861                 if (displayEnd && end) {
7862                     return dateEnv.formatRange(start, end, formatter, {
7863                         forcedStartTzo: forcedStartTzo,
7864                         forcedEndTzo: forcedEndTzo
7865                     });
7866                 }
7867                 else {
7868                     return dateEnv.format(start, formatter, {
7869                         forcedTzo: forcedStartTzo
7870                     });
7871                 }
7872             }
7873             return '';
7874         };
7875         FgEventRenderer.prototype.computeEventTimeFormat = function () {
7876             return {
7877                 hour: 'numeric',
7878                 minute: '2-digit',
7879                 omitZeroMinute: true
7880             };
7881         };
7882         FgEventRenderer.prototype.computeDisplayEventTime = function () {
7883             return true;
7884         };
7885         FgEventRenderer.prototype.computeDisplayEventEnd = function () {
7886             return true;
7887         };
7888         // Utility for generating event skin-related CSS properties
7889         FgEventRenderer.prototype.getSkinCss = function (ui) {
7890             return {
7891                 'background-color': ui.backgroundColor,
7892                 'border-color': ui.borderColor,
7893                 color: ui.textColor
7894             };
7895         };
7896         FgEventRenderer.prototype.sortEventSegs = function (segs) {
7897             var specs = this.context.view.eventOrderSpecs;
7898             var objs = segs.map(buildSegCompareObj);
7899             objs.sort(function (obj0, obj1) {
7900                 return compareByFieldSpecs(obj0, obj1, specs);
7901             });
7902             return objs.map(function (c) {
7903                 return c._seg;
7904             });
7905         };
7906         FgEventRenderer.prototype.computeSizes = function (force) {
7907             if (force || this.isSizeDirty) {
7908                 this.computeSegSizes(this.segs);
7909             }
7910         };
7911         FgEventRenderer.prototype.assignSizes = function (force) {
7912             if (force || this.isSizeDirty) {
7913                 this.assignSegSizes(this.segs);
7914                 this.isSizeDirty = false;
7915             }
7916         };
7917         FgEventRenderer.prototype.computeSegSizes = function (segs) {
7918         };
7919         FgEventRenderer.prototype.assignSegSizes = function (segs) {
7920         };
7921         // Manipulation on rendered segs
7922         FgEventRenderer.prototype.hideByHash = function (hash) {
7923             if (hash) {
7924                 for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
7925                     var seg = _a[_i];
7926                     if (hash[seg.eventRange.instance.instanceId]) {
7927                         seg.el.style.visibility = 'hidden';
7928                     }
7929                 }
7930             }
7931         };
7932         FgEventRenderer.prototype.showByHash = function (hash) {
7933             if (hash) {
7934                 for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
7935                     var seg = _a[_i];
7936                     if (hash[seg.eventRange.instance.instanceId]) {
7937                         seg.el.style.visibility = '';
7938                     }
7939                 }
7940             }
7941         };
7942         FgEventRenderer.prototype.selectByInstanceId = function (instanceId) {
7943             if (instanceId) {
7944                 for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
7945                     var seg = _a[_i];
7946                     var eventInstance = seg.eventRange.instance;
7947                     if (eventInstance && eventInstance.instanceId === instanceId &&
7948                         seg.el // necessary?
7949                     ) {
7950                         seg.el.classList.add('fc-selected');
7951                     }
7952                 }
7953             }
7954         };
7955         FgEventRenderer.prototype.unselectByInstanceId = function (instanceId) {
7956             if (instanceId) {
7957                 for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
7958                     var seg = _a[_i];
7959                     if (seg.el) { // necessary?
7960                         seg.el.classList.remove('fc-selected');
7961                     }
7962                 }
7963             }
7964         };
7965         return FgEventRenderer;
7966     }());
7967     // returns a object with all primitive props that can be compared
7968     function buildSegCompareObj(seg) {
7969         var eventDef = seg.eventRange.def;
7970         var range = seg.eventRange.instance.range;
7971         var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
7972         var end = range.end ? range.end.valueOf() : 0; // "
7973         return __assign({}, eventDef.extendedProps, eventDef, { id: eventDef.publicId, start: start,
7974             end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg // for later retrieval
7975          });
7976     }
7977
7978     var FillRenderer = /** @class */ (function () {
7979         function FillRenderer(context) {
7980             this.fillSegTag = 'div';
7981             this.dirtySizeFlags = {};
7982             this.context = context;
7983             this.containerElsByType = {};
7984             this.segsByType = {};
7985         }
7986         FillRenderer.prototype.getSegsByType = function (type) {
7987             return this.segsByType[type] || [];
7988         };
7989         FillRenderer.prototype.renderSegs = function (type, segs) {
7990             var _a;
7991             var renderedSegs = this.renderSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs
7992             var containerEls = this.attachSegs(type, renderedSegs);
7993             if (containerEls) {
7994                 (_a = (this.containerElsByType[type] || (this.containerElsByType[type] = []))).push.apply(_a, containerEls);
7995             }
7996             this.segsByType[type] = renderedSegs;
7997             if (type === 'bgEvent') {
7998                 this.context.view.triggerRenderedSegs(renderedSegs, false); // isMirror=false
7999             }
8000             this.dirtySizeFlags[type] = true;
8001         };
8002         // Unrenders a specific type of fill that is currently rendered on the grid
8003         FillRenderer.prototype.unrender = function (type) {
8004             var segs = this.segsByType[type];
8005             if (segs) {
8006                 if (type === 'bgEvent') {
8007                     this.context.view.triggerWillRemoveSegs(segs, false); // isMirror=false
8008                 }
8009                 this.detachSegs(type, segs);
8010             }
8011         };
8012         // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
8013         // Only returns segments that successfully rendered.
8014         FillRenderer.prototype.renderSegEls = function (type, segs) {
8015             var _this = this;
8016             var html = '';
8017             var i;
8018             if (segs.length) {
8019                 // build a large concatenation of segment HTML
8020                 for (i = 0; i < segs.length; i++) {
8021                     html += this.renderSegHtml(type, segs[i]);
8022                 }
8023                 // Grab individual elements from the combined HTML string. Use each as the default rendering.
8024                 // Then, compute the 'el' for each segment.
8025                 htmlToElements(html).forEach(function (el, i) {
8026                     var seg = segs[i];
8027                     if (el) {
8028                         seg.el = el;
8029                     }
8030                 });
8031                 if (type === 'bgEvent') {
8032                     segs = filterSegsViaEls(this.context.view, segs, false // isMirror. background events can never be mirror elements
8033                     );
8034                 }
8035                 // correct element type? (would be bad if a non-TD were inserted into a table for example)
8036                 segs = segs.filter(function (seg) {
8037                     return elementMatches(seg.el, _this.fillSegTag);
8038                 });
8039             }
8040             return segs;
8041         };
8042         // Builds the HTML needed for one fill segment. Generic enough to work with different types.
8043         FillRenderer.prototype.renderSegHtml = function (type, seg) {
8044             var css = null;
8045             var classNames = [];
8046             if (type !== 'highlight' && type !== 'businessHours') {
8047                 css = {
8048                     'background-color': seg.eventRange.ui.backgroundColor
8049                 };
8050             }
8051             if (type !== 'highlight') {
8052                 classNames = classNames.concat(seg.eventRange.ui.classNames);
8053             }
8054             if (type === 'businessHours') {
8055                 classNames.push('fc-bgevent');
8056             }
8057             else {
8058                 classNames.push('fc-' + type.toLowerCase());
8059             }
8060             return '<' + this.fillSegTag +
8061                 (classNames.length ? ' class="' + classNames.join(' ') + '"' : '') +
8062                 (css ? ' style="' + cssToStr(css) + '"' : '') +
8063                 '></' + this.fillSegTag + '>';
8064         };
8065         FillRenderer.prototype.detachSegs = function (type, segs) {
8066             var containerEls = this.containerElsByType[type];
8067             if (containerEls) {
8068                 containerEls.forEach(removeElement);
8069                 delete this.containerElsByType[type];
8070             }
8071         };
8072         FillRenderer.prototype.computeSizes = function (force) {
8073             for (var type in this.segsByType) {
8074                 if (force || this.dirtySizeFlags[type]) {
8075                     this.computeSegSizes(this.segsByType[type]);
8076                 }
8077             }
8078         };
8079         FillRenderer.prototype.assignSizes = function (force) {
8080             for (var type in this.segsByType) {
8081                 if (force || this.dirtySizeFlags[type]) {
8082                     this.assignSegSizes(this.segsByType[type]);
8083                 }
8084             }
8085             this.dirtySizeFlags = {};
8086         };
8087         FillRenderer.prototype.computeSegSizes = function (segs) {
8088         };
8089         FillRenderer.prototype.assignSegSizes = function (segs) {
8090         };
8091         return FillRenderer;
8092     }());
8093
8094     var NamedTimeZoneImpl = /** @class */ (function () {
8095         function NamedTimeZoneImpl(timeZoneName) {
8096             this.timeZoneName = timeZoneName;
8097         }
8098         return NamedTimeZoneImpl;
8099     }());
8100
8101     /*
8102     An abstraction for a dragging interaction originating on an event.
8103     Does higher-level things than PointerDragger, such as possibly:
8104     - a "mirror" that moves with the pointer
8105     - a minimum number of pixels or other criteria for a true drag to begin
8106
8107     subclasses must emit:
8108     - pointerdown
8109     - dragstart
8110     - dragmove
8111     - pointerup
8112     - dragend
8113     */
8114     var ElementDragging = /** @class */ (function () {
8115         function ElementDragging(el) {
8116             this.emitter = new EmitterMixin();
8117         }
8118         ElementDragging.prototype.destroy = function () {
8119         };
8120         ElementDragging.prototype.setMirrorIsVisible = function (bool) {
8121             // optional if subclass doesn't want to support a mirror
8122         };
8123         ElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
8124             // optional if subclass doesn't want to support a mirror
8125         };
8126         ElementDragging.prototype.setAutoScrollEnabled = function (bool) {
8127             // optional
8128         };
8129         return ElementDragging;
8130     }());
8131
8132     function formatDate(dateInput, settings) {
8133         if (settings === void 0) { settings = {}; }
8134         var dateEnv = buildDateEnv$1(settings);
8135         var formatter = createFormatter(settings);
8136         var dateMeta = dateEnv.createMarkerMeta(dateInput);
8137         if (!dateMeta) { // TODO: warning?
8138             return '';
8139         }
8140         return dateEnv.format(dateMeta.marker, formatter, {
8141             forcedTzo: dateMeta.forcedTzo
8142         });
8143     }
8144     function formatRange(startInput, endInput, settings // mixture of env and formatter settings
8145     ) {
8146         var dateEnv = buildDateEnv$1(typeof settings === 'object' && settings ? settings : {}); // pass in if non-null object
8147         var formatter = createFormatter(settings, globalDefaults.defaultRangeSeparator);
8148         var startMeta = dateEnv.createMarkerMeta(startInput);
8149         var endMeta = dateEnv.createMarkerMeta(endInput);
8150         if (!startMeta || !endMeta) { // TODO: warning?
8151             return '';
8152         }
8153         return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
8154             forcedStartTzo: startMeta.forcedTzo,
8155             forcedEndTzo: endMeta.forcedTzo,
8156             isEndExclusive: settings.isEndExclusive
8157         });
8158     }
8159     // TODO: more DRY and optimized
8160     function buildDateEnv$1(settings) {
8161         var locale = buildLocale(settings.locale || 'en', parseRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
8162         // ensure required settings
8163         settings = __assign({ timeZone: globalDefaults.timeZone, calendarSystem: 'gregory' }, settings, { locale: locale });
8164         return new DateEnv(settings);
8165     }
8166
8167     var DRAG_META_PROPS = {
8168         startTime: createDuration,
8169         duration: createDuration,
8170         create: Boolean,
8171         sourceId: String
8172     };
8173     var DRAG_META_DEFAULTS = {
8174         create: true
8175     };
8176     function parseDragMeta(raw) {
8177         var leftoverProps = {};
8178         var refined = refineProps(raw, DRAG_META_PROPS, DRAG_META_DEFAULTS, leftoverProps);
8179         refined.leftoverProps = leftoverProps;
8180         return refined;
8181     }
8182
8183     // Computes a default column header formatting string if `colFormat` is not explicitly defined
8184     function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
8185         // if more than one week row, or if there are a lot of columns with not much space,
8186         // put just the day numbers will be in each cell
8187         if (!datesRepDistinctDays || dayCnt > 10) {
8188             return { weekday: 'short' }; // "Sat"
8189         }
8190         else if (dayCnt > 1) {
8191             return { weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }; // "Sat 11/12"
8192         }
8193         else {
8194             return { weekday: 'long' }; // "Saturday"
8195         }
8196     }
8197     function renderDateCell(dateMarker, dateProfile, datesRepDistinctDays, colCnt, colHeadFormat, context, colspan, otherAttrs) {
8198         var view = context.view, dateEnv = context.dateEnv, theme = context.theme, options = context.options;
8199         var isDateValid = rangeContainsMarker(dateProfile.activeRange, dateMarker); // TODO: called too frequently. cache somehow.
8200         var classNames = [
8201             'fc-day-header',
8202             theme.getClass('widgetHeader')
8203         ];
8204         var innerHtml;
8205         if (typeof options.columnHeaderHtml === 'function') {
8206             innerHtml = options.columnHeaderHtml(dateEnv.toDate(dateMarker));
8207         }
8208         else if (typeof options.columnHeaderText === 'function') {
8209             innerHtml = htmlEscape(options.columnHeaderText(dateEnv.toDate(dateMarker)));
8210         }
8211         else {
8212             innerHtml = htmlEscape(dateEnv.format(dateMarker, colHeadFormat));
8213         }
8214         // if only one row of days, the classNames on the header can represent the specific days beneath
8215         if (datesRepDistinctDays) {
8216             classNames = classNames.concat(
8217             // includes the day-of-week class
8218             // noThemeHighlight=true (don't highlight the header)
8219             getDayClasses(dateMarker, dateProfile, context, true));
8220         }
8221         else {
8222             classNames.push('fc-' + DAY_IDS[dateMarker.getUTCDay()]); // only add the day-of-week class
8223         }
8224         return '' +
8225             '<th class="' + classNames.join(' ') + '"' +
8226             ((isDateValid && datesRepDistinctDays) ?
8227                 ' data-date="' + dateEnv.formatIso(dateMarker, { omitTime: true }) + '"' :
8228                 '') +
8229             (colspan > 1 ?
8230                 ' colspan="' + colspan + '"' :
8231                 '') +
8232             (otherAttrs ?
8233                 ' ' + otherAttrs :
8234                 '') +
8235             '>' +
8236             (isDateValid ?
8237                 // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff)
8238                 buildGotoAnchorHtml(view, { date: dateMarker, forceOff: !datesRepDistinctDays || colCnt === 1 }, innerHtml) :
8239                 // if not valid, display text, but no link
8240                 innerHtml) +
8241             '</th>';
8242     }
8243
8244     var DayHeader = /** @class */ (function (_super) {
8245         __extends(DayHeader, _super);
8246         function DayHeader(context, parentEl) {
8247             var _this = _super.call(this, context) || this;
8248             parentEl.innerHTML = ''; // because might be nbsp
8249             parentEl.appendChild(_this.el = htmlToElement('<div class="fc-row ' + _this.theme.getClass('headerRow') + '">' +
8250                 '<table class="' + _this.theme.getClass('tableGrid') + '">' +
8251                 '<thead></thead>' +
8252                 '</table>' +
8253                 '</div>'));
8254             _this.thead = _this.el.querySelector('thead');
8255             return _this;
8256         }
8257         DayHeader.prototype.destroy = function () {
8258             removeElement(this.el);
8259         };
8260         DayHeader.prototype.render = function (props) {
8261             var dates = props.dates, datesRepDistinctDays = props.datesRepDistinctDays;
8262             var parts = [];
8263             if (props.renderIntroHtml) {
8264                 parts.push(props.renderIntroHtml());
8265             }
8266             var colHeadFormat = createFormatter(this.opt('columnHeaderFormat') ||
8267                 computeFallbackHeaderFormat(datesRepDistinctDays, dates.length));
8268             for (var _i = 0, dates_1 = dates; _i < dates_1.length; _i++) {
8269                 var date = dates_1[_i];
8270                 parts.push(renderDateCell(date, props.dateProfile, datesRepDistinctDays, dates.length, colHeadFormat, this.context));
8271             }
8272             if (this.isRtl) {
8273                 parts.reverse();
8274             }
8275             this.thead.innerHTML = '<tr>' + parts.join('') + '</tr>';
8276         };
8277         return DayHeader;
8278     }(Component));
8279
8280     var DaySeries = /** @class */ (function () {
8281         function DaySeries(range, dateProfileGenerator) {
8282             var date = range.start;
8283             var end = range.end;
8284             var indices = [];
8285             var dates = [];
8286             var dayIndex = -1;
8287             while (date < end) { // loop each day from start to end
8288                 if (dateProfileGenerator.isHiddenDay(date)) {
8289                     indices.push(dayIndex + 0.5); // mark that it's between indices
8290                 }
8291                 else {
8292                     dayIndex++;
8293                     indices.push(dayIndex);
8294                     dates.push(date);
8295                 }
8296                 date = addDays(date, 1);
8297             }
8298             this.dates = dates;
8299             this.indices = indices;
8300             this.cnt = dates.length;
8301         }
8302         DaySeries.prototype.sliceRange = function (range) {
8303             var firstIndex = this.getDateDayIndex(range.start); // inclusive first index
8304             var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
8305             var clippedFirstIndex = Math.max(0, firstIndex);
8306             var clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
8307             // deal with in-between indices
8308             clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
8309             clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
8310             if (clippedFirstIndex <= clippedLastIndex) {
8311                 return {
8312                     firstIndex: clippedFirstIndex,
8313                     lastIndex: clippedLastIndex,
8314                     isStart: firstIndex === clippedFirstIndex,
8315                     isEnd: lastIndex === clippedLastIndex
8316                 };
8317             }
8318             else {
8319                 return null;
8320             }
8321         };
8322         // Given a date, returns its chronolocial cell-index from the first cell of the grid.
8323         // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
8324         // If before the first offset, returns a negative number.
8325         // If after the last offset, returns an offset past the last cell offset.
8326         // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
8327         DaySeries.prototype.getDateDayIndex = function (date) {
8328             var indices = this.indices;
8329             var dayOffset = Math.floor(diffDays(this.dates[0], date));
8330             if (dayOffset < 0) {
8331                 return indices[0] - 1;
8332             }
8333             else if (dayOffset >= indices.length) {
8334                 return indices[indices.length - 1] + 1;
8335             }
8336             else {
8337                 return indices[dayOffset];
8338             }
8339         };
8340         return DaySeries;
8341     }());
8342
8343     var DayTable = /** @class */ (function () {
8344         function DayTable(daySeries, breakOnWeeks) {
8345             var dates = daySeries.dates;
8346             var daysPerRow;
8347             var firstDay;
8348             var rowCnt;
8349             if (breakOnWeeks) {
8350                 // count columns until the day-of-week repeats
8351                 firstDay = dates[0].getUTCDay();
8352                 for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow++) {
8353                     if (dates[daysPerRow].getUTCDay() === firstDay) {
8354                         break;
8355                     }
8356                 }
8357                 rowCnt = Math.ceil(dates.length / daysPerRow);
8358             }
8359             else {
8360                 rowCnt = 1;
8361                 daysPerRow = dates.length;
8362             }
8363             this.rowCnt = rowCnt;
8364             this.colCnt = daysPerRow;
8365             this.daySeries = daySeries;
8366             this.cells = this.buildCells();
8367             this.headerDates = this.buildHeaderDates();
8368         }
8369         DayTable.prototype.buildCells = function () {
8370             var rows = [];
8371             for (var row = 0; row < this.rowCnt; row++) {
8372                 var cells = [];
8373                 for (var col = 0; col < this.colCnt; col++) {
8374                     cells.push(this.buildCell(row, col));
8375                 }
8376                 rows.push(cells);
8377             }
8378             return rows;
8379         };
8380         DayTable.prototype.buildCell = function (row, col) {
8381             return {
8382                 date: this.daySeries.dates[row * this.colCnt + col]
8383             };
8384         };
8385         DayTable.prototype.buildHeaderDates = function () {
8386             var dates = [];
8387             for (var col = 0; col < this.colCnt; col++) {
8388                 dates.push(this.cells[0][col].date);
8389             }
8390             return dates;
8391         };
8392         DayTable.prototype.sliceRange = function (range) {
8393             var colCnt = this.colCnt;
8394             var seriesSeg = this.daySeries.sliceRange(range);
8395             var segs = [];
8396             if (seriesSeg) {
8397                 var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex;
8398                 var index = firstIndex;
8399                 while (index <= lastIndex) {
8400                     var row = Math.floor(index / colCnt);
8401                     var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
8402                     segs.push({
8403                         row: row,
8404                         firstCol: index % colCnt,
8405                         lastCol: (nextIndex - 1) % colCnt,
8406                         isStart: seriesSeg.isStart && index === firstIndex,
8407                         isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex
8408                     });
8409                     index = nextIndex;
8410                 }
8411             }
8412             return segs;
8413         };
8414         return DayTable;
8415     }());
8416
8417     var Slicer = /** @class */ (function () {
8418         function Slicer() {
8419             this.sliceBusinessHours = memoize(this._sliceBusinessHours);
8420             this.sliceDateSelection = memoize(this._sliceDateSpan);
8421             this.sliceEventStore = memoize(this._sliceEventStore);
8422             this.sliceEventDrag = memoize(this._sliceInteraction);
8423             this.sliceEventResize = memoize(this._sliceInteraction);
8424         }
8425         Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, component) {
8426             var extraArgs = [];
8427             for (var _i = 4; _i < arguments.length; _i++) {
8428                 extraArgs[_i - 4] = arguments[_i];
8429             }
8430             var eventUiBases = props.eventUiBases;
8431             var eventSegs = this.sliceEventStore.apply(this, [props.eventStore, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs));
8432             return {
8433                 dateSelectionSegs: this.sliceDateSelection.apply(this, [props.dateSelection, eventUiBases, component].concat(extraArgs)),
8434                 businessHourSegs: this.sliceBusinessHours.apply(this, [props.businessHours, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8435                 fgEventSegs: eventSegs.fg,
8436                 bgEventSegs: eventSegs.bg,
8437                 eventDrag: this.sliceEventDrag.apply(this, [props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8438                 eventResize: this.sliceEventResize.apply(this, [props.eventResize, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8439                 eventSelection: props.eventSelection
8440             }; // TODO: give interactionSegs?
8441         };
8442         Slicer.prototype.sliceNowDate = function (// does not memoize
8443         date, component) {
8444             var extraArgs = [];
8445             for (var _i = 2; _i < arguments.length; _i++) {
8446                 extraArgs[_i - 2] = arguments[_i];
8447             }
8448             return this._sliceDateSpan.apply(this, [{ range: { start: date, end: addMs(date, 1) }, allDay: false },
8449                 {},
8450                 component].concat(extraArgs));
8451         };
8452         Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, component) {
8453             var extraArgs = [];
8454             for (var _i = 4; _i < arguments.length; _i++) {
8455                 extraArgs[_i - 4] = arguments[_i];
8456             }
8457             if (!businessHours) {
8458                 return [];
8459             }
8460             return this._sliceEventStore.apply(this, [expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), component.calendar),
8461                 {},
8462                 dateProfile,
8463                 nextDayThreshold,
8464                 component].concat(extraArgs)).bg;
8465         };
8466         Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold, component) {
8467             var extraArgs = [];
8468             for (var _i = 5; _i < arguments.length; _i++) {
8469                 extraArgs[_i - 5] = arguments[_i];
8470             }
8471             if (eventStore) {
8472                 var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8473                 return {
8474                     bg: this.sliceEventRanges(rangeRes.bg, component, extraArgs),
8475                     fg: this.sliceEventRanges(rangeRes.fg, component, extraArgs)
8476                 };
8477             }
8478             else {
8479                 return { bg: [], fg: [] };
8480             }
8481         };
8482         Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold, component) {
8483             var extraArgs = [];
8484             for (var _i = 5; _i < arguments.length; _i++) {
8485                 extraArgs[_i - 5] = arguments[_i];
8486             }
8487             if (!interaction) {
8488                 return null;
8489             }
8490             var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8491             return {
8492                 segs: this.sliceEventRanges(rangeRes.fg, component, extraArgs),
8493                 affectedInstances: interaction.affectedEvents.instances,
8494                 isEvent: interaction.isEvent,
8495                 sourceSeg: interaction.origSeg
8496             };
8497         };
8498         Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, component) {
8499             var extraArgs = [];
8500             for (var _i = 3; _i < arguments.length; _i++) {
8501                 extraArgs[_i - 3] = arguments[_i];
8502             }
8503             if (!dateSpan) {
8504                 return [];
8505             }
8506             var eventRange = fabricateEventRange(dateSpan, eventUiBases, component.calendar);
8507             var segs = this.sliceRange.apply(this, [dateSpan.range].concat(extraArgs));
8508             for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) {
8509                 var seg = segs_1[_a];
8510                 seg.component = component;
8511                 seg.eventRange = eventRange;
8512             }
8513             return segs;
8514         };
8515         /*
8516         "complete" seg means it has component and eventRange
8517         */
8518         Slicer.prototype.sliceEventRanges = function (eventRanges, component, // TODO: kill
8519         extraArgs) {
8520             var segs = [];
8521             for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
8522                 var eventRange = eventRanges_1[_i];
8523                 segs.push.apply(segs, this.sliceEventRange(eventRange, component, extraArgs));
8524             }
8525             return segs;
8526         };
8527         /*
8528         "complete" seg means it has component and eventRange
8529         */
8530         Slicer.prototype.sliceEventRange = function (eventRange, component, // TODO: kill
8531         extraArgs) {
8532             var segs = this.sliceRange.apply(this, [eventRange.range].concat(extraArgs));
8533             for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
8534                 var seg = segs_2[_i];
8535                 seg.component = component;
8536                 seg.eventRange = eventRange;
8537                 seg.isStart = eventRange.isStart && seg.isStart;
8538                 seg.isEnd = eventRange.isEnd && seg.isEnd;
8539             }
8540             return segs;
8541         };
8542         return Slicer;
8543     }());
8544     /*
8545     for incorporating minTime/maxTime if appropriate
8546     TODO: should be part of DateProfile!
8547     TimelineDateProfile already does this btw
8548     */
8549     function computeActiveRange(dateProfile, isComponentAllDay) {
8550         var range = dateProfile.activeRange;
8551         if (isComponentAllDay) {
8552             return range;
8553         }
8554         return {
8555             start: addMs(range.start, dateProfile.minTime.milliseconds),
8556             end: addMs(range.end, dateProfile.maxTime.milliseconds - 864e5) // 864e5 = ms in a day
8557         };
8558     }
8559
8560     // exports
8561     // --------------------------------------------------------------------------------------------------
8562     var version = '4.3.1';
8563
8564     exports.Calendar = Calendar;
8565     exports.Component = Component;
8566     exports.DateComponent = DateComponent;
8567     exports.DateEnv = DateEnv;
8568     exports.DateProfileGenerator = DateProfileGenerator;
8569     exports.DayHeader = DayHeader;
8570     exports.DaySeries = DaySeries;
8571     exports.DayTable = DayTable;
8572     exports.ElementDragging = ElementDragging;
8573     exports.ElementScrollController = ElementScrollController;
8574     exports.EmitterMixin = EmitterMixin;
8575     exports.EventApi = EventApi;
8576     exports.FgEventRenderer = FgEventRenderer;
8577     exports.FillRenderer = FillRenderer;
8578     exports.Interaction = Interaction;
8579     exports.Mixin = Mixin;
8580     exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
8581     exports.PositionCache = PositionCache;
8582     exports.ScrollComponent = ScrollComponent;
8583     exports.ScrollController = ScrollController;
8584     exports.Slicer = Slicer;
8585     exports.Splitter = Splitter;
8586     exports.Theme = Theme;
8587     exports.View = View;
8588     exports.WindowScrollController = WindowScrollController;
8589     exports.addDays = addDays;
8590     exports.addDurations = addDurations;
8591     exports.addMs = addMs;
8592     exports.addWeeks = addWeeks;
8593     exports.allowContextMenu = allowContextMenu;
8594     exports.allowSelection = allowSelection;
8595     exports.appendToElement = appendToElement;
8596     exports.applyAll = applyAll;
8597     exports.applyMutationToEventStore = applyMutationToEventStore;
8598     exports.applyStyle = applyStyle;
8599     exports.applyStyleProp = applyStyleProp;
8600     exports.asRoughMinutes = asRoughMinutes;
8601     exports.asRoughMs = asRoughMs;
8602     exports.asRoughSeconds = asRoughSeconds;
8603     exports.buildGotoAnchorHtml = buildGotoAnchorHtml;
8604     exports.buildSegCompareObj = buildSegCompareObj;
8605     exports.capitaliseFirstLetter = capitaliseFirstLetter;
8606     exports.combineEventUis = combineEventUis;
8607     exports.compareByFieldSpec = compareByFieldSpec;
8608     exports.compareByFieldSpecs = compareByFieldSpecs;
8609     exports.compareNumbers = compareNumbers;
8610     exports.compensateScroll = compensateScroll;
8611     exports.computeClippingRect = computeClippingRect;
8612     exports.computeEdges = computeEdges;
8613     exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat;
8614     exports.computeHeightAndMargins = computeHeightAndMargins;
8615     exports.computeInnerRect = computeInnerRect;
8616     exports.computeRect = computeRect;
8617     exports.computeVisibleDayRange = computeVisibleDayRange;
8618     exports.config = config;
8619     exports.constrainPoint = constrainPoint;
8620     exports.createDuration = createDuration;
8621     exports.createElement = createElement;
8622     exports.createEmptyEventStore = createEmptyEventStore;
8623     exports.createEventInstance = createEventInstance;
8624     exports.createFormatter = createFormatter;
8625     exports.createPlugin = createPlugin;
8626     exports.cssToStr = cssToStr;
8627     exports.debounce = debounce;
8628     exports.diffDates = diffDates;
8629     exports.diffDayAndTime = diffDayAndTime;
8630     exports.diffDays = diffDays;
8631     exports.diffPoints = diffPoints;
8632     exports.diffWeeks = diffWeeks;
8633     exports.diffWholeDays = diffWholeDays;
8634     exports.diffWholeWeeks = diffWholeWeeks;
8635     exports.disableCursor = disableCursor;
8636     exports.distributeHeight = distributeHeight;
8637     exports.elementClosest = elementClosest;
8638     exports.elementMatches = elementMatches;
8639     exports.enableCursor = enableCursor;
8640     exports.eventTupleToStore = eventTupleToStore;
8641     exports.filterEventStoreDefs = filterEventStoreDefs;
8642     exports.filterHash = filterHash;
8643     exports.findChildren = findChildren;
8644     exports.findElements = findElements;
8645     exports.flexibleCompare = flexibleCompare;
8646     exports.forceClassName = forceClassName;
8647     exports.formatDate = formatDate;
8648     exports.formatIsoTimeString = formatIsoTimeString;
8649     exports.formatRange = formatRange;
8650     exports.getAllDayHtml = getAllDayHtml;
8651     exports.getClippingParents = getClippingParents;
8652     exports.getDayClasses = getDayClasses;
8653     exports.getElSeg = getElSeg;
8654     exports.getRectCenter = getRectCenter;
8655     exports.getRelevantEvents = getRelevantEvents;
8656     exports.globalDefaults = globalDefaults;
8657     exports.greatestDurationDenominator = greatestDurationDenominator;
8658     exports.hasBgRendering = hasBgRendering;
8659     exports.htmlEscape = htmlEscape;
8660     exports.htmlToElement = htmlToElement;
8661     exports.insertAfterElement = insertAfterElement;
8662     exports.interactionSettingsStore = interactionSettingsStore;
8663     exports.interactionSettingsToStore = interactionSettingsToStore;
8664     exports.intersectRanges = intersectRanges;
8665     exports.intersectRects = intersectRects;
8666     exports.isArraysEqual = isArraysEqual;
8667     exports.isDateSpansEqual = isDateSpansEqual;
8668     exports.isInt = isInt;
8669     exports.isInteractionValid = isInteractionValid;
8670     exports.isMultiDayRange = isMultiDayRange;
8671     exports.isPropsEqual = isPropsEqual;
8672     exports.isPropsValid = isPropsValid;
8673     exports.isSingleDay = isSingleDay;
8674     exports.isValidDate = isValidDate;
8675     exports.listenBySelector = listenBySelector;
8676     exports.mapHash = mapHash;
8677     exports.matchCellWidths = matchCellWidths;
8678     exports.memoize = memoize;
8679     exports.memoizeOutput = memoizeOutput;
8680     exports.memoizeRendering = memoizeRendering;
8681     exports.mergeEventStores = mergeEventStores;
8682     exports.multiplyDuration = multiplyDuration;
8683     exports.padStart = padStart;
8684     exports.parseBusinessHours = parseBusinessHours;
8685     exports.parseDragMeta = parseDragMeta;
8686     exports.parseEventDef = parseEventDef;
8687     exports.parseFieldSpecs = parseFieldSpecs;
8688     exports.parseMarker = parse;
8689     exports.pointInsideRect = pointInsideRect;
8690     exports.prependToElement = prependToElement;
8691     exports.preventContextMenu = preventContextMenu;
8692     exports.preventDefault = preventDefault;
8693     exports.preventSelection = preventSelection;
8694     exports.processScopedUiProps = processScopedUiProps;
8695     exports.rangeContainsMarker = rangeContainsMarker;
8696     exports.rangeContainsRange = rangeContainsRange;
8697     exports.rangesEqual = rangesEqual;
8698     exports.rangesIntersect = rangesIntersect;
8699     exports.refineProps = refineProps;
8700     exports.removeElement = removeElement;
8701     exports.removeExact = removeExact;
8702     exports.renderDateCell = renderDateCell;
8703     exports.requestJson = requestJson;
8704     exports.sliceEventStore = sliceEventStore;
8705     exports.startOfDay = startOfDay;
8706     exports.subtractInnerElHeight = subtractInnerElHeight;
8707     exports.translateRect = translateRect;
8708     exports.uncompensateScroll = uncompensateScroll;
8709     exports.undistributeHeight = undistributeHeight;
8710     exports.unpromisify = unpromisify;
8711     exports.version = version;
8712     exports.whenTransitionDone = whenTransitionDone;
8713     exports.wholeDivideDurations = wholeDivideDurations;
8714
8715     Object.defineProperty(exports, '__esModule', { value: true });
8716
8717 }));