PageSourceSearch

https://m.seesaw.land/lib/fullcalendar-4.4.0/packages/core/main.js

js seesaw.land collected 2026-10-02 02:00:11 UTC 373,202 bytes, 8,740 lines download raw bytes

1/*!
2FullCalendar Core Package v4.4.0
3Docs & 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 >
193= 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");
1135 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, biggestUnitForParti
1644al);
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(context, segs, isMirror) {
2396        var calendar = context.calendar, view = context.view;
2397        if (calendar.hasPublicHandlers('eventRender')) {
2398            segs = segs.filter(function (seg) {
2399                var custom = calendar.publiclyTrigger('eventRender', [
2400                    {
2401                        event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
2402                        isMirror: isMirror,
2403                        isStart: seg.isStart,
2404                        isEnd: seg.isEnd,
2405                        // TODO: include seg.range once all components consistently generate it
2406                        el: seg.el,
2407                        view: view
2408                    }
2409                ]);
2410                if (custom === false) { // means don't render at all
2411                    return false;
2412                }
2413                else if (custom && custom !== true) {
2414                    seg.el = custom;
2415                }
2416                return true;
2417            });
2418        }
2419        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
2420            var seg = segs_1[_i];
2421            setElSeg(seg.el, seg);
2422        }
2423        return segs;
2424    }
2425    function setElSeg(el, seg) {
2426        el.fcSeg = seg;
2427    }
2428    function getElSeg(el) {
2429        return el.fcSeg || null;
2430    }
2431    // event ui computation
2432    function compileEventUis(eventDefs, eventUiBases) {
2433        return mapHash(eventDefs, function (eventDef) {
2434            return compileEventUi(eventDef, eventUiBases);
2435        });
2436    }
2437    function compileEventUi(eventDef, eventUiBases) {
2438        var uis = [];
2439        if (eventUiBases['']) {
2440            uis.push(eventUiBases['']);
2441        }
2442        if (eventUiBases[eventDef.defId]) {
2443            uis.push(eventUiBases[eventDef.defId]);
2444        }
2445        uis.push(eventDef.ui);
2446        return combineEventUis(uis);
2447    }
2448    // triggers
2449    function triggerRenderedSegs(context, segs, isMirrors) {
2450        var calendar = context.calendar, view = context.view;
2451        if (calendar.hasPublicHandlers('eventPositioned')) {
2452            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
2453                var seg = segs_2[_i];
2454                calendar.publiclyTriggerAfterSizing('eventPositioned', [
2455                    {
2456                        event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
2457                        isMirror: isMirrors,
2458                        isStart: seg.isStart,
2459                        isEnd: seg.isEnd,
2460                        el: seg.el,
2461                        view: view
2462                    }
2463                ]);
2464            }
2465        }
2466        if (!calendar.state.loadingLevel) { // avoid initial empty state while pending
2467            calendar.afterSizingTriggers._eventsPositioned = [null]; // fire once
2468        }
2469    }
2470    function triggerWillRemoveSegs(context, segs, isMirrors) {
2471        var calendar = context.calendar, view = context.view;
2472        for (var _i = 0, segs_3 = segs; _i < segs_3.length; _i++) {
2473            var seg = segs_3[_i];
2474            calendar.trigger('eventElRemove', seg.el);
2475        }
2476        if (calendar.hasPublicHandlers('eventDestroy')) {
2477            for (var _a = 0, segs_4 = segs; _a < segs_4.length; _a++) {
2478                var seg = segs_4[_a];
2479                calendar.publiclyTrigger('eventDestroy', [
2480                    {
2481                        event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
2482                        isMirror: isMirrors,
2483                        el: seg.el,
2484                        view: view
2485                    }
2486                ]);
2487            }
2488        }
2489    }
2490    // is-interactable
2491    function computeEventDraggable(context, eventDef, eventUi) {
2492        var calendar = context.calendar, view = context.view;
2493        var transformers = calendar.pluginSystem.hooks.isDraggableTransformers;
2494        var val = eventUi.startEditable;
2495        for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
2496            var transformer = transformers_1[_i];
2497            val = transformer(val, eventDef, eventUi, view);
2498        }
2499        return val;
2500    }
2501    function computeEventStartResizable(context, eventDef, eventUi) {
2502        return eventUi.durationEditable && context.options.eventResizableFromStart;
2503    }
2504    function computeEventEndResizable(context, eventDef, eventUi) {
2505        return eventUi.durationEditable;
2506    }
2507
2508    // applies the mutation to ALL defs/instances within the event store
2509    function applyMutationToEventStore(eventStore, eventConfigBase, mutation, calendar) {
2510        var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
2511        var dest = createEmptyEventStore();
2512        for (var defId in eventStore.defs) {
2513            var def = eventStore.defs[defId];
2514            dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, calendar.pluginSystem.hooks.eventDefMutationAppliers, calendar);
2515        }
2516        for (var instanceId in eventStore.instances) {
2517            var instance = eventStore.instances[instanceId];
2518            var def = dest.defs[instance.defId]; // important to grab the newly modified def
2519            dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, calendar);
2520        }
2521        return dest;
2522    }
2523    function applyMutationToEventDef(eventDef, eventConfig, mutation, appliers, calendar) {
2524        var standardProps = mutation.standardProps || {};
2525        // if hasEnd has not been specified, guess a good value based on deltas.
2526        // if duration will change, there's no way the default duration will persist,
2527        // and thus, we need to mark the event as having a real end
2528        if (standardProps.hasEnd == null &&
2529            eventConfig.durationEditable &&
2530            (mutation.startDelta || mutation.endDelta)) {
2531            standardProps.hasEnd = true; // TODO: is this mutation okay?
2532        }
2533        var copy = __assign({}, eventDef, standardProps, { ui: __assign({}, eventDef.ui, standardProps.ui) });
2534        if (mutation.extendedProps) {
2535            copy.extendedProps = __assign({}, copy.extendedProps, mutation.extendedProps);
2536        }
2537        for (var _i = 0, appliers_1 = appliers; _i < appliers_1.length; _i++) {
2538            var applier = appliers_1[_i];
2539            applier(copy, mutation, calendar);
2540        }
2541        if (!copy.hasEnd && calendar.opt('forceEventDuration')) {
2542            copy.hasEnd = true;
2543        }
2544        return copy;
2545    }
2546    function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
2547    eventConfig, mutation, calendar) {
2548        var dateEnv = calendar.dateEnv;
2549        var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
2550        var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
2551        var copy = __assign({}, eventInstance);
2552        if (forceAllDay) {
2553            copy.range = computeAlignedDayRange(copy.range);
2554        }
2555        if (mutation.datesDelta && eventConfig.startEditable) {
2556            copy.range = {
2557                start: dateEnv.add(copy.range.start, mutation.datesDelta),
2558                end: dateEnv.add(copy.range.end, mutation.datesDelta)
2559            };
2560        }
2561        if (mutation.startDelta && eventConfig.durationEditable) {
2562            copy.range = {
2563                start: dateEnv.add(copy.range.start, mutation.startDelta),
2564                end: copy.range.end
2565            };
2566        }
2567        if (mutation.endDelta && eventConfig.durationEditable) {
2568            copy.range = {
2569                start: copy.range.start,
2570                end: dateEnv.add(copy.range.end, mutation.endDelta)
2571            };
2572        }
2573        if (clearEnd) {
2574            copy.range = {
2575                start: copy.range.start,
2576                end: calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start)
2577            };
2578        }
2579        // in case event was all-day but the supplied deltas were not
2580        // better util for this?
2581        if (eventDef.allDay) {
2582            copy.range = {
2583                start: startOfDay(copy.range.start),
2584                end: startOfDay(copy.range.end)
2585            };
2586        }
2587        // handle invalid durations
2588        if (copy.range.end < copy.range.start) {
2589            copy.range.end = calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start);
2590        }
2591        return copy;
2592    }
2593
2594    function reduceEventStore (eventStore, action, eventSources, dateProfile, calendar) {
2595        switch (action.type) {
2596            case 'RECEIVE_EVENTS': // raw
2597                return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, calendar);
2598            case 'ADD_EVENTS': // already parsed, but not expanded
2599                return addEvent(eventStore, action.eventStore, // new ones
2600                dateProfile ? dateProfile.activeRange : null, calendar);
2601            case 'MERGE_EVENTS': // already parsed and expanded
2602                return mergeEventStores(eventStore, action.eventStore);
2603            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
2604            case 'NEXT':
2605            case 'SET_DATE':
2606            case 'SET_VIEW_TYPE':
2607                if (dateProfile) {
2608                    return expandRecurring(eventStore, dateProfile.activeRange, calendar);
2609                }
2610                else {
2611                    return eventStore;
2612                }
2613            case 'CHANGE_TIMEZONE':
2614                return rezoneDates(eventStore, action.oldDateEnv, calendar.dateEnv);
2615            case 'MUTATE_EVENTS':
2616                return applyMutationToRelated(eventStore, action.instanceId, action.mutation, action.fromApi, calendar);
2617            case 'REMOVE_EVENT_INSTANCES':
2618                return excludeInstances(eventStore, action.instances);
2619            case 'REMOVE_EVENT_DEF':
2620                return filterEventStoreDefs(eventStore, function (eventDef) {
2621                    return eventDef.defId !== action.defId;
2622                });
2623            case 'REMOVE_EVENT_SOURCE':
2624                return excludeEventsBySourceId(eventStore, action.sourceId);
2625            case 'REMOVE_ALL_EVENT_SOURCES':
2626                return filterEventStoreDefs(eventStore, function (eventDef) {
2627                    return !eventDef.sourceId; // only keep events with no source id
2628                });
2629            case 'REMOVE_ALL_EVENTS':
2630                return createEmptyEventStore();
2631            case 'RESET_EVENTS':
2632                return {
2633                    defs: eventStore.defs,
2634                    instances: eventStore.instances
2635                };
2636            default:
2637                return eventStore;
2638        }
2639    }
2640    function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, calendar) {
2641        if (eventSource && // not already removed
2642            fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
2643        ) {
2644            var subset = parseEvents(transformRawEvents(rawEvents, eventSource, calendar), eventSource.sourceId, calendar);
2645            if (fetchRange) {
2646                subset = expandRecurring(subset, fetchRange, calendar);
2647            }
2648            return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
2649        }
2650        return eventStore;
2651    }
2652    function addEvent(eventStore, subset, expandRange, calendar) {
2653        if (expandRange) {
2654            subset = expandRecurring(subset, expandRange, calendar);
2655        }
2656        return mergeEventStores(eventStore, subset);
2657    }
2658    function rezoneDates(eventStore, oldDateEnv, newDateEnv) {
2659        var defs = eventStore.defs;
2660        var instances = mapHash(eventStore.instances, function (instance) {
2661            var def = defs[instance.defId];
2662            if (def.allDay || def.recurringDef) {
2663                return instance; // isn't dependent on timezone
2664            }
2665            else {
2666                return __assign({}, instance, { range: {
2667                        start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
2668                        end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo))
2669                    }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
2670            }
2671        });
2672        return { defs: defs, instances: instances };
2673    }
2674    function applyMutationToRelated(eventStore, instanceId, mutation, fromApi, calendar) {
2675        var relevant = getRelevantEvents(eventStore, instanceId);
2676        var eventConfigBase = fromApi ?
2677            { '': {
2678                    startEditable: true,
2679                    durationEditable: true,
2680                    constraints: [],
2681                    overlap: null,
2682                    allows: [],
2683                    backgroundColor: '',
2684                    borderColor: '',
2685                    textColor: '',
2686                    classNames: []
2687                } } :
2688            calendar.eventUiBases;
2689        relevant = applyMutationToEventStore(relevant, eventConfigBase, mutation, calendar);
2690        return mergeEventStores(eventStore, relevant);
2691    }
2692    function excludeEventsBySourceId(eventStore, sourceId) {
2693        return filterEventStoreDefs(eventStore, function (eventDef) {
2694            return eventDef.sourceId !== sourceId;
2695        });
2696    }
2697    // QUESTION: why not just return instances? do a general object-property-exclusion util
2698    function excludeInstances(eventStore, removals) {
2699        return {
2700            defs: eventStore.defs,
2701            instances: filterHash(eventStore.instances, function (instance) {
2702                return !removals[instance.instanceId];
2703            })
2704        };
2705    }
2706
2707    // high-level segmenting-aware tester functions
2708    // ------------------------------------------------------------------------------------------------------------------------
2709    function isInteractionValid(interaction, calendar) {
2710        return isNewPropsValid({ eventDrag: interaction }, calendar); // HACK: the eventDrag props is used for ALL interactions
2711    }
2712    function isDateSelectionValid(dateSelection, calendar) {
2713        return isNewPropsValid({ dateSelection: dateSelection }, calendar);
2714    }
2715    function isNewPropsValid(newProps, calendar) {
2716        var view = calendar.view;
2717        var props = __assign({ businessHours: view ? view.props.businessHours : createEmptyEventStore(), dateSelection: '', eventStore: calendar.state.eventStore, eventUiBases: calendar.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
2718        return (calendar.pluginSystem.hooks.isPropsValid || isPropsValid)(props, calendar);
2719    }
2720    function isPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2721        if (dateSpanMeta === void 0) { dateSpanMeta = {}; }
2722        if (state.eventDrag && !isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
2723            return false;
2724        }
2725        if (state.dateSelection && !isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
2726            return false;
2727        }
2728        return true;
2729    }
2730    // Moving Event Validation
2731    // ------------------------------------------------------------------------------------------------------------------------
2732    function isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2733        var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
2734        var subjectEventStore = interaction.mutatedEvents;
2735        var subjectDefs = subjectEventStore.defs;
2736        var subjectInstances = subjectEventStore.instances;
2737        var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
2738            state.eventUiBases :
2739            { '': calendar.selectionConfig } // if not a real event, validate as a selection
2740        );
2741        if (filterConfig) {
2742            subjectConfigs = mapHash(subjectConfigs, filterConfig);
2743        }
2744        var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); // exclude the subject events. TODO: exclude defs too?
2745        var otherDefs = otherEventStore.defs;
2746        var otherInstances = otherEventStore.instances;
2747        var otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
2748        for (var subjectInstanceId in subjectInstances) {
2749            var subjectInstance = subjectInstances[subjectInstanceId];
2750            var subjectRange = subjectInstance.range;
2751            var subjectConfig = subjectConfigs[subjectInstance.defId];
2752            var subjectDef = subjectDefs[subjectInstance.defId];
2753            // constraint
2754            if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, calendar)) {
2755                return false;
2756            }
2757            // overlap
2758            var overlapFunc = calendar.opt('eventOverlap');
2759            if (typeof overlapFunc !== 'function') {
2760                overlapFunc = null;
2761            }
2762            for (var otherInstanceId in otherInstances) {
2763                var otherInstance = otherInstances[otherInstanceId];
2764                // intersect! evaluate
2765                if (rangesIntersect(subjectRange, otherInstance.range)) {
2766                    var otherOverlap = otherConfigs[otherInstance.defId].overlap;
2767                    // consider the other event's overlap. only do this if the subject event is a "real" event
2768                    if (otherOverlap === false && interaction.isEvent) {
2769                        return false;
2770                    }
2771                    if (subjectConfig.overlap === false) {
2772                        return false;
2773                    }
2774                    if (overlapFunc && !overlapFunc(new EventApi(calendar, otherDefs[otherInstance.defId], otherInstance), // still event
2775                    new EventApi(calendar, subjectDef, subjectInstance) // moving event
2776                    )) {
2777                        return false;
2778                    }
2779                }
2780            }
2781            // allow (a function)
2782            var calendarEventStore = calendar.state.eventStore; // need global-to-calendar, not local to component (splittable)state
2783            for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) {
2784                var subjectAllow = _a[_i];
2785                var subjectDateSpan = __assign({}, dateSpanMeta, { range: subjectInstance.range, allDay: subjectDef.allDay });
2786                var origDef = calendarEventStore.defs[subjectDef.defId];
2787                var origInstance = calendarEventStore.instances[subjectInstanceId];
2788                var eventApi = void 0;
2789                if (origDef) { // was previously in the calendar
2790                    eventApi = new EventApi(calendar, origDef, origInstance);
2791                }
2792                else { // was an external event
2793                    eventApi = new EventApi(calendar, subjectDef); // no instance, because had no dates
2794                }
2795                if (!subjectAllow(calendar.buildDateSpanApi(subjectDateSpan), eventApi)) {
2796                    return false;
2797                }
2798            }
2799        }
2800        return true;
2801    }
2802    // Date Selection Validation
2803    // ------------------------------------------------------------------------------------------------------------------------
2804    function isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2805        var relevantEventStore = state.eventStore;
2806        var relevantDefs = relevantEventStore.defs;
2807        var relevantInstances = relevantEventStore.instances;
2808        var selection = state.dateSelection;
2809        var selectionRange = selection.range;
2810        var selectionConfig = calendar.selectionConfig;
2811        if (filterConfig) {
2812            selectionConfig = filterConfig(selectionConfig);
2813        }
2814        // constraint
2815        if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, calendar)) {
2816            return false;
2817        }
2818        // overlap
2819        var overlapFunc = calendar.opt('selectOverlap');
2820        if (typeof overlapFunc !== 'function') {
2821            overlapFunc = null;
2822        }
2823        for (var relevantInstanceId in relevantInstances) {
2824            var relevantInstance = relevantInstances[relevantInstanceId];
2825            // intersect! evaluate
2826            if (rangesIntersect(selectionRange, relevantInstance.range)) {
2827                if (selectionConfig.overlap === false) {
2828                    return false;
2829                }
2830                if (overlapFunc && !overlapFunc(new EventApi(calendar, relevantDefs[relevantInstance.defId], relevantInstance))) {
2831                    return false;
2832                }
2833            }
2834        }
2835        // allow (a function)
2836        for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) {
2837            var selectionAllow = _a[_i];
2838            var fullDateSpan = __assign({}, dateSpanMeta, selection);
2839            if (!selectionAllow(calendar.buildDateSpanApi(fullDateSpan), null)) {
2840                return false;
2841            }
2842        }
2843        return true;
2844    }
2845    // Constraint Utils
2846    // ------------------------------------------------------------------------------------------------------------------------
2847    function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, calendar) {
2848        for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
2849            var constraint = constraints_1[_i];
2850            if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, calendar), subjectRange)) {
2851                return false;
2852            }
2853        }
2854        return true;
2855    }
2856    function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
2857    otherEventStore, // for if constraint is an even group ID
2858    businessHoursUnexpanded, // for if constraint is 'businessHours'
2859    calendar // for expanding businesshours
2860    ) {
2861        if (constraint === 'businessHours') {
2862            return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, calendar));
2863        }
2864        else if (typeof constraint === 'string') { // an group ID
2865            return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) {
2866                return eventDef.groupId === constraint;
2867            }));
2868        }
2869        else if (typeof constraint === 'object' && constraint) { // non-null object
2870            return eventStoreToRanges(expandRecurring(constraint, subjectRange, calendar));
2871        }
2872        return []; // if it's false
2873    }
2874    // TODO: move to event-store file?
2875    function eventStoreToRanges(eventStore) {
2876        var instances = eventStore.instances;
2877        var ranges = [];
2878        for (var instanceId in instances) {
2879            ranges.push(instances[instanceId].range);
2880        }
2881        return ranges;
2882    }
2883    // TODO: move to geom file?
2884    function anyRangesContainRange(outerRanges, innerRange) {
2885        for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) {
2886            var outerRange = outerRanges_1[_i];
2887            if (rangeContainsRange(outerRange, innerRange)) {
2888                return true;
2889            }
2890        }
2891        return false;
2892    }
2893    // Parsing
2894    // ------------------------------------------------------------------------------------------------------------------------
2895    function normalizeConstraint(input, calendar) {
2896        if (Array.isArray(input)) {
2897            return parseEvents(input, '', calendar, true); // allowOpenRange=true
2898        }
2899        else if (typeof input === 'object' && input) { // non-null object
2900            return parseEvents([input], '', calendar, true); // allowOpenRange=true
2901        }
2902        else if (input != null) {
2903            return String(input);
2904        }
2905        else {
2906            return null;
2907        }
2908    }
2909
2910    function htmlEscape(s) {
2911        return (s + '').replace(/&/g, '&amp;')
2912            .replace(/</g, '&lt;')
2913            .replace(/>/g, '&gt;')
2914            .replace(/'/g, '&#039;')
2915            .replace(/"/g, '&quot;')
2916            .replace(/\n/g, '<br />');
2917    }
2918    // Given a hash of CSS properties, returns a string of CSS.
2919    // Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.
2920    function cssToStr(cssProps) {
2921        var statements = [];
2922        for (var name_1 in cssProps) {
2923            var val = cssProps[name_1];
2924            if (val != null && val !== '') {
2925                statements.push(name_1 + ':' + val);
2926            }
2927        }
2928        return statements.join(';');
2929    }
2930    // Given an object hash of HTML attribute names to values,
2931    // generates a string that can be injected between < > in HTML
2932    function attrsToStr(attrs) {
2933        var parts = [];
2934        for (var name_2 in attrs) {
2935            var val = attrs[name_2];
2936            if (val != null) {
2937                parts.push(name_2 + '="' + htmlEscape(val) + '"');
2938            }
2939        }
2940        return parts.join(' ');
2941    }
2942    function parseClassName(raw) {
2943        if (Array.isArray(raw)) {
2944            return raw;
2945        }
2946        else if (typeof raw === 'string') {
2947            return raw.split(/\s+/);
2948        }
2949        else {
2950            return [];
2951        }
2952    }
2953
2954    var UNSCOPED_EVENT_UI_PROPS = {
2955        editable: Boolean,
2956        startEditable: Boolean,
2957        durationEditable: Boolean,
2958        constraint: null,
2959        overlap: null,
2960        allow: null,
2961        className: parseClassName,
2962        classNames: parseClassName,
2963        color: String,
2964        backgroundColor: String,
2965        borderColor: String,
2966        textColor: String
2967    };
2968    function processUnscopedUiProps(rawProps, calendar, leftovers) {
2969        var props = refineProps(rawProps, UNSCOPED_EVENT_UI_PROPS, {}, leftovers);
2970        var constraint = normalizeConstraint(props.constraint, calendar);
2971        return {
2972            startEditable: props.startEditable != null ? props.startEditable : props.editable,
2973            durationEditable: props.durationEditable != null ? props.durationEditable : props.editable,
2974            constraints: constraint != null ? [constraint] : [],
2975            overlap: props.overlap,
2976            allows: props.allow != null ? [props.allow] : [],
2977            backgroundColor: props.backgroundColor || props.color,
2978            borderColor: props.borderColor || props.color,
2979            textColor: props.textColor,
2980            classNames: props.classNames.concat(props.className)
2981        };
2982    }
2983    function processScopedUiProps(prefix, rawScoped, calendar, leftovers) {
2984        var rawUnscoped = {};
2985        var wasFound = {};
2986        for (var key in UNSCOPED_EVENT_UI_PROPS) {
2987            var scopedKey = prefix + capitaliseFirstLetter(key);
2988            rawUnscoped[key] = rawScoped[scopedKey];
2989            wasFound[scopedKey] = true;
2990        }
2991        if (prefix === 'event') {
2992            rawUnscoped.editable = rawScoped.editable; // special case. there is no 'eventEditable', just 'editable'
2993        }
2994        if (leftovers) {
2995            for (var key in rawScoped) {
2996                if (!wasFound[key]) {
2997                    leftovers[key] = rawScoped[key];
2998                }
2999            }
3000        }
3001        return processUnscopedUiProps(rawUnscoped, calendar);
3002    }
3003    var EMPTY_EVENT_UI = {
3004        startEditable: null,
3005        durationEditable: null,
3006        constraints: [],
3007        overlap: null,
3008        allows: [],
3009        backgroundColor: '',
3010        borderColor: '',
3011        textColor: '',
3012        classNames: []
3013    };
3014    // prevent against problems with <2 args!
3015    function combineEventUis(uis) {
3016        return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
3017    }
3018    function combineTwoEventUis(item0, item1) {
3019        return {
3020            startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
3021            durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
3022            constraints: item0.constraints.concat(item1.constraints),
3023            overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
3024            allows: item0.allows.concat(item1.allows),
3025            backgroundColor: item1.backgroundColor || item0.backgroundColor,
3026            borderColor: item1.borderColor || item0.borderColor,
3027            textColor: item1.textColor || item0.textColor,
3028            classNames: item0.classNames.concat(item1.classNames)
3029        };
3030    }
3031
3032    var NON_DATE_PROPS = {
3033        id: String,
3034        groupId: String,
3035        title: String,
3036        url: String,
3037        rendering: String,
3038        extendedProps: null
3039    };
3040    var DATE_PROPS = {
3041        start: null,
3042        date: null,
3043        end: null,
3044        allDay: null
3045    };
3046    var uid = 0;
3047    function parseEvent(raw, sourceId, calendar, allowOpenRange) {
3048        var allDayDefault = computeIsAllDayDefault(sourceId, calendar);
3049        var leftovers0 = {};
3050        var recurringRes = parseRecurring(raw, // raw, but with single-event stuff stripped out
3051        allDayDefault, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes, leftovers0 // will populate with non-recurring props
3052        );
3053        if (recurringRes) {
3054            var def = parseEventDef(leftovers0, sourceId, recurringRes.allDay, Boolean(recurringRes.duration), calendar);
3055            def.recurringDef = {
3056                typeId: recurringRes.typeId,
3057                typeData: recurringRes.typeData,
3058                duration: recurringRes.duration
3059            };
3060            return { def: def, instance: null };
3061        }
3062        else {
3063            var leftovers1 = {};
3064            var singleRes = parseSingle(raw, allDayDefault, calendar, leftovers1, allowOpenRange);
3065            if (singleRes) {
3066                var def = parseEventDef(leftovers1, sourceId, singleRes.allDay, singleRes.hasEnd, calendar);
3067                var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
3068                return { def: def, instance: instance };
3069            }
3070        }
3071        return null;
3072    }
3073    /*
3074    Will NOT populate extendedProps with the leftover properties.
3075    Will NOT populate date-related props.
3076    The EventNonDateInput has been normalized (id => publicId, etc).
3077    */
3078    function parseEventDef(raw, sourceId, allDay, hasEnd, calendar) {
3079        var leftovers = {};
3080        var def = pluckNonDateProps(raw, calendar, leftovers);
3081        def.defId = String(uid++);
3082        def.sourceId = sourceId;
3083        def.allDay = allDay;
3084        def.hasEnd = hasEnd;
3085        for (var _i = 0, _a = calendar.pluginSystem.hooks.eventDefParsers; _i < _a.length; _i++) {
3086            var eventDefParser = _a[_i];
3087            var newLeftovers = {};
3088            eventDefParser(def, leftovers, newLeftovers);
3089            leftovers = newLeftovers;
3090        }
3091        def.extendedProps = __assign(leftovers, def.extendedProps || {});
3092        // help out EventApi from having user modify props
3093        Object.freeze(def.ui.classNames);
3094        Object.freeze(def.extendedProps);
3095        return def;
3096    }
3097    function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
3098        return {
3099            instanceId: String(uid++),
3100            defId: defId,
3101            range: range,
3102            forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
3103            forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo
3104        };
3105    }
3106    function parseSingle(raw, allDayDefault, calendar, leftovers, allowOpenRange) {
3107        var props = pluckDateProps(raw, leftovers);
3108        var allDay = props.allDay;
3109        var startMeta;
3110        var startMarker = null;
3111        var hasEnd = false;
3112        var endMeta;
3113        var endMarker = null;
3114        startMeta = calendar.dateEnv.createMarkerMeta(props.start);
3115        if (startMeta) {
3116            startMarker = startMeta.marker;
3117        }
3118        else if (!allowOpenRange) {
3119            return null;
3120        }
3121        if (props.end != null) {
3122            endMeta = calendar.dateEnv.createMarkerMeta(props.end);
3123        }
3124        if (allDay == null) {
3125            if (allDayDefault != null) {
3126                allDay = allDayDefault;
3127            }
3128            else {
3129                // fall back to the date props LAST
3130                allDay = (!startMeta || startMeta.isTimeUnspecified) &&
3131                    (!endMeta || endMeta.isTimeUnspecified);
3132            }
3133        }
3134        if (allDay && startMarker) {
3135            startMarker = startOfDay(startMarker);
3136        }
3137        if (endMeta) {
3138            endMarker = endMeta.marker;
3139            if (allDay) {
3140                endMarker = startOfDay(endMarker);
3141            }
3142            if (startMarker && endMarker <= startMarker) {
3143                endMarker = null;
3144            }
3145        }
3146        if (endMarker) {
3147            hasEnd = true;
3148        }
3149        else if (!allowOpenRange) {
3150            hasEnd = calendar.opt('forceEventDuration') || false;
3151            endMarker = calendar.dateEnv.add(startMarker, allDay ?
3152                calendar.defaultAllDayEventDuration :
3153                calendar.defaultTimedEventDuration);
3154        }
3155        return {
3156            allDay: allDay,
3157            hasEnd: hasEnd,
3158            range: { start: startMarker, end: endMarker },
3159            forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
3160            forcedEndTzo: endMeta ? endMeta.forcedTzo : null
3161        };
3162    }
3163    function pluckDateProps(raw, leftovers) {
3164        var props = refineProps(raw, DATE_PROPS, {}, leftovers);
3165        props.start = (props.start !== null) ? props.start : props.date;
3166        delete props.date;
3167        return props;
3168    }
3169    function pluckNonDateProps(raw, calendar, leftovers) {
3170        var preLeftovers = {};
3171        var props = refineProps(raw, NON_DATE_PROPS, {}, preLeftovers);
3172        var ui = processUnscopedUiProps(preLeftovers, calendar, leftovers);
3173        props.publicId = props.id;
3174        delete props.id;
3175        props.ui = ui;
3176        return props;
3177    }
3178    function computeIsAllDayDefault(sourceId, calendar) {
3179        var res = null;
3180        if (sourceId) {
3181            var source = calendar.state.eventSources[sourceId];
3182            res = source.allDayDefault;
3183        }
3184        if (res == null) {
3185            res = calendar.opt('allDayDefault');
3186        }
3187        return res;
3188    }
3189
3190    var DEF_DEFAULTS = {
3191        startTime: '09:00',
3192        endTime: '17:00',
3193        daysOfWeek: [1, 2, 3, 4, 5],
3194        rendering: 'inverse-background',
3195        classNames: 'fc-nonbusiness',
3196        groupId: '_businessHours' // so multiple defs get grouped
3197    };
3198    /*
3199    TODO: pass around as EventDefHash!!!
3200    */
3201    function parseBusinessHours(input, calendar) {
3202        return parseEvents(refineInputs(input), '', calendar);
3203    }
3204    function refineInputs(input) {
3205        var rawDefs;
3206        if (input === true) {
3207            rawDefs = [{}]; // will get DEF_DEFAULTS verbatim
3208        }
3209        else if (Array.isArray(input)) {
3210            // if specifying an array, every sub-definition NEEDS a day-of-week
3211            rawDefs = input.filter(function (rawDef) {
3212                return rawDef.daysOfWeek;
3213            });
3214        }
3215        else if (typeof input === 'object' && input) { // non-null object
3216            rawDefs = [input];
3217        }
3218        else { // is probably false
3219            rawDefs = [];
3220        }
3221        rawDefs = rawDefs.map(function (rawDef) {
3222            return __assign({}, DEF_DEFAULTS, rawDef);
3223        });
3224        return rawDefs;
3225    }
3226
3227    function memoizeRendering(renderFunc, unrenderFunc, dependencies) {
3228        if (dependencies === void 0) { dependencies = []; }
3229        var dependents = [];
3230        var thisContext;
3231        var prevArgs;
3232        function unrender() {
3233            if (prevArgs) {
3234                for (var _i = 0, dependents_1 = dependents; _i < dependents_1.length; _i++) {
3235                    var dependent = dependents_1[_i];
3236                    dependent.unrender();
3237                }
3238                if (unrenderFunc) {
3239                    unrenderFunc.apply(thisContext, prevArgs);
3240                }
3241                prevArgs = null;
3242            }
3243        }
3244        function res() {
3245            if (!prevArgs || !isArraysEqual(prevArgs, arguments)) {
3246                unrender();
3247                thisContext = this;
3248                prevArgs = arguments;
3249                renderFunc.apply(this, arguments);
3250            }
3251        }
3252        res.dependents = dependents;
3253        res.unrender = unrender;
3254        for (var _i = 0, dependencies_1 = dependencies; _i < dependencies_1.length; _i++) {
3255            var dependency = dependencies_1[_i];
3256            dependency.dependents.push(res);
3257        }
3258        return res;
3259    }
3260
3261    var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
3262    var Splitter = /** @class */ (function () {
3263        function Splitter() {
3264            this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
3265            this.splitDateSelection = memoize(this._splitDateSpan);
3266            this.splitEventStore = memoize(this._splitEventStore);
3267            this.splitIndividualUi = memoize(this._splitIndividualUi);
3268            this.splitEventDrag = memoize(this._splitInteraction);
3269            this.splitEventResize = memoize(this._splitInteraction);
3270            this.eventUiBuilders = {}; // TODO: typescript protection
3271        }
3272        Splitter.prototype.splitProps = function (props) {
3273            var _this = this;
3274            var keyInfos = this.getKeyInfo(props);
3275            var defKeys = this.getKeysForEventDefs(props.eventStore);
3276            var dateSelections = this.splitDateSelection(props.dateSelection);
3277            var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
3278            var eventStores = this.splitEventStore(props.eventStore, defKeys);
3279            var eventDrags = this.splitEventDrag(props.eventDrag);
3280            var eventResizes = this.splitEventResize(props.eventResize);
3281            var splitProps = {};
3282            this.eventUiBuilders = mapHash(keyInfos, function (info, key) {
3283                return _this.eventUiBuilders[key] || memoize(buildEventUiForKey);
3284            });
3285            for (var key in keyInfos) {
3286                var keyInfo = keyInfos[key];
3287                var eventStore = eventStores[key] || EMPTY_EVENT_STORE;
3288                var buildEventUi = this.eventUiBuilders[key];
3289                splitProps[key] = {
3290                    businessHours: keyInfo.businessHours || props.businessHours,
3291                    dateSelection: dateSelections[key] || null,
3292                    eventStore: eventStore,
3293                    eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
3294                    eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
3295                    eventDrag: eventDrags[key] || null,
3296                    eventResize: eventResizes[key] || null
3297                };
3298            }
3299            return splitProps;
3300        };
3301        Splitter.prototype._splitDateSpan = function (dateSpan) {
3302            var dateSpans = {};
3303            if (dateSpan) {
3304                var keys = this.getKeysForDateSpan(dateSpan);
3305                for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
3306                    var key = keys_1[_i];
3307                    dateSpans[key] = dateSpan;
3308                }
3309            }
3310            return dateSpans;
3311        };
3312        Splitter.prototype._getKeysForEventDefs = function (eventStore) {
3313            var _this = this;
3314            return mapHash(eventStore.defs, function (eventDef) {
3315                return _this.getKeysForEventDef(eventDef);
3316            });
3317        };
3318        Splitter.prototype._splitEventStore = function (eventStore, defKeys) {
3319            var defs = eventStore.defs, instances = eventStore.instances;
3320            var splitStores = {};
3321            for (var defId in defs) {
3322                for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
3323                    var key = _a[_i];
3324                    if (!splitStores[key]) {
3325                        splitStores[key] = createEmptyEventStore();
3326                    }
3327                    splitStores[key].defs[defId] = defs[defId];
3328                }
3329            }
3330            for (var instanceId in instances) {
3331                var instance = instances[instanceId];
3332                for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) {
3333                    var key = _c[_b];
3334                    if (splitStores[key]) { // must have already been created
3335                        splitStores[key].instances[instanceId] = instance;
3336                    }
3337                }
3338            }
3339            return splitStores;
3340        };
3341        Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) {
3342            var splitHashes = {};
3343            for (var defId in eventUiBases) {
3344                if (defId) { // not the '' key
3345                    for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
3346                        var key = _a[_i];
3347                        if (!splitHashes[key]) {
3348                            splitHashes[key] = {};
3349                        }
3350                        splitHashes[key][defId] = eventUiBases[defId];
3351                    }
3352                }
3353            }
3354            return splitHashes;
3355        };
3356        Splitter.prototype._splitInteraction = function (interaction) {
3357            var splitStates = {};
3358            if (interaction) {
3359                var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents) // can't use cached. might be events from other calendar
3360                );
3361                // can't rely on defKeys because event data is mutated
3362                var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
3363                var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
3364                var populate = function (key) {
3365                    if (!splitStates[key]) {
3366                        splitStates[key] = {
3367                            affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE,
3368                            mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE,
3369                            isEvent: interaction.isEvent,
3370                            origSeg: interaction.origSeg
3371                        };
3372                    }
3373                };
3374                for (var key in affectedStores_1) {
3375                    populate(key);
3376                }
3377                for (var key in mutatedStores_1) {
3378                    populate(key);
3379                }
3380            }
3381            return splitStates;
3382        };
3383        return Splitter;
3384    }());
3385    function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
3386        var baseParts = [];
3387        if (allUi) {
3388            baseParts.push(allUi);
3389        }
3390        if (eventUiForKey) {
3391            baseParts.push(eventUiForKey);
3392        }
3393        var stuff = {
3394            '': combineEventUis(baseParts)
3395        };
3396        if (individualUi) {
3397            __assign(stuff, individualUi);
3398        }
3399        return stuff;
3400    }
3401
3402    // Generates HTML for an anchor to another view into the calendar.
3403    // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings.
3404    // `gotoOptions` can either be a DateMarker, or an object with the form:
3405    // { date, type, forceOff }
3406    // `type` is a view-type like "day" or "week". default value is "day".
3407    // `attrs` and `innerHtml` are use to generate the rest of the HTML tag.
3408    function buildGotoAnchorHtml(allOptions, dateEnv, gotoOptions, attrs, innerHtml) {
3409        var date;
3410        var type;
3411        var forceOff;
3412        var finalOptions;
3413        if (gotoOptions instanceof Date) {
3414            date = gotoOptions; // a single date-like input
3415        }
3416        else {
3417            date = gotoOptions.date;
3418            type = gotoOptions.type;
3419            forceOff = gotoOptions.forceOff;
3420        }
3421        finalOptions = {
3422            date: dateEnv.formatIso(date, { omitTime: true }),
3423            type: type || 'day'
3424        };
3425        if (typeof attrs === 'string') {
3426            innerHtml = attrs;
3427            attrs = null;
3428        }
3429        attrs = attrs ? ' ' + attrsToStr(attrs) : ''; // will have a leading space
3430        innerHtml = innerHtml || '';
3431        if (!forceOff && allOptions.navLinks) {
3432            return '<a' + attrs +
3433                ' data-goto="' + htmlEscape(JSON.stringify(finalOptions)) + '">' +
3434                innerHtml +
3435                '</a>';
3436        }
3437        else {
3438            return '<span' + attrs + '>' +
3439                innerHtml +
3440                '</span>';
3441        }
3442    }
3443    function getAllDayHtml(allOptions) {
3444        return allOptions.allDayHtml || htmlEscape(allOptions.allDayText);
3445    }
3446    // Computes HTML classNames for a single-day element
3447    function getDayClasses(date, dateProfile, context, noThemeHighlight) {
3448        var calendar = context.calendar, options = context.options, theme = context.theme, dateEnv = context.dateEnv;
3449        var classes = [];
3450        var todayStart;
3451        var todayEnd;
3452        if (!rangeContainsMarker(dateProfile.activeRange, date)) {
3453            classes.push('fc-disabled-day');
3454        }
3455        else {
3456            classes.push('fc-' + DAY_IDS[date.getUTCDay()]);
3457            if (options.monthMode &&
3458                dateEnv.getMonth(date) !== dateEnv.getMonth(dateProfile.currentRange.start)) {
3459                classes.push('fc-other-month');
3460            }
3461            todayStart = startOfDay(calendar.getNow());
3462            todayEnd = addDays(todayStart, 1);
3463            if (date < todayStart) {
3464                classes.push('fc-past');
3465            }
3466            else if (date >= todayEnd) {
3467                classes.push('fc-future');
3468            }
3469            else {
3470                classes.push('fc-today');
3471                if (noThemeHighlight !== true) {
3472                    classes.push(theme.getClass('today'));
3473                }
3474            }
3475        }
3476        return classes;
3477    }
3478
3479    // given a function that resolves a result asynchronously.
3480    // the function can either call passed-in success and failure callbacks,
3481    // or it can return a promise.
3482    // if you need to pass additional params to func, bind them first.
3483    function unpromisify(func, success, failure) {
3484        // guard against success/failure callbacks being called more than once
3485        // and guard against a promise AND callback being used together.
3486        var isResolved = false;
3487        var wrappedSuccess = function () {
3488            if (!isResolved) {
3489                isResolved = true;
3490                success.apply(this, arguments);
3491            }
3492        };
3493        var wrappedFailure = function () {
3494            if (!isResolved) {
3495                isResolved = true;
3496                if (failure) {
3497                    failure.apply(this, arguments);
3498                }
3499            }
3500        };
3501        var res = func(wrappedSuccess, wrappedFailure);
3502        if (res && typeof res.then === 'function') {
3503            res.then(wrappedSuccess, wrappedFailure);
3504        }
3505    }
3506
3507    var Mixin = /** @class */ (function () {
3508        function Mixin() {
3509        }
3510        // mix into a CLASS
3511        Mixin.mixInto = function (destClass) {
3512            this.mixIntoObj(destClass.prototype);
3513        };
3514        // mix into ANY object
3515        Mixin.mixIntoObj = function (destObj) {
3516            var _this = this;
3517            Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
3518                if (!destObj[name]) { // if destination doesn't already define it
3519                    destObj[name] = _this.prototype[name];
3520                }
3521            });
3522        };
3523        /*
3524        will override existing methods
3525        TODO: remove! not used anymore
3526        */
3527        Mixin.mixOver = function (destClass) {
3528            var _this = this;
3529            Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
3530                destClass.prototype[name] = _this.prototype[name];
3531            });
3532        };
3533        return Mixin;
3534    }());
3535
3536    /*
3537    USAGE:
3538      import { default as EmitterMixin, EmitterInterface } from './EmitterMixin'
3539    in class:
3540      on: EmitterInterface['on']
3541      one: EmitterInterface['one']
3542      off: EmitterInterface['off']
3543      trigger: EmitterInterface['trigger']
3544      triggerWith: EmitterInterface['triggerWith']
3545      hasHandlers: EmitterInterface['hasHandlers']
3546    after class:
3547      EmitterMixin.mixInto(TheClass)
3548    */
3549    var EmitterMixin = /** @class */ (function (_super) {
3550        __extends(EmitterMixin, _super);
3551        function EmitterMixin() {
3552            return _super !== null && _super.apply(this, arguments) || this;
3553        }
3554        EmitterMixin.prototype.on = function (type, handler) {
3555            addToHash(this._handlers || (this._handlers = {}), type, handler);
3556            return this; // for chaining
3557        };
3558        // todo: add comments
3559        EmitterMixin.prototype.one = function (type, handler) {
3560            addToHash(this._oneHandlers || (this._oneHandlers = {}), type, handler);
3561            return this; // for chaining
3562        };
3563        EmitterMixin.prototype.off = function (type, handler) {
3564            if (this._handlers) {
3565                removeFromHash(this._handlers, type, handler);
3566            }
3567            if (this._oneHandlers) {
3568                removeFromHash(this._oneHandlers, type, handler);
3569            }
3570            return this; // for chaining
3571        };
3572        EmitterMixin.prototype.trigger = function (type) {
3573            var args = [];
3574            for (var _i = 1; _i < arguments.length; _i++) {
3575                args[_i - 1] = arguments[_i];
3576            }
3577            this.triggerWith(type, this, args);
3578            return this; // for chaining
3579        };
3580        EmitterMixin.prototype.triggerWith = function (type, context, args) {
3581            if (this._handlers) {
3582                applyAll(this._handlers[type], context, args);
3583            }
3584            if (this._oneHandlers) {
3585                applyAll(this._oneHandlers[type], context, args);
3586                delete this._oneHandlers[type]; // will never fire again
3587            }
3588            return this; // for chaining
3589        };
3590        EmitterMixin.prototype.hasHandlers = function (type) {
3591            return (this._handlers && this._handlers[type] && this._handlers[type].length) ||
3592                (this._oneHandlers && this._oneHandlers[type] && this._oneHandlers[type].length);
3593        };
3594        return EmitterMixin;
3595    }(Mixin));
3596    function addToHash(hash, type, handler) {
3597        (hash[type] || (hash[type] = []))
3598            .push(handler);
3599    }
3600    function removeFromHash(hash, type, handler) {
3601        if (handler) {
3602            if (hash[type]) {
3603                hash[type] = hash[type].filter(function (func) {
3604                    return func !== handler;
3605                });
3606            }
3607        }
3608        else {
3609            delete hash[type]; // remove all handler funcs for this type
3610        }
3611    }
3612
3613    /*
3614    Records offset information for a set of elements, relative to an origin element.
3615    Can record the left/right OR the top/bottom OR both.
3616    Provides methods for querying the cache by position.
3617    */
3618    var PositionCache = /** @class */ (function () {
3619        function PositionCache(originEl, els, isHorizontal, isVertical) {
3620            this.originEl = originEl;
3621            this.els = els;
3622            this.isHorizontal = isHorizontal;
3623            this.isVertical = isVertical;
3624        }
3625        // Queries the els for coordinates and stores them.
3626        // Call this method before using and of the get* methods below.
3627        PositionCache.prototype.build = function () {
3628            var originEl = this.originEl;
3629            var originClientRect = this.originClientRect =
3630                originEl.getBoundingClientRect(); // relative to viewport top-left
3631            if (this.isHorizontal) {
3632                this.buildElHorizontals(originClientRect.left);
3633            }
3634            if (this.isVertical) {
3635                this.buildElVerticals(originClientRect.top);
3636            }
3637        };
3638        // Populates the left/right internal coordinate arrays
3639        PositionCache.prototype.buildElHorizontals = function (originClientLeft) {
3640            var lefts = [];
3641            var rights = [];
3642            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
3643                var el = _a[_i];
3644                var rect = el.getBoundingClientRect();
3645                lefts.push(rect.left - originClientLeft);
3646                rights.push(rect.right - originClientLeft);
3647            }
3648            this.lefts = lefts;
3649            this.rights = rights;
3650        };
3651        // Populates the top/bottom internal coordinate arrays
3652        PositionCache.prototype.buildElVerticals = function (originClientTop) {
3653            var tops = [];
3654            var bottoms = [];
3655            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
3656                var el = _a[_i];
3657                var rect = el.getBoundingClientRect();
3658                tops.push(rect.top - originClientTop);
3659                bottoms.push(rect.bottom - originClientTop);
3660            }
3661            this.tops = tops;
3662            this.bottoms = bottoms;
3663        };
3664        // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
3665        // If no intersection is made, returns undefined.
3666        PositionCache.prototype.leftToIndex = function (leftPosition) {
3667            var lefts = this.lefts;
3668            var rights = this.rights;
3669            var len = lefts.length;
3670            var i;
3671            for (i = 0; i < len; i++) {
3672                if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
3673                    return i;
3674                }
3675            }
3676        };
3677        // Given a top offset (from document top), returns the index of the el that it vertically intersects.
3678        // If no intersection is made, returns undefined.
3679        PositionCache.prototype.topToIndex = function (topPosition) {
3680            var tops = this.tops;
3681            var bottoms = this.bottoms;
3682            var len = tops.length;
3683            var i;
3684            for (i = 0; i < len; i++) {
3685                if (topPosition >= tops[i] && topPosition < bottoms[i]) {
3686                    return i;
3687                }
3688            }
3689        };
3690        // Gets the width of the element at the given index
3691        PositionCache.prototype.getWidth = function (leftIndex) {
3692            return this.rights[leftIndex] - this.lefts[leftIndex];
3693        };
3694        // Gets the height of the element at the given index
3695        PositionCache.prototype.getHeight = function (topIndex) {
3696            return this.bottoms[topIndex] - this.tops[topIndex];
3697        };
3698        return PositionCache;
3699    }());
3700
3701    /*
3702    An object for getting/setting scroll-related information for an element.
3703    Internally, this is done very differently for window versus DOM element,
3704    so this object serves as a common interface.
3705    */
3706    var ScrollController = /** @class */ (function () {
3707        function ScrollController() {
3708        }
3709        ScrollController.prototype.getMaxScrollTop = function () {
3710            return this.getScrollHeight() - this.getClientHeight();
3711        };
3712        ScrollController.prototype.getMaxScrollLeft = function () {
3713            return this.getScrollWidth() - this.getClientWidth();
3714        };
3715        ScrollController.prototype.canScrollVertically = function () {
3716            return this.getMaxScrollTop() > 0;
3717        };
3718        ScrollController.prototype.canScrollHorizontally = function () {
3719            return this.getMaxScrollLeft() > 0;
3720        };
3721        ScrollController.prototype.canScrollUp = function () {
3722            return this.getScrollTop() > 0;
3723        };
3724        ScrollController.prototype.canScrollDown = function () {
3725            return this.getScrollTop() < this.getMaxScrollTop();
3726        };
3727        ScrollController.prototype.canScrollLeft = function () {
3728            return this.getScrollLeft() > 0;
3729        };
3730        ScrollController.prototype.canScrollRight = function () {
3731            return this.getScrollLeft() < this.getMaxScrollLeft();
3732        };
3733        return ScrollController;
3734    }());
3735    var ElementScrollController = /** @class */ (function (_super) {
3736        __extends(ElementScrollController, _super);
3737        function ElementScrollController(el) {
3738            var _this = _super.call(this) || this;
3739            _this.el = el;
3740            return _this;
3741        }
3742        ElementScrollController.prototype.getScrollTop = function () {
3743            return this.el.scrollTop;
3744        };
3745        ElementScrollController.prototype.getScrollLeft = function () {
3746            return this.el.scrollLeft;
3747        };
3748        ElementScrollController.prototype.setScrollTop = function (top) {
3749            this.el.scrollTop = top;
3750        };
3751        ElementScrollController.prototype.setScrollLeft = function (left) {
3752            this.el.scrollLeft = left;
3753        };
3754        ElementScrollController.prototype.getScrollWidth = function () {
3755            return this.el.scrollWidth;
3756        };
3757        ElementScrollController.prototype.getScrollHeight = function () {
3758            return this.el.scrollHeight;
3759        };
3760        ElementScrollController.prototype.getClientHeight = function () {
3761            return this.el.clientHeight;
3762        };
3763        ElementScrollController.prototype.getClientWidth = function () {
3764            return this.el.clientWidth;
3765        };
3766        return ElementScrollController;
3767    }(ScrollController));
3768    var WindowScrollController = /** @class */ (function (_super) {
3769        __extends(WindowScrollController, _super);
3770        function WindowScrollController() {
3771            return _super !== null && _super.apply(this, arguments) || this;
3772        }
3773        WindowScrollController.prototype.getScrollTop = function () {
3774            return window.pageYOffset;
3775        };
3776        WindowScrollController.prototype.getScrollLeft = function () {
3777            return window.pageXOffset;
3778        };
3779        WindowScrollController.prototype.setScrollTop = function (n) {
3780            window.scroll(window.pageXOffset, n);
3781        };
3782        WindowScrollController.prototype.setScrollLeft = function (n) {
3783            window.scroll(n, window.pageYOffset);
3784        };
3785        WindowScrollController.prototype.getScrollWidth = function () {
3786            return document.documentElement.scrollWidth;
3787        };
3788        WindowScrollController.prototype.getScrollHeight = function () {
3789            return document.documentElement.scrollHeight;
3790        };
3791        WindowScrollController.prototype.getClientHeight = function () {
3792            return document.documentElement.clientHeight;
3793        };
3794        WindowScrollController.prototype.getClientWidth = function () {
3795            return document.documentElement.clientWidth;
3796        };
3797        return WindowScrollController;
3798    }(ScrollController));
3799
3800    /*
3801    Embodies a div that has potential scrollbars
3802    */
3803    var ScrollComponent = /** @class */ (function (_super) {
3804        __extends(ScrollComponent, _super);
3805        function ScrollComponent(overflowX, overflowY) {
3806            var _this = _super.call(this, createElement('div', {
3807                className: 'fc-scroller'
3808            })) || this;
3809            _this.overflowX = overflowX;
3810            _this.overflowY = overflowY;
3811            _this.applyOverflow();
3812            return _this;
3813        }
3814        // sets to natural height, unlocks overflow
3815        ScrollComponent.prototype.clear = function () {
3816            this.setHeight('auto');
3817            this.applyOverflow();
3818        };
3819        ScrollComponent.prototype.destroy = function () {
3820            removeElement(this.el);
3821        };
3822        // Overflow
3823        // -----------------------------------------------------------------------------------------------------------------
3824        ScrollComponent.prototype.applyOverflow = function () {
3825            applyStyle(this.el, {
3826                overflowX: this.overflowX,
3827                overflowY: this.overflowY
3828            });
3829        };
3830        // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
3831        // Useful for preserving scrollbar widths regardless of future resizes.
3832        // Can pass in scrollbarWidths for optimization.
3833        ScrollComponent.prototype.lockOverflow = function (scrollbarWidths) {
3834            var overflowX = this.overflowX;
3835            var overflowY = this.overflowY;
3836            scrollbarWidths = scrollbarWidths || this.getScrollbarWidths();
3837            if (overflowX === 'auto') {
3838                overflowX = (scrollbarWidths.bottom || // horizontal scrollbars?
3839                    this.canScrollHorizontally() // OR scrolling pane with massless scrollbars?
3840                ) ? 'scroll' : 'hidden';
3841            }
3842            if (overflowY === 'auto') {
3843                overflowY = (scrollbarWidths.left || scrollbarWidths.right || // horizontal scrollbars?
3844                    this.canScrollVertically() // OR scrolling pane with massless scrollbars?
3845                ) ? 'scroll' : 'hidden';
3846            }
3847            applyStyle(this.el, { overflowX: overflowX, overflowY: overflowY });
3848        };
3849        ScrollComponent.prototype.setHeight = function (height) {
3850            applyStyleProp(this.el, 'height', height);
3851        };
3852        ScrollComponent.prototype.getScrollbarWidths = function () {
3853            var edges = computeEdges(this.el);
3854            return {
3855                left: edges.scrollbarLeft,
3856                right: edges.scrollbarRight,
3857                bottom: edges.scrollbarBottom
3858            };
3859        };
3860        return ScrollComponent;
3861    }(ElementScrollController));
3862
3863    var Theme = /** @class */ (function () {
3864        function Theme(calendarOptions) {
3865            this.calendarOptions = calendarOptions;
3866            this.processIconOverride();
3867        }
3868        Theme.prototype.processIconOverride = function () {
3869            if (this.iconOverrideOption) {
3870                this.setIconOverride(this.calendarOptions[this.iconOverrideOption]);
3871            }
3872        };
3873        Theme.prototype.setIconOverride = function (iconOverrideHash) {
3874            var iconClassesCopy;
3875            var buttonName;
3876            if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object
3877                iconClassesCopy = __assign({}, this.iconClasses);
3878                for (buttonName in iconOverrideHash) {
3879                    iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
3880                }
3881                this.iconClasses = iconClassesCopy;
3882            }
3883            else if (iconOverrideHash === false) {
3884                this.iconClasses = {};
3885            }
3886        };
3887        Theme.prototype.applyIconOverridePrefix = function (className) {
3888            var prefix = this.iconOverridePrefix;
3889            if (prefix && className.indexOf(prefix) !== 0) { // if not already present
3890                className = prefix + className;
3891            }
3892            return className;
3893        };
3894        Theme.prototype.getClass = function (key) {
3895            return this.classes[key] || '';
3896        };
3897        Theme.prototype.getIconClass = function (buttonName) {
3898            var className = this.iconClasses[buttonName];
3899            if (className) {
3900                return this.baseIconClass + ' ' + className;
3901            }
3902            return '';
3903        };
3904        Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
3905            var className;
3906            if (this.iconOverrideCustomButtonOption) {
3907                className = customButtonProps[this.iconOverrideCustomButtonOption];
3908                if (className) {
3909                    return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className);
3910                }
3911            }
3912            return '';
3913        };
3914        return Theme;
3915    }());
3916    Theme.prototype.classes = {};
3917    Theme.prototype.iconClasses = {};
3918    Theme.prototype.baseIconClass = '';
3919    Theme.prototype.iconOverridePrefix = '';
3920
3921    var guid = 0;
3922    var ComponentContext = /** @class */ (function () {
3923        function ComponentContext(calendar, theme, dateEnv, options, view) {
3924            this.calendar = calendar;
3925            this.theme = theme;
3926            this.dateEnv = dateEnv;
3927            this.options = options;
3928            this.view = view;
3929            this.isRtl = options.dir === 'rtl';
3930            this.eventOrderSpecs = parseFieldSpecs(options.eventOrder);
3931            this.nextDayThreshold = createDuration(options.nextDayThreshold);
3932        }
3933        ComponentContext.prototype.extend = function (options, view) {
3934            return new ComponentContext(this.calendar, this.theme, this.dateEnv, options || this.options, view || this.view);
3935        };
3936        return ComponentContext;
3937    }());
3938    var Component = /** @class */ (function () {
3939        function Component() {
3940            this.uid = String(guid++);
3941        }
3942        Component.addEqualityFuncs = function (newFuncs) {
3943            this.prototype.equalityFuncs = __assign({}, this.prototype.equalityFuncs, newFuncs);
3944        };
3945        Component.prototype.receiveProps = function (props, context) {
3946            var oldContext = this.context;
3947            this.context = context;
3948            if (!oldContext) {
3949                this.firstContext(context);
3950            }
3951            var _a = recycleProps(this.props || {}, props, this.equalityFuncs), anyChanges = _a.anyChanges, comboProps = _a.comboProps;
3952            this.props = comboProps;
3953            if (anyChanges) {
3954                if (oldContext) {
3955                    this.beforeUpdate();
3956                }
3957                this.render(comboProps, context);
3958                if (oldContext) {
3959                    this.afterUpdate();
3960                }
3961            }
3962        };
3963        Component.prototype.render = function (props, context) {
3964        };
3965        Component.prototype.firstContext = function (context) {
3966        };
3967        Component.prototype.beforeUpdate = function () {
3968        };
3969        Component.prototype.afterUpdate = function () {
3970        };
3971        // after destroy is called, this component won't ever be used again
3972        Component.prototype.destroy = function () {
3973        };
3974        return Component;
3975    }());
3976    Component.prototype.equalityFuncs = {};
3977    /*
3978    Reuses old values when equal. If anything is unequal, returns newProps as-is.
3979    Great for PureComponent, but won't be feasible with React, so just eliminate and use React's DOM diffing.
3980    */
3981    function recycleProps(oldProps, newProps, equalityFuncs) {
3982        var comboProps = {}; // some old, some new
3983        var anyChanges = false;
3984        for (var key in newProps) {
3985            if (key in oldProps && (oldProps[key] === newProps[key] ||
3986                (equalityFuncs[key] && equalityFuncs[key](oldProps[key], newProps[key])))) {
3987                // equal to old? use old prop
3988                comboProps[key] = oldProps[key];
3989            }
3990            else {
3991                comboProps[key] = newProps[key];
3992                anyChanges = true;
3993            }
3994        }
3995        for (var key in oldProps) {
3996            if (!(key in newProps)) {
3997                anyChanges = true;
3998                break;
3999            }
4000        }
4001        return { anyChanges: anyChanges, comboProps: comboProps };
4002    }
4003
4004    /*
4005    PURPOSES:
4006    - hook up to fg, fill, and mirror renderers
4007    - interface for dragging and hits
4008    */
4009    var DateComponent = /** @class */ (function (_super) {
4010        __extends(DateComponent, _super);
4011        function DateComponent(el) {
4012            var _this = _super.call(this) || this;
4013            _this.el = el;
4014            return _this;
4015        }
4016        DateComponent.prototype.destroy = function () {
4017            _super.prototype.destroy.call(this);
4018            removeElement(this.el);
4019        };
4020        // Hit System
4021        // -----------------------------------------------------------------------------------------------------------------
4022        DateComponent.prototype.buildPositionCaches = function () {
4023        };
4024        DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
4025            return null; // this should be abstract
4026        };
4027        // Validation
4028        // -----------------------------------------------------------------------------------------------------------------
4029        DateComponent.prototype.isInteractionValid = function (interaction) {
4030            var calendar = this.context.calendar;
4031            var dateProfile = this.props.dateProfile; // HACK
4032            var instances = interaction.mutatedEvents.instances;
4033            if (dateProfile) { // HACK for DayTile
4034                for (var instanceId in instances) {
4035                    if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
4036                        return false;
4037                    }
4038                }
4039            }
4040            return isInteractionValid(interaction, calendar);
4041        };
4042        DateComponent.prototype.isDateSelectionValid = function (selection) {
4043            var calendar = this.context.calendar;
4044            var dateProfile = this.props.dateProfile; // HACK
4045            if (dateProfile && // HACK for DayTile
4046                !rangeContainsRange(dateProfile.validRange, selection.range)) {
4047                return false;
4048            }
4049            return isDateSelectionValid(selection, calendar);
4050        };
4051        // Pointer Interaction Utils
4052        // -----------------------------------------------------------------------------------------------------------------
4053        DateComponent.prototype.isValidSegDownEl = function (el) {
4054            return !this.props.eventDrag && // HACK
4055                !this.props.eventResize && // HACK
4056                !elementClosest(el, '.fc-mirror') &&
4057                (this.isPopover() || !this.isInPopover(el));
4058            // ^above line ensures we don't detect a seg interaction within a nested component.
4059            // it's a HACK because it only supports a popover as the nested component.
4060        };
4061        DateComponent.prototype.isValidDateDownEl = function (el) {
4062            var segEl = elementClosest(el, this.fgSegSelector);
4063            return (!segEl || segEl.classList.contains('fc-mirror')) &&
4064                !elementClosest(el, '.fc-more') && // a "more.." link
4065                !elementClosest(el, 'a[data-goto]') && // a clickable nav link
4066                !this.isInPopover(el);
4067        };
4068        DateComponent.prototype.isPopover = function () {
4069            return this.el.classList.contains('fc-popover');
4070        };
4071        DateComponent.prototype.isInPopover = function (el) {
4072            return Boolean(elementClosest(el, '.fc-popover'));
4073        };
4074        return DateComponent;
4075    }(Component));
4076    DateComponent.prototype.fgSegSelector = '.fc-event-container > *';
4077    DateComponent.prototype.bgSegSelector = '.fc-bgevent:not(.fc-nonbusiness)';
4078
4079    var uid$1 = 0;
4080    function createPlugin(input) {
4081        return {
4082            id: String(uid$1++),
4083            deps: input.deps || [],
4084            reducers: input.reducers || [],
4085            eventDefParsers: input.eventDefParsers || [],
4086            isDraggableTransformers: input.isDraggableTransformers || [],
4087            eventDragMutationMassagers: input.eventDragMutationMassagers || [],
4088            eventDefMutationAppliers: input.eventDefMutationAppliers || [],
4089            dateSelectionTransformers: input.dateSelectionTransformers || [],
4090            datePointTransforms: input.datePointTransforms || [],
4091            dateSpanTransforms: input.dateSpanTransforms || [],
4092            views: input.views || {},
4093            viewPropsTransformers: input.viewPropsTransformers || [],
4094            isPropsValid: input.isPropsValid || null,
4095            externalDefTransforms: input.externalDefTransforms || [],
4096            eventResizeJoinTransforms: input.eventResizeJoinTransforms || [],
4097            viewContainerModifiers: input.viewContainerModifiers || [],
4098            eventDropTransformers: input.eventDropTransformers || [],
4099            componentInteractions: input.componentInteractions || [],
4100            calendarInteractions: input.calendarInteractions || [],
4101            themeClasses: input.themeClasses || {},
4102            eventSourceDefs: input.eventSourceDefs || [],
4103            cmdFormatter: input.cmdFormatter,
4104            recurringTypes: input.recurringTypes || [],
4105            namedTimeZonedImpl: input.namedTimeZonedImpl,
4106            defaultView: input.defaultView || '',
4107            elementDraggingImpl: input.elementDraggingImpl,
4108            optionChangeHandlers: input.optionChangeHandlers || {}
4109        };
4110    }
4111    var PluginSystem = /** @class */ (function () {
4112        function PluginSystem() {
4113            this.hooks = {
4114                reducers: [],
4115                eventDefParsers: [],
4116                isDraggableTransformers: [],
4117                eventDragMutationMassagers: [],
4118                eventDefMutationAppliers: [],
4119                dateSelectionTransformers: [],
4120                datePointTransforms: [],
4121                dateSpanTransforms: [],
4122                views: {},
4123                viewPropsTransformers: [],
4124                isPropsValid: null,
4125                externalDefTransforms: [],
4126                eventResizeJoinTransforms: [],
4127                viewContainerModifiers: [],
4128                eventDropTransformers: [],
4129                componentInteractions: [],
4130                calendarInteractions: [],
4131                themeClasses: {},
4132                eventSourceDefs: [],
4133                cmdFormatter: null,
4134                recurringTypes: [],
4135                namedTimeZonedImpl: null,
4136                defaultView: '',
4137                elementDraggingImpl: null,
4138                optionChangeHandlers: {}
4139            };
4140            this.addedHash = {};
4141        }
4142        PluginSystem.prototype.add = function (plugin) {
4143            if (!this.addedHash[plugin.id]) {
4144                this.addedHash[plugin.id] = true;
4145                for (var _i = 0, _a = plugin.deps; _i < _a.length; _i++) {
4146                    var dep = _a[_i];
4147                    this.add(dep);
4148                }
4149                this.hooks = combineHooks(this.hooks, plugin);
4150            }
4151        };
4152        return PluginSystem;
4153    }());
4154    function combineHooks(hooks0, hooks1) {
4155        return {
4156            reducers: hooks0.reducers.concat(hooks1.reducers),
4157            eventDefParsers: hooks0.eventDefParsers.concat(hooks1.eventDefParsers),
4158            isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),
4159            eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
4160            eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
4161            dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
4162            datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
4163            dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
4164            views: __assign({}, hooks0.views, hooks1.views),
4165            viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
4166            isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
4167            externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
4168            eventResizeJoinTransforms: hooks0.eventResizeJoinTransforms.concat(hooks1.eventResizeJoinTransforms),
4169            viewContainerModifiers: hooks0.viewContainerModifiers.concat(hooks1.viewContainerModifiers),
4170            eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
4171            calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
4172            componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
4173            themeClasses: __assign({}, hooks0.themeClasses, hooks1.themeClasses),
4174            eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
4175            cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
4176            recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
4177            namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
4178            defaultView: hooks0.defaultView || hooks1.defaultView,
4179            elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
4180            optionChangeHandlers: __assign({}, hooks0.optionChangeHandlers, hooks1.optionChangeHandlers)
4181        };
4182    }
4183
4184    var eventSourceDef = {
4185        ignoreRange: true,
4186        parseMeta: function (raw) {
4187            if (Array.isArray(raw)) { // short form
4188                return raw;
4189            }
4190            else if (Array.isArray(raw.events)) {
4191                return raw.events;
4192            }
4193            return null;
4194        },
4195        fetch: function (arg, success) {
4196            success({
4197                rawEvents: arg.eventSource.meta
4198            });
4199        }
4200    };
4201    var ArrayEventSourcePlugin = createPlugin({
4202        eventSourceDefs: [eventSourceDef]
4203    });
4204
4205    var eventSourceDef$1 = {
4206        parseMeta: function (raw) {
4207            if (typeof raw === 'function') { // short form
4208                return raw;
4209            }
4210            else if (typeof raw.events === 'function') {
4211                return raw.events;
4212            }
4213            return null;
4214        },
4215        fetch: function (arg, success, failure) {
4216            var dateEnv = arg.calendar.dateEnv;
4217            var func = arg.eventSource.meta;
4218            unpromisify(func.bind(null, {
4219                start: dateEnv.toDate(arg.range.start),
4220                end: dateEnv.toDate(arg.range.end),
4221                startStr: dateEnv.formatIso(arg.range.start),
4222                endStr: dateEnv.formatIso(arg.range.end),
4223                timeZone: dateEnv.timeZone
4224            }), function (rawEvents) {
4225                success({ rawEvents: rawEvents }); // needs an object response
4226            }, failure // send errorObj directly to failure callback
4227            );
4228        }
4229    };
4230    var FuncEventSourcePlugin = createPlugin({
4231        eventSourceDefs: [eventSourceDef$1]
4232    });
4233
4234    function requestJson(method, url, params, successCallback, failureCallback) {
4235        method = method.toUpperCase();
4236        var body = null;
4237        if (method === 'GET') {
4238            url = injectQueryStringParams(url, params);
4239        }
4240        else {
4241            body = encodeParams(params);
4242        }
4243        var xhr = new XMLHttpRequest();
4244        xhr.open(method, url, true);
4245        if (method !== 'GET') {
4246            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
4247        }
4248        xhr.onload = function () {
4249            if (xhr.status >= 200 && xhr.status < 400) {
4250                try {
4251                    var res = JSON.parse(xhr.responseText);
4252                    successCallback(res, xhr);
4253                }
4254                catch (err) {
4255                    failureCallback('Failure parsing JSON', xhr);
4256                }
4257            }
4258            else {
4259                failureCallback('Request failed', xhr);
4260            }
4261        };
4262        xhr.onerror = function () {
4263            failureCallback('Request failed', xhr);
4264        };
4265        xhr.send(body);
4266    }
4267    function injectQueryStringParams(url, params) {
4268        return url +
4269            (url.indexOf('?') === -1 ? '?' : '&') +
4270            encodeParams(params);
4271    }
4272    function encodeParams(params) {
4273        var parts = [];
4274        for (var key in params) {
4275            parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
4276        }
4277        return parts.join('&');
4278    }
4279
4280    var eventSourceDef$2 = {
4281        parseMeta: function (raw) {
4282            if (typeof raw === 'string') { // short form
4283                raw = { url: raw };
4284            }
4285            else if (!raw || typeof raw !== 'object' || !raw.url) {
4286                return null;
4287            }
4288            return {
4289                url: raw.url,
4290                method: (raw.method || 'GET').toUpperCase(),
4291                extraParams: raw.extraParams,
4292                startParam: raw.startParam,
4293                endParam: raw.endParam,
4294                timeZoneParam: raw.timeZoneParam
4295            };
4296        },
4297        fetch: function (arg, success, failure) {
4298            var meta = arg.eventSource.meta;
4299            var requestParams = buildRequestParams(meta, arg.range, arg.calendar);
4300            requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) {
4301                success({ rawEvents: rawEvents, xhr: xhr });
4302            }, function (errorMessage, xhr) {
4303                failure({ message: errorMessage, xhr: xhr });
4304            });
4305        }
4306    };
4307    var JsonFeedEventSourcePlugin = createPlugin({
4308        eventSourceDefs: [eventSourceDef$2]
4309    });
4310    function buildRequestParams(meta, range, calendar) {
4311        var dateEnv = calendar.dateEnv;
4312        var startParam;
4313        var endParam;
4314        var timeZoneParam;
4315        var customRequestParams;
4316        var params = {};
4317        startParam = meta.startParam;
4318        if (startParam == null) {
4319            startParam = calendar.opt('startParam');
4320        }
4321        endParam = meta.endParam;
4322        if (endParam == null) {
4323            endParam = calendar.opt('endParam');
4324        }
4325        timeZoneParam = meta.timeZoneParam;
4326        if (timeZoneParam == null) {
4327            timeZoneParam = calendar.opt('timeZoneParam');
4328        }
4329        // retrieve any outbound GET/POST data from the options
4330        if (typeof meta.extraParams === 'function') {
4331            // supplied as a function that returns a key/value object
4332            customRequestParams = meta.extraParams();
4333        }
4334        else {
4335            // probably supplied as a straight key/value object
4336            customRequestParams = meta.extraParams || {};
4337        }
4338        __assign(params, customRequestParams);
4339        params[startParam] = dateEnv.formatIso(range.start);
4340        params[endParam] = dateEnv.formatIso(range.end);
4341        if (dateEnv.timeZone !== 'local') {
4342            params[timeZoneParam] = dateEnv.timeZone;
4343        }
4344        return params;
4345    }
4346
4347    var recurring = {
4348        parse: function (rawEvent, leftoverProps, dateEnv) {
4349            var createMarker = dateEnv.createMarker.bind(dateEnv);
4350            var processors = {
4351                daysOfWeek: null,
4352                startTime: createDuration,
4353                endTime: createDuration,
4354                startRecur: createMarker,
4355                endRecur: createMarker
4356            };
4357            var props = refineProps(rawEvent, processors, {}, leftoverProps);
4358            var anyValid = false;
4359            for (var propName in props) {
4360                if (props[propName] != null) {
4361                    anyValid = true;
4362                    break;
4363                }
4364            }
4365            if (anyValid) {
4366                var duration = null;
4367                if ('duration' in leftoverProps) {
4368                    duration = createDuration(leftoverProps.duration);
4369                    delete leftoverProps.duration;
4370                }
4371                if (!duration && props.startTime && props.endTime) {
4372                    duration = subtractDurations(props.endTime, props.startTime);
4373                }
4374                return {
4375                    allDayGuess: Boolean(!props.startTime && !props.endTime),
4376                    duration: duration,
4377                    typeData: props // doesn't need endTime anymore but oh well
4378                };
4379            }
4380            return null;
4381        },
4382        expand: function (typeData, framingRange, dateEnv) {
4383            var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
4384            if (clippedFramingRange) {
4385                return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
4386            }
4387            else {
4388                return [];
4389            }
4390        }
4391    };
4392    var SimpleRecurrencePlugin = createPlugin({
4393        recurringTypes: [recurring]
4394    });
4395    function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
4396        var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
4397        var dayMarker = startOfDay(framingRange.start);
4398        var endMarker = framingRange.end;
4399        var instanceStarts = [];
4400        while (dayMarker < endMarker) {
4401            var instanceStart 
4402            // if everyday, or this particular day-of-week
4403            = void 0;
4404            // if everyday, or this particular day-of-week
4405            if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
4406                if (startTime) {
4407                    instanceStart = dateEnv.add(dayMarker, startTime);
4408                }
4409                else {
4410                    instanceStart = dayMarker;
4411                }
4412                instanceStarts.push(instanceStart);
4413            }
4414            dayMarker = addDays(dayMarker, 1);
4415        }
4416        return instanceStarts;
4417    }
4418
4419    var DefaultOptionChangeHandlers = createPlugin({
4420        optionChangeHandlers: {
4421            events: function (events, calendar, deepEqual) {
4422                handleEventSources([events], calendar, deepEqual);
4423            },
4424            eventSources: handleEventSources,
4425            plugins: handlePlugins
4426        }
4427    });
4428    function handleEventSources(inputs, calendar, deepEqual) {
4429        var unfoundSources = hashValuesToArray(calendar.state.eventSources);
4430        var newInputs = [];
4431        for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
4432            var input = inputs_1[_i];
4433            var inputFound = false;
4434            for (var i = 0; i < unfoundSources.length; i++) {
4435                if (deepEqual(unfoundSources[i]._raw, input)) {
4436                    unfoundSources.splice(i, 1); // delete
4437                    inputFound = true;
4438                    break;
4439                }
4440            }
4441            if (!inputFound) {
4442                newInputs.push(input);
4443            }
4444        }
4445        for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) {
4446            var unfoundSource = unfoundSources_1[_a];
4447            calendar.dispatch({
4448                type: 'REMOVE_EVENT_SOURCE',
4449                sourceId: unfoundSource.sourceId
4450            });
4451        }
4452        for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) {
4453            var newInput = newInputs_1[_b];
4454            calendar.addEventSource(newInput);
4455        }
4456    }
4457    // shortcoming: won't remove plugins
4458    function handlePlugins(inputs, calendar) {
4459        calendar.addPluginInputs(inputs); // will gracefully handle duplicates
4460    }
4461
4462    var config = {}; // TODO: make these options
4463    var globalDefaults = {
4464        defaultRangeSeparator: ' - ',
4465        titleRangeSeparator: ' \u2013 ',
4466        defaultTimedEventDuration: '01:00:00',
4467        defaultAllDayEventDuration: { day: 1 },
4468        forceEventDuration: false,
4469        nextDayThreshold: '00:00:00',
4470        // display
4471        columnHeader: true,
4472        defaultView: '',
4473        aspectRatio: 1.35,
4474        header: {
4475            left: 'title',
4476            center: '',
4477            right: 'today prev,next'
4478        },
4479        weekends: true,
4480        weekNumbers: false,
4481        weekNumberCalculation: 'local',
4482        editable: false,
4483        // nowIndicator: false,
4484        scrollTime: '06:00:00',
4485        minTime: '00:00:00',
4486        maxTime: '24:00:00',
4487        showNonCurrentDates: true,
4488        // event ajax
4489        lazyFetching: true,
4490        startParam: 'start',
4491        endParam: 'end',
4492        timeZoneParam: 'timeZone',
4493        timeZone: 'local',
4494        // allDayDefault: undefined,
4495        // locale
4496        locales: [],
4497        locale: '',
4498        // dir: will get this from the default locale
4499        // buttonIcons: null,
4500        // allows setting a min-height to the event segment to prevent short events overlapping each other
4501        timeGridEventMinHeight: 0,
4502        themeSystem: 'standard',
4503        // eventResizableFromStart: false,
4504        dragRevertDuration: 500,
4505        dragScroll: true,
4506        allDayMaintainDuration: false,
4507        // selectable: false,
4508        unselectAuto: true,
4509        // selectMinDistance: 0,
4510        dropAccept: '*',
4511        eventOrder: 'start,-duration,allDay,title',
4512        // ^ if start tie, longer events go before shorter. final tie-breaker is title text
4513        // rerenderDelay: null,
4514        eventLimit: false,
4515        eventLimitClick: 'popover',
4516        dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
4517        handleWindowResize: true,
4518        windowResizeDelay: 100,
4519        longPressDelay: 1000,
4520        eventDragMinDistance: 5 // only applies to mouse
4521    };
4522    var rtlDefaults = {
4523        header: {
4524            left: 'next,prev today',
4525            center: '',
4526            right: 'title'
4527        },
4528        buttonIcons: {
4529            // TODO: make RTL support the responibility of the theme
4530            prev: 'fc-icon-chevron-right',
4531            next: 'fc-icon-chevron-left',
4532            prevYear: 'fc-icon-chevrons-right',
4533            nextYear: 'fc-icon-chevrons-left'
4534        }
4535    };
4536    var complexOptions = [
4537        'header',
4538        'footer',
4539        'buttonText',
4540        'buttonIcons'
4541    ];
4542    // Merges an array of option objects into a single object
4543    function mergeOptions(optionObjs) {
4544        return mergeProps(optionObjs, complexOptions);
4545    }
4546    // TODO: move this stuff to a "plugin"-related file...
4547    var INTERNAL_PLUGINS = [
4548        ArrayEventSourcePlugin,
4549        FuncEventSourcePlugin,
4550        JsonFeedEventSourcePlugin,
4551        SimpleRecurrencePlugin,
4552        DefaultOptionChangeHandlers
4553    ];
4554    function refinePluginDefs(pluginInputs) {
4555        var plugins = [];
4556        for (var _i = 0, pluginInputs_1 = pluginInputs; _i < pluginInputs_1.length; _i++) {
4557            var pluginInput = pluginInputs_1[_i];
4558            if (typeof pluginInput === 'string') {
4559                var globalName = 'FullCalendar' + capitaliseFirstLetter(pluginInput);
4560                if (!window[globalName]) {
4561                    console.warn('Plugin file not loaded for ' + pluginInput);
4562                }
4563                else {
4564                    plugins.push(window[globalName].default); // is an ES6 module
4565                }
4566            }
4567            else {
4568                plugins.push(pluginInput);
4569            }
4570        }
4571        return INTERNAL_PLUGINS.concat(plugins);
4572    }
4573
4574    var RAW_EN_LOCALE = {
4575        code: 'en',
4576        week: {
4577            dow: 0,
4578            doy: 4 // 4 days need to be within the year to be considered the first week
4579        },
4580        dir: 'ltr',
4581        buttonText: {
4582            prev: 'prev',
4583            next: 'next',
4584            prevYear: 'prev year',
4585            nextYear: 'next year',
4586            year: 'year',
4587            today: 'today',
4588            month: 'month',
4589            week: 'week',
4590            day: 'day',
4591            list: 'list'
4592        },
4593        weekLabel: 'W',
4594        allDayText: 'all-day',
4595        eventLimitText: 'more',
4596        noEventsMessage: 'No events to display'
4597    };
4598    function parseRawLocales(explicitRawLocales) {
4599        var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
4600        var globalArray = window['FullCalendarLocalesAll'] || []; // from locales-all.js
4601        var globalObject = window['FullCalendarLocales'] || {}; // from locales/*.js. keys are meaningless
4602        var allRawLocales = globalArray.concat(// globalArray is low prio
4603        hashValuesToArray(globalObject), // medium prio
4604        explicitRawLocales // highest prio
4605        );
4606        var rawLocaleMap = {
4607            en: RAW_EN_LOCALE // necessary?
4608        };
4609        for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) {
4610            var rawLocale = allRawLocales_1[_i];
4611            rawLocaleMap[rawLocale.code] = rawLocale;
4612        }
4613        return {
4614            map: rawLocaleMap,
4615            defaultCode: defaultCode
4616        };
4617    }
4618    function buildLocale(inputSingular, available) {
4619        if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
4620            return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
4621        }
4622        else {
4623            return queryLocale(inputSingular, available);
4624        }
4625    }
4626    function queryLocale(codeArg, available) {
4627        var codes = [].concat(codeArg || []); // will convert to array
4628        var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
4629        return parseLocale(codeArg, codes, raw);
4630    }
4631    function queryRawLocale(codes, available) {
4632        for (var i = 0; i < codes.length; i++) {
4633            var parts = codes[i].toLocaleLowerCase().split('-');
4634            for (var j = parts.length; j > 0; j--) {
4635                var simpleId = parts.slice(0, j).join('-');
4636                if (available[simpleId]) {
4637                    return available[simpleId];
4638                }
4639            }
4640        }
4641        return null;
4642    }
4643    function parseLocale(codeArg, codes, raw) {
4644        var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']);
4645        delete merged.code; // don't want this part of the options
4646        var week = merged.week;
4647        delete merged.week;
4648        return {
4649            codeArg: codeArg,
4650            codes: codes,
4651            week: week,
4652            simpleNumberFormat: new Intl.NumberFormat(codeArg),
4653            options: merged
4654        };
4655    }
4656
4657    var OptionsManager = /** @class */ (function () {
4658        function OptionsManager(overrides) {
4659            this.overrides = __assign({}, overrides); // make a copy
4660            this.dynamicOverrides = {};
4661            this.compute();
4662        }
4663        OptionsManager.prototype.mutate = function (updates, removals, isDynamic) {
4664            if (!Object.keys(updates).length && !removals.length) {
4665                return;
4666            }
4667            var overrideHash = isDynamic ? this.dynamicOverrides : this.overrides;
4668            __assign(overrideHash, updates);
4669            for (var _i = 0, removals_1 = removals; _i < removals_1.length; _i++) {
4670                var propName = removals_1[_i];
4671                delete overrideHash[propName];
4672            }
4673            this.compute();
4674        };
4675        // Computes the flattened options hash for the calendar and assigns to `this.options`.
4676        // Assumes this.overrides and this.dynamicOverrides have already been initialized.
4677        OptionsManager.prototype.compute = function () {
4678            // TODO: not a very efficient system
4679            var locales = firstDefined(// explicit locale option given?
4680            this.dynamicOverrides.locales, this.overrides.locales, globalDefaults.locales);
4681            var locale = firstDefined(// explicit locales option given?
4682            this.dynamicOverrides.locale, this.overrides.locale, globalDefaults.locale);
4683            var available = parseRawLocales(locales);
4684            var localeDefaults = buildLocale(locale || available.defaultCode, available.map).options;
4685            var dir = firstDefined(// based on options computed so far, is direction RTL?
4686            this.dynamicOverrides.dir, this.overrides.dir, localeDefaults.dir);
4687            var dirDefaults = dir === 'rtl' ? rtlDefaults : {};
4688            this.dirDefaults = dirDefaults;
4689            this.localeDefaults = localeDefaults;
4690            this.computed = mergeOptions([
4691                globalDefaults,
4692                dirDefaults,
4693                localeDefaults,
4694                this.overrides,
4695                this.dynamicOverrides
4696            ]);
4697        };
4698        return OptionsManager;
4699    }());
4700
4701    var calendarSystemClassMap = {};
4702    function registerCalendarSystem(name, theClass) {
4703        calendarSystemClassMap[name] = theClass;
4704    }
4705    function createCalendarSystem(name) {
4706        return new calendarSystemClassMap[name]();
4707    }
4708    var GregorianCalendarSystem = /** @class */ (function () {
4709        function GregorianCalendarSystem() {
4710        }
4711        GregorianCalendarSystem.prototype.getMarkerYear = function (d) {
4712            return d.getUTCFullYear();
4713        };
4714        GregorianCalendarSystem.prototype.getMarkerMonth = function (d) {
4715            return d.getUTCMonth();
4716        };
4717        GregorianCalendarSystem.prototype.getMarkerDay = function (d) {
4718            return d.getUTCDate();
4719        };
4720        GregorianCalendarSystem.prototype.arrayToMarker = function (arr) {
4721            return arrayToUtcDate(arr);
4722        };
4723        GregorianCalendarSystem.prototype.markerToArray = function (marker) {
4724            return dateToUtcArray(marker);
4725        };
4726        return GregorianCalendarSystem;
4727    }());
4728    registerCalendarSystem('gregory', GregorianCalendarSystem);
4729
4730    var ISO_RE = /^\s*(\d{4})(-(\d{2})(-(\d{2})([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
4731    function parse(str) {
4732        var m = ISO_RE.exec(str);
4733        if (m) {
4734            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));
4735            if (isValidDate(marker)) {
4736                var timeZoneOffset = null;
4737                if (m[13]) {
4738                    timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
4739                        Number(m[18] || 0));
4740                }
4741                return {
4742                    marker: marker,
4743                    isTimeUnspecified: !m[6],
4744                    timeZoneOffset: timeZoneOffset
4745                };
4746            }
4747        }
4748        return null;
4749    }
4750
4751    var DateEnv = /** @class */ (function () {
4752        function DateEnv(settings) {
4753            var timeZone = this.timeZone = settings.timeZone;
4754            var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
4755            if (settings.namedTimeZoneImpl && isNamedTimeZone) {
4756                this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
4757            }
4758            this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
4759            this.calendarSystem = createCalendarSystem(settings.calendarSystem);
4760            this.locale = settings.locale;
4761            this.weekDow = settings.locale.week.dow;
4762            this.weekDoy = settings.locale.week.doy;
4763            if (settings.weekNumberCalculation === 'ISO') {
4764                this.weekDow = 1;
4765                this.weekDoy = 4;
4766            }
4767            if (typeof settings.firstDay === 'number') {
4768                this.weekDow = settings.firstDay;
4769            }
4770            if (typeof settings.weekNumberCalculation === 'function') {
4771                this.weekNumberFunc = settings.weekNumberCalculation;
4772            }
4773            this.weekLabel = settings.weekLabel != null ? settings.weekLabel : settings.locale.options.weekLabel;
4774            this.cmdFormatter = settings.cmdFormatter;
4775        }
4776        // Creating / Parsing
4777        DateEnv.prototype.createMarker = function (input) {
4778            var meta = this.createMarkerMeta(input);
4779            if (meta === null) {
4780                return null;
4781            }
4782            return meta.marker;
4783        };
4784        DateEnv.prototype.createNowMarker = function () {
4785            if (this.canComputeOffset) {
4786                return this.timestampToMarker(new Date().valueOf());
4787            }
4788            else {
4789                // if we can't compute the current date val for a timezone,
4790                // better to give the current local date vals than UTC
4791                return arrayToUtcDate(dateToLocalArray(new Date()));
4792            }
4793        };
4794        DateEnv.prototype.createMarkerMeta = function (input) {
4795            if (typeof input === 'string') {
4796                return this.parse(input);
4797            }
4798            var marker = null;
4799            if (typeof input === 'number') {
4800                marker = this.timestampToMarker(input);
4801            }
4802            else if (input instanceof Date) {
4803                input = input.valueOf();
4804                if (!isNaN(input)) {
4805                    marker = this.timestampToMarker(input);
4806                }
4807            }
4808            else if (Array.isArray(input)) {
4809                marker = arrayToUtcDate(input);
4810            }
4811            if (marker === null || !isValidDate(marker)) {
4812                return null;
4813            }
4814            return { marker: marker, isTimeUnspecified: false, forcedTzo: null };
4815        };
4816        DateEnv.prototype.parse = function (s) {
4817            var parts = parse(s);
4818            if (parts === null) {
4819                return null;
4820            }
4821            var marker = parts.marker;
4822            var forcedTzo = null;
4823            if (parts.timeZoneOffset !== null) {
4824                if (this.canComputeOffset) {
4825                    marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
4826                }
4827                else {
4828                    forcedTzo = parts.timeZoneOffset;
4829                }
4830            }
4831            return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo };
4832        };
4833        // Accessors
4834        DateEnv.prototype.getYear = function (marker) {
4835            return this.calendarSystem.getMarkerYear(marker);
4836        };
4837        DateEnv.prototype.getMonth = function (marker) {
4838            return this.calendarSystem.getMarkerMonth(marker);
4839        };
4840        // Adding / Subtracting
4841        DateEnv.prototype.add = function (marker, dur) {
4842            var a = this.calendarSystem.markerToArray(marker);
4843            a[0] += dur.years;
4844            a[1] += dur.months;
4845            a[2] += dur.days;
4846            a[6] += dur.milliseconds;
4847            return this.calendarSystem.arrayToMarker(a);
4848        };
4849        DateEnv.prototype.subtract = function (marker, dur) {
4850            var a = this.calendarSystem.markerToArray(marker);
4851            a[0] -= dur.years;
4852            a[1] -= dur.months;
4853            a[2] -= dur.days;
4854            a[6] -= dur.milliseconds;
4855            return this.calendarSystem.arrayToMarker(a);
4856        };
4857        DateEnv.prototype.addYears = function (marker, n) {
4858            var a = this.calendarSystem.markerToArray(marker);
4859            a[0] += n;
4860            return this.calendarSystem.arrayToMarker(a);
4861        };
4862        DateEnv.prototype.addMonths = function (marker, n) {
4863            var a = this.calendarSystem.markerToArray(marker);
4864            a[1] += n;
4865            return this.calendarSystem.arrayToMarker(a);
4866        };
4867        // Diffing Whole Units
4868        DateEnv.prototype.diffWholeYears = function (m0, m1) {
4869            var calendarSystem = this.calendarSystem;
4870            if (timeAsMs(m0) === timeAsMs(m1) &&
4871                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
4872                calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
4873                return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
4874            }
4875            return null;
4876        };
4877        DateEnv.prototype.diffWholeMonths = function (m0, m1) {
4878            var calendarSystem = this.calendarSystem;
4879            if (timeAsMs(m0) === timeAsMs(m1) &&
4880                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
4881                return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
4882                    (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
4883            }
4884            return null;
4885        };
4886        // Range / Duration
4887        DateEnv.prototype.greatestWholeUnit = function (m0, m1) {
4888            var n = this.diffWholeYears(m0, m1);
4889            if (n !== null) {
4890                return { unit: 'year', value: n };
4891            }
4892            n = this.diffWholeMonths(m0, m1);
4893            if (n !== null) {
4894                return { unit: 'month', value: n };
4895            }
4896            n = diffWholeWeeks(m0, m1);
4897            if (n !== null) {
4898                return { unit: 'week', value: n };
4899            }
4900            n = diffWholeDays(m0, m1);
4901            if (n !== null) {
4902                return { unit: 'day', value: n };
4903            }
4904            n = diffHours(m0, m1);
4905            if (isInt(n)) {
4906                return { unit: 'hour', value: n };
4907            }
4908            n = diffMinutes(m0, m1);
4909            if (isInt(n)) {
4910                return { unit: 'minute', value: n };
4911            }
4912            n = diffSeconds(m0, m1);
4913            if (isInt(n)) {
4914                return { unit: 'second', value: n };
4915            }
4916            return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
4917        };
4918        DateEnv.prototype.countDurationsBetween = function (m0, m1, d) {
4919            // TODO: can use greatestWholeUnit
4920            var diff;
4921            if (d.years) {
4922                diff = this.diffWholeYears(m0, m1);
4923                if (diff !== null) {
4924                    return diff / asRoughYears(d);
4925                }
4926            }
4927            if (d.months) {
4928                diff = this.diffWholeMonths(m0, m1);
4929                if (diff !== null) {
4930                    return diff / asRoughMonths(d);
4931                }
4932            }
4933            if (d.days) {
4934                diff = diffWholeDays(m0, m1);
4935                if (diff !== null) {
4936                    return diff / asRoughDays(d);
4937                }
4938            }
4939            return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
4940        };
4941        // Start-Of
4942        DateEnv.prototype.startOf = function (m, unit) {
4943            if (unit === 'year') {
4944                return this.startOfYear(m);
4945            }
4946            else if (unit === 'month') {
4947                return this.startOfMonth(m);
4948            }
4949            else if (unit === 'week') {
4950                return this.startOfWeek(m);
4951            }
4952            else if (unit === 'day') {
4953                return startOfDay(m);
4954            }
4955            else if (unit === 'hour') {
4956                return startOfHour(m);
4957            }
4958            else if (unit === 'minute') {
4959                return startOfMinute(m);
4960            }
4961            else if (unit === 'second') {
4962                return startOfSecond(m);
4963            }
4964        };
4965        DateEnv.prototype.startOfYear = function (m) {
4966            return this.calendarSystem.arrayToMarker([
4967                this.calendarSystem.getMarkerYear(m)
4968            ]);
4969        };
4970        DateEnv.prototype.startOfMonth = function (m) {
4971            return this.calendarSystem.arrayToMarker([
4972                this.calendarSystem.getMarkerYear(m),
4973                this.calendarSystem.getMarkerMonth(m)
4974            ]);
4975        };
4976        DateEnv.prototype.startOfWeek = function (m) {
4977            return this.calendarSystem.arrayToMarker([
4978                this.calendarSystem.getMarkerYear(m),
4979                this.calendarSystem.getMarkerMonth(m),
4980                m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7)
4981            ]);
4982        };
4983        // Week Number
4984        DateEnv.prototype.computeWeekNumber = function (marker) {
4985            if (this.weekNumberFunc) {
4986                return this.weekNumberFunc(this.toDate(marker));
4987            }
4988            else {
4989                return weekOfYear(marker, this.weekDow, this.weekDoy);
4990            }
4991        };
4992        // TODO: choke on timeZoneName: long
4993        DateEnv.prototype.format = function (marker, formatter, dateOptions) {
4994            if (dateOptions === void 0) { dateOptions = {}; }
4995            return formatter.format({
4996                marker: marker,
4997                timeZoneOffset: dateOptions.forcedTzo != null ?
4998                    dateOptions.forcedTzo :
4999                    this.offsetForMarker(marker)
5000            }, this);
5001        };
5002        DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) {
5003            if (dateOptions === void 0) { dateOptions = {}; }
5004            if (dateOptions.isEndExclusive) {
5005                end = addMs(end, -1);
5006            }
5007            return formatter.formatRange({
5008                marker: start,
5009                timeZoneOffset: dateOptions.forcedStartTzo != null ?
5010                    dateOptions.forcedStartTzo :
5011                    this.offsetForMarker(start)
5012            }, {
5013                marker: end,
5014                timeZoneOffset: dateOptions.forcedEndTzo != null ?
5015                    dateOptions.forcedEndTzo :
5016                    this.offsetForMarker(end)
5017            }, this);
5018        };
5019        DateEnv.prototype.formatIso = function (marker, extraOptions) {
5020            if (extraOptions === void 0) { extraOptions = {}; }
5021            var timeZoneOffset = null;
5022            if (!extraOptions.omitTimeZoneOffset) {
5023                if (extraOptions.forcedTzo != null) {
5024                    timeZoneOffset = extraOptions.forcedTzo;
5025                }
5026                else {
5027                    timeZoneOffset = this.offsetForMarker(marker);
5028                }
5029            }
5030            return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
5031        };
5032        // TimeZone
5033        DateEnv.prototype.timestampToMarker = function (ms) {
5034            if (this.timeZone === 'local') {
5035                return arrayToUtcDate(dateToLocalArray(new Date(ms)));
5036            }
5037            else if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
5038                return new Date(ms);
5039            }
5040            else {
5041                return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
5042            }
5043        };
5044        DateEnv.prototype.offsetForMarker = function (m) {
5045            if (this.timeZone === 'local') {
5046                return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
5047            }
5048            else if (this.timeZone === 'UTC') {
5049                return 0;
5050            }
5051            else if (this.namedTimeZoneImpl) {
5052                return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
5053            }
5054            return null;
5055        };
5056        // Conversion
5057        DateEnv.prototype.toDate = function (m, forcedTzo) {
5058            if (this.timeZone === 'local') {
5059                return arrayToLocalDate(dateToUtcArray(m));
5060            }
5061            else if (this.timeZone === 'UTC') {
5062                return new Date(m.valueOf()); // make sure it's a copy
5063            }
5064            else if (!this.namedTimeZoneImpl) {
5065                return new Date(m.valueOf() - (forcedTzo || 0));
5066            }
5067            else {
5068                return new Date(m.valueOf() -
5069                    this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60 // convert minutes -> ms
5070                );
5071            }
5072        };
5073        return DateEnv;
5074    }());
5075
5076    var SIMPLE_SOURCE_PROPS = {
5077        id: String,
5078        allDayDefault: Boolean,
5079        eventDataTransform: Function,
5080        success: Function,
5081        failure: Function
5082    };
5083    var uid$2 = 0;
5084    function doesSourceNeedRange(eventSource, calendar) {
5085        var defs = calendar.pluginSystem.hooks.eventSourceDefs;
5086        return !defs[eventSource.sourceDefId].ignoreRange;
5087    }
5088    function parseEventSource(raw, calendar) {
5089        var defs = calendar.pluginSystem.hooks.eventSourceDefs;
5090        for (var i = defs.length - 1; i >= 0; i--) { // later-added plugins take precedence
5091            var def = defs[i];
5092            var meta = def.parseMeta(raw);
5093            if (meta) {
5094                var res = parseEventSourceProps(typeof raw === 'object' ? raw : {}, meta, i, calendar);
5095                res._raw = raw;
5096                return res;
5097            }
5098        }
5099        return null;
5100    }
5101    function parseEventSourceProps(raw, meta, sourceDefId, calendar) {
5102        var leftovers0 = {};
5103        var props = refineProps(raw, SIMPLE_SOURCE_PROPS, {}, leftovers0);
5104        var leftovers1 = {};
5105        var ui = processUnscopedUiProps(leftovers0, calendar, leftovers1);
5106        props.isFetching = false;
5107        props.latestFetchId = '';
5108        props.fetchRange = null;
5109        props.publicId = String(raw.id || '');
5110        props.sourceId = String(uid$2++);
5111        props.sourceDefId = sourceDefId;
5112        props.meta = meta;
5113        props.ui = ui;
5114        props.extendedProps = leftovers1;
5115        return props;
5116    }
5117
5118    function reduceEventSources (eventSources, action, dateProfile, calendar) {
5119        switch (action.type) {
5120            case 'ADD_EVENT_SOURCES': // already parsed
5121                return addSources(eventSources, action.sources, dateProfile ? dateProfile.activeRange : null, calendar);
5122            case 'REMOVE_EVENT_SOURCE':
5123                return removeSource(eventSources, action.sourceId);
5124            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
5125            case 'NEXT':
5126            case 'SET_DATE':
5127            case 'SET_VIEW_TYPE':
5128                if (dateProfile) {
5129                    return fetchDirtySources(eventSources, dateProfile.activeRange, calendar);
5130                }
5131                else {
5132                    return eventSources;
5133                }
5134            case 'FETCH_EVENT_SOURCES':
5135            case 'CHANGE_TIMEZONE':
5136                return fetchSourcesByIds(eventSources, action.sourceIds ?
5137                    arrayToHash(action.sourceIds) :
5138                    excludeStaticSources(eventSources, calendar), dateProfile ? dateProfile.activeRange : null, calendar);
5139            case 'RECEIVE_EVENTS':
5140            case 'RECEIVE_EVENT_ERROR':
5141                return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
5142            case 'REMOVE_ALL_EVENT_SOURCES':
5143                return {};
5144            default:
5145                return eventSources;
5146        }
5147    }
5148    var uid$3 = 0;
5149    function addSources(eventSourceHash, sources, fetchRange, calendar) {
5150        var hash = {};
5151        for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
5152            var source = sources_1[_i];
5153            hash[source.sourceId] = source;
5154        }
5155        if (fetchRange) {
5156            hash = fetchDirtySources(hash, fetchRange, calendar);
5157        }
5158        return __assign({}, eventSourceHash, hash);
5159    }
5160    function removeSource(eventSourceHash, sourceId) {
5161        return filterHash(eventSourceHash, function (eventSource) {
5162            return eventSource.sourceId !== sourceId;
5163        });
5164    }
5165    function fetchDirtySources(sourceHash, fetchRange, calendar) {
5166        return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) {
5167            return isSourceDirty(eventSource, fetchRange, calendar);
5168        }), fetchRange, calendar);
5169    }
5170    function isSourceDirty(eventSource, fetchRange, calendar) {
5171        if (!doesSourceNeedRange(eventSource, calendar)) {
5172            return !eventSource.latestFetchId;
5173        }
5174        else {
5175            return !calendar.opt('lazyFetching') ||
5176                !eventSource.fetchRange ||
5177                eventSource.isFetching || // always cancel outdated in-progress fetches
5178                fetchRange.start < eventSource.fetchRange.start ||
5179                fetchRange.end > eventSource.fetchRange.end;
5180        }
5181    }
5182    function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, calendar) {
5183        var nextSources = {};
5184        for (var sourceId in prevSources) {
5185            var source = prevSources[sourceId];
5186            if (sourceIdHash[sourceId]) {
5187                nextSources[sourceId] = fetchSource(source, fetchRange, calendar);
5188            }
5189            else {
5190                nextSources[sourceId] = source;
5191            }
5192        }
5193        return nextSources;
5194    }
5195    function fetchSource(eventSource, fetchRange, calendar) {
5196        var sourceDef = calendar.pluginSystem.hooks.eventSourceDefs[eventSource.sourceDefId];
5197        var fetchId = String(uid$3++);
5198        sourceDef.fetch({
5199            eventSource: eventSource,
5200            calendar: calendar,
5201            range: fetchRange
5202        }, function (res) {
5203            var rawEvents = res.rawEvents;
5204            var calSuccess = calendar.opt('eventSourceSuccess');
5205            var calSuccessRes;
5206            var sourceSuccessRes;
5207            if (eventSource.success) {
5208                sourceSuccessRes = eventSource.success(rawEvents, res.xhr);
5209            }
5210            if (calSuccess) {
5211                calSuccessRes = calSuccess(rawEvents, res.xhr);
5212            }
5213            rawEvents = sourceSuccessRes || calSuccessRes || rawEvents;
5214            calendar.dispatch({
5215                type: 'RECEIVE_EVENTS',
5216                sourceId: eventSource.sourceId,
5217                fetchId: fetchId,
5218                fetchRange: fetchRange,
5219                rawEvents: rawEvents
5220            });
5221        }, function (error) {
5222            var callFailure = calendar.opt('eventSourceFailure');
5223            console.warn(error.message, error);
5224            if (eventSource.failure) {
5225                eventSource.failure(error);
5226            }
5227            if (callFailure) {
5228                callFailure(error);
5229            }
5230            calendar.dispatch({
5231                type: 'RECEIVE_EVENT_ERROR',
5232                sourceId: eventSource.sourceId,
5233                fetchId: fetchId,
5234                fetchRange: fetchRange,
5235                error: error
5236            });
5237        });
5238        return __assign({}, eventSource, { isFetching: true, latestFetchId: fetchId });
5239    }
5240    function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
5241        var _a;
5242        var eventSource = sourceHash[sourceId];
5243        if (eventSource && // not already removed
5244            fetchId === eventSource.latestFetchId) {
5245            return __assign({}, sourceHash, (_a = {}, _a[sourceId] = __assign({}, eventSource, { isFetching: false, fetchRange: fetchRange // also serves as a marker that at least one fetch has completed
5246             }), _a));
5247        }
5248        return sourceHash;
5249    }
5250    function excludeStaticSources(eventSources, calendar) {
5251        return filterHash(eventSources, function (eventSource) {
5252            return doesSourceNeedRange(eventSource, calendar);
5253        });
5254    }
5255
5256    var DateProfileGenerator = /** @class */ (function () {
5257        function DateProfileGenerator(viewSpec, calendar) {
5258            this.viewSpec = viewSpec;
5259            this.options = viewSpec.options;
5260            this.dateEnv = calendar.dateEnv;
5261            this.calendar = calendar;
5262            this.initHiddenDays();
5263        }
5264        /* Date Range Computation
5265        ------------------------------------------------------------------------------------------------------------------*/
5266        // Builds a structure with info about what the dates/ranges will be for the "prev" view.
5267        DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate) {
5268            var dateEnv = this.dateEnv;
5269            var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5270            currentDateProfile.dateIncrement);
5271            return this.build(prevDate, -1);
5272        };
5273        // Builds a structure with info about what the dates/ranges will be for the "next" view.
5274        DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate) {
5275            var dateEnv = this.dateEnv;
5276            var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5277            currentDateProfile.dateIncrement);
5278            return this.build(nextDate, 1);
5279        };
5280        // Builds a structure holding dates/ranges for rendering around the given date.
5281        // Optional direction param indicates whether the date is being incremented/decremented
5282        // from its previous value. decremented = -1, incremented = 1 (default).
5283        DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) {
5284            if (forceToValid === void 0) { forceToValid = false; }
5285            var validRange;
5286            var minTime = null;
5287            var maxTime = null;
5288            var currentInfo;
5289            var isRangeAllDay;
5290            var renderRange;
5291            var activeRange;
5292            var isValid;
5293            validRange = this.buildValidRange();
5294            validRange = this.trimHiddenDays(validRange);
5295            if (forceToValid) {
5296                currentDate = constrainMarkerToRange(currentDate, validRange);
5297            }
5298            currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
5299            isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
5300            renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
5301            renderRange = this.trimHiddenDays(renderRange);
5302            activeRange = renderRange;
5303            if (!this.options.showNonCurrentDates) {
5304                activeRange = intersectRanges(activeRange, currentInfo.range);
5305            }
5306            minTime = createDuration(this.options.minTime);
5307            maxTime = createDuration(this.options.maxTime);
5308            activeRange = this.adjustActiveRange(activeRange, minTime, maxTime);
5309            activeRange = intersectRanges(activeRange, validRange); // might return null
5310            // it's invalid if the originally requested date is not contained,
5311            // or if the range is completely outside of the valid range.
5312            isValid = rangesIntersect(currentInfo.range, validRange);
5313            return {
5314                // constraint for where prev/next operations can go and where events can be dragged/resized to.
5315                // an object with optional start and end properties.
5316                validRange: validRange,
5317                // range the view is formally responsible for.
5318                // for example, a month view might have 1st-31st, excluding padded dates
5319                currentRange: currentInfo.range,
5320                // name of largest unit being displayed, like "month" or "week"
5321                currentRangeUnit: currentInfo.unit,
5322                isRangeAllDay: isRangeAllDay,
5323                // dates that display events and accept drag-n-drop
5324                // will be `null` if no dates accept events
5325                activeRange: activeRange,
5326                // date range with a rendered skeleton
5327                // includes not-active days that need some sort of DOM
5328                renderRange: renderRange,
5329                // Duration object that denotes the first visible time of any given day
5330                minTime: minTime,
5331                // Duration object that denotes the exclusive visible end time of any given day
5332                maxTime: maxTime,
5333                isValid: isValid,
5334                // how far the current date will move for a prev/next operation
5335                dateIncrement: this.buildDateIncrement(currentInfo.duration)
5336                // pass a fallback (might be null) ^
5337            };
5338        };
5339        // Builds an object with optional start/end properties.
5340        // Indicates the minimum/maximum dates to display.
5341        // not responsible for trimming hidden days.
5342        DateProfileGenerator.prototype.buildValidRange = function () {
5343            return this.getRangeOption('validRange', this.calendar.getNow()) ||
5344                { start: null, end: null }; // completely open-ended
5345        };
5346        // Builds a structure with info about the "current" range, the range that is
5347        // highlighted as being the current month for example.
5348        // See build() for a description of `direction`.
5349        // Guaranteed to have `range` and `unit` properties. `duration` is optional.
5350        DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
5351            var _a = this, viewSpec = _a.viewSpec, dateEnv = _a.dateEnv;
5352            var duration = null;
5353            var unit = null;
5354            var range = null;
5355            var dayCount;
5356            if (viewSpec.duration) {
5357                duration = viewSpec.duration;
5358                unit = viewSpec.durationUnit;
5359                range = this.buildRangeFromDuration(date, direction, duration, unit);
5360            }
5361            else if ((dayCount = this.options.dayCount)) {
5362                unit = 'day';
5363                range = this.buildRangeFromDayCount(date, direction, dayCount);
5364            }
5365            else if ((range = this.buildCustomVisibleRange(date))) {
5366                unit = dateEnv.greatestWholeUnit(range.start, range.end).unit;
5367            }
5368            else {
5369                duration = this.getFallbackDuration();
5370                unit = greatestDurationDenominator(duration).unit;
5371                range = this.buildRangeFromDuration(date, direction, duration, unit);
5372            }
5373            return { duration: duration, unit: unit, range: range };
5374        };
5375        DateProfileGenerator.prototype.getFallbackDuration = function () {
5376            return createDuration({ day: 1 });
5377        };
5378        // Returns a new activeRange to have time values (un-ambiguate)
5379        // minTime or maxTime causes the range to expand.
5380        DateProfileGenerator.prototype.adjustActiveRange = function (range, minTime, maxTime) {
5381            var dateEnv = this.dateEnv;
5382            var start = range.start;
5383            var end = range.end;
5384            if (this.viewSpec.class.prototype.usesMinMaxTime) {
5385                // expand active range if minTime is negative (why not when positive?)
5386                if (asRoughDays(minTime) < 0) {
5387                    start = startOfDay(start); // necessary?
5388                    start = dateEnv.add(start, minTime);
5389                }
5390                // expand active range if maxTime is beyond one day (why not when positive?)
5391                if (asRoughDays(maxTime) > 1) {
5392                    end = startOfDay(end); // necessary?
5393                    end = addDays(end, -1);
5394                    end = dateEnv.add(end, maxTime);
5395                }
5396            }
5397            return { start: start, end: end };
5398        };
5399        // Builds the "current" range when it is specified as an explicit duration.
5400        // `unit` is the already-computed greatestDurationDenominator unit of duration.
5401        DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
5402            var dateEnv = this.dateEnv;
5403            var alignment = this.options.dateAlignment;
5404            var dateIncrementInput;
5405            var dateIncrementDuration;
5406            var start;
5407            var end;
5408            var res;
5409            // compute what the alignment should be
5410            if (!alignment) {
5411                dateIncrementInput = this.options.dateIncrement;
5412                if (dateIncrementInput) {
5413                    dateIncrementDuration = createDuration(dateIncrementInput);
5414                    // use the smaller of the two units
5415                    if (asRoughMs(dateIncrementDuration) < asRoughMs(duration)) {
5416                        alignment = greatestDurationDenominator(dateIncrementDuration, !getWeeksFromInput(dateIncrementInput)).unit;
5417                    }
5418                    else {
5419                        alignment = unit;
5420                    }
5421                }
5422                else {
5423                    alignment = unit;
5424                }
5425            }
5426            // if the view displays a single day or smaller
5427            if (asRoughDays(duration) <= 1) {
5428                if (this.isHiddenDay(start)) {
5429                    start = this.skipHiddenDays(start, direction);
5430                    start = startOfDay(start);
5431                }
5432            }
5433            function computeRes() {
5434                start = dateEnv.startOf(date, alignment);
5435                end = dateEnv.add(start, duration);
5436                res = { start: start, end: end };
5437            }
5438            computeRes();
5439            // if range is completely enveloped by hidden days, go past the hidden days
5440            if (!this.trimHiddenDays(res)) {
5441                date = this.skipHiddenDays(date, direction);
5442                computeRes();
5443            }
5444            return res;
5445        };
5446        // Builds the "current" range when a dayCount is specified.
5447        DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
5448            var dateEnv = this.dateEnv;
5449            var customAlignment = this.options.dateAlignment;
5450            var runningCount = 0;
5451            var start = date;
5452            var end;
5453            if (customAlignment) {
5454                start = dateEnv.startOf(start, customAlignment);
5455            }
5456            start = startOfDay(start);
5457            start = this.skipHiddenDays(start, direction);
5458            end = start;
5459            do {
5460                end = addDays(end, 1);
5461                if (!this.isHiddenDay(end)) {
5462                    runningCount++;
5463                }
5464            } while (runningCount < dayCount);
5465            return { start: start, end: end };
5466        };
5467        // Builds a normalized range object for the "visible" range,
5468        // which is a way to define the currentRange and activeRange at the same time.
5469        DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
5470            var dateEnv = this.dateEnv;
5471            var visibleRange = this.getRangeOption('visibleRange', dateEnv.toDate(date));
5472            if (visibleRange && (visibleRange.start == null || visibleRange.end == null)) {
5473                return null;
5474            }
5475            return visibleRange;
5476        };
5477        // Computes the range that will represent the element/cells for *rendering*,
5478        // but which may have voided days/times.
5479        // not responsible for trimming hidden days.
5480        DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
5481            return currentRange;
5482        };
5483        // Compute the duration value that should be added/substracted to the current date
5484        // when a prev/next operation happens.
5485        DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
5486            var dateIncrementInput = this.options.dateIncrement;
5487            var customAlignment;
5488            if (dateIncrementInput) {
5489                return createDuration(dateIncrementInput);
5490            }
5491            else if ((customAlignment = this.options.dateAlignment)) {
5492                return createDuration(1, customAlignment);
5493            }
5494            else if (fallback) {
5495                return fallback;
5496            }
5497            else {
5498                return createDuration({ days: 1 });
5499            }
5500        };
5501        // Arguments after name will be forwarded to a hypothetical function value
5502        // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects.
5503        // Always clone your objects if you fear mutation.
5504        DateProfileGenerator.prototype.getRangeOption = function (name) {
5505            var otherArgs = [];
5506            for (var _i = 1; _i < arguments.length; _i++) {
5507                otherArgs[_i - 1] = arguments[_i];
5508            }
5509            var val = this.options[name];
5510            if (typeof val === 'function') {
5511                val = val.apply(null, otherArgs);
5512            }
5513            if (val) {
5514                val = parseRange(val, this.dateEnv);
5515            }
5516            if (val) {
5517                val = computeVisibleDayRange(val);
5518            }
5519            return val;
5520        };
5521        /* Hidden Days
5522        ------------------------------------------------------------------------------------------------------------------*/
5523        // Initializes internal variables related to calculating hidden days-of-week
5524        DateProfileGenerator.prototype.initHiddenDays = function () {
5525            var hiddenDays = this.options.hiddenDays || []; // array of day-of-week indices that are hidden
5526            var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
5527            var dayCnt = 0;
5528            var i;
5529            if (this.options.weekends === false) {
5530                hiddenDays.push(0, 6); // 0=sunday, 6=saturday
5531            }
5532            for (i = 0; i < 7; i++) {
5533                if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
5534                    dayCnt++;
5535                }
5536            }
5537            if (!dayCnt) {
5538                throw new Error('invalid hiddenDays'); // all days were hidden? bad.
5539            }
5540            this.isHiddenDayHash = isHiddenDayHash;
5541        };
5542        // Remove days from the beginning and end of the range that are computed as hidden.
5543        // If the whole range is trimmed off, returns null
5544        DateProfileGenerator.prototype.trimHiddenDays = function (range) {
5545            var start = range.start;
5546            var end = range.end;
5547            if (start) {
5548                start = this.skipHiddenDays(start);
5549            }
5550            if (end) {
5551                end = this.skipHiddenDays(end, -1, true);
5552            }
5553            if (start == null || end == null || start < end) {
5554                return { start: start, end: end };
5555            }
5556            return null;
5557        };
5558        // Is the current day hidden?
5559        // `day` is a day-of-week index (0-6), or a Date (used for UTC)
5560        DateProfileGenerator.prototype.isHiddenDay = function (day) {
5561            if (day instanceof Date) {
5562                day = day.getUTCDay();
5563            }
5564            return this.isHiddenDayHash[day];
5565        };
5566        // Incrementing the current day until it is no longer a hidden day, returning a copy.
5567        // DOES NOT CONSIDER validRange!
5568        // If the initial value of `date` is not a hidden day, don't do anything.
5569        // Pass `isExclusive` as `true` if you are dealing with an end date.
5570        // `inc` defaults to `1` (increment one day forward each time)
5571        DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) {
5572            if (inc === void 0) { inc = 1; }
5573            if (isExclusive === void 0) { isExclusive = false; }
5574            while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
5575                date = addDays(date, inc);
5576            }
5577            return date;
5578        };
5579        return DateProfileGenerator;
5580    }());
5581    // TODO: find a way to avoid comparing DateProfiles. it's tedious
5582    function isDateProfilesEqual(p0, p1) {
5583        return rangesEqual(p0.validRange, p1.validRange) &&
5584            rangesEqual(p0.activeRange, p1.activeRange) &&
5585            rangesEqual(p0.renderRange, p1.renderRange) &&
5586            durationsEqual(p0.minTime, p1.minTime) &&
5587            durationsEqual(p0.maxTime, p1.maxTime);
5588        /*
5589        TODO: compare more?
5590          currentRange: DateRange
5591          currentRangeUnit: string
5592          isRangeAllDay: boolean
5593          isValid: boolean
5594          dateIncrement: Duration
5595        */
5596    }
5597
5598    function reduce (state, action, calendar) {
5599        var viewType = reduceViewType(state.viewType, action);
5600        var dateProfile = reduceDateProfile(state.dateProfile, action, state.currentDate, viewType, calendar);
5601        var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendar);
5602        var nextState = __assign({}, state, { viewType: viewType,
5603            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) });
5604        for (var _i = 0, _a = calendar.pluginSystem.hooks.reducers; _i < _a.length; _i++) {
5605            var reducerFunc = _a[_i];
5606            nextState = reducerFunc(nextState, action, calendar);
5607        }
5608        // console.log(action.type, nextState)
5609        return nextState;
5610    }
5611    function reduceViewType(currentViewType, action) {
5612        switch (action.type) {
5613            case 'SET_VIEW_TYPE':
5614                return action.viewType;
5615            default:
5616                return currentViewType;
5617        }
5618    }
5619    function reduceDateProfile(currentDateProfile, action, currentDate, viewType, calendar) {
5620        var newDateProfile;
5621        switch (action.type) {
5622            case 'PREV':
5623                newDateProfile = calendar.dateProfileGenerators[viewType].buildPrev(currentDateProfile, currentDate);
5624                break;
5625            case 'NEXT':
5626                newDateProfile = calendar.dateProfileGenerators[viewType].buildNext(currentDateProfile, currentDate);
5627                break;
5628            case 'SET_DATE':
5629                if (!currentDateProfile.activeRange ||
5630                    !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker)) {
5631                    newDateProfile = calendar.dateProfileGenerators[viewType].build(action.dateMarker, undefined, true // forceToValid
5632                    );
5633                }
5634                break;
5635            case 'SET_VIEW_TYPE':
5636                var generator = calendar.dateProfileGenerators[viewType];
5637                if (!generator) {
5638                    throw new Error(viewType ?
5639                        'The FullCalendar view "' + viewType + '" does not exist. Make sure your plugins are loaded correctly.' :
5640                        'No available FullCalendar view plugins.');
5641                }
5642                newDateProfile = generator.build(action.dateMarker || currentDate, undefined, true // forceToValid
5643                );
5644                break;
5645        }
5646        if (newDateProfile &&
5647            newDateProfile.isValid &&
5648            !(currentDateProfile && isDateProfilesEqual(currentDateProfile, newDateProfile))) {
5649            return newDateProfile;
5650        }
5651        else {
5652            return currentDateProfile;
5653        }
5654    }
5655    function reduceCurrentDate(currentDate, action, dateProfile) {
5656        switch (action.type) {
5657            case 'PREV':
5658            case 'NEXT':
5659                if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) {
5660                    return dateProfile.currentRange.start;
5661                }
5662                else {
5663                    return currentDate;
5664                }
5665            case 'SET_DATE':
5666            case 'SET_VIEW_TYPE':
5667                var newDate = action.dateMarker || currentDate;
5668                if (dateProfile.activeRange && !rangeContainsMarker(dateProfile.activeRange, newD
5668ate)) {
5669                    return dateProfile.currentRange.start;
5670                }
5671                else {
5672                    return newDate;
5673                }
5674            default:
5675                return currentDate;
5676        }
5677    }
5678    function reduceDateSelection(currentSelection, action, calendar) {
5679        switch (action.type) {
5680            case 'SELECT_DATES':
5681                return action.selection;
5682            case 'UNSELECT_DATES':
5683                return null;
5684            default:
5685                return currentSelection;
5686        }
5687    }
5688    function reduceSelectedEvent(currentInstanceId, action) {
5689        switch (action.type) {
5690            case 'SELECT_EVENT':
5691                return action.eventInstanceId;
5692            case 'UNSELECT_EVENT':
5693                return '';
5694            default:
5695                return currentInstanceId;
5696        }
5697    }
5698    function reduceEventDrag(currentDrag, action, sources, calendar) {
5699        switch (action.type) {
5700            case 'SET_EVENT_DRAG':
5701                var newDrag = action.state;
5702                return {
5703                    affectedEvents: newDrag.affectedEvents,
5704                    mutatedEvents: newDrag.mutatedEvents,
5705                    isEvent: newDrag.isEvent,
5706                    origSeg: newDrag.origSeg
5707                };
5708            case 'UNSET_EVENT_DRAG':
5709                return null;
5710            default:
5711                return currentDrag;
5712        }
5713    }
5714    function reduceEventResize(currentResize, action, sources, calendar) {
5715        switch (action.type) {
5716            case 'SET_EVENT_RESIZE':
5717                var newResize = action.state;
5718                return {
5719                    affectedEvents: newResize.affectedEvents,
5720                    mutatedEvents: newResize.mutatedEvents,
5721                    isEvent: newResize.isEvent,
5722                    origSeg: newResize.origSeg
5723                };
5724            case 'UNSET_EVENT_RESIZE':
5725                return null;
5726            default:
5727                return currentResize;
5728        }
5729    }
5730    function computeLoadingLevel(eventSources) {
5731        var cnt = 0;
5732        for (var sourceId in eventSources) {
5733            if (eventSources[sourceId].isFetching) {
5734                cnt++;
5735            }
5736        }
5737        return cnt;
5738    }
5739
5740    var STANDARD_PROPS = {
5741        start: null,
5742        end: null,
5743        allDay: Boolean
5744    };
5745    function parseDateSpan(raw, dateEnv, defaultDuration) {
5746        var span = parseOpenDateSpan(raw, dateEnv);
5747        var range = span.range;
5748        if (!range.start) {
5749            return null;
5750        }
5751        if (!range.end) {
5752            if (defaultDuration == null) {
5753                return null;
5754            }
5755            else {
5756                range.end = dateEnv.add(range.start, defaultDuration);
5757            }
5758        }
5759        return span;
5760    }
5761    /*
5762    TODO: somehow combine with parseRange?
5763    Will return null if the start/end props were present but parsed invalidly.
5764    */
5765    function parseOpenDateSpan(raw, dateEnv) {
5766        var leftovers = {};
5767        var standardProps = refineProps(raw, STANDARD_PROPS, {}, leftovers);
5768        var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
5769        var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
5770        var allDay = standardProps.allDay;
5771        if (allDay == null) {
5772            allDay = (startMeta && startMeta.isTimeUnspecified) &&
5773                (!endMeta || endMeta.isTimeUnspecified);
5774        }
5775        // use this leftover object as the selection object
5776        leftovers.range = {
5777            start: startMeta ? startMeta.marker : null,
5778            end: endMeta ? endMeta.marker : null
5779        };
5780        leftovers.allDay = allDay;
5781        return leftovers;
5782    }
5783    function isDateSpansEqual(span0, span1) {
5784        return rangesEqual(span0.range, span1.range) &&
5785            span0.allDay === span1.allDay &&
5786            isSpanPropsEqual(span0, span1);
5787    }
5788    // the NON-DATE-RELATED props
5789    function isSpanPropsEqual(span0, span1) {
5790        for (var propName in span1) {
5791            if (propName !== 'range' && propName !== 'allDay') {
5792                if (span0[propName] !== span1[propName]) {
5793                    return false;
5794                }
5795            }
5796        }
5797        // are there any props that span0 has that span1 DOESN'T have?
5798        // both have range/allDay, so no need to special-case.
5799        for (var propName in span0) {
5800            if (!(propName in span1)) {
5801                return false;
5802            }
5803        }
5804        return true;
5805    }
5806    function buildDateSpanApi(span, dateEnv) {
5807        return {
5808            start: dateEnv.toDate(span.range.start),
5809            end: dateEnv.toDate(span.range.end),
5810            startStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
5811            endStr: dateEnv.formatIso(span.range.end, { omitTime: span.allDay }),
5812            allDay: span.allDay
5813        };
5814    }
5815    function buildDatePointApi(span, dateEnv) {
5816        return {
5817            date: dateEnv.toDate(span.range.start),
5818            dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
5819            allDay: span.allDay
5820        };
5821    }
5822    function fabricateEventRange(dateSpan, eventUiBases, calendar) {
5823        var def = parseEventDef({ editable: false }, '', // sourceId
5824        dateSpan.allDay, true, // hasEnd
5825        calendar);
5826        return {
5827            def: def,
5828            ui: compileEventUi(def, eventUiBases),
5829            instance: createEventInstance(def.defId, dateSpan.range),
5830            range: dateSpan.range,
5831            isStart: true,
5832            isEnd: true
5833        };
5834    }
5835
5836    function compileViewDefs(defaultConfigs, overrideConfigs) {
5837        var hash = {};
5838        var viewType;
5839        for (viewType in defaultConfigs) {
5840            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5841        }
5842        for (viewType in overrideConfigs) {
5843            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5844        }
5845        return hash;
5846    }
5847    function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5848        if (hash[viewType]) {
5849            return hash[viewType];
5850        }
5851        var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5852        if (viewDef) {
5853            hash[viewType] = viewDef;
5854        }
5855        return viewDef;
5856    }
5857    function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5858        var defaultConfig = defaultConfigs[viewType];
5859        var overrideConfig = overrideConfigs[viewType];
5860        var queryProp = function (name) {
5861            return (defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
5862                ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null);
5863        };
5864        var theClass = queryProp('class');
5865        var superType = queryProp('superType');
5866        if (!superType && theClass) {
5867            superType =
5868                findViewNameBySubclass(theClass, overrideConfigs) ||
5869                    findViewNameBySubclass(theClass, defaultConfigs);
5870        }
5871        var superDef = null;
5872        if (superType) {
5873            if (superType === viewType) {
5874                throw new Error('Can\'t have a custom view type that references itself');
5875            }
5876            superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);
5877        }
5878        if (!theClass && superDef) {
5879            theClass = superDef.class;
5880        }
5881        if (!theClass) {
5882            return null; // don't throw a warning, might be settings for a single-unit view
5883        }
5884        return {
5885            type: viewType,
5886            class: theClass,
5887            defaults: __assign({}, (superDef ? superDef.defaults : {}), (defaultConfig ? defaultConfig.options : {})),
5888            overrides: __assign({}, (superDef ? superDef.overrides : {}), (overrideConfig ? overrideConfig.options : {}))
5889        };
5890    }
5891    function findViewNameBySubclass(viewSubclass, configs) {
5892        var superProto = Object.getPrototypeOf(viewSubclass.prototype);
5893        for (var viewType in configs) {
5894            var parsed = configs[viewType];
5895            // need DIRECT subclass, so instanceof won't do it
5896            if (parsed.class && parsed.class.prototype === superProto) {
5897                return viewType;
5898            }
5899        }
5900        return '';
5901    }
5902
5903    function parseViewConfigs(inputs) {
5904        return mapHash(inputs, parseViewConfig);
5905    }
5906    var VIEW_DEF_PROPS = {
5907        type: String,
5908        class: null
5909    };
5910    function parseViewConfig(input) {
5911        if (typeof input === 'function') {
5912            input = { class: input };
5913        }
5914        var options = {};
5915        var props = refineProps(input, VIEW_DEF_PROPS, {}, options);
5916        return {
5917            superType: props.type,
5918            class: props.class,
5919            options: options
5920        };
5921    }
5922
5923    function buildViewSpecs(defaultInputs, optionsManager) {
5924        var defaultConfigs = parseViewConfigs(defaultInputs);
5925        var overrideConfigs = parseViewConfigs(optionsManager.overrides.views);
5926        var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
5927        return mapHash(viewDefs, function (viewDef) {
5928            return buildViewSpec(viewDef, overrideConfigs, optionsManager);
5929        });
5930    }
5931    function buildViewSpec(viewDef, overrideConfigs, optionsManager) {
5932        var durationInput = viewDef.overrides.duration ||
5933            viewDef.defaults.duration ||
5934            optionsManager.dynamicOverrides.duration ||
5935            optionsManager.overrides.duration;
5936        var duration = null;
5937        var durationUnit = '';
5938        var singleUnit = '';
5939        var singleUnitOverrides = {};
5940        if (durationInput) {
5941            duration = createDuration(durationInput);
5942            if (duration) { // valid?
5943                var denom = greatestDurationDenominator(duration, !getWeeksFromInput(durationInput));
5944                durationUnit = denom.unit;
5945                if (denom.value === 1) {
5946                    singleUnit = durationUnit;
5947                    singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].options : {};
5948                }
5949            }
5950        }
5951        var queryButtonText = function (options) {
5952            var buttonTextMap = options.buttonText || {};
5953            var buttonTextKey = viewDef.defaults.buttonTextKey;
5954            if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
5955                return buttonTextMap[buttonTextKey];
5956            }
5957            if (buttonTextMap[viewDef.type] != null) {
5958                return buttonTextMap[viewDef.type];
5959            }
5960            if (buttonTextMap[singleUnit] != null) {
5961                return buttonTextMap[singleUnit];
5962            }
5963        };
5964        return {
5965            type: viewDef.type,
5966            class: viewDef.class,
5967            duration: duration,
5968            durationUnit: durationUnit,
5969            singleUnit: singleUnit,
5970            options: __assign({}, globalDefaults, viewDef.defaults, optionsManager.dirDefaults, optionsManager.localeDefaults, optionsManager.overrides, singleUnitOverrides, viewDef.overrides, optionsManager.dynamicOverrides),
5971            buttonTextOverride: queryButtonText(optionsManager.dynamicOverrides) ||
5972                queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence
5973                viewDef.overrides.buttonText,
5974            buttonTextDefault: queryButtonText(optionsManager.localeDefaults) ||
5975                queryButtonText(optionsManager.dirDefaults) ||
5976                viewDef.defaults.buttonText ||
5977                queryButtonText(globalDefaults) ||
5978                viewDef.type // fall back to given view name
5979        };
5980    }
5981
5982    var Toolbar = /** @class */ (function (_super) {
5983        __extends(Toolbar, _super);
5984        function Toolbar(extraClassName) {
5985            var _this = _super.call(this) || this;
5986            _this._renderLayout = memoizeRendering(_this.renderLayout, _this.unrenderLayout);
5987            _this._updateTitle = memoizeRendering(_this.updateTitle, null, [_this._renderLayout]);
5988            _this._updateActiveButton = memoizeRendering(_this.updateActiveButton, null, [_this._renderLayout]);
5989            _this._updateToday = memoizeRendering(_this.updateToday, null, [_this._renderLayout]);
5990            _this._updatePrev = memoizeRendering(_this.updatePrev, null, [_this._renderLayout]);
5991            _this._updateNext = memoizeRendering(_this.updateNext, null, [_this._renderLayout]);
5992            _this.el = createElement('div', { className: 'fc-toolbar ' + extraClassName });
5993            return _this;
5994        }
5995        Toolbar.prototype.destroy = function () {
5996            _super.prototype.destroy.call(this);
5997            this._renderLayout.unrender(); // should unrender everything else
5998            removeElement(this.el);
5999        };
6000        Toolbar.prototype.render = function (props) {
6001            this._renderLayout(props.layout);
6002            this._updateTitle(props.title);
6003            this._updateActiveButton(props.activeButton);
6004            this._updateToday(props.isTodayEnabled);
6005            this._updatePrev(props.isPrevEnabled);
6006            this._updateNext(props.isNextEnabled);
6007        };
6008        Toolbar.prototype.renderLayout = function (layout) {
6009            var el = this.el;
6010            this.viewsWithButtons = [];
6011            appendToElement(el, this.renderSection('left', layout.left));
6012            appendToElement(el, this.renderSection('center', layout.center));
6013            appendToElement(el, this.renderSection('right', layout.right));
6014        };
6015        Toolbar.prototype.unrenderLayout = function () {
6016            this.el.innerHTML = '';
6017        };
6018        Toolbar.prototype.renderSection = function (position, buttonStr) {
6019            var _this = this;
6020            var _a = this.context, theme = _a.theme, calendar = _a.calendar;
6021            var optionsManager = calendar.optionsManager;
6022            var viewSpecs = calendar.viewSpecs;
6023            var sectionEl = createElement('div', { className: 'fc-' + position });
6024            var calendarCustomButtons = optionsManager.computed.customButtons || {};
6025            var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {};
6026            var calendarButtonText = optionsManager.computed.buttonText || {};
6027            if (buttonStr) {
6028                buttonStr.split(' ').forEach(function (buttonGroupStr, i) {
6029                    var groupChildren = [];
6030                    var isOnlyButtons = true;
6031                    var groupEl;
6032                    buttonGroupStr.split(',').forEach(function (buttonName, j) {
6033                        var customButtonProps;
6034                        var viewSpec;
6035                        var buttonClick;
6036                        var buttonIcon; // only one of these will be set
6037                        var buttonText; // "
6038                        var buttonInnerHtml;
6039                        var buttonClasses;
6040                        var buttonEl;
6041                        var buttonAriaAttr;
6042                        if (buttonName === 'title') {
6043                            groupChildren.push(htmlToElement('<h2>&nbsp;</h2>')); // we always want it to take up height
6044                            isOnlyButtons = false;
6045                        }
6046                        else {
6047                            if ((customButtonProps = calendarCustomButtons[buttonName])) {
6048                                buttonClick = function (ev) {
6049                                    if (customButtonProps.click) {
6050                                        customButtonProps.click.call(buttonEl, ev);
6051                                    }
6052                                };
6053                                (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
6054                                    (buttonIcon = theme.getIconClass(buttonName)) ||
6055                                    (buttonText = customButtonProps.text);
6056                            }
6057                            else if ((viewSpec = viewSpecs[buttonName])) {
6058                                _this.viewsWithButtons.push(buttonName);
6059                                buttonClick = function () {
6060                                    calendar.changeView(buttonName);
6061                                };
6062                                (buttonText = viewSpec.buttonTextOverride) ||
6063                                    (buttonIcon = theme.getIconClass(buttonName)) ||
6064                                    (buttonText = viewSpec.buttonTextDefault);
6065                            }
6066                            else if (calendar[buttonName]) { // a calendar method
6067                                buttonClick = function () {
6068                                    calendar[buttonName]();
6069                                };
6070                                (buttonText = calendarButtonTextOverrides[buttonName]) ||
6071                                    (buttonIcon = theme.getIconClass(buttonName)) ||
6072                                    (buttonText = calendarButtonText[buttonName]);
6073                                //            ^ everything else is considered default
6074                            }
6075                            if (buttonClick) {
6076                                buttonClasses = [
6077                                    'fc-' + buttonName + '-button',
6078                                    theme.getClass('button')
6079                                ];
6080                                if (buttonText) {
6081                                    buttonInnerHtml = htmlEscape(buttonText);
6082                                    buttonAriaAttr = '';
6083                                }
6084                                else if (buttonIcon) {
6085                                    buttonInnerHtml = "<span class='" + buttonIcon + "'></span>";
6086                                    buttonAriaAttr = ' aria-label="' + buttonName + '"';
6087                                }
6088                                buttonEl = htmlToElement(// type="button" so that it doesn't submit a form
6089                                '<button type="button" class="' + buttonClasses.join(' ') + '"' +
6090                                    buttonAriaAttr +
6091                                    '>' + buttonInnerHtml + '</button>');
6092                                buttonEl.addEventListener('click', buttonClick);
6093                                groupChildren.push(buttonEl);
6094                            }
6095                        }
6096                    });
6097                    if (groupChildren.length > 1) {
6098                        groupEl = document.createElement('div');
6099                        var buttonGroupClassName = theme.getClass('buttonGroup');
6100                        if (isOnlyButtons && buttonGroupClassName) {
6101                            groupEl.classList.add(buttonGroupClassName);
6102                        }
6103                        appendToElement(groupEl, groupChildren);
6104                        sectionEl.appendChild(groupEl);
6105                    }
6106                    else {
6107                        appendToElement(sectionEl, groupChildren); // 1 or 0 children
6108                    }
6109                });
6110            }
6111            return sectionEl;
6112        };
6113        Toolbar.prototype.updateToday = function (isTodayEnabled) {
6114            this.toggleButtonEnabled('today', isTodayEnabled);
6115        };
6116        Toolbar.prototype.updatePrev = function (isPrevEnabled) {
6117            this.toggleButtonEnabled('prev', isPrevEnabled);
6118        };
6119        Toolbar.prototype.updateNext = function (isNextEnabled) {
6120            this.toggleButtonEnabled('next', isNextEnabled);
6121        };
6122        Toolbar.prototype.updateTitle = function (text) {
6123            findElements(this.el, 'h2').forEach(function (titleEl) {
6124                titleEl.innerText = text;
6125            });
6126        };
6127        Toolbar.prototype.updateActiveButton = function (buttonName) {
6128            var theme = this.context.theme;
6129            var className = theme.getClass('buttonActive');
6130            findElements(this.el, 'button').forEach(function (buttonEl) {
6131                if (buttonName && buttonEl.classList.contains('fc-' 
6131+ buttonName + '-button')) {
6132                    buttonEl.classList.add(className);
6133                }
6134                else {
6135                    buttonEl.classList.remove(className);
6136                }
6137            });
6138        };
6139        Toolbar.prototype.toggleButtonEnabled = function (buttonName, bool) {
6140            findElements(this.el, '.fc-' + buttonName + '-button').forEach(function (buttonEl) {
6141                buttonEl.disabled = !bool;
6142            });
6143        };
6144        return Toolbar;
6145    }(Component));
6146
6147    var CalendarComponent = /** @class */ (function (_super) {
6148        __extends(CalendarComponent, _super);
6149        function CalendarComponent(el) {
6150            var _this = _super.call(this) || this;
6151            _this.elClassNames = [];
6152            _this.renderSkeleton = memoizeRendering(_this._renderSkeleton, _this._unrenderSkeleton);
6153            _this.renderToolbars = memoizeRendering(_this._renderToolbars, _this._unrenderToolbars, [_this.renderSkeleton]);
6154            _this.buildComponentContext = memoize(buildComponentContext);
6155            _this.buildViewPropTransformers = memoize(buildViewPropTransformers);
6156            _this.el = el;
6157            _this.computeTitle = memoize(computeTitle);
6158            _this.parseBusinessHours = memoize(function (input) {
6159                return parseBusinessHours(input, _this.context.calendar);
6160            });
6161            return _this;
6162        }
6163        CalendarComponent.prototype.render = function (props, context) {
6164            this.freezeHeight();
6165            var title = this.computeTitle(props.dateProfile, props.viewSpec.options);
6166            this.renderSkeleton(context);
6167            this.renderToolbars(props.viewSpec, props.dateProfile, props.currentDate, title);
6168            this.renderView(props, title);
6169            this.updateSize();
6170            this.thawHeight();
6171        };
6172        CalendarComponent.prototype.destroy = function () {
6173            if (this.header) {
6174                this.header.destroy();
6175            }
6176            if (this.footer) {
6177                this.footer.destroy();
6178            }
6179            this.renderSkeleton.unrender(); // will call destroyView
6180            _super.prototype.destroy.call(this);
6181        };
6182        CalendarComponent.prototype._renderSkeleton = function (context) {
6183            this.updateElClassNames(context);
6184            prependToElement(this.el, this.contentEl = createElement('div', { className: 'fc-view-container' }));
6185            var calendar = context.calendar;
6186            for (var _i = 0, _a = calendar.pluginSystem.hooks.viewContainerModifiers; _i < _a.length; _i++) {
6187                var modifyViewContainer = _a[_i];
6188                modifyViewContainer(this.contentEl, calendar);
6189            }
6190        };
6191        CalendarComponent.prototype._unrenderSkeleton = function () {
6192            // weird to have this here
6193            if (this.view) {
6194                this.savedScroll = this.view.queryScroll();
6195                this.view.destroy();
6196                this.view = null;
6197            }
6198            removeElement(this.contentEl);
6199            this.removeElClassNames();
6200        };
6201        CalendarComponent.prototype.removeElClassNames = function () {
6202            var classList = this.el.classList;
6203            for (var _i = 0, _a = this.elClassNames; _i < _a.length; _i++) {
6204                var className = _a[_i];
6205                classList.remove(className);
6206            }
6207            this.elClassNames = [];
6208        };
6209        CalendarComponent.prototype.updateElClassNames = function (context) {
6210            this.removeElClassNames();
6211            var theme = context.theme, options = context.options;
6212            this.elClassNames = [
6213                'fc',
6214                'fc-' + options.dir,
6215                theme.getClass('widget')
6216            ];
6217            var classList = this.el.classList;
6218            for (var _i = 0, _a = this.elClassNames; _i < _a.length; _i++) {
6219                var className = _a[_i];
6220                classList.add(className);
6221            }
6222        };
6223        CalendarComponent.prototype._renderToolbars = function (viewSpec, dateProfile, currentDate, title) {
6224            var _a = this, context = _a.context, header = _a.header, footer = _a.footer;
6225            var options = context.options, calendar = context.calendar;
6226            var headerLayout = options.header;
6227            var footerLayout = options.footer;
6228            var dateProfileGenerator = this.props.dateProfileGenerator;
6229            var now = calendar.getNow();
6230            var todayInfo = dateProfileGenerator.build(now);
6231            var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate);
6232            var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate);
6233            var toolbarProps = {
6234                title: title,
6235                activeButton: viewSpec.type,
6236                isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now),
6237                isPrevEnabled: prevInfo.isValid,
6238                isNextEnabled: nextInfo.isValid
6239            };
6240            if (headerLayout) {
6241                if (!header) {
6242                    header = this.header = new Toolbar('fc-header-toolbar');
6243                    prependToElement(this.el, header.el);
6244                }
6245                header.receiveProps(__assign({ layout: headerLayout }, toolbarProps), context);
6246            }
6247            else if (header) {
6248                header.destroy();
6249                header = this.header = null;
6250            }
6251            if (footerLayout) {
6252                if (!footer) {
6253                    footer = this.footer = new Toolbar('fc-footer-toolbar');
6254                    appendToElement(this.el, footer.el);
6255                }
6256                footer.receiveProps(__assign({ layout: footerLayout }, toolbarProps), context);
6257            }
6258            else if (footer) {
6259                footer.destroy();
6260                footer = this.footer = null;
6261            }
6262        };
6263        CalendarComponent.prototype._unrenderToolbars = function () {
6264            if (this.header) {
6265                this.header.destroy();
6266                this.header = null;
6267            }
6268            if (this.footer) {
6269                this.footer.destroy();
6270                this.footer = null;
6271            }
6272        };
6273        CalendarComponent.prototype.renderView = function (props, title) {
6274            var view = this.view;
6275            var _a = this.context, calendar = _a.calendar, options = _a.options;
6276            var viewSpec = props.viewSpec, dateProfileGenerator = props.dateProfileGenerator;
6277            if (!view || view.viewSpec !== viewSpec) {
6278                if (view) {
6279                    view.destroy();
6280                }
6281                view = this.view = new viewSpec['class'](viewSpec, this.contentEl);
6282                if (this.savedScroll) {
6283                    view.addScroll(this.savedScroll, true);
6284                    this.savedScroll = null;
6285                }
6286            }
6287            view.title = title; // for the API
6288            var viewProps = {
6289                dateProfileGenerator: dateProfileGenerator,
6290                dateProfile: props.dateProfile,
6291                businessHours: this.parseBusinessHours(viewSpec.options.businessHours),
6292                eventStore: props.eventStore,
6293                eventUiBases: props.eventUiBases,
6294                dateSelection: props.dateSelection,
6295                eventSelection: props.eventSelection,
6296                eventDrag: props.eventDrag,
6297                eventResize: props.eventResize
6298            };
6299            var transformers = this.buildViewPropTransformers(calendar.pluginSystem.hooks.viewPropsTransformers);
6300            for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
6301                var transformer = transformers_1[_i];
6302                __assign(viewProps, transformer.transform(viewProps, viewSpec, props, options));
6303            }
6304            view.receiveProps(viewProps, this.buildComponentContext(this.context, viewSpec, view));
6305        };
6306        // Sizing
6307        // -----------------------------------------------------------------------------------------------------------------
6308        CalendarComponent.prototype.updateSize = function (isResize) {
6309            if (isResize === void 0) { isResize = false; }
6310            var view = this.view;
6311            if (!view) {
6312                return; // why?
6313            }
6314            if (isResize || this.isHeightAuto == null) {
6315                this.computeHeightVars();
6316            }
6317            view.updateSize(isResize, this.viewHeight, this.isHeightAuto);
6318            view.updateNowIndicator(); // we need to guarantee this will run after updateSize
6319            view.popScroll(isResize);
6320        };
6321        CalendarComponent.prototype.computeHeightVars = function () {
6322            var calendar = this.context.calendar; // yuck. need to handle dynamic options
6323            var heightInput = calendar.opt('height');
6324            var contentHeightInput = calendar.opt('contentHeight');
6325            this.isHeightAuto = heightInput === 'auto' || contentHeightInput === 'auto';
6326            if (typeof contentHeightInput === 'number') { // exists and not 'auto'
6327                this.viewHeight = contentHeightInput;
6328            }
6329            else if (typeof contentHeightInput === 'function') { // exists and is a function
6330                this.viewHeight = contentHeightInput();
6331            }
6332            else if (typeof heightInput === 'number') { // exists and not 'auto'
6333                this.viewHeight = heightInput - this.queryToolbarsHeight();
6334            }
6335            else if (typeof heightInput === 'function') { // exists and is a function
6336                this.viewHeight = heightInput() - this.queryToolbarsHeight();
6337            }
6338            else if (heightInput === 'parent') { // set to height of parent element
6339                var parentEl = this.el.parentNode;
6340                this.viewHeight = parentEl.getBoundingClientRect().height - this.queryToolbarsHeight();
6341            }
6342            else {
6343                this.viewHeight = Math.round(this.contentEl.getBoundingClientRect().width /
6344                    Math.max(calendar.opt('aspectRatio'), .5));
6345            }
6346        };
6347        CalendarComponent.prototype.queryToolbarsHeight = function () {
6348            var height = 0;
6349            if (this.header) {
6350                height += computeHeightAndMargins(this.header.el);
6351            }
6352            if (this.footer) {
6353                height += computeHeightAndMargins(this.footer.el);
6354            }
6355            return height;
6356        };
6357        // Height "Freezing"
6358        // -----------------------------------------------------------------------------------------------------------------
6359        CalendarComponent.prototype.freezeHeight = function () {
6360            applyStyle(this.el, {
6361                height: this.el.getBoundingClientRect().height,
6362                overflow: 'hidden'
6363            });
6364        };
6365        CalendarComponent.prototype.thawHeight = function () {
6366            applyStyle(this.el, {
6367                height: '',
6368                overflow: ''
6369            });
6370        };
6371        return CalendarComponent;
6372    }(Component));
6373    // Title and Date Formatting
6374    // -----------------------------------------------------------------------------------------------------------------
6375    // Computes what the title at the top of the calendar should be for this view
6376    function computeTitle(dateProfile, viewOptions) {
6377        var range;
6378        // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
6379        if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
6380            range = dateProfile.currentRange;
6381        }
6382        else { // for day units or smaller, use the actual day range
6383            range = dateProfile.activeRange;
6384        }
6385        return this.context.dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || computeTitleFormat(dateProfile), viewOptions.titleRangeSeparator), { isEndExclusive: dateProfile.isRangeAllDay });
6386    }
6387    // Generates the format string that should be used to generate the title for the current date range.
6388    // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
6389    function computeTitleFormat(dateProfile) {
6390        var currentRangeUnit = dateProfile.currentRangeUnit;
6391        if (currentRangeUnit === 'year') {
6392            return { year: 'numeric' };
6393        }
6394        else if (currentRangeUnit === 'month') {
6395            return { year: 'numeric', month: 'long' }; // like "September 2014"
6396        }
6397        else {
6398            var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
6399            if (days !== null && days > 1) {
6400                // multi-day range. shorter, like "Sep 9 - 10 2014"
6401                return { year: 'numeric', month: 'short', day: 'numeric' };
6402            }
6403            else {
6404                // one day. longer, like "September 9 2014"
6405                return { year: 'numeric', month: 'long', day: 'numeric' };
6406            }
6407        }
6408    }
6409    // build a context scoped to the view
6410    function buildComponentContext(context, viewSpec, view) {
6411        return context.extend(viewSpec.options, view);
6412    }
6413    // Plugin
6414    // -----------------------------------------------------------------------------------------------------------------
6415    function buildViewPropTransformers(theClasses) {
6416        return theClasses.map(function (theClass) {
6417            return new theClass();
6418        });
6419    }
6420
6421    var Interaction = /** @class */ (function () {
6422        function Interaction(settings) {
6423            this.component = settings.component;
6424        }
6425        Interaction.prototype.destroy = function () {
6426        };
6427        return Interaction;
6428    }());
6429    function parseInteractionSettings(component, input) {
6430        return {
6431            component: component,
6432            el: input.el,
6433            useEventCenter: input.useEventCenter != null ? input.useEventCenter : true
6434        };
6435    }
6436    function interactionSettingsToStore(settings) {
6437        var _a;
6438        return _a = {},
6439            _a[settings.component.uid] = settings,
6440            _a;
6441    }
6442    // global state
6443    var interactionSettingsStore = {};
6444
6445    /*
6446    Detects when the user clicks on an event within a DateComponent
6447    */
6448    var EventClicking = /** @class */ (function (_super) {
6449        __extends(EventClicking, _super);
6450        function EventClicking(settings) {
6451            var _this = _super.call(this, settings) || this;
6452            _this.handleSegClick = function (ev, segEl) {
6453                var component = _this.component;
6454                var _a = component.context, calendar = _a.calendar, view = _a.view;
6455                var seg = getElSeg(segEl);
6456                if (seg && // might be the <div> surrounding the more link
6457                    component.isValidSegDownEl(ev.target)) {
6458                    // our way to simulate a link click for elements that can't be <a> tags
6459                    // grab before trigger fired in case trigger trashes DOM thru rerendering
6460                    var hasUrlContainer = elementClosest(ev.target, '.fc-has-url');
6461                    var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
6462                    calendar.publiclyTrigger('eventClick', [
6463                        {
6464                            el: segEl,
6465                            event: new EventApi(component.context.calendar, seg.eventRange.def, seg.eventRange.instance),
6466                            jsEvent: ev,
6467                            view: view
6468                        }
6469                    ]);
6470                    if (url && !ev.defaultPrevented) {
6471                        window.location.href = url;
6472                    }
6473                }
6474            };
6475            var component = settings.component;
6476            _this.destroy = listenBySelector(component.el, 'click', component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegClick);
6477            return _this;
6478        }
6479        return EventClicking;
6480    }(Interaction));
6481
6482    /*
6483    Triggers events and adds/removes core classNames when the user's pointer
6484    enters/leaves event-elements of a component.
6485    */
6486    var EventHovering = /** @class */ (function (_super) {
6487        __extends(EventHovering, _super);
6488        function EventHovering(settings) {
6489            var _this = _super.call(this, settings) || this;
6490            // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
6491            _this.handleEventElRemove = function (el) {
6492                if (el === _this.currentSegEl) {
6493                    _this.handleSegLeave(null, _this.currentSegEl);
6494                }
6495            };
6496            _this.handleSegEnter = function (ev, segEl) {
6497                if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
6498                    segEl.classList.add('fc-allow-mouse-resize');
6499                    _this.currentSegEl = segEl;
6500                    _this.triggerEvent('eventMouseEnter', ev, segEl);
6501                }
6502            };
6503            _this.handleSegLeave = function (ev, segEl) {
6504                if (_this.currentSegEl) {
6505                    segEl.classList.remove('fc-allow-mouse-resize');
6506                    _this.currentSegEl = null;
6507                    _this.triggerEvent('eventMouseLeave', ev, segEl);
6508                }
6509            };
6510            var component = settings.component;
6511            _this.removeHoverListeners = listenToHoverBySelector(component.el, component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegEnter, _this.handleSegLeave);
6512            // how to make sure component already has context?
6513            component.context.calendar.on('eventElRemove', _this.handleEventElRemove);
6514            return _this;
6515        }
6516        EventHovering.prototype.destroy = function () {
6517            this.removeHoverListeners();
6518            this.component.context.calendar.off('eventElRemove', this.handleEventElRemove);
6519        };
6520        EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) {
6521            var component = this.component;
6522            var _a = component.context, calendar = _a.calendar, view = _a.view;
6523            var seg = getElSeg(segEl);
6524            if (!ev || component.isValidSegDownEl(ev.target)) {
6525                calendar.publiclyTrigger(publicEvName, [
6526                    {
6527                        el: segEl,
6528                        event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
6529                        jsEvent: ev,
6530                        view: view
6531                    }
6532                ]);
6533            }
6534        };
6535        return EventHovering;
6536    }(Interaction));
6537
6538    var StandardTheme = /** @class */ (function (_super) {
6539        __extends(StandardTheme, _super);
6540        function StandardTheme() {
6541            return _super !== null && _super.apply(this, arguments) || this;
6542        }
6543        return StandardTheme;
6544    }(Theme));
6545    StandardTheme.prototype.classes = {
6546        widget: 'fc-unthemed',
6547        widgetHeader: 'fc-widget-header',
6548        widgetContent: 'fc-widget-content',
6549        buttonGroup: 'fc-button-group',
6550        button: 'fc-button fc-button-primary',
6551        buttonActive: 'fc-button-active',
6552        popoverHeader: 'fc-widget-header',
6553        popoverContent: 'fc-widget-content',
6554        // day grid
6555        headerRow: 'fc-widget-header',
6556        dayRow: 'fc-widget-content',
6557        // list view
6558        listView: 'fc-widget-content'
6559    };
6560    StandardTheme.prototype.baseIconClass = 'fc-icon';
6561    StandardTheme.prototype.iconClasses = {
6562        close: 'fc-icon-x',
6563        prev: 'fc-icon-chevron-left',
6564        next: 'fc-icon-chevron-right',
6565        prevYear: 'fc-icon-chevrons-left',
6566        nextYear: 'fc-icon-chevrons-right'
6567    };
6568    StandardTheme.prototype.iconOverrideOption = 'buttonIcons';
6569    StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
6570    StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
6571
6572    var Calendar = /** @class */ (function () {
6573        function Calendar(el, overrides) {
6574            var _this = this;
6575            this.buildComponentContext = memoize(buildComponentContext$1);
6576            this.parseRawLocales = memoize(parseRawLocales);
6577            this.buildLocale = memoize(buildLocale);
6578            this.buildDateEnv = memoize(buildDateEnv);
6579            this.buildTheme = memoize(buildTheme);
6580            this.buildEventUiSingleBase = memoize(this._buildEventUiSingleBase);
6581            this.buildSelectionConfig = memoize(this._buildSelectionConfig);
6582            this.buildEventUiBySource = memoizeOutput(buildEventUiBySource, isPropsEqual);
6583            this.buildEventUiBases = memoize(buildEventUiBases);
6584            this.interactionsStore = {};
6585            this.actionQueue = [];
6586            this.isReducing = false;
6587            // isDisplaying: boolean = false // installed in DOM? accepting renders?
6588            this.needsRerender = false; // needs a render?
6589            this.isRendering = false; // currently in the executeRender function?
6590            this.renderingPauseDepth = 0;
6591            this.buildDelayedRerender = memoize(buildDelayedRerender);
6592            this.afterSizingTriggers = {};
6593            this.isViewUpdated = false;
6594            this.isDatesUpdated = false;
6595            this.isEventsUpdated = false;
6596            this.el = el;
6597            this.optionsManager = new OptionsManager(overrides || {});
6598            this.pluginSystem = new PluginSystem();
6599            // only do once. don't do in handleOptions. because can't remove plugins
6600            this.addPluginInputs(this.optionsManager.computed.plugins || []);
6601            this.handleOptions(this.optionsManager.computed);
6602            this.publiclyTrigger('_init'); // for tests
6603            this.hydrate();
6604            this.calendarInteractions = this.pluginSystem.hooks.calendarInteractions
6605                .map(function (calendarInteractionClass) {
6606                return new calendarInteractionClass(_this);
6607            });
6608        }
6609        Calendar.prototype.addPluginInputs = function (pluginInputs) {
6610            var pluginDefs = refinePluginDefs(pluginInputs);
6611            for (var _i = 0, pluginDefs_1 = pluginDefs; _i < pluginDefs_1.length; _i++) {
6612                var pluginDef = pluginDefs_1[_i];
6613                this.pluginSystem.add(pluginDef);
6614            }
6615        };
6616        Object.defineProperty(Calendar.prototype, "view", {
6617            // public API
6618            get: function () {
6619                return this.component ? this.component.view : null;
6620            },
6621            enumerable: true,
6622            configurable: true
6623        });
6624        // Public API for rendering
6625        // -----------------------------------------------------------------------------------------------------------------
6626        Calendar.prototype.render = function () {
6627            if (!this.component) {
6628                this.component = new CalendarComponent(this.el);
6629                this.renderableEventStore = createEmptyEventStore();
6630                this.bindHandlers();
6631                this.executeRender();
6632            }
6633            else {
6634                this.requestRerender();
6635            }
6636        };
6637        Calendar.prototype.destroy = function () {
6638            if (this.component) {
6639                this.unbindHandlers();
6640                this.component.destroy(); // don't null-out. in case API needs access
6641                this.component = null; // umm ???
6642                for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) {
6643                    var interaction = _a[_i];
6644                    interaction.destroy();
6645                }
6646                this.publiclyTrigger('_destroyed');
6647            }
6648        };
6649        // Handlers
6650        // -----------------------------------------------------------------------------------------------------------------
6651        Calendar.prototype.bindHandlers = function () {
6652            var _this = this;
6653            // event delegation for nav links
6654            this.removeNavLinkListener = listenBySelector(this.el, 'click', 'a[data-goto]', function (ev, anchorEl) {
6655                var gotoOptions = anchorEl.getAttribute('data-goto');
6656                gotoOptions = gotoOptions ? JSON.parse(gotoOptions) : {};
6657                var dateEnv = _this.dateEnv;
6658                var dateMarker = dateEnv.createMarker(gotoOptions.date);
6659                var viewType = gotoOptions.type;
6660                // property like "navLinkDayClick". might be a string or a function
6661                var customAction = _this.viewOpt('navLink' + capitaliseFirstLetter(viewType) + 'Click');
6662                if (typeof customAction === 'function') {
6663                    customAction(dateEnv.toDate(dateMarker), ev);
6664                }
6665                else {
6666                    if (typeof customAction === 'string') {
6667                        viewType = customAction;
6668                    }
6669                    _this.zoomTo(dateMarker, viewType);
6670                }
6671            });
6672            if (this.opt('handleWindowResize')) {
6673                window.addEventListener('resize', this.windowResizeProxy = debounce(// prevents rapid calls
6674                this.windowResize.bind(this), this.opt('windowResizeDelay')));
6675            }
6676        };
6677        Calendar.prototype.unbindHandlers = function () {
6678            this.removeNavLinkListener();
6679            if (this.windowResizeProxy) {
6680                window.removeEventListener('resize', this.windowResizeProxy);
6681                this.windowResizeProxy = null;
6682            }
6683        };
6684        // Dispatcher
6685        // -----------------------------------------------------------------------------------------------------------------
6686        Calendar.prototype.hydrate = function () {
6687            var _this = this;
6688            this.state = this.buildInitialState();
6689            var rawSources = this.opt('eventSources') || [];
6690            var singleRawSource = this.opt('events');
6691            var sources = []; // parsed
6692            if (singleRawSource) {
6693                rawSources.unshift(singleRawSource);
6694            }
6695            for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) {
6696                var rawSource = rawSources_1[_i];
6697                var source = parseEventSource(rawSource, this);
6698                if (source) {
6699                    sources.push(source);
6700                }
6701            }
6702            this.batchRendering(function () {
6703                _this.dispatch({ type: 'INIT' }); // pass in sources here?
6704                _this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: sources });
6705                _this.dispatch({
6706                    type: 'SET_VIEW_TYPE',
6707                    viewType: _this.opt('defaultView') || _this.pluginSystem.hooks.defaultView
6708                });
6709            });
6710        };
6711        Calendar.prototype.buildInitialState = function () {
6712            return {
6713                viewType: null,
6714                loadingLevel: 0,
6715                eventSourceLoadingLevel: 0,
6716                currentDate: this.getInitialDate(),
6717                dateProfile: null,
6718                eventSources: {},
6719                eventStore: createEmptyEventStore(),
6720                dateSelection: null,
6721                eventSelection: '',
6722                eventDrag: null,
6723                eventResize: null
6724            };
6725        };
6726        Calendar.prototype.dispatch = function (action) {
6727            this.actionQueue.push(action);
6728            if (!this.isReducing) {
6729                this.isReducing = true;
6730                var oldState = this.state;
6731                while (this.actionQueue.length) {
6732                    this.state = this.reduce(this.state, this.actionQueue.shift(), this);
6733                }
6734                var newState = this.state;
6735                this.isReducing = false;
6736                if (!oldState.loadingLevel && newState.loadingLevel) {
6737                    this.publiclyTrigger('loading', [true]);
6738                }
6739                else if (oldState.loadingLevel && !newState.loadingLevel) {
6740                    this.publiclyTrigger('loading', [false]);
6741                }
6742                var view = this.component && this.component.view;
6743                if (oldState.eventStore !== newState.eventStore) {
6744                    if (oldState.eventStore) {
6745                        this.isEventsUpdated = true;
6746                    }
6747                }
6748                if (oldState.dateProfile !== newState.dateProfile) {
6749                    if (oldState.dateProfile && view) { // why would view be null!?
6750                        this.publiclyTrigger('datesDestroy', [
6751                            {
6752                                view: view,
6753                                el: view.el
6754                            }
6755                        ]);
6756                    }
6757                    this.isDatesUpdated = true;
6758                }
6759                if (oldState.viewType !== newState.viewType) {
6760                    if (oldState.viewType && view) { // why would view be null!?
6761                        this.publiclyTrigger('viewSkeletonDestroy', [
6762                            {
6763                                view: view,
6764                                el: view.el
6765                            }
6766                        ]);
6767                    }
6768                    this.isViewUpdated = true;
6769                }
6770                this.requestRerender();
6771            }
6772        };
6773        Calendar.prototype.reduce = function (state, action, calendar) {
6774            return reduce(state, action, calendar);
6775        };
6776        // Render Queue
6777        // -----------------------------------------------------------------------------------------------------------------
6778        Calendar.prototype.requestRerender = function () {
6779            this.needsRerender = true;
6780            this.delayedRerender(); // will call a debounced-version of tryRerender
6781        };
6782        Calendar.prototype.tryRerender = function () {
6783            if (this.component && // must be accepting renders
6784                this.needsRerender && // indicates that a rerender was requested
6785                !this.renderingPauseDepth && // not paused
6786                !this.isRendering // not currently in the render loop
6787            ) {
6788                this.executeRender();
6789            }
6790        };
6791        Calendar.prototype.batchRendering = function (func) {
6792            this.renderingPauseDepth++;
6793            func();
6794            this.renderingPauseDepth--;
6795            if (this.needsRerender) {
6796                this.requestRerender();
6797            }
6798        };
6799        // Rendering
6800        // -----------------------------------------------------------------------------------------------------------------
6801        Calendar.prototype.executeRender = function () {
6802            // clear these BEFORE the render so that new values will accumulate during render
6803            this.needsRerender = false;
6804            this.isRendering = true;
6805            this.renderComponent();
6806            this.isRendering = false;
6807            // received a rerender request while rendering
6808            if (this.needsRerender) {
6809                this.delayedRerender();
6810            }
6811        };
6812        /*
6813        don't call this directly. use executeRender instead
6814        */
6815        Calendar.prototype.renderComponent = function () {
6816            var _a = this, state = _a.state, component = _a.component;
6817            var viewType = state.viewType;
6818            var viewSpec = this.viewSpecs[viewType];
6819            if (!viewSpec) {
6820                throw new Error("View type \"" + viewType + "\" is not valid");
6821            }
6822            // if event sources are still loading and progressive rendering hasn't been enabled,
6823            // keep rendering the last fully loaded set of events
6824            var renderableEventStore = this.renderableEventStore =
6825                (state.eventSourceLoadingLevel && !this.opt('progressiveEventRendering')) ?
6826                    this.renderableEventStore :
6827                    state.eventStore;
6828            var eventUiSingleBase = this.buildEventUiSingleBase(viewSpec.options);
6829            var eventUiBySource = this.buildEventUiBySource(state.eventSources);
6830            var eventUiBases = this.eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
6831            component.receiveProps(__assign({}, state, { viewSpec: viewSpec, dateProfileGenerator: this.dateProfileGenerators[viewType], dateProfile: state.dateProfile, eventStore: renderableEventStore, eventUiBases: eventUiBases, dateSelection: state.dateSelection, eventSelection: state.eventSelection, eventDrag: state.eventDrag, eventResize: state.eventResize }), this.buildComponentContext(this.theme, this.dateEnv, this.optionsManager.computed));
6832            if (this.isViewUpdated) {
6833                this.isViewUpdated = false;
6834                this.publiclyTrigger('viewSkeletonRender', [
6835                    {
6836                        view: component.view,
6837                        el: component.view.el
6838                    }
6839                ]);
6840            }
6841            if (this.isDatesUpdated) {
6842                this.isDatesUpdated = false;
6843                this.publiclyTrigger('datesRender', [
6844                    {
6845                        view: component.view,
6846                        el: component.view.el
6847                    }
6848                ]);
6849            }
6850            if (this.isEventsUpdated) {
6851                this.isEventsUpdated = false;
6852            }
6853            this.releaseAfterSizingTriggers();
6854        };
6855        // Options
6856        // -----------------------------------------------------------------------------------------------------------------
6857        Calendar.prototype.setOption = function (name, val) {
6858            var _a;
6859            this.mutateOptions((_a = {}, _a[name] = val, _a), [], true);
6860        };
6861        Calendar.prototype.getOption = function (name) {
6862            return this.optionsManager.computed[name];
6863        };
6864        Calendar.prototype.opt = function (name) {
6865            return this.optionsManager.computed[name];
6866        };
6867        Calendar.prototype.viewOpt = function (name) {
6868            return this.viewOpts()[name];
6869        };
6870        Calendar.prototype.viewOpts = function () {
6871            return this.viewSpecs[this.state.viewType].options;
6872        };
6873        /*
6874        handles option changes (like a diff)
6875        */
6876        Calendar.prototype.mutateOptions = function (updates, removals, isDynamic, deepEqual) {
6877            var _this = this;
6878            var changeHandlers = this.pluginSystem.hooks.optionChangeHandlers;
6879            var normalUpdates = {};
6880            var specialUpdates = {};
6881            var oldDateEnv = this.dateEnv; // do this before handleOptions
6882            var isTimeZoneDirty = false;
6883            var isSizeDirty = false;
6884            var anyDifficultOptions = Boolean(removals.length);
6885            for (var name_1 in updates) {
6886                if (changeHandlers[name_1]) {
6887                    specialUpdates[name_1] = updates[name_1];
6888                }
6889                else {
6890                    normalUpdates[name_1] = updates[name_1];
6891                }
6892            }
6893            for (var name_2 in normalUpdates) {
6894                if (/^(height|contentHeight|aspectRatio)$/.test(name_2)) {
6895                    isSizeDirty = true;
6896                }
6897                else if (/^(defaultDate|defaultView)$/.test(name_2)) ;
6898                else {
6899                    anyDifficultOptions = true;
6900                    if (name_2 === 'timeZone') {
6901                        isTimeZoneDirty = true;
6902                    }
6903                }
6904            }
6905            this.optionsManager.mutate(normalUpdates, removals, isDynamic);
6906            if (anyDifficultOptions) {
6907                this.handleOptions(this.optionsManager.computed);
6908            }
6909            this.batchRendering(function () {
6910                if (anyDifficultOptions) {
6911                    if (isTimeZoneDirty) {
6912                        _this.dispatch({
6913                            type: 'CHANGE_TIMEZONE',
6914                            oldDateEnv: oldDateEnv
6915                        });
6916                    }
6917                    /* HACK
6918                    has the same effect as calling this.requestRerender()
6919                    but recomputes the state's dateProfile
6920                    */
6921                    _this.dispatch({
6922                        type: 'SET_VIEW_TYPE',
6923                        viewType: _this.state.viewType
6924                    });
6925                }
6926                else if (isSizeDirty) {
6927                    _this.updateSize();
6928                }
6929                // special updates
6930                if (deepEqual) {
6931                    for (var name_3 in specialUpdates) {
6932                        changeHandlers[name_3](specialUpdates[name_3], _this, deepEqual);
6933                    }
6934                }
6935            });
6936        };
6937        /*
6938        rebuilds things based off of a complete set of refined options
6939        */
6940        Calendar.prototype.handleOptions = function (options) {
6941            var _this = this;
6942            var pluginHooks = this.pluginSystem.hooks;
6943            this.defaultAllDayEventDuration = createDuration(options.defaultAllDayEventDuration);
6944            this.defaultTimedEventDuration = createDuration(options.defaultTimedEventDuration);
6945            this.delayedRerender = this.buildDelayedRerender(options.rerenderDelay);
6946            this.theme = this.buildTheme(options);
6947            var available = this.parseRawLocales(options.locales);
6948            this.availableRawLocales = available.map;
6949            var locale = this.buildLocale(options.locale || available.defaultCode, available.map);
6950            this.dateEnv = this.buildDateEnv(locale, options.timeZone, pluginHooks.namedTimeZonedImpl, options.firstDay, options.weekNumberCalculation, options.weekLabel, pluginHooks.cmdFormatter);
6951            this.selectionConfig = this.buildSelectionConfig(options); // needs dateEnv. do after :(
6952            // ineffecient to do every time?
6953            this.viewSpecs = buildViewSpecs(pluginHooks.views, this.optionsManager);
6954            // ineffecient to do every time?
6955            this.dateProfileGenerators = mapHash(this.viewSpecs, function (viewSpec) {
6956                return new viewSpec.class.prototype.dateProfileGeneratorClass(viewSpec, _this);
6957            });
6958        };
6959        Calendar.prototype.getAvailableLocaleCodes = function () {
6960            return Object.keys(this.availableRawLocales);
6961        };
6962        Calendar.prototype._buildSelectionConfig = function (rawOpts) {
6963            return processScopedUiProps('select', rawOpts, this);
6964        };
6965        Calendar.prototype._buildEventUiSingleBase = function (rawOpts) {
6966            if (rawOpts.editable) { // so 'editable' affected events
6967                rawOpts = __assign({}, rawOpts, { eventEditable: true });
6968            }
6969            return processScopedUiProps('event', rawOpts, this);
6970        };
6971        // Trigger
6972        // -----------------------------------------------------------------------------------------------------------------
6973        Calendar.prototype.hasPublicHandlers = function (name) {
6974            return this.hasHandlers(name) ||
6975                this.opt(name); // handler specified in options
6976        };
6977        Calendar.prototype.publiclyTrigger = function (name, args) {
6978            var optHandler = this.opt(name);
6979            this.triggerWith(name, this, args);
6980            if (optHandler) {
6981                return optHandler.apply(this, args);
6982            }
6983        };
6984        Calendar.prototype.publiclyTriggerAfterSizing = function (name, args) {
6985            var afterSizingTriggers = this.afterSizingTriggers;
6986            (afterSizingTriggers[name] || (afterSizingTriggers[name] = [])).push(args);
6987        };
6988        Calendar.prototype.releaseAfterSizingTriggers = function () {
6989            var afterSizingTriggers = this.afterSizingTriggers;
6990            for (var name_4 in afterSizingTriggers) {
6991                for (var _i = 0, _a = afterSizingTriggers[name_4]; _i < _a.length; _i++) {
6992                    var args = _a[_i];
6993                    this.publiclyTrigger(name_4, args);
6994                }
6995            }
6996            this.afterSizingTriggers = {};
6997        };
6998        // View
6999        // -----------------------------------------------------------------------------------------------------------------
7000        // Returns a boolean about whether the view is okay to instantiate at some point
7001        Calendar.prototype.isValidViewType = function (viewType) {
7002            return Boolean(this.viewSpecs[viewType]);
7003        };
7004        Calendar.prototype.changeView = function (viewType, dateOrRange) {
7005            var dateMarker = null;
7006            if (dateOrRange) {
7007                if (dateOrRange.start && dateOrRange.end) { // a range
7008                    this.optionsManager.mutate({ visibleRange: dateOrRange }, []); // will not rerender
7009                    this.handleOptions(this.optionsManager.computed); // ...but yuck
7010                }
7011                else { // a date
7012                    dateMarker = this.dateEnv.createMarker(dateOrRange); // just like gotoDate
7013                }
7014            }
7015            this.unselect();
7016            this.dispatch({
7017                type: 'SET_VIEW_TYPE',
7018                viewType: viewType,
7019                dateMarker: dateMarker
7020            });
7021        };
7022        // Forces navigation to a view for the given date.
7023        // `viewType` can be a specific view name or a generic one like "week" or "day".
7024        // needs to change
7025        Calendar.prototype.zoomTo = function (dateMarker, viewType) {
7026            var spec;
7027            viewType = viewType || 'day'; // day is default zoom
7028            spec = this.viewSpecs[viewType] ||
7029                this.getUnitViewSpec(viewType);
7030            this.unselect();
7031            if (spec) {
7032                this.dispatch({
7033                    type: 'SET_VIEW_TYPE',
7034                    viewType: spec.type,
7035                    dateMarker: dateMarker
7036                });
7037            }
7038            else {
7039                this.dispatch({
7040                    type: 'SET_DATE',
7041                    dateMarker: dateMarker
7042                });
7043            }
7044        };
7045        // Given a duration singular unit, like "week" or "day", finds a matching view spec.
7046        // Preference is given to views that have corresponding buttons.
7047        Calendar.prototype.getUnitViewSpec = function (unit) {
7048            var component = this.component;
7049            var viewTypes = [];
7050            var i;
7051            var spec;
7052            // put views that have buttons first. there will be duplicates, but oh
7053            if (component.header) {
7054                viewTypes.push.apply(viewTypes, component.header.viewsWithButtons);
7055            }
7056            if (component.footer) {
7057                viewTypes.push.apply(viewTypes, component.footer.viewsWithButtons);
7058            }
7059            for (var viewType in this.viewSpecs) {
7060                viewTypes.push(viewType);
7061            }
7062            for (i = 0; i < viewTypes.length; i++) {
7063                spec = this.viewSpecs[viewTypes[i]];
7064                if (spec) {
7065                    if (spec.singleUnit === unit) {
7066                        return spec;
7067                    }
7068                }
7069            }
7070        };
7071        // Current Date
7072        // -----------------------------------------------------------------------------------------------------------------
7073        Calendar.prototype.getInitialDate = function () {
7074            var defaultDateInput = this.opt('defaultDate');
7075            // compute the initial ambig-timezone date
7076            if (defaultDateInput != null) {
7077                return this.dateEnv.createMarker(defaultDateInput);
7078            }
7079            else {
7080                return this.getNow(); // getNow already returns unzoned
7081            }
7082        };
7083        Calendar.prototype.prev = function () {
7084            this.unselect();
7085            this.dispatch({ type: 'PREV' });
7086        };
7087        Calendar.prototype.next = function () {
7088            this.unselect();
7089            this.dispatch({ type: 'NEXT' });
7090        };
7091        Calendar.prototype.prevYear = function () {
7092            this.unselect();
7093            this.dispatch({
7094                type: 'SET_DATE',
7095                dateMarker: this.dateEnv.addYears(this.state.currentDate, -1)
7096            });
7097        };
7098        Calendar.prototype.nextYear = function () {
7099            this.unselect();
7100            this.dispatch({
7101                type: 'SET_DATE',
7102                dateMarker: this.dateEnv.addYears(this.state.currentDate, 1)
7103            });
7104        };
7105        Calendar.prototype.today = function () {
7106            this.unselect();
7107            this.dispatch({
7108                type: 'SET_DATE',
7109                dateMarker: this.getNow()
7110            });
7111        };
7112        Calendar.prototype.gotoDate = function (zonedDateInput) {
7113            this.unselect();
7114            this.dispatch({
7115                type: 'SET_DATE',
7116                dateMarker: this.dateEnv.createMarker(zonedDateInput)
7117            });
7118        };
7119        Calendar.prototype.incrementDate = function (deltaInput) {
7120            var delta = createDuration(deltaInput);
7121            if (delta) { // else, warn about invalid input?
7122                this.unselect();
7123                this.dispatch({
7124                    type: 'SET_DATE',
7125                    dateMarker: this.dateEnv.add(this.state.currentDate, delta)
7126                });
7127            }
7128        };
7129        // for external API
7130        Calendar.prototype.getDate = function () {
7131            return this.dateEnv.toDate(this.state.currentDate);
7132        };
7133        // Date Formatting Utils
7134        // -----------------------------------------------------------------------------------------------------------------
7135        Calendar.prototype.formatDate = function (d, formatter) {
7136            var dateEnv = this.dateEnv;
7137            return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
7138        };
7139        // `settings` is for formatter AND isEndExclusive
7140        Calendar.prototype.formatRange = function (d0, d1, settings) {
7141            var dateEnv = this.dateEnv;
7142            return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings, this.opt('defaultRangeSeparator')), settings);
7143        };
7144        Calendar.prototype.formatIso = function (d, omitTime) {
7145            var dateEnv = this.dateEnv;
7146            return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime });
7147        };
7148        // Sizing
7149        // -----------------------------------------------------------------------------------------------------------------
7150        Calendar.prototype.windowResize = function (ev) {
7151            if (!this.isHandlingWindowResize &&
7152                this.component && // why?
7153                ev.target === window // not a jqui resize event
7154            ) {
7155                this.isHandlingWindowResize = true;
7156                this.updateSize();
7157                this.publiclyTrigger('windowResize', [this.view]);
7158                this.isHandlingWindowResize = false;
7159            }
7160        };
7161        Calendar.prototype.updateSize = function () {
7162            if (this.component) { // when?
7163                this.component.updateSize(true);
7164            }
7165        };
7166        // Component Registration
7167        // -----------------------------------------------------------------------------------------------------------------
7168        Calendar.prototype.registerInteractiveComponent = function (component, settingsInput) {
7169            var settings = parseInteractionSettings(component, settingsInput);
7170            var DEFAULT_INTERACTIONS = [
7171                EventClicking,
7172                EventHovering
7173            ];
7174            var interactionClasses = DEFAULT_INTERACTIONS.concat(this.pluginSystem.hooks.componentInteractions);
7175            var interactions = interactionClasses.map(function (interactionClass) {
7176                return new interactionClass(settings);
7177            });
7178            this.interactionsStore[component.uid] = interactions;
7179            interactionSettingsStore[component.uid] = settings;
7180        };
7181        Calendar.prototype.unregisterInteractiveComponent = function (component) {
7182            for (var _i = 0, _a = this.interactionsStore[component.uid]; _i < _a.length; _i++) {
7183                var listener = _a[_i];
7184                listener.destroy();
7185            }
7186            delete this.interactionsStore[component.uid];
7187            delete interactionSettingsStore[component.uid];
7188        };
7189        // Date Selection / Event Selection / DayClick
7190        // -----------------------------------------------------------------------------------------------------------------
7191        // this public method receives start/end dates in any format, with any timezone
7192        // NOTE: args were changed from v3
7193        Calendar.prototype.select = function (dateOrObj, endDate) {
7194            var selectionInput;
7195            if (endDate == null) {
7196                if (dateOrObj.start != null) {
7197                    selectionInput = dateOrObj;
7198                }
7199                else {
7200                    selectionInput = {
7201                        start: dateOrObj,
7202                        end: null
7203                    };
7204                }
7205            }
7206            else {
7207                selectionInput = {
7208                    start: dateOrObj,
7209                    end: endDate
7210                };
7211            }
7212            var selection = parseDateSpan(selectionInput, this.dateEnv, createDuration({ days: 1 }) // TODO: cache this?
7213            );
7214            if (selection) { // throw parse error otherwise?
7215                this.dispatch({ type: 'SELECT_DATES', selection: selection });
7216                this.triggerDateSelect(selection);
7217            }
7218        };
7219        // public method
7220        Calendar.prototype.unselect = function (pev) {
7221            if (this.state.dateSelection) {
7222                this.dispatch({ type: 'UNSELECT_DATES' });
7223                this.triggerDateUnselect(pev);
7224            }
7225        };
7226        Calendar.prototype.triggerDateSelect = function (selection, pev) {
7227            var arg = __assign({}, this.buildDateSpanApi(selection), { jsEvent: pev ? pev.origEvent : null, view: this.view });
7228            this.publiclyTrigger('select', [arg]);
7229        };
7230        Calendar.prototype.triggerDateUnselect = function (pev) {
7231            this.publiclyTrigger('unselect', [
7232                {
7233                    jsEvent: pev ? pev.origEvent : null,
7234                    view: this.view
7235                }
7236            ]);
7237        };
7238        // TODO: receive pev?
7239        Calendar.prototype.triggerDateClick = function (dateSpan, dayEl, view, ev) {
7240            var arg = __assign({}, this.buildDatePointApi(dateSpan), { dayEl: dayEl, jsEvent: ev, // Is this always a mouse event? See #4655
7241                view: view });
7242            this.publiclyTrigger('dateClick', [arg]);
7243        };
7244        Calendar.prototype.buildDatePointApi = function (dateSpan) {
7245            var props = {};
7246            for (var _i = 0, _a = this.pluginSystem.hooks.datePointTransforms; _i < _a.length; _i++) {
7247                var transform = _a[_i];
7248                __assign(props, transform(dateSpan, this));
7249            }
7250            __assign(props, buildDatePointApi(dateSpan, this.dateEnv));
7251            return props;
7252        };
7253        Calendar.prototype.buildDateSpanApi = function (dateSpan) {
7254            var props = {};
7255            for (var _i = 0, _a = this.pluginSystem.hooks.dateSpanTransforms; _i < _a.length; _i++) {
7256                var transform = _a[_i];
7257                __assign(props, transform(dateSpan, this));
7258            }
7259            __assign(props, buildDateSpanApi(dateSpan, this.dateEnv));
7260            return props;
7261        };
7262        // Date Utils
7263        // -----------------------------------------------------------------------------------------------------------------
7264        // Returns a DateMarker for the current date, as defined by the client's computer or from the `now` option
7265        Calendar.prototype.getNow = function () {
7266            var now = this.opt('now');
7267            if (typeof now === 'function') {
7268                now = now();
7269            }
7270            if (now == null) {
7271                return this.dateEnv.createNowMarker();
7272            }
7273            return this.dateEnv.createMarker(now);
7274        };
7275        // Event-Date Utilities
7276        // -----------------------------------------------------------------------------------------------------------------
7277        // Given an event's allDay status and start date, return what its fallback end date should be.
7278        // TODO: rename to computeDefaultEventEnd
7279        Calendar.prototype.getDefaultEventEnd = function (allDay, marker) {
7280            var end = marker;
7281            if (allDay) {
7282                end = startOfDay(end);
7283                end = this.dateEnv.add(end, this.defaultAllDayEventDuration);
7284            }
7285            else {
7286                end = this.dateEnv.add(end, this.defaultTimedEventDuration);
7287            }
7288            return end;
7289        };
7290        // Public Events API
7291        // -----------------------------------------------------------------------------------------------------------------
7292        Calendar.prototype.addEvent = function (eventInput, sourceIn
7292put) {
7293            if (eventInput instanceof EventApi) {
7294                var def = eventInput._def;
7295                var instance = eventInput._instance;
7296                // not already present? don't want to add an old snapshot
7297                if (!this.state.eventStore.defs[def.defId]) {
7298                    this.dispatch({
7299                        type: 'ADD_EVENTS',
7300                        eventStore: eventTupleToStore({ def: def, instance: instance }) // TODO: better util for two args?
7301                    });
7302                }
7303                return eventInput;
7304            }
7305            var sourceId;
7306            if (sourceInput instanceof EventSourceApi) {
7307                sourceId = sourceInput.internalEventSource.sourceId;
7308            }
7309            else if (sourceInput != null) {
7310                var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
7311                if (!sourceApi) {
7312                    console.warn('Could not find an event source with ID "' + sourceInput + '"'); // TODO: test
7313                    return null;
7314                }
7315                else {
7316                    sourceId = sourceApi.internalEventSource.sourceId;
7317                }
7318            }
7319            var tuple = parseEvent(eventInput, sourceId, this);
7320            if (tuple) {
7321                this.dispatch({
7322                    type: 'ADD_EVENTS',
7323                    eventStore: eventTupleToStore(tuple)
7324                });
7325                return new EventApi(this, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
7326            }
7327            return null;
7328        };
7329        // TODO: optimize
7330        Calendar.prototype.getEventById = function (id) {
7331            var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
7332            id = String(id);
7333            for (var defId in defs) {
7334                var def = defs[defId];
7335                if (def.publicId === id) {
7336                    if (def.recurringDef) {
7337                        return new EventApi(this, def, null);
7338                    }
7339                    else {
7340                        for (var instanceId in instances) {
7341                            var instance = instances[instanceId];
7342                            if (instance.defId === def.defId) {
7343                                return new EventApi(this, def, instance);
7344                            }
7345                        }
7346                    }
7347                }
7348            }
7349            return null;
7350        };
7351        Calendar.prototype.getEvents = function () {
7352            var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
7353            var eventApis = [];
7354            for (var id in instances) {
7355                var instance = instances[id];
7356                var def = defs[instance.defId];
7357                eventApis.push(new EventApi(this, def, instance));
7358            }
7359            return eventApis;
7360        };
7361        Calendar.prototype.removeAllEvents = function () {
7362            this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
7363        };
7364        Calendar.prototype.rerenderEvents = function () {
7365            this.dispatch({ type: 'RESET_EVENTS' });
7366        };
7367        // Public Event Sources API
7368        // -----------------------------------------------------------------------------------------------------------------
7369        Calendar.prototype.getEventSources = function () {
7370            var sourceHash = this.state.eventSources;
7371            var sourceApis = [];
7372            for (var internalId in sourceHash) {
7373                sourceApis.push(new EventSourceApi(this, sourceHash[internalId]));
7374            }
7375            return sourceApis;
7376        };
7377        Calendar.prototype.getEventSourceById = function (id) {
7378            var sourceHash = this.state.eventSources;
7379            id = String(id);
7380            for (var sourceId in sourceHash) {
7381                if (sourceHash[sourceId].publicId === id) {
7382                    return new EventSourceApi(this, sourceHash[sourceId]);
7383                }
7384            }
7385            return null;
7386        };
7387        Calendar.prototype.addEventSource = function (sourceInput) {
7388            if (sourceInput instanceof EventSourceApi) {
7389                // not already present? don't want to add an old snapshot
7390                if (!this.state.eventSources[sourceInput.internalEventSource.sourceId]) {
7391                    this.dispatch({
7392                        type: 'ADD_EVENT_SOURCES',
7393                        sources: [sourceInput.internalEventSource]
7394                    });
7395                }
7396                return sourceInput;
7397            }
7398            var eventSource = parseEventSource(sourceInput, this);
7399            if (eventSource) { // TODO: error otherwise?
7400                this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
7401                return new EventSourceApi(this, eventSource);
7402            }
7403            return null;
7404        };
7405        Calendar.prototype.removeAllEventSources = function () {
7406            this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
7407        };
7408        Calendar.prototype.refetchEvents = function () {
7409            this.dispatch({ type: 'FETCH_EVENT_SOURCES' });
7410        };
7411        // Scroll
7412        // -----------------------------------------------------------------------------------------------------------------
7413        Calendar.prototype.scrollToTime = function (timeInput) {
7414            var duration = createDuration(timeInput);
7415            if (duration) {
7416                this.component.view.scrollToDuration(duration);
7417            }
7418        };
7419        return Calendar;
7420    }());
7421    EmitterMixin.mixInto(Calendar);
7422    // for memoizers
7423    // -----------------------------------------------------------------------------------------------------------------
7424    function buildComponentContext$1(theme, dateEnv, options) {
7425        return new ComponentContext(this, theme, dateEnv, options, null);
7426    }
7427    function buildDateEnv(locale, timeZone, namedTimeZoneImpl, firstDay, weekNumberCalculation, weekLabel, cmdFormatter) {
7428        return new DateEnv({
7429            calendarSystem: 'gregory',
7430            timeZone: timeZone,
7431            namedTimeZoneImpl: namedTimeZoneImpl,
7432            locale: locale,
7433            weekNumberCalculation: weekNumberCalculation,
7434            firstDay: firstDay,
7435            weekLabel: weekLabel,
7436            cmdFormatter: cmdFormatter
7437        });
7438    }
7439    function buildTheme(calendarOptions) {
7440        var themeClass = this.pluginSystem.hooks.themeClasses[calendarOptions.themeSystem] || StandardTheme;
7441        return new themeClass(calendarOptions);
7442    }
7443    function buildDelayedRerender(wait) {
7444        var func = this.tryRerender.bind(this);
7445        if (wait != null) {
7446            func = debounce(func, wait);
7447        }
7448        return func;
7449    }
7450    function buildEventUiBySource(eventSources) {
7451        return mapHash(eventSources, function (eventSource) {
7452            return eventSource.ui;
7453        });
7454    }
7455    function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
7456        var eventUiBases = { '': eventUiSingleBase };
7457        for (var defId in eventDefs) {
7458            var def = eventDefs[defId];
7459            if (def.sourceId && eventUiBySource[def.sourceId]) {
7460                eventUiBases[defId] = eventUiBySource[def.sourceId];
7461            }
7462        }
7463        return eventUiBases;
7464    }
7465
7466    var View = /** @class */ (function (_super) {
7467        __extends(View, _super);
7468        function View(viewSpec, parentEl) {
7469            var _this = _super.call(this, createElement('div', { className: 'fc-view fc-' + viewSpec.type + '-view' })) || this;
7470            _this.renderDatesMem = memoizeRendering(_this.renderDatesWrap, _this.unrenderDatesWrap);
7471            _this.renderBusinessHoursMem = memoizeRendering(_this.renderBusinessHours, _this.unrenderBusinessHours, [_this.renderDatesMem]);
7472            _this.renderDateSelectionMem = memoizeRendering(_this.renderDateSelectionWrap, _this.unrenderDateSelectionWrap, [_this.renderDatesMem]);
7473            _this.renderEventsMem = memoizeRendering(_this.renderEvents, _this.unrenderEvents, [_this.renderDatesMem]);
7474            _this.renderEventSelectionMem = memoizeRendering(_this.renderEventSelectionWrap, _this.unrenderEventSelectionWrap, [_this.renderEventsMem]);
7475            _this.renderEventDragMem = memoizeRendering(_this.renderEventDragWrap, _this.unrenderEventDragWrap, [_this.renderDatesMem]);
7476            _this.renderEventResizeMem = memoizeRendering(_this.renderEventResizeWrap, _this.unrenderEventResizeWrap, [_this.renderDatesMem]);
7477            _this.viewSpec = viewSpec;
7478            _this.type = viewSpec.type;
7479            parentEl.appendChild(_this.el);
7480            _this.initialize();
7481            return _this;
7482        }
7483        View.prototype.initialize = function () {
7484        };
7485        Object.defineProperty(View.prototype, "activeStart", {
7486            // Date Setting/Unsetting
7487            // -----------------------------------------------------------------------------------------------------------------
7488            get: function () {
7489                return this.context.dateEnv.toDate(this.props.dateProfile.activeRange.start);
7490            },
7491            enumerable: true,
7492            configurable: true
7493        });
7494        Object.defineProperty(View.prototype, "activeEnd", {
7495            get: function () {
7496                return this.context.dateEnv.toDate(this.props.dateProfile.activeRange.end);
7497            },
7498            enumerable: true,
7499            configurable: true
7500        });
7501        Object.defineProperty(View.prototype, "currentStart", {
7502            get: function () {
7503                return this.context.dateEnv.toDate(this.props.dateProfile.currentRange.start);
7504            },
7505            enumerable: true,
7506            configurable: true
7507        });
7508        Object.defineProperty(View.prototype, "currentEnd", {
7509            get: function () {
7510                return this.context.dateEnv.toDate(this.props.dateProfile.currentRange.end);
7511            },
7512            enumerable: true,
7513            configurable: true
7514        });
7515        // General Rendering
7516        // -----------------------------------------------------------------------------------------------------------------
7517        View.prototype.render = function (props, context) {
7518            this.renderDatesMem(props.dateProfile);
7519            this.renderBusinessHoursMem(props.businessHours);
7520            this.renderDateSelectionMem(props.dateSelection);
7521            this.renderEventsMem(props.eventStore);
7522            this.renderEventSelectionMem(props.eventSelection);
7523            this.renderEventDragMem(props.eventDrag);
7524            this.renderEventResizeMem(props.eventResize);
7525        };
7526        View.prototype.beforeUpdate = function () {
7527            this.addScroll(this.queryScroll());
7528        };
7529        View.prototype.destroy = function () {
7530            _super.prototype.destroy.call(this);
7531            this.renderDatesMem.unrender(); // should unrender everything else
7532        };
7533        // Sizing
7534        // -----------------------------------------------------------------------------------------------------------------
7535        View.prototype.updateSize = function (isResize, viewHeight, isAuto) {
7536            var calendar = this.context.calendar;
7537            if (isResize) {
7538                this.addScroll(this.queryScroll()); // NOTE: same code as in beforeUpdate
7539            }
7540            if (isResize || // HACKS...
7541                calendar.isViewUpdated ||
7542                calendar.isDatesUpdated ||
7543                calendar.isEventsUpdated) {
7544                // sort of the catch-all sizing
7545                // anything that might cause dimension changes
7546                this.updateBaseSize(isResize, viewHeight, isAuto);
7547            }
7548            // NOTE: popScroll is called by CalendarComponent
7549        };
7550        View.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
7551        };
7552        // Date Rendering
7553        // -----------------------------------------------------------------------------------------------------------------
7554        View.prototype.renderDatesWrap = function (dateProfile) {
7555            this.renderDates(dateProfile);
7556            this.addScroll({
7557                duration: createDuration(this.context.options.scrollTime)
7558            });
7559        };
7560        View.prototype.unrenderDatesWrap = function () {
7561            this.stopNowIndicator();
7562            this.unrenderDates();
7563        };
7564        View.prototype.renderDates = function (dateProfile) { };
7565        View.prototype.unrenderDates = function () { };
7566        // Business Hours
7567        // -----------------------------------------------------------------------------------------------------------------
7568        View.prototype.renderBusinessHours = function (businessHours) { };
7569        View.prototype.unrenderBusinessHours = function () { };
7570        // Date Selection
7571        // -----------------------------------------------------------------------------------------------------------------
7572        View.prototype.renderDateSelectionWrap = function (selection) {
7573            if (selection) {
7574                this.renderDateSelection(selection);
7575            }
7576        };
7577        View.prototype.unrenderDateSelectionWrap = function (selection) {
7578            if (selection) {
7579                this.unrenderDateSelection(selection);
7580            }
7581        };
7582        View.prototype.renderDateSelection = function (selection) { };
7583        View.prototype.unrenderDateSelection = function (selection) { };
7584        // Event Rendering
7585        // -----------------------------------------------------------------------------------------------------------------
7586        View.prototype.renderEvents = function (eventStore) { };
7587        View.prototype.unrenderEvents = function () { };
7588        // util for subclasses
7589        View.prototype.sliceEvents = function (eventStore, allDay) {
7590            var props = this.props;
7591            return sliceEventStore(eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? this.context.nextDayThreshold : null).fg;
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        // USAGE: must be called manually from subclasses' render methods! don't need to call stopNowIndicator tho
7641        View.prototype.startNowIndicator = function (dateProfile, dateProfileGenerator) {
7642            var _this = this;
7643            var _a = this.context, calendar = _a.calendar, dateEnv = _a.dateEnv, options = _a.options;
7644            var unit;
7645            var update;
7646            var delay; // ms wait value
7647            if (options.nowIndicator && !this.initialNowDate) {
7648                unit = this.getNowIndicatorUnit(dateProfile, dateProfileGenerator);
7649                if (unit) {
7650                    update = this.updateNowIndicator.bind(this);
7651                    this.initialNowDate = calendar.getNow();
7652                    this.initialNowQueriedMs = new Date().valueOf();
7653                    // wait until the beginning of the next interval
7654                    delay = dateEnv.add(dateEnv.startOf(this.initialNowDate, unit), createDuration(1, unit)).valueOf() - this.initialNowDate.valueOf();
7655                    // TODO: maybe always use setTimeout, waiting until start of next unit
7656                    this.nowIndicatorTimeoutID = setTimeout(function () {
7657                        _this.nowIndicatorTimeoutID = null;
7658                        update();
7659                        if (unit === 'second') {
7660                            delay = 1000; // every second
7661                        }
7662                        else {
7663                            delay = 1000 * 60; // otherwise, every minute
7664                        }
7665                        _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval
7666                    }, delay);
7667                }
7668                // rendering will be initiated in updateSize
7669            }
7670        };
7671        // rerenders the now indicator, computing the new current time from the amount of time that has passed
7672        // since the initial getNow call.
7673        View.prototype.updateNowIndicator = function () {
7674            if (this.props.dateProfile && // a way to determine if dates were rendered yet
7675                this.initialNowDate // activated before?
7676            ) {
7677                this.unrenderNowIndicator(); // won't unrender if unnecessary
7678                this.renderNowIndicator(addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs));
7679                this.isNowIndicatorRendered = true;
7680            }
7681        };
7682        // Immediately unrenders the view's current time indicator and stops any re-rendering timers.
7683        // Won't cause side effects if indicator isn't rendered.
7684        View.prototype.stopNowIndicator = function () {
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            if (this.isNowIndicatorRendered) {
7694                this.unrenderNowIndicator();
7695                this.isNowIndicatorRendered = false;
7696            }
7697        };
7698        View.prototype.getNowIndicatorUnit = function (dateProfile, dateProfileGenerator) {
7699            // subclasses should implement
7700        };
7701        // Renders a current time indicator at the given datetime
7702        View.prototype.renderNowIndicator = function (date) {
7703            // SUBCLASSES MUST PASS TO CHILDREN!
7704        };
7705        // Undoes the rendering actions from renderNowIndicator
7706        View.prototype.unrenderNowIndicator = function () {
7707            // SUBCLASSES MUST PASS TO CHILDREN!
7708        };
7709        /* Scroller
7710        ------------------------------------------------------------------------------------------------------------------*/
7711        View.prototype.addScroll = function (scroll, isForced) {
7712            if (isForced) {
7713                scroll.isForced = isForced;
7714            }
7715            __assign(this.queuedScroll || (this.queuedScroll = {}), scroll);
7716        };
7717        View.prototype.popScroll = function (isResize) {
7718            this.applyQueuedScroll(isResize);
7719            this.queuedScroll = null;
7720        };
7721        View.prototype.applyQueuedScroll = function (isResize) {
7722            if (this.queuedScroll) {
7723                this.applyScroll(this.queuedScroll, isResize);
7724            }
7725        };
7726        View.prototype.queryScroll = function () {
7727            var scroll = {};
7728            if (this.props.dateProfile) { // dates rendered yet?
7729                __assign(scroll, this.queryDateScroll());
7730            }
7731            return scroll;
7732        };
7733        View.prototype.applyScroll = function (scroll, isResize) {
7734            var duration = scroll.duration, isForced = scroll.isForced;
7735            if (duration != null && !isForced) {
7736                delete scroll.duration;
7737                if (this.props.dateProfile) { // dates rendered yet?
7738                    __assign(scroll, this.computeDateScroll(duration));
7739                }
7740            }
7741            if (this.props.dateProfile) { // dates rendered yet?
7742                this.applyDateScroll(scroll);
7743            }
7744        };
7745        View.prototype.computeDateScroll = function (duration) {
7746            return {}; // subclasses must implement
7747        };
7748        View.prototype.queryDateScroll = function () {
7749            return {}; // subclasses must implement
7750        };
7751        View.prototype.applyDateScroll = function (scroll) {
7752            // subclasses must implement
7753        };
7754        // for API
7755        View.prototype.scrollToDuration = function (duration) {
7756            this.applyScroll({ duration: duration }, false);
7757        };
7758        return View;
7759    }(DateComponent));
7760    EmitterMixin.mixInto(View);
7761    View.prototype.usesMinMaxTime = false;
7762    View.prototype.dateProfileGeneratorClass = DateProfileGenerator;
7763
7764    var FgEventRenderer = /** @class */ (function () {
7765        function FgEventRenderer() {
7766            this.segs = [];
7767            this.isSizeDirty = false;
7768        }
7769        FgEventRenderer.prototype.renderSegs = function (context, segs, mirrorInfo) {
7770            this.context = context;
7771            this.rangeUpdated(); // called too frequently :(
7772            // render an `.el` on each seg
7773            // returns a subset of the segs. segs that were actually rendered
7774            segs = this.renderSegEls(segs, mirrorInfo);
7775            this.segs = segs;
7776            this.attachSegs(segs, mirrorInfo);
7777            this.isSizeDirty = true;
7778            triggerRenderedSegs(this.context, this.segs, Boolean(mirrorInfo));
7779        };
7780        FgEventRenderer.prototype.unrender = function (context, _segs, mirrorInfo) {
7781            triggerWillRemoveSegs(this.context, this.segs, Boolean(mirrorInfo));
7782            this.detachSegs(this.segs);
7783            this.segs = [];
7784        };
7785        // Updates values that rely on options and also relate to range
7786        FgEventRenderer.prototype.rangeUpdated = function () {
7787            var options = this.context.options;
7788            var displayEventTime;
7789            var displayEventEnd;
7790            this.eventTimeFormat = createFormatter(options.eventTimeFormat || this.computeEventTimeFormat(), options.defaultRangeSeparator);
7791            displayEventTime = options.displayEventTime;
7792            if (displayEventTime == null) {
7793                displayEventTime = this.computeDisplayEventTime(); // might be based off of range
7794            }
7795            displayEventEnd = options.displayEventEnd;
7796            if (displayEventEnd == null) {
7797                displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range
7798            }
7799            this.displayEventTime = displayEventTime;
7800            this.displayEventEnd = displayEventEnd;
7801        };
7802        // Renders and assigns an `el` property for each foreground event segment.
7803        // Only returns segments that successfully rendered.
7804        FgEventRenderer.prototype.renderSegEls = function (segs, mirrorInfo) {
7805            var html = '';
7806            var i;
7807            if (segs.length) { // don't build an empty html string
7808                // build a large concatenation of event segment HTML
7809                for (i = 0; i < segs.length; i++) {
7810                    html += this.renderSegHtml(segs[i], mirrorInfo);
7811                }
7812                // Grab individual elements from the combined HTML string. Use each as the default rendering.
7813                // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
7814                htmlToElements(html).forEach(function (el, i) {
7815                    var seg = segs[i];
7816                    if (el) {
7817                        seg.el = el;
7818                    }
7819                });
7820                segs = filterSegsViaEls(this.context, segs, Boolean(mirrorInfo));
7821            }
7822            return segs;
7823        };
7824        // Generic utility for generating the HTML classNames for an event segment's element
7825        FgEventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable, mirrorInfo) {
7826            var classes = [
7827                'fc-event',
7828                seg.isStart ? 'fc-start' : 'fc-not-start',
7829                seg.isEnd ? 'fc-end' : 'fc-not-end'
7830            ].concat(seg.eventRange.ui.classNames);
7831            if (isDraggable) {
7832                classes.push('fc-draggable');
7833            }
7834            if (isResizable) {
7835                classes.push('fc-resizable');
7836            }
7837            if (mirrorInfo) {
7838                classes.push('fc-mirror');
7839                if (mirrorInfo.isDragging) {
7840                    classes.push('fc-dragging');
7841                }
7842                if (mirrorInfo.isResizing) {
7843                    classes.push('fc-resizing');
7844                }
7845            }
7846            return classes;
7847        };
7848        // Compute the text that should be displayed on an event's element.
7849        // `range` can be the Event object itself, or something range-like, with at least a `start`.
7850        // If event times are disabled, or the event has no time, will return a blank string.
7851        // If not specified, formatter will default to the eventTimeFormat setting,
7852        // and displayEnd will default to the displayEventEnd setting.
7853        FgEventRenderer.prototype.getTimeText = function (eventRange, formatter, displayEnd) {
7854            var def = eventRange.def, instance = eventRange.instance;
7855            return this._getTimeText(instance.range.start, def.hasEnd ? instance.range.end : null, def.allDay, formatter, displayEnd, instance.forcedStartTzo, instance.forcedEndTzo);
7856        };
7857        FgEventRenderer.prototype._getTimeText = function (start, end, allDay, formatter, displayEnd, forcedStartTzo, forcedEndTzo) {
7858            var dateEnv = this.context.dateEnv;
7859            if (formatter == null) {
7860                formatter = this.eventTimeFormat;
7861            }
7862            if (displayEnd == null) {
7863                displayEnd = this.displayEventEnd;
7864            }
7865            if (this.displayEventTime && !allDay) {
7866                if (displayEnd && end) {
7867                    return dateEnv.formatRange(start, end, formatter, {
7868                        forcedStartTzo: forcedStartTzo,
7869                        forcedEndTzo: forcedEndTzo
7870                    });
7871                }
7872                else {
7873                    return dateEnv.format(start, formatter, {
7874                        forcedTzo: forcedStartTzo
7875                    });
7876                }
7877            }
7878            return '';
7879        };
7880        FgEventRenderer.prototype.computeEventTimeFormat = function () {
7881            return {
7882                hour: 'numeric',
7883                minute: '2-digit',
7884                omitZeroMinute: true
7885            };
7886        };
7887        FgEventRenderer.prototype.computeDisplayEventTime = function () {
7888            return true;
7889        };
7890        FgEventRenderer.prototype.computeDisplayEventEnd = function () {
7891            return true;
7892        };
7893        // Utility for generating event skin-related CSS properties
7894        FgEventRenderer.prototype.getSkinCss = function (ui) {
7895            return {
7896                'background-color': ui.backgroundColor,
7897                'border-color': ui.borderColor,
7898                color: ui.textColor
7899            };
7900        };
7901        FgEventRenderer.prototype.sortEventSegs = function (segs) {
7902            var specs = this.context.eventOrderSpecs;
7903            var objs = segs.map(buildSegCompareObj);
7904            objs.sort(function (obj0, obj1) {
7905                return compareByFieldSpecs(obj0, obj1, specs);
7906            });
7907            return objs.map(function (c) {
7908                return c._seg;
7909            });
7910        };
7911        FgEventRenderer.prototype.computeSizes = function (force) {
7912            if (force || this.isSizeDirty) {
7913                this.computeSegSizes(this.segs);
7914            }
7915        };
7916        FgEventRenderer.prototype.assignSizes = function (force) {
7917            if (force || this.isSizeDirty) {
7918                this.assignSegSizes(this.segs);
7919                this.isSizeDirty = false;
7920            }
7921        };
7922        FgEventRenderer.prototype.computeSegSizes = function (segs) {
7923        };
7924        FgEventRenderer.prototype.assignSegSizes = function (segs) {
7925        };
7926        // Manipulation on rendered segs
7927        FgEventRenderer.prototype.hideByHash = function (hash) {
7928            if (hash) {
7929                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
7930                    var seg = _a[_i];
7931                    if (hash[seg.eventRange.instance.instanceId]) {
7932                        seg.el.style.visibility = 'hidden';
7933                    }
7934                }
7935            }
7936        };
7937        FgEventRenderer.prototype.showByHash = function (hash) {
7938            if (hash) {
7939                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
7940                    var seg = _a[_i];
7941                    if (hash[seg.eventRange.instance.instanceId]) {
7942                        seg.el.style.visibility = '';
7943                    }
7944                }
7945            }
7946        };
7947        FgEventRenderer.prototype.selectByInstanceId = function (instanceId) {
7948            if (instanceId) {
7949                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
7950                    var seg = _a[_i];
7951                    var eventInstance = seg.eventRange.instance;
7952                    if (eventInstance && eventInstance.instanceId === instanceId &&
7953                        seg.el // necessary?
7954                    ) {
7955                        seg.el.classList.add('fc-selected');
7956                    }
7957                }
7958            }
7959        };
7960        FgEventRenderer.prototype.unselectByInstanceId = function (instanceId) {
7961            if (instanceId) {
7962                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
7963                    var seg = _a[_i];
7964                    if (seg.el) { // necessary?
7965                        seg.el.classList.remove('fc-selected');
7966                    }
7967                }
7968            }
7969        };
7970        return FgEventRenderer;
7971    }());
7972    // returns a object with all primitive props that can be compared
7973    function buildSegCompareObj(seg) {
7974        var eventDef = seg.eventRange.def;
7975        var range = seg.eventRange.instance.range;
7976        var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
7977        var end = range.end ? range.end.valueOf() : 0; // "
7978        return __assign({}, eventDef.extendedProps, eventDef, { id: eventDef.publicId, start: start,
7979            end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg // for later retrieval
7980         });
7981    }
7982
7983    /*
7984    TODO: when refactoring this class, make a new FillRenderer instance for each `type`
7985    */
7986    var FillRenderer = /** @class */ (function () {
7987        function FillRenderer() {
7988            this.fillSegTag = 'div';
7989            this.dirtySizeFlags = {};
7990            this.containerElsByType = {};
7991            this.segsByType = {};
7992        }
7993        FillRenderer.prototype.getSegsByType = function (type) {
7994            return this.segsByType[type] || [];
7995        };
7996        FillRenderer.prototype.renderSegs = function (type, context, segs) {
7997            var _a;
7998            this.context = context;
7999            var renderedSegs = this.renderSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs
8000            var containerEls = this.attachSegs(type, renderedSegs);
8001            if (containerEls) {
8002                (_a = (this.containerElsByType[type] || (this.containerElsByType[type] = []))).push.apply(_a, containerEls);
8003            }
8004            this.segsByType[type] = renderedSegs;
8005            if (type === 'bgEvent') {
8006                triggerRenderedSegs(context, renderedSegs, false); // isMirror=false
8007            }
8008            this.dirtySizeFlags[type] = true;
8009        };
8010        // Unrenders a specific type of fill that is currently rendered on the grid
8011        FillRenderer.prototype.unrender = function (type, context) {
8012            var segs = this.segsByType[type];
8013            if (segs) {
8014                if (type === 'bgEvent') {
8015                    triggerWillRemoveSegs(context, segs, false); // isMirror=false
8016                }
8017                this.detachSegs(type, segs);
8018            }
8019        };
8020        // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
8021        // Only returns segments that successfully rendered.
8022        FillRenderer.prototype.renderSegEls = function (type, segs) {
8023            var _this = this;
8024            var html = '';
8025            var i;
8026            if (segs.length) {
8027                // build a large concatenation of segment HTML
8028                for (i = 0; i < segs.length; i++) {
8029                    html += this.renderSegHtml(type, segs[i]);
8030                }
8031                // Grab individual elements from the combined HTML string. Use each as the default rendering.
8032                // Then, compute the 'el' for each segment.
8033                htmlToElements(html).forEach(function (el, i) {
8034                    var seg = segs[i];
8035                    if (el) {
8036                        seg.el = el;
8037                    }
8038                });
8039                if (type === 'bgEvent') {
8040                    segs = filterSegsViaEls(this.context, segs, false // isMirror. background events can never be mirror elements
8041                    );
8042                }
8043                // correct element type? (would be bad if a non-TD were inserted into a table for example)
8044                segs = segs.filter(function (seg) {
8045                    return elementMatches(seg.el, _this.fillSegTag);
8046                });
8047            }
8048            return segs;
8049        };
8050        // Builds the HTML needed for one fill segment. Generic enough to work with different types.
8051        FillRenderer.prototype.renderSegHtml = function (type, seg) {
8052            var css = null;
8053            var classNames = [];
8054            if (type !== 'highlight' && type !== 'businessHours') {
8055                css = {
8056                    'background-color': seg.eventRange.ui.backgroundColor
8057                };
8058            }
8059            if (type !== 'highlight') {
8060                classNames = classNames.concat(seg.eventRange.ui.classNames);
8061            }
8062            if (type === 'businessHours') {
8063                classNames.push('fc-bgevent');
8064            }
8065            else {
8066                classNames.push('fc-' + type.toLowerCase());
8067            }
8068            return '<' + this.fillSegTag +
8069                (classNames.length ? ' class="' + classNames.join(' ') + '"' : '') +
8070                (css ? ' style="' + cssToStr(css) + '"' : '') +
8071                '></' + this.fillSegTag + '>';
8072        };
8073        FillRenderer.prototype.detachSegs = function (type, segs) {
8074            var containerEls = this.containerElsByType[type];
8075            if (containerEls) {
8076                containerEls.forEach(removeElement);
8077                delete this.containerElsByType[type];
8078            }
8079        };
8080        FillRenderer.prototype.computeSizes = function (force) {
8081            for (var type in this.segsByType) {
8082                if (force || this.dirtySizeFlags[type]) {
8083                    this.computeSegSizes(this.segsByType[type]);
8084                }
8085            }
8086        };
8087        FillRenderer.prototype.assignSizes = function (force) {
8088            for (var type in this.segsByType) {
8089                if (force || this.dirtySizeFlags[type]) {
8090                    this.assignSegSizes(this.segsByType[type]);
8091                }
8092            }
8093            this.dirtySizeFlags = {};
8094        };
8095        FillRenderer.prototype.computeSegSizes = function (segs) {
8096        };
8097        FillRenderer.prototype.assignSegSizes = function (segs) {
8098        };
8099        return FillRenderer;
8100    }());
8101
8102    var NamedTimeZoneImpl = /** @class */ (function () {
8103        function NamedTimeZoneImpl(timeZoneName) {
8104            this.timeZoneName = timeZoneName;
8105        }
8106        return NamedTimeZoneImpl;
8107    }());
8108
8109    /*
8110    An abstraction for a dragging interaction originating on an event.
8111    Does higher-level things than PointerDragger, such as possibly:
8112    - a "mirror" that moves with the pointer
8113    - a minimum number of pixels or other criteria for a true drag to begin
8114
8115    subclasses must emit:
8116    - pointerdown
8117    - dragstart
8118    - dragmove
8119    - pointerup
8120    - dragend
8121    */
8122    var ElementDragging = /** @class */ (function () {
8123        function ElementDragging(el) {
8124            this.emitter = new EmitterMixin();
8125        }
8126        ElementDragging.prototype.destroy = function () {
8127        };
8128        ElementDragging.prototype.setMirrorIsVisible = function (bool) {
8129            // optional if subclass doesn't want to support a mirror
8130        };
8131        ElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
8132            // optional if subclass doesn't want to support a mirror
8133        };
8134        ElementDragging.prototype.setAutoScrollEnabled = function (bool) {
8135            // optional
8136        };
8137        return ElementDragging;
8138    }());
8139
8140    function formatDate(dateInput, settings) {
8141        if (settings === void 0) { settings = {}; }
8142        var dateEnv = buildDateEnv$1(settings);
8143        var formatter = createFormatter(settings);
8144        var dateMeta = dateEnv.createMarkerMeta(dateInput);
8145        if (!dateMeta) { // TODO: warning?
8146            return '';
8147        }
8148        return dateEnv.format(dateMeta.marker, formatter, {
8149            forcedTzo: dateMeta.forcedTzo
8150        });
8151    }
8152    function formatRange(startInput, endInput, settings // mixture of env and formatter settings
8153    ) {
8154        var dateEnv = buildDateEnv$1(typeof settings === 'object' && settings ? settings : {}); // pass in if non-null object
8155        var formatter = createFormatter(settings, globalDefaults.defaultRangeSeparator);
8156        var startMeta = dateEnv.createMarkerMeta(startInput);
8157        var endMeta = dateEnv.createMarkerMeta(endInput);
8158        if (!startMeta || !endMeta) { // TODO: warning?
8159            return '';
8160        }
8161        return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
8162            forcedStartTzo: startMeta.forcedTzo,
8163            forcedEndTzo: endMeta.forcedTzo,
8164            isEndExclusive: settings.isEndExclusive
8165        });
8166    }
8167    // TODO: more DRY and optimized
8168    function buildDateEnv$1(settings) {
8169        var locale = buildLocale(settings.locale || 'en', parseRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
8170        // ensure required settings
8171        settings = __assign({ timeZone: globalDefaults.timeZone, calendarSystem: 'gregory' }, settings, { locale: locale });
8172        return new DateEnv(settings);
8173    }
8174
8175    var DRAG_META_PROPS = {
8176        startTime: createDuration,
8177        duration: createDuration,
8178        create: Boolean,
8179        sourceId: String
8180    };
8181    var DRAG_META_DEFAULTS = {
8182        create: true
8183    };
8184    function parseDragMeta(raw) {
8185        var leftoverProps = {};
8186        var refined = refineProps(raw, DRAG_META_PROPS, DRAG_META_DEFAULTS, leftoverProps);
8187        refined.leftoverProps = leftoverProps;
8188        return refined;
8189    }
8190
8191    // Computes a default column header formatting string if `colFormat` is not explicitly defined
8192    function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
8193        // if more than one week row, or if there are a lot of columns with not much space,
8194        // put just the day numbers will be in each cell
8195        if (!datesRepDistinctDays || dayCnt > 10) {
8196            return { weekday: 'short' }; // "Sat"
8197        }
8198        else if (dayCnt > 1) {
8199            return { weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }; // "Sat 11/12"
8200        }
8201        else {
8202            return { weekday: 'long' }; // "Saturday"
8203        }
8204    }
8205    function renderDateCell(dateMarker, dateProfile, datesRepDistinctDays, colCnt, colHeadFormat, context, colspan, otherAttrs) {
8206        var dateEnv = context.dateEnv, theme = context.theme, options = context.options;
8207        var isDateValid = rangeContainsMarker(dateProfile.activeRange, dateMarker); // TODO: called too frequently. cache somehow.
8208        var classNames = [
8209            'fc-day-header',
8210            theme.getClass('widgetHeader')
8211        ];
8212        var innerHtml;
8213        if (typeof options.columnHeaderHtml === 'function') {
8214            innerHtml = options.columnHeaderHtml(dateEnv.toDate(dateMarker));
8215        }
8216        else if (typeof options.columnHeaderText === 'function') {
8217            innerHtml = htmlEscape(options.columnHeaderText(dateEnv.toDate(dateMarker)));
8218        }
8219        else {
8220            innerHtml = htmlEscape(dateEnv.format(dateMarker, colHeadFormat));
8221        }
8222        // if only one row of days, the classNames on the header can represent the specific days beneath
8223        if (datesRepDistinctDays) {
8224            classNames = classNames.concat(
8225            // includes the day-of-week class
8226            // noThemeHighlight=true (don't highlight the header)
8227            getDayClasses(dateMarker, dateProfile, context, true));
8228        }
8229        else {
8230            classNames.push('fc-' + DAY_IDS[dateMarker.getUTCDay()]); // only add the day-of-week class
8231        }
8232        return '' +
8233            '<th class="' + classNames.join(' ') + '"' +
8234            ((isDateValid && datesRepDistinctDays) ?
8235                ' data-date="' + dateEnv.formatIso(dateMarker, { omitTime: true }) + '"' :
8236                '') +
8237            (colspan > 1 ?
8238                ' colspan="' + colspan + '"' :
8239                '') +
8240            (otherAttrs ?
8241                ' ' + otherAttrs :
8242                '') +
8243            '>' +
8244            (isDateValid ?
8245                // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff)
8246                buildGotoAnchorHtml(options, dateEnv, { date: dateMarker, forceOff: !datesRepDistinctDays || colCnt === 1 }, innerHtml) :
8247                // if not valid, display text, but no link
8248                innerHtml) +
8249            '</th>';
8250    }
8251
8252    var DayHeader = /** @class */ (function (_super) {
8253        __extends(DayHeader, _super);
8254        function DayHeader(parentEl) {
8255            var _this = _super.call(this) || this;
8256            _this.renderSkeleton = memoizeRendering(_this._renderSkeleton, _this._unrenderSkeleton);
8257            _this.parentEl = parentEl;
8258            return _this;
8259        }
8260        DayHeader.prototype.render = function (props, context) {
8261            var dates = props.dates, datesRepDistinctDays = props.datesRepDistinctDays;
8262            var parts = [];
8263            this.renderSkeleton(context);
8264            if (props.renderIntroHtml) {
8265                parts.push(props.renderIntroHtml());
8266            }
8267            var colHeadFormat = createFormatter(context.options.columnHeaderFormat ||
8268                computeFallbackHeaderFormat(datesRepDistinctDays, dates.length));
8269            for (var _i = 0, dates_1 = dates; _i < dates_1.length; _i++) {
8270                var date = dates_1[_i];
8271                parts.push(renderDateCell(date, props.dateProfile, datesRepDistinctDays, dates.length, colHeadFormat, context));
8272            }
8273            if (context.isRtl) {
8274                parts.reverse();
8275            }
8276            this.thead.innerHTML = '<tr>' + parts.join('') + '</tr>';
8277        };
8278        DayHeader.prototype.destroy = function () {
8279            _super.prototype.destroy.call(this);
8280            this.renderSkeleton.unrender();
8281        };
8282        DayHeader.prototype._renderSkeleton = function (context) {
8283            var theme = context.theme;
8284            var parentEl = this.parentEl;
8285            parentEl.innerHTML = ''; // because might be nbsp
8286            parentEl.appendChild(this.el = htmlToElement('<div class="fc-row ' + theme.getClass('headerRow') + '">' +
8287                '<table class="' + theme.getClass('tableGrid') + '">' +
8288                '<thead></thead>' +
8289                '</table>' +
8290                '</div>'));
8291            this.thead = this.el.querySelector('thead');
8292        };
8293        DayHeader.prototype._unrenderSkeleton = function () {
8294            removeElement(this.el);
8295        };
8296        return DayHeader;
8297    }(Component));
8298
8299    var DaySeries = /** @class */ (function () {
8300        function DaySeries(range, dateProfileGenerator) {
8301            var date = range.start;
8302            var end = range.end;
8303            var indices = [];
8304            var dates = [];
8305            var dayIndex = -1;
8306            while (date < end) { // loop each day from start to end
8307                if (dateProfileGenerator.isHiddenDay(date)) {
8308                    indices.push(dayIndex + 0.5); // mark that it's between indices
8309                }
8310                else {
8311                    dayIndex++;
8312                    indices.push(dayIndex);
8313                    dates.push(date);
8314                }
8315                date = addDays(date, 1);
8316            }
8317            this.dates = dates;
8318            this.indices = indices;
8319            this.cnt = dates.length;
8320        }
8321        DaySeries.prototype.sliceRange = function (range) {
8322            var firstIndex = this.getDateDayIndex(range.start); // inclusive first index
8323            var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
8324            var clippedFirstIndex = Math.max(0, firstIndex);
8325            var clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
8326            // deal with in-between indices
8327            clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
8328            clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
8329            if (clippedFirstIndex <= clippedLastIndex) {
8330                return {
8331                    firstIndex: clippedFirstIndex,
8332                    lastIndex: clippedLastIndex,
8333                    isStart: firstIndex === clippedFirstIndex,
8334                    isEnd: lastIndex === clippedLastIndex
8335                };
8336            }
8337            else {
8338                return null;
8339            }
8340        };
8341        // Given a date, returns its chronolocial cell-index from the first cell of the grid.
8342        // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
8343        // If before the first offset, returns a negative number.
8344        // If after the last offset, returns an offset past the last cell offset.
8345        // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
8346        DaySeries.prototype.getDateDayIndex = function (date) {
8347            var indices = this.indices;
8348            var dayOffset = Math.floor(diffDays(this.dates[0], date));
8349            if (dayOffset < 0) {
8350                return indices[0] - 1;
8351            }
8352            else if (dayOffset >= indices.length) {
8353                return indices[indices.length - 1] + 1;
8354            }
8355            else {
8356                return indices[dayOffset];
8357            }
8358        };
8359        return DaySeries;
8360    }());
8361
8362    var DayTable = /** @class */ (function () {
8363        function DayTable(daySeries, breakOnWeeks) {
8364            var dates = daySeries.dates;
8365            var daysPerRow;
8366            var firstDay;
8367            var rowCnt;
8368            if (breakOnWeeks) {
8369                // count columns until the day-of-week repeats
8370                firstDay = dates[0].getUTCDay();
8371                for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow++) {
8372                    if (dates[daysPerRow].getUTCDay() === firstDay) {
8373                        break;
8374                    }
8375                }
8376                rowCnt = Math.ceil(dates.length / daysPerRow);
8377            }
8378            else {
8379                rowCnt = 1;
8380                daysPerRow = dates.length;
8381            }
8382            this.rowCnt = rowCnt;
8383            this.colCnt = daysPerRow;
8384            this.daySeries = daySeries;
8385            this.cells = this.buildCells();
8386            this.headerDates = this.buildHeaderDates();
8387        }
8388        DayTable.prototype.buildCells = function () {
8389            var rows = [];
8390            for (var row = 0; row < this.rowCnt; row++) {
8391                var cells = [];
8392                for (var col = 0; col < this.colCnt; col++) {
8393                    cells.push(this.buildCell(row, col));
8394                }
8395                rows.push(cells);
8396            }
8397            return rows;
8398        };
8399        DayTable.prototype.buildCell = function (row, col) {
8400            return {
8401                date: this.daySeries.dates[row * this.colCnt + col]
8402            };
8403        };
8404        DayTable.prototype.buildHeaderDates = function () {
8405            var dates = [];
8406            for (var col = 0; col < this.colCnt; col++) {
8407                dates.push(this.cells[0][col].date);
8408            }
8409            return dates;
8410        };
8411        DayTable.prototype.sliceRange = function (range) {
8412            var colCnt = this.colCnt;
8413            var seriesSeg = this.daySeries.sliceRange(range);
8414            var segs = [];
8415            if (seriesSeg) {
8416                var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex;
8417                var index = firstIndex;
8418                while (index <= lastIndex) {
8419                    var row = Math.floor(index / colCnt);
8420                    var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
8421                    segs.push({
8422                        row: row,
8423                        firstCol: index % colCnt,
8424                        lastCol: (nextIndex - 1) % colCnt,
8425                        isStart: seriesSeg.isStart && index === firstIndex,
8426                        isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex
8427                    });
8428                    index = nextIndex;
8429                }
8430            }
8431            return segs;
8432        };
8433        return DayTable;
8434    }());
8435
8436    var Slicer = /** @class */ (function () {
8437        function Slicer() {
8438            this.sliceBusinessHours = memoize(this._sliceBusinessHours);
8439            this.sliceDateSelection = memoize(this._sliceDateSpan);
8440            this.sliceEventStore = memoize(this._sliceEventStore);
8441            this.sliceEventDrag = memoize(this._sliceInteraction);
8442            this.sliceEventResize = memoize(this._sliceInteraction);
8443        }
8444        Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, calendar, component) {
8445            var extraArgs = [];
8446            for (var _i = 5; _i < arguments.length; _i++) {
8447                extraArgs[_i - 5] = arguments[_i];
8448            }
8449            var eventUiBases = props.eventUiBases;
8450            var eventSegs = this.sliceEventStore.apply(this, [props.eventStore, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs));
8451            return {
8452                dateSelectionSegs: this.sliceDateSelection.apply(this, [props.dateSelection, eventUiBases, component].concat(extraArgs)),
8453                businessHourSegs: this.sliceBusinessHours.apply(this, [props.businessHours, dateProfile, nextDayThreshold, calendar, component].concat(extraArgs)),
8454                fgEventSegs: eventSegs.fg,
8455                bgEventSegs: eventSegs.bg,
8456                eventDrag: this.sliceEventDrag.apply(this, [props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8457                eventResize: this.sliceEventResize.apply(this, [props.eventResize, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8458                eventSelection: props.eventSelection
8459            }; // TODO: give interactionSegs?
8460        };
8461        Slicer.prototype.sliceNowDate = function (// does not memoize
8462        date, component) {
8463            var extraArgs = [];
8464            for (var _i = 2; _i < arguments.length; _i++) {
8465                extraArgs[_i - 2] = arguments[_i];
8466            }
8467            return this._sliceDateSpan.apply(this, [{ range: { start: date, end: addMs(date, 1) }, allDay: false },
8468                {},
8469                component].concat(extraArgs));
8470        };
8471        Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, calendar, component) {
8472            var extraArgs = [];
8473            for (var _i = 5; _i < arguments.length; _i++) {
8474                extraArgs[_i - 5] = arguments[_i];
8475            }
8476            if (!businessHours) {
8477                return [];
8478            }
8479            return this._sliceEventStore.apply(this, [expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), calendar),
8480                {},
8481                dateProfile,
8482                nextDayThreshold,
8483                component].concat(extraArgs)).bg;
8484        };
8485        Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold, component) {
8486            var extraArgs = [];
8487            for (var _i = 5; _i < arguments.length; _i++) {
8488                extraArgs[_i - 5] = arguments[_i];
8489            }
8490            if (eventStore) {
8491                var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8492                return {
8493                    bg: this.sliceEventRanges(rangeRes.bg, component, extraArgs),
8494                    fg: this.sliceEventRanges(rangeRes.fg, component, extraArgs)
8495                };
8496            }
8497            else {
8498                return { bg: [], fg: [] };
8499            }
8500        };
8501        Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold, component) {
8502            var extraArgs = [];
8503            for (var _i = 5; _i < arguments.length; _i++) {
8504                extraArgs[_i - 5] = arguments[_i];
8505            }
8506            if (!interaction) {
8507                return null;
8508            }
8509            var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8510            return {
8511                segs: this.sliceEventRanges(rangeRes.fg, component, extraArgs),
8512                affectedInstances: interaction.affectedEvents.instances,
8513                isEvent: interaction.isEvent,
8514                sourceSeg: interaction.origSeg
8515            };
8516        };
8517        Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, component) {
8518            var extraArgs = [];
8519            for (var _i = 3; _i < arguments.length; _i++) {
8520                extraArgs[_i - 3] = arguments[_i];
8521            }
8522            if (!dateSpan) {
8523                return [];
8524            }
8525            var eventRange = fabricateEventRange(dateSpan, eventUiBases, component.context.calendar);
8526            var segs = this.sliceRange.apply(this, [dateSpan.range].concat(extraArgs));
8527            for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) {
8528                var seg = segs_1[_a];
8529                seg.component = component;
8530                seg.eventRange = eventRange;
8531            }
8532            return segs;
8533        };
8534        /*
8535        "complete" seg means it has component and eventRange
8536        */
8537        Slicer.prototype.sliceEventRanges = function (eventRanges, component, // TODO: kill
8538        extraArgs) {
8539            var segs = [];
8540            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
8541                var eventRange = eventRanges_1[_i];
8542                segs.push.apply(segs, this.sliceEventRange(eventRange, component, extraArgs));
8543            }
8544            return segs;
8545        };
8546        /*
8547        "complete" seg means it has component and eventRange
8548        */
8549        Slicer.prototype.sliceEventRange = function (eventRange, component, // TODO: kill
8550        extraArgs) {
8551            var segs = this.sliceRange.apply(this, [eventRange.range].concat(extraArgs));
8552            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
8553                var seg = segs_2[_i];
8554                seg.component = component;
8555                seg.eventRange = eventRange;
8556                seg.isStart = eventRange.isStart && seg.isStart;
8557                seg.isEnd = eventRange.isEnd && seg.isEnd;
8558            }
8559            return segs;
8560        };
8561        return Slicer;
8562    }());
8563    /*
8564    for incorporating minTime/maxTime if appropriate
8565    TODO: should be part of DateProfile!
8566    TimelineDateProfile already does this btw
8567    */
8568    function computeActiveRange(dateProfile, isComponentAllDay) {
8569        var range = dateProfile.activeRange;
8570        if (isComponentAllDay) {
8571            return range;
8572        }
8573        return {
8574            start: addMs(range.start, dateProfile.minTime.milliseconds),
8575            end: addMs(range.end, dateProfile.maxTime.milliseconds - 864e5) // 864e5 = ms in a day
8576        };
8577    }
8578
8579    // exports
8580    // --------------------------------------------------------------------------------------------------
8581    var version = '4.4.0';
8582
8583    exports.Calendar = Calendar;
8584    exports.Component = Component;
8585    exports.ComponentContext = ComponentContext;
8586    exports.DateComponent = DateComponent;
8587    exports.DateEnv = DateEnv;
8588    exports.DateProfileGenerator = DateProfileGenerator;
8589    exports.DayHeader = DayHeader;
8590    exports.DaySeries = DaySeries;
8591    exports.DayTable = DayTable;
8592    exports.ElementDragging = ElementDragging;
8593    exports.ElementScrollController = ElementScrollController;
8594    exports.EmitterMixin = EmitterMixin;
8595    exports.EventApi = EventApi;
8596    exports.FgEventRenderer = FgEventRenderer;
8597    exports.FillRenderer = FillRenderer;
8598    exports.Interaction = Interaction;
8599    exports.Mixin = Mixin;
8600    exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
8601    exports.PositionCache = PositionCache;
8602    exports.ScrollComponent = ScrollComponent;
8603    exports.ScrollController = ScrollController;
8604    exports.Slicer = Slicer;
8605    exports.Splitter = Splitter;
8606    exports.Theme = Theme;
8607    exports.View = View;
8608    exports.WindowScrollController = WindowScrollController;
8609    exports.addDays = addDays;
8610    exports.addDurations = addDurations;
8611    exports.addMs = addMs;
8612    exports.addWeeks = addWeeks;
8613    exports.allowContextMenu = allowContextMenu;
8614    exports.allowSelection = allowSelection;
8615    exports.appendToElement = appendToElement;
8616    exports.applyAll = applyAll;
8617    exports.applyMutationToEventStore = applyMutationToEventStore;
8618    exports.applyStyle = applyStyle;
8619    exports.applyStyleProp = applyStyleProp;
8620    exports.asRoughMinutes = asRoughMinutes;
8621    exports.asRoughMs = asRoughMs;
8622    exports.asRoughSeconds = asRoughSeconds;
8623    exports.buildGotoAnchorHtml = buildGotoAnchorHtml;
8624    exports.buildSegCompareObj = buildSegCompareObj;
8625    exports.capitaliseFirstLetter = capitaliseFirstLetter;
8626    exports.combineEventUis = combineEventUis;
8627    exports.compareByFieldSpec = compareByFieldSpec;
8628    exports.compareByFieldSpecs = compareByFieldSpecs;
8629    exports.compareNumbers = compareNumbers;
8630    exports.compensateScroll = compensateScroll;
8631    exports.computeClippingRect = computeClippingRect;
8632    exports.computeEdges = computeEdges;
8633    exports.computeEventDraggable = computeEventDraggable;
8634    exports.computeEventEndResizable = computeEventEndResizable;
8635    exports.computeEventStartResizable = computeEventStartResizable;
8636    exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat;
8637    exports.computeHeightAndMargins = computeHeightAndMargins;
8638    exports.computeInnerRect = computeInnerRect;
8639    exports.computeRect = computeRect;
8640    exports.computeVisibleDayRange = computeVisibleDayRange;
8641    exports.config = config;
8642    exports.constrainPoint = constrainPoint;
8643    exports.createDuration = createDuration;
8644    exports.createElement = createElement;
8645    exports.createEmptyEventStore = createEmptyEventStore;
8646    exports.createEventInstance = createEventInstance;
8647    exports.createFormatter = createFormatter;
8648    exports.createPlugin = createPlugin;
8649    exports.cssToStr = cssToStr;
8650    exports.debounce = debounce;
8651    exports.diffDates = diffDates;
8652    exports.diffDayAndTime = diffDayAndTime;
8653    exports.diffDays = diffDays;
8654    exports.diffPoints = diffPoints;
8655    exports.diffWeeks = diffWeeks;
8656    exports.diffWholeDays = diffWholeDays;
8657    exports.diffWholeWeeks = diffWholeWeeks;
8658    exports.disableCursor = disableCursor;
8659    exports.distributeHeight = distributeHeight;
8660    exports.elementClosest = elementClosest;
8661    exports.elementMatches = elementMatches;
8662    exports.enableCursor = enableCursor;
8663    exports.eventTupleToStore = eventTupleToStore;
8664    exports.filterEventStoreDefs = filterEventStoreDefs;
8665    exports.filterHash = filterHash;
8666    exports.findChildren = findChildren;
8667    exports.findElements = findElements;
8668    exports.flexibleCompare = flexibleCompare;
8669    exports.forceClassName = forceClassName;
8670    exports.formatDate = formatDate;
8671    exports.formatIsoTimeString = formatIsoTimeString;
8672    exports.formatRange = formatRange;
8673    exports.getAllDayHtml = getAllDayHtml;
8674    exports.getClippingParents = getClippingParents;
8675    exports.getDayClasses = getDayClasses;
8676    exports.getElSeg = getElSeg;
8677    exports.getRectCenter = getRectCenter;
8678    exports.getRelevantEvents = getRelevantEvents;
8679    exports.globalDefaults = globalDefaults;
8680    exports.greatestDurationDenominator = greatestDurationDenominator;
8681    exports.hasBgRendering = hasBgRendering;
8682    exports.htmlEscape = htmlEscape;
8683    exports.htmlToElement = htmlToElement;
8684    exports.insertAfterElement = insertAfterElement;
8685    exports.interactionSettingsStore = interactionSettingsStore;
8686    exports.interactionSettingsToStore = interactionSettingsToStore;
8687    exports.intersectRanges = intersectRanges;
8688    exports.intersectRects = intersectRects;
8689    exports.isArraysEqual = isArraysEqual;
8690    exports.isDateSpansEqual = isDateSpansEqual;
8691    exports.isInt = isInt;
8692    exports.isInteractionValid = isInteractionValid;
8693    exports.isMultiDayRange = isMultiDayRange;
8694    exports.isPropsEqual = isPropsEqual;
8695    exports.isPropsValid = isPropsValid;
8696    exports.isSingleDay = isSingleDay;
8697    exports.isValidDate = isValidDate;
8698    exports.listenBySelector = listenBySelector;
8699    exports.mapHash = mapHash;
8700    exports.matchCellWidths = matchCellWidths;
8701    exports.memoize = memoize;
8702    exports.memoizeOutput = memoizeOutput;
8703    exports.memoizeRendering = memoizeRendering;
8704    exports.mergeEventStores = mergeEventStores;
8705    exports.multiplyDuration = multiplyDuration;
8706    exports.padStart = padStart;
8707    exports.parseBusinessHours = parseBusinessHours;
8708    exports.parseDragMeta = parseDragMeta;
8709    exports.parseEventDef = parseEventDef;
8710    exports.parseFieldSpecs = parseFieldSpecs;
8711    exports.parseMarker = parse;
8712    exports.pointInsideRect = pointInsideRect;
8713    exports.prependToElement = prependToElement;
8714    exports.preventContextMenu = preventContextMenu;
8715    exports.preventDefault = preventDefault;
8716    exports.preventSelection = preventSelection;
8717    exports.processScopedUiProps = processScopedUiProps;
8718    exports.rangeContainsMarker = rangeContainsMarker;
8719    exports.rangeContainsRange = rangeContainsRange;
8720    exports.rangesEqual = rangesEqual;
8721    exports.rangesIntersect = rangesIntersect;
8722    exports.refineProps = refineProps;
8723    exports.removeElement = removeElement;
8724    exports.removeExact = removeExact;
8725    exports.renderDateCell = renderDateCell;
8726    exports.requestJson = requestJson;
8727    exports.sliceEventStore = sliceEventStore;
8728    exports.startOfDay = startOfDay;
8729    exports.subtractInnerElHeight = subtractInnerElHeight;
8730    exports.translateRect = translateRect;
8731    exports.uncompensateScroll = uncompensateScroll;
8732    exports.undistributeHeight = undistributeHeight;
8733    exports.unpromisify = unpromisify;
8734    exports.version = version;
8735    exports.whenTransitionDone = whenTransitionDone;
8736    exports.wholeDivideDurations = wholeDivideDurations;
8737
8738    Object.defineProperty(exports, '__esModule', { value: true });
8739
8740}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.