PageSourceSearch

https://www.df.gov.br/o/gdf-secretarias-lf7_4-2026-theme/js/full-c…=js&languageId=pt_BR&t=1790294974000

js www.df.gov.br collected 2026-10-02 07:50:20 UTC 538,645 bytes, 12,140 lines download raw bytes

1/*1790294974000*/
2/*!
3FullCalendar Core Package v4.1.0
4Docs & License: https://fullcalendar.io/
5(c) 2019 Adam Shaw
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        var scrollbarLeftRight = sanitizeScrollbarWidth(el.offsetWidth - el.clientWidth - borderLeft - borderRight);
281        var scrollbarBottom = sanitizeScrollbarWidth(el.offsetHeight - el.clientHeight - borderTop - borderBottom);
282        var res = {
283            borderLeft: borderLeft,
284            borderRight: borderRight,
285            borderTop: borderTop,
286            borderBottom: borderBottom,
287            scrollbarBottom: scrollbarBottom,
288            scrollbarLeft: 0,
289            scrollbarRight: 0
290        };
291        if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side?
292            res.scrollbarLeft = scrollbarLeftRight;
293        }
294        else {
295            res.scrollbarRight = scrollbarLeftRight;
296        }
297        if (getPadding) {
298            res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
299            res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
300            res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
301            res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
302        }
303        return res;
304    }
305    function computeInnerRect(el, goWithinPadding) {
306        if (goWithinPadding === void 0) { goWithinPadding = false; }
307        var outerRect = computeRect(el);
308        var edges = computeEdges(el, goWithinPadding);
309        var res = {
310            left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
311            right: outerRect.right - edges.borderRight - edges.scrollbarRight,
312            top: outerRect.top + edges.borderTop,
313            bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom
314        };
315        if (goWithinPadding) {
316            res.left += edges.paddingLeft;
317            res.right -= edges.paddingRight;
318            res.top += edges.paddingTop;
319            res.bottom -= edges.paddingBottom;
320        }
321        return res;
322    }
323    function computeRect(el) {
324        var rect = el.getBoundingClientRect();
325        return {
326            left: rect.left + window.pageXOffset,
327            top: rect.top + window.pageYOffset,
328            right: rect.right + window.pageXOffset,
329            bottom: rect.bottom + window.pageYOffset
330        };
331    }
332    function computeViewportRect() {
333        return {
334            left: window.pageXOffset,
335            right: window.pageXOffset + document.documentElement.clientWidth,
336            top: window.pageYOffset,
337            bottom: window.pageYOffset + document.documentElement.clientHeight
338        };
339    }
340    function computeHeightAndMargins(el) {
341        var computed = window.getComputedStyle(el);
342        return el.getBoundingClientRect().height +
343            parseInt(computed.marginTop, 10) +
344            parseInt(computed.marginBottom, 10);
345    }
346    // does not return window
347    function getClippingParents(el) {
348        var parents = [];
349        while (el instanceof HTMLElement) { // will stop when gets to document or null
350            var computedStyle = window.getComputedStyle(el);
351            if (computedStyle.position === 'fixed') {
352                break;
353            }
354            if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
355                parents.push(el);
356            }
357            el = el.parentNode;
358        }
359        return parents;
360    }
361    function computeClippingRect(el) {
362        return getClippingParents(el)
363            .map(function (el) {
364            return computeInnerRect(el);
365        })
366            .concat(computeViewportRect())
367            .reduce(function (rect0, rect1) {
368            return intersectRects(rect0, rect1) || rect1; // should always intersect
369        });
370    }
371
372    // Stops a mouse/touch event from doing it's native browser action
373    function preventDefault(ev) {
374        ev.preventDefault();
375    }
376    // Event Delegation
377    // ----------------------------------------------------------------------------------------------------------------
378    function listenBySelector(container, eventType, selector, handler) {
379        function realHandler(ev) {
380            var matchedChild = elementClosest(ev.target, selector);
381            if (matchedChild) {
382                handler.call(matchedChild, ev, matchedChild);
383            }
384        }
385        container.addEventListener(eventType, realHandler);
386        return function () {
387            container.removeEventListener(eventType, realHandler);
388        };
389    }
390    function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
391        var currentMatchedChild;
392        return listenBySelector(container, 'mouseover', selector, function (ev, matchedChild) {
393            if (matchedChild !== currentMatchedChild) {
394                currentMatchedChild = matchedChild;
395                onMouseEnter(ev, matchedChild);
396                var realOnMouseLeave_1 = function (ev) {
397                    currentMatchedChild = null;
398                    onMouseLeave(ev, matchedChild);
399                    matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1);
400                };
401                // listen to the next mouseleave, and then unattach
402                matchedChild.addEventListener('mouseleave', realOnMouseLeave_1);
403            }
404        });
405    }
406    // Animation
407    // ----------------------------------------------------------------------------------------------------------------
408    var transitionEventNames = [
409        'webkitTransitionEnd',
410        'otransitionend',
411        'oTransitionEnd',
412        'msTransitionEnd',
413        'transitionend'
414    ];
415    // triggered only when the next single subsequent transition finishes
416    function whenTransitionDone(el, callback) {
417        var realCallback = function (ev) {
418            callback(ev);
419            transitionEventNames.forEach(function (eventName) {
420                el.removeEventListener(eventName, realCallback);
421            });
422        };
423        transitionEventNames.forEach(function (eventName) {
424            el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes
425        });
426    }
427
428    var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
429    // Adding
430    function addWeeks(m, n) {
431        var a = dateToUtcArray(m);
432        a[2] += n * 7;
433        return arrayToUtcDate(a);
434    }
435    function addDays(m, n) {
436        var a = dateToUtcArray(m);
437        a[2] += n;
438        return arrayToUtcDate(a);
439    }
440    function addMs(m, n) {
441        var a = dateToUtcArray(m);
442        a[6] += n;
443        return arrayToUtcDate(a);
444    }
445    // Diffing (all return floats)
446    function diffWeeks(m0, m1) {
447        return diffDays(m0, m1) / 7;
448    }
449    function diffDays(m0, m1) {
450        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
451    }
452    function diffHours(m0, m1) {
453        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
454    }
455    function diffMinutes(m0, m1) {
456        return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
457    }
458    function diffSeconds(m0, m1) {
459        return (m1.valueOf() - m0.valueOf()) / 1000;
460    }
461    function diffDayAndTime(m0, m1) {
462        var m0day = startOfDay(m0);
463        var m1day = startOfDay(m1);
464        return {
465            years: 0,
466            months: 0,
467            days: Math.round(diffDays(m0day, m1day)),
468            milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf())
469        };
470    }
471    // Diffing Whole Units
472    function diffWholeWeeks(m0, m1) {
473        var d = diffWholeDays(m0, m1);
474        if (d !== null && d % 7 === 0) {
475            return d / 7;
476        }
477        return null;
478    }
479    function diffWholeDays(m0, m1) {
480        if (timeAsMs(m0) === timeAsMs(m1)) {
481            return Math.round(diffDays(m0, m1));
482        }
483        return null;
484    }
485    // Start-Of
486    function startOfDay(m) {
487        return arrayToUtcDate([
488            m.getUTCFullYear(),
489            m.getUTCMonth(),
490            m.getUTCDate()
491        ]);
492    }
493    function startOfHour(m) {
494        return arrayToUtcDate([
495            m.getUTCFullYear(),
496            m.getUTCMonth(),
497            m.getUTCDate(),
498            m.getUTCHours()
499        ]);
500    }
501    function startOfMinute(m) {
502        return arrayToUtcDate([
503            m.getUTCFullYear(),
504            m.getUTCMonth(),
505            m.getUTCDate(),
506            m.getUTCHours(),
507            m.getUTCMinutes()
508        ]);
509    }
510    function startOfSecond(m) {
511        return arrayToUtcDate([
512            m.getUTCFullYear(),
513            m.getUTCMonth(),
514            m.getUTCDate(),
515            m.getUTCHours(),
516            m.getUTCMinutes(),
517            m.getUTCSeconds()
518        ]);
519    }
520    // Week Computation
521    function weekOfYear(marker, dow, doy) {
522        var y = marker.getUTCFullYear();
523        var w = weekOfGivenYear(marker, y, dow, doy);
524        if (w < 1) {
525            return weekOfGivenYear(marker, y - 1, dow, doy);
526        }
527        var nextW = weekOfGivenYear(marker, y + 1, dow, doy);
528        if (nextW >= 1) {
529            return Math.min(w, nextW);
530        }
531        return w;
532    }
533    function weekOfGivenYear(marker, year, dow, doy) {
534        var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
535        var dayStart = startOfDay(marker);
536        var days = Math.round(diffDays(firstWeekStart, dayStart));
537        return Math.floor(days / 7) + 1; // zero-indexed
538    }
539    // start-of-first-week - start-of-year
540    function firstWeekOffset(year, dow, doy) {
541        // first-week day -- which january is always in the first week (4 for iso, 1 for other)
542        var fwd = 7 + dow - doy;
543        // first-week day local weekday -- which local weekday is fwd
544        var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
545        return -fwdlw + fwd - 1;
546    }
547    // Array Conversion
548    function dateToLocalArray(date) {
549        return [
550            date.getFullYear(),
551            date.getMonth(),
552            date.getDate(),
553            date.getHours(),
554            date.getMinutes(),
555            date.getSeconds(),
556            date.getMilliseconds()
557        ];
558    }
559    function arrayToLocalDate(a) {
560        return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month
561        a[3] || 0, a[4] || 0, a[5] || 0);
562    }
563    function dateToUtcArray(date) {
564        return [
565            date.getUTCFullYear(),
566            date.getUTCMonth(),
567            date.getUTCDate(),
568            date.getUTCHours(),
569            date.getUTCMinutes(),
570            date.getUTCSeconds(),
571            date.getUTCMilliseconds()
572        ];
573    }
574    function arrayToUtcDate(a) {
575        // according to web standards (and Safari), a month index is required.
576        // massage if only given a year.
577        if (a.length === 1) {
578            a = a.concat([0]);
579        }
580        return new Date(Date.UTC.apply(Date, a));
581    }
582    // Other Utils
583    function isValidDate(m) {
584        return !isNaN(m.valueOf());
585    }
586    function timeAsMs(m) {
587        return m.getUTCHours() * 1000 * 60 * 60 +
588            m.getUTCMinutes() * 1000 * 60 +
589            m.getUTCSeconds() * 1000 +
590            m.getUTCMilliseconds();
591    }
592
593    var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
594    var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
595    // Parsing and Creation
596    function createDuration(input, unit) {
597        var _a;
598        if (typeof input === 'string') {
599            return parseString(input);
600        }
601        else if (typeof input === 'object' && input) { // non-null object
602            return normalizeObject(input);
603        }
604        else if (typeof input === 'number') {
605            return normalizeObject((_a = {}, _a[unit || 'milliseconds'] = input, _a));
606        }
607        else {
608            return null;
609        }
610    }
611    function parseString(s) {
612        var m = PARSE_RE.exec(s);
613        if (m) {
614            var sign = m[1] ? -1 : 1;
615            return {
616                years: 0,
617                months: 0,
618                days: sign * (m[2] ? parseInt(m[2], 10) : 0),
619                milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours
620                    (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes
621                    (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds
622                    (m[6] ? parseInt(m[6], 10) : 0) // ms
623                )
624            };
625        }
626        return null;
627    }
628    function normalizeObject(obj) {
629        return {
630            years: obj.years || obj.year || 0,
631            months: obj.months || obj.month || 0,
632            days: (obj.days || obj.day || 0) +
633                getWeeksFromInput(obj) * 7,
634            milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours
635                (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes
636                (obj.seconds || obj.second || 0) * 1000 + // seconds
637                (obj.milliseconds || obj.millisecond || obj.ms || 0) // ms
638        };
639    }
640    function getWeeksFromInput(obj) {
641        return obj.weeks || obj.week || 0;
642    }
643    // Equality
644    function durationsEqual(d0, d1) {
645        return d0.years === d1.years &&
646            d0.months === d1.months &&
647            d0.days === d1.days &&
648            d0.milliseconds === d1.milliseconds;
649    }
650    function isSingleDay(dur) {
651        return dur.years === 0 && dur.months === 0 && dur.days === 1 && dur.milliseconds === 0;
652    }
653    // Simple Math
654    function addDurations(d0, d1) {
655        return {
656            years: d0.years + d1.years,
657            months: d0.months + d1.months,
658            days: d0.days + d1.days,
659            milliseconds: d0.milliseconds + d1.milliseconds
660        };
661    }
662    function subtractDurations(d1, d0) {
663        return {
664            years: d1.years - d0.years,
665            months: d1.months - d0.months,
666            days: d1.days - d0.days,
667            milliseconds: d1.milliseconds - d0.milliseconds
668        };
669    }
670    function multiplyDuration(d, n) {
671        return {
672            years: d.years * n,
673            months: d.months * n,
674            days: d.days * n,
675            milliseconds: d.milliseconds * n
676        };
677    }
678    // Conversions
679    // "Rough" because they are based on average-case Gregorian months/years
680    function asRoughYears(dur) {
681        return asRoughDays(dur) / 365;
682    }
683    function asRoughMonths(dur) {
684        return asRoughDays(dur) / 30;
685    }
686    function asRoughDays(dur) {
687        return asRoughMs(dur) / 864e5;
688    }
689    function asRoughMinutes(dur) {
690        return asRoughMs(dur) / (1000 * 60);
691    }
692    function asRoughSeconds(dur) {
693        return asRoughMs(dur) / 1000;
694    }
695    function asRoughMs(dur) {
696        return dur.years * (365 * 864e5) +
697            dur.months * (30 * 864e5) +
698            dur.days * 864e5 +
699            dur.milliseconds;
700    }
701    // Advanced Math
702    function wholeDivideDurations(numerator, denominator) {
703        var res = null;
704        for (var i = 0; i < INTERNAL_UNITS.length; i++) {
705            var unit = INTERNAL_UNITS[i];
706            if (denominator[unit]) {
707                var localRes = numerator[unit] / denominator[unit];
708                if (!isInt(localRes) || (res !== null && res !== localRes)) {
709                    return null;
710                }
711                res = localRes;
712            }
713            else if (numerator[unit]) {
714                // needs to divide by something but can't!
715                return null;
716            }
717        }
718        return res;
719    }
720    function greatestDurationDenominator(dur, dontReturnWeeks) {
721        var ms = dur.milliseconds;
722        if (ms) {
723            if (ms % 1000 !== 0) {
724                return { unit: 'millisecond', value: ms };
725            }
726            if (ms % (1000 * 60) !== 0) {
727                return { unit: 'second', value: ms / 1000 };
728            }
729            if (ms % (1000 * 60 * 60) !== 0) {
730                return { unit: 'minute', value: ms / (1000 * 60) };
731            }
732            if (ms) {
733                return { unit: 'hour', value: ms / (1000 * 60 * 60) };
734            }
735        }
736        if (dur.days) {
737            if (!dontReturnWeeks && dur.days % 7 === 0) {
738                return { unit: 'week', value: dur.days / 7 };
739            }
740            return { unit: 'day', value: dur.days };
741        }
742        if (dur.months) {
743            return { unit: 'month', value: dur.months };
744        }
745        if (dur.years) {
746            return { unit: 'year', value: dur.years };
747        }
748        return { unit: 'millisecond', value: 0 };
749    }
750
751    /* FullCalendar-specific DOM Utilities
752    ----------------------------------------------------------------------------------------------------------------------*/
753    // Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left
754    // and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.
755    function compensateScroll(rowEl, scrollbarWidths) {
756        if (scrollbarWidths.left) {
757            applyStyle(rowEl, {
758                borderLeftWidth: 1,
759                marginLeft: scrollbarWidths.left - 1
760            });
761        }
762        if (scrollbarWidths.right) {
763            applyStyle(rowEl, {
764                borderRightWidth: 1,
765                marginRight: scrollbarWidths.right - 1
766            });
767        }
768    }
769    // Undoes compensateScroll and restores all borders/margins
770    function uncompensateScroll(rowEl) {
771        applyStyle(rowEl, {
772            marginLeft: '',
773            marginRight: '',
774            borderLeftWidth: '',
775            borderRightWidth: ''
776        });
777    }
778    // Make the mouse cursor express that an event is not allowed in the current area
779    function disableCursor() {
780        document.body.classList.add('fc-not-allowed');
781    }
782    // Returns the mouse cursor to its original look
783    function enableCursor() {
784        document.body.classList.remove('fc-not-allowed');
785    }
786    // Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.
787    // By default, all elements that are shorter than the recommended height are expanded uniformly, not considering
788    // any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and
789    // reduces the available height.
790    function distributeHeight(els, availableHeight, shouldRedistribute) {
791        // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,
792        // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.
793        var minOffset1 = Math.floor(availableHeight / els.length); // for non-last element
794        var minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE*
795        var flexEls = []; // elements that are allowed to expand. array of DOM nodes
796        var flexOffsets = []; // amount of vertical space it takes up
797        var flexHeights = []; // actual css height
798        var usedHeight = 0;
799        undistributeHeight(els); // give all elements their natural height
800        // find elements that are below the recommended height (expandable).
801        // important to query for heights in a single first pass (to avoid reflow oscillation).
802        els.forEach(function (el, i) {
803            var minOffset = i === els.length - 1 ? minOffset2 : minOffset1;
804            var naturalOffset = computeHeightAndMargins(el);
805            if (naturalOffset < minOffset) {
806                flexEls.push(el);
807                flexOffsets.push(naturalOffset);
808                flexHeights.push(el.offsetHeight);
809            }
810            else {
811                // this element stretches past recommended height (non-expandable). mark the space as occupied.
812                usedHeight += naturalOffset;
813            }
814        });
815        // readjust the recommended height to only consider the height available to non-maxed-out rows.
816        if (shouldRedistribute) {
817            availableHeight -= usedHeight;
818            minOffset1 = Math.floor(availableHeight / flexEls.length);
819            minOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE*
820        }
821        // assign heights to all expandable elements
822        flexEls.forEach(function (el, i) {
823            var minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1;
824            var naturalOffset = flexOffsets[i];
825            var naturalHeight = flexHeights[i];
826            var newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding
827            if (naturalOffset < minOffset) { // we check this again because redistribution might have changed things
828                el.style.height = newHeight + 'px';
829            }
830        });
831    }
832    // Undoes distrubuteHeight, restoring all els to their natural height
833    function undistributeHeight(els) {
834        els.forEach(function (el) {
835            el.style.height = '';
836        });
837    }
838    // Given `els`, a set of <td> cells, find the cell with the largest natural width and set the widths of all the
839    // cells to be that width.
840    // PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline
841    function matchCellWidths(els) {
842        var maxInnerWidth = 0;
843        els.forEach(function (el) {
844            var innerEl = el.firstChild; // hopefully an element
845            if (innerEl instanceof HTMLElement) {
846                var innerWidth_1 = innerEl.offsetWidth;
847                if (innerWidth_1 > maxInnerWidth) {
848                    maxInnerWidth = innerWidth_1;
849                }
850            }
851        });
852        maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance
853        els.forEach(function (el) {
854            el.style.width = maxInnerWidth + 'px';
855        });
856        return maxInnerWidth;
857    }
858    // Given one element that resides inside another,
859    // Subtracts the height of the inner element from the outer element.
860    function subtractInnerElHeight(outerEl, innerEl) {
861        // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
862        var reflowStyleProps = {
863            position: 'relative',
864            left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll
865        };
866        applyStyle(outerEl, reflowStyleProps);
867        applyStyle(innerEl, reflowStyleProps);
868        var diff = outerEl.offsetHeight - innerEl.offsetHeight; // grab the dimensions
869        // undo hack
870        var resetStyleProps = { position: '', left: '' };
871        applyStyle(outerEl, resetStyleProps);
872        applyStyle(innerEl, resetStyleProps);
873        return diff;
874    }
875    /* Selection
876    ----------------------------------------------------------------------------------------------------------------------*/
877    function preventSelection(el) {
878        el.classList.add('fc-unselectable');
879        el.addEventListener('selectstart', preventDefault);
880    }
881    function allowSelection(el) {
882        el.classList.remove('fc-unselectable');
883        el.removeEventListener('selectstart', preventDefault);
884    }
885    /* Context Menu
886    ----------------------------------------------------------------------------------------------------------------------*/
887    function preventContextMenu(el) {
888        el.addEventListener('contextmenu', preventDefault);
889    }
890    function allowContextMenu(el) {
891        el.removeEventListener('contextmenu', preventDefault);
892    }
893    /* Object Ordering by Field
894    ----------------------------------------------------------------------------------------------------------------------*/
895    function parseFieldSpecs(input) {
896        var specs = [];
897        var tokens = [];
898        var i;
899        var token;
900        if (typeof input === 'string') {
901            tokens = input.split(/\s*,\s*/);
902        }
903        else if (typeof input === 'function') {
904            tokens = [input];
905        }
906        else if (Array.isArray(input)) {
907            tokens = input;
908        }
909        for (i = 0; i < tokens.length; i++) {
910            token = tokens[i];
911            if (typeof token === 'string') {
912                specs.push(token.charAt(0) === '-' ?
913                    { field: token.substring(1), order: -1 } :
914                    { field: token, order: 1 });
915            }
916            else if (typeof token === 'function') {
917                specs.push({ func: token });
918            }
919        }
920        return specs;
921    }
922    function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
923        var i;
924        var cmp;
925        for (i = 0; i < fieldSpecs.length; i++) {
926            cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
927            if (cmp) {
928                return cmp;
929            }
930        }
931        return 0;
932    }
933    function compareByFieldSpec(obj0, obj1, fieldSpec) {
934        if (fieldSpec.func) {
935            return fieldSpec.func(obj0, obj1);
936        }
937        return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])
938            * (fieldSpec.order || 1);
939    }
940    function flexibleCompare(a, b) {
941        if (!a && !b) {
942            return 0;
943        }
944        if (b == null) {
945            return -1;
946        }
947        if (a == null) {
948            return 1;
949        }
950        if (typeof a === 'string' || typeof b === 'string') {
951            return String(a).localeCompare(String(b));
952        }
953        return a - b;
954    }
955    /* String Utilities
956    ----------------------------------------------------------------------------------------------------------------------*/
957    function capitaliseFirstLetter(str) {
958        return str.charAt(0).toUpperCase() + str.slice(1);
959    }
960    function padStart(val, len) {
961        var s = String(val);
962        return '000'.substr(0, len - s.length) + s;
963    }
964    /* Number Utilities
965    ----------------------------------------------------------------------------------------------------------------------*/
966    function compareNumbers(a, b) {
967        return a - b;
968    }
969    function isInt(n) {
970        return n % 1 === 0;
971    }
972    /* Weird Utilities
973    ----------------------------------------------------------------------------------------------------------------------*/
974    function applyAll(functions, thisObj, args) {
975        if (typeof functions === 'function') { // supplied a single function
976            functions = [functions];
977        }
978        if (functions) {
979            var i = void 0;
980            var ret = void 0;
981            for (i = 0; i < functions.length; i++) {
982                ret = functions[i].apply(thisObj, args) || ret;
983            }
984            return ret;
985        }
986    }
987    function firstDefined() {
988        var args = [];
989        for (var _i = 0; _i < arguments.length; _i++) {
990            args[_i] = arguments[_i];
991        }
992        for (var i = 0; i < args.length; i++) {
993            if (args[i] !== undefined) {
994                return args[i];
995            }
996        }
997    }
998    // Returns a function, that, as long as it continues to be invoked, will not
999    // be triggered. The function will be called after it stops being called for
1000    // N milliseconds. If `immediate` is passed, trigger the function on the
1001    // leading edge, instead of the trailing.
1002    // https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714
1003    function debounce(func, wait) {
1004        var timeout;
1005        var args;
1006        var context;
1007        var timestamp;
1008        var result;
1009        var later = function () {
1010            var last = new Date().valueOf() - timestamp;
1011            if (last < wait) {
1012                timeout = setTimeout(later, wait - last);
1013            }
1014            else {
1015                timeout = null;
1016                result = func.apply(context, args);
1017                context = args = null;
1018            }
1019        };
1020        return function () {
1021            context = this;
1022            args = arguments;
1023            timestamp = new Date().valueOf();
1024            if (!timeout) {
1025                timeout = setTimeout(later, wait);
1026            }
1027            return result;
1028        };
1029    }
1030    // Number and Boolean are only types that defaults or not computed for
1031    // TODO: write more comments
1032    function refineProps(rawProps, processors, defaults, leftoverProps) {
1033        if (defaults === void 0) { defaults = {}; }
1034        var refined = {};
1035        for (var key in processors) {
1036            var processor = processors[key];
1037            if (rawProps[key] !== undefined) {
1038                // found
1039                if (processor === Function) {
1040                    refined[key] = typeof rawProps[key] === 'function' ? rawProps[key] : null;
1041                }
1042                else if (processor) { // a refining function?
1043                    refined[key] = processor(rawProps[key]);
1044                }
1045                else {
1046                    refined[key] = rawProps[key];
1047                }
1048            }
1049            else if (defaults[key] !== undefined) {
1050                // there's an explicit default
1051                refined[key] = defaults[key];
1052            }
1053            else {
1054                // must compute a default
1055                if (processor === String) {
1056                    refined[key] = ''; // empty string is default for String
1057                }
1058                else if (!processor || processor === Number || processor === Boolean || processor === Function) {
1059                    refined[key] = null; // assign null for other non-custom processor funcs
1060                }
1061                else {
1062                    refined[key] = processor(null); // run the custom processor func
1063                }
1064            }
1065        }
1066        if (leftoverProps) {
1067            for (var key in rawProps) {
1068                if (processors[key] === undefined) {
1069                    leftoverProps[key] = rawProps[key];
1070                }
1071            }
1072        }
1073        return refined;
1074    }
1075    /*
1076    Get a snapshot of an object, so we can compare it to later revisions.
1077    Intentionally only works with arrays, jaja
1078    */
1079    function freezeRaw(raw) {
1080        if (Array.isArray(raw)) {
1081            return Array.prototype.slice.call(raw);
1082        }
1083        return raw;
1084    }
1085    /* Date stuff that doesn't belong in datelib core
1086    ----------------------------------------------------------------------------------------------------------------------*/
1087    // given a timed range, computes an all-day range that has the same exact duration,
1088    // but whose start time is aligned with the start of the day.
1089    function computeAlignedDayRange(timedRange) {
1090        var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
1091        var start = startOfDay(timedRange.start);
1092        var end = addDays(start, dayCnt);
1093        return { start: start, end: end };
1094    }
1095    // given a timed range, computes an all-day range based on how for the end date bleeds into the next day
1096    // TODO: give nextDayThreshold a default arg
1097    function computeVisibleDayRange(timedRange, nextDayThreshold) {
1098        if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); }
1099        var startDay = null;
1100        var endDay = null;
1101        if (timedRange.end) {
1102            endDay = startOfDay(timedRange.end);
1103            var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`
1104            // If the end time is actually inclusively part of the next day and is equal to or
1105            // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
1106            // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
1107            if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
1108                endDay = addDays(endDay, 1);
1109            }
1110        }
1111        if (timedRange.start) {
1112            startDay = startOfDay(timedRange.start); // the beginning of the day the range starts
1113            // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
1114            if (endDay && endDay <= startDay) {
1115                endDay = addDays(startDay, 1);
1116            }
1117        }
1118        return { start: startDay, end: endDay };
1119    }
1120    // spans from one day into another?
1121    function isMultiDayRange(range) {
1122        var visibleRange = computeVisibleDayRange(range);
1123        return diffDays(visibleRange.start, visibleRange.end) > 1;
1124    }
1125    function diffDates(date0, date1, dateEnv, largeUnit) {
1126        if (largeUnit === 'year') {
1127            return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
1128        }
1129        else if (largeUnit === 'month') {
1130            return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
1131        }
1132        else {
1133            return diffDayAndTime(date0, date1); // returns a duration
1134        }
1135    }
1136
1137    /*! *****************************************************************************
1138    Copyright (c) Microsoft Corporation. All rights reserved.
1139    Licensed under the Apache License, Version 2.0 (the "License");
1139 you may not use
1140    this file except in compliance with the License. You may obtain a copy of the
1141    License at http://www.apache.org/licenses/LICENSE-2.0
1142
1143    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1144    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
1145    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
1146    MERCHANTABLITY OR NON-INFRINGEMENT.
1147
1148    See the Apache Version 2.0 License for specific language governing permissions
1149    and limitations under the License.
1150    ***************************************************************************** */
1151    /* global Reflect, Promise */
1152
1153    var extendStatics = function(d, b) {
1154        extendStatics = Object.setPrototypeOf ||
1155            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
1156            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
1157        return extendStatics(d, b);
1158    };
1159
1160    function __extends(d, b) {
1161        extendStatics(d, b);
1162        function __() { this.constructor = d; }
1163        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1164    }
1165
1166    var __assign = function() {
1167        __assign = Object.assign || function __assign(t) {
1168            for (var s, i = 1, n = arguments.length; i < n; i++) {
1169                s = arguments[i];
1170                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
1171            }
1172            return t;
1173        };
1174        return __assign.apply(this, arguments);
1175    };
1176
1177    function parseRecurring(eventInput, allDayDefault, dateEnv, recurringTypes, leftovers) {
1178        for (var i = 0; i < recurringTypes.length; i++) {
1179            var localLeftovers = {};
1180            var parsed = recurringTypes[i].parse(eventInput, localLeftovers, dateEnv);
1181            if (parsed) {
1182                var allDay = localLeftovers.allDay;
1183                delete localLeftovers.allDay; // remove from leftovers
1184                if (allDay == null) {
1185                    allDay = allDayDefault;
1186                    if (allDay == null) {
1187                        allDay = parsed.allDayGuess;
1188                        if (allDay == null) {
1189                            allDay = false;
1190                        }
1191                    }
1192                }
1193                __assign(leftovers, localLeftovers);
1194                return {
1195                    allDay: allDay,
1196                    duration: parsed.duration,
1197                    typeData: parsed.typeData,
1198                    typeId: i
1199                };
1200            }
1201        }
1202        return null;
1203    }
1204    /*
1205    Event MUST have a recurringDef
1206    */
1207    function expandRecurringRanges(eventDef, framingRange, dateEnv, recurringTypes) {
1208        var typeDef = recurringTypes[eventDef.recurringDef.typeId];
1209        var markers = typeDef.expand(eventDef.recurringDef.typeData, framingRange, dateEnv);
1210        // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to
1211        if (eventDef.allDay) {
1212            markers = markers.map(startOfDay);
1213        }
1214        return markers;
1215    }
1216
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
1291    function parseEvents(rawEvents, sourceId, calendar, allowOpenRange) {
1292        var eventStore = createEmptyEventStore();
1293        for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
1294            var rawEvent = rawEvents_1[_i];
1295            var tuple = parseEvent(rawEvent, sourceId, calendar, allowOpenRange);
1296            if (tuple) {
1297                eventTupleToStore(tuple, eventStore);
1298            }
1299        }
1300        return eventStore;
1301    }
1302    function eventTupleToStore(tuple, eventStore) {
1303        if (eventStore === void 0) { eventStore = createEmptyEventStore(); }
1304        eventStore.defs[tuple.def.defId] = tuple.def;
1305        if (tuple.instance) {
1306            eventStore.instances[tuple.instance.instanceId] = tuple.instance;
1307        }
1308        return eventStore;
1309    }
1310    function expandRecurring(eventStore, framingRange, calendar) {
1311        var dateEnv = calendar.dateEnv;
1312        var defs = eventStore.defs, instances = eventStore.instances;
1313        // remove existing recurring instances
1314        instances = filterHash(instances, function (instance) {
1315            return !defs[instance.defId].recurringDef;
1316        });
1317        for (var defId in defs) {
1318            var def = defs[defId];
1319            if (def.recurringDef) {
1320                var starts = expandRecurringRanges(def, framingRange, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes);
1321                var duration = def.recurringDef.duration;
1322                if (!duration) {
1323                    duration = def.allDay ?
1324                        calendar.defaultAllDayEventDuration :
1325                        calendar.defaultTimedEventDuration;
1326                }
1327                for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) {
1328                    var start = starts_1[_i];
1329                    var instance = createEventInstance(defId, {
1330                        start: start,
1331                        end: dateEnv.add(start, duration)
1332                    });
1333                    instances[instance.instanceId] = instance;
1334                }
1335            }
1336        }
1337        return { defs: defs, instances: instances };
1338    }
1339    // retrieves events that have the same groupId as the instance specified by `instanceId`
1340    // or they are the same as the instance.
1341    // why might instanceId not be in the store? an event from another calendar?
1342    function getRelevantEvents(eventStore, instanceId) {
1343        var instance = eventStore.instances[instanceId];
1344        if (instance) {
1345            var def_1 = eventStore.defs[instance.defId];
1346            // get events/instances with same group
1347            var newStore = filterEventStoreDefs(eventStore, function (lookDef) {
1348                return isEventDefsGrouped(def_1, lookDef);
1349            });
1350            // add the original
1351            // TODO: wish we could use eventTupleToStore or something like it
1352            newStore.defs[def_1.defId] = def_1;
1353            newStore.instances[instance.instanceId] = instance;
1354            return newStore;
1355        }
1356        return createEmptyEventStore();
1357    }
1358    function isEventDefsGrouped(def0, def1) {
1359        return Boolean(def0.groupId && def0.groupId === def1.groupId);
1360    }
1361    function transformRawEvents(rawEvents, eventSource, calendar) {
1362        var calEachTransform = calendar.opt('eventDataTransform');
1363        var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
1364        if (sourceEachTransform) {
1365            rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
1366        }
1367        if (calEachTransform) {
1368            rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
1369        }
1370        return rawEvents;
1371    }
1372    function transformEachRawEvent(rawEvents, func) {
1373        var refinedEvents;
1374        if (!func) {
1375            refinedEvents = rawEvents;
1376        }
1377        else {
1378            refinedEvents = [];
1379            for (var _i = 0, rawEvents_2 = rawEvents; _i < rawEvents_2.length; _i++) {
1380                var rawEvent = rawEvents_2[_i];
1381                var refinedEvent = func(rawEvent);
1382                if (refinedEvent) {
1383                    refinedEvents.push(refinedEvent);
1384                }
1385                else if (refinedEvent == null) {
1386                    refinedEvents.push(rawEvent);
1387                } // if a different falsy value, do nothing
1388            }
1389        }
1390        return refinedEvents;
1391    }
1392    function createEmptyEventStore() {
1393        return { defs: {}, instances: {} };
1394    }
1395    function mergeEventStores(store0, store1) {
1396        return {
1397            defs: __assign({}, store0.defs, store1.defs),
1398            instances: __assign({}, store0.instances, store1.instances)
1399        };
1400    }
1401    function filterEventStoreDefs(eventStore, filterFunc) {
1402        var defs = filterHash(eventStore.defs, filterFunc);
1403        var instances = filterHash(eventStore.instances, function (instance) {
1404            return defs[instance.defId]; // still exists?
1405        });
1406        return { defs: defs, instances: instances };
1407    }
1408
1409    function parseRange(input, dateEnv) {
1410        var start = null;
1411        var end = null;
1412        if (input.start) {
1413            start = dateEnv.createMarker(input.start);
1414        }
1415        if (input.end) {
1416            end = dateEnv.createMarker(input.end);
1417        }
1418        if (!start && !end) {
1419            return null;
1420        }
1421        if (start && end && end < start) {
1422            return null;
1423        }
1424        return { start: start, end: end };
1425    }
1426    // SIDE-EFFECT: will mutate ranges.
1427    // Will return a new array result.
1428    function invertRanges(ranges, constraintRange) {
1429        var invertedRanges = [];
1430        var start = constraintRange.start; // the end of the previous range. the start of the new range
1431        var i;
1432        var dateRange;
1433        // ranges need to be in order. required for our date-walking algorithm
1434        ranges.sort(compareRanges);
1435        for (i = 0; i < ranges.length; i++) {
1436            dateRange = ranges[i];
1437            // add the span of time before the event (if there is any)
1438            if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)
1439                invertedRanges.push({ start: start, end: dateRange.start });
1440            }
1441            if (dateRange.end > start) {
1442                start = dateRange.end;
1443            }
1444        }
1445        // add the span of time after the last event (if there is any)
1446        if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)
1447            invertedRanges.push({ start: start, end: constraintRange.end });
1448        }
1449        return invertedRanges;
1450    }
1451    function compareRanges(range0, range1) {
1452        return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
1453    }
1454    function intersectRanges(range0, range1) {
1455        var start = range0.start;
1456        var end = range0.end;
1457        var newRange = null;
1458        if (range1.start !== null) {
1459            if (start === null) {
1460                start = range1.start;
1461            }
1462            else {
1463                start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
1464            }
1465        }
1466        if (range1.end != null) {
1467            if (end === null) {
1468                end = range1.end;
1469            }
1470            else {
1471                end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
1472            }
1473        }
1474        if (start === null || end === null || start < end) {
1475            newRange = { start: start, end: end };
1476        }
1477        return newRange;
1478    }
1479    function rangesEqual(range0, range1) {
1480        return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
1481            (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
1482    }
1483    function rangesIntersect(range0, range1) {
1484        return (range0.end === null || range1.start === null || range0.end > range1.start) &&
1485            (range0.start === null || range1.end === null || range0.start < range1.end);
1486    }
1487    function rangeContainsRange(outerRange, innerRange) {
1488        return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
1489            (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
1490    }
1491    function rangeContainsMarker(range, date) {
1492        return (range.start === null || date >= range.start) &&
1493            (range.end === null || date < range.end);
1494    }
1495    // If the given date is not within the given range, move it inside.
1496    // (If it's past the end, make it one millisecond before the end).
1497    function constrainMarkerToRange(date, range) {
1498        if (range.start != null && date < range.start) {
1499            return range.start;
1500        }
1501        if (range.end != null && date >= range.end) {
1502            return new Date(range.end.valueOf() - 1);
1503        }
1504        return date;
1505    }
1506
1507    function removeExact(array, exactVal) {
1508        var removeCnt = 0;
1509        var i = 0;
1510        while (i < array.length) {
1511            if (array[i] === exactVal) {
1512                array.splice(i, 1);
1513                removeCnt++;
1514            }
1515            else {
1516                i++;
1517            }
1518        }
1519        return removeCnt;
1520    }
1521    function isArraysEqual(a0, a1) {
1522        var len = a0.length;
1523        var i;
1524        if (len !== a1.length) { // not array? or not same length?
1525            return false;
1526        }
1527        for (i = 0; i < len; i++) {
1528            if (a0[i] !== a1[i]) {
1529                return false;
1530            }
1531        }
1532        return true;
1533    }
1534
1535    function memoize(workerFunc) {
1536        var args;
1537        var res;
1538        return function () {
1539            if (!args || !isArraysEqual(args, arguments)) {
1540                args = arguments;
1541                res = workerFunc.apply(this, arguments);
1542            }
1543            return res;
1544        };
1545    }
1546    /*
1547    always executes the workerFunc, but if the result is equal to the previous result,
1548    return the previous result instead.
1549    */
1550    function memoizeOutput(workerFunc, equalityFunc) {
1551        var cachedRes = null;
1552        return function () {
1553            var newRes = workerFunc.apply(this, arguments);
1554            if (cachedRes === null || !(cachedRes === newRes || equalityFunc(cachedRes, newRes))) {
1555                cachedRes = newRes;
1556            }
1557            return cachedRes;
1558        };
1559    }
1560
1561    var EXTENDED_SETTINGS_AND_SEVERITIES = {
1562        week: 3,
1563        separator: 0,
1564        omitZeroMinute: 0,
1565        meridiem: 0,
1566        omitCommas: 0
1567    };
1568    var STANDARD_DATE_PROP_SEVERITIES = {
1569        timeZoneName: 7,
1570        era: 6,
1571        year: 5,
1572        month: 4,
1573        day: 2,
1574        weekday: 2,
1575        hour: 1,
1576        minute: 1,
1577        second: 1
1578    };
1579    var MERIDIEM_RE = /\s*([ap])\.?m\.?/i; // eats up leading spaces too
1580    var COMMA_RE = /,/g; // we need re for globalness
1581    var MULTI_SPACE_RE = /\s+/g;
1582    var LTR_RE = /\u200e/g; // control character
1583    var UTC_RE = /UTC|GMT/;
1584    var NativeFormatter = /** @class */ (function () {
1585        function NativeFormatter(formatSettings) {
1586            var standardDateProps = {};
1587            var extendedSettings = {};
1588            var severity = 0;
1589            for (var name_1 in formatSettings) {
1590                if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) {
1591                    extendedSettings[name_1] = formatSettings[name_1];
1592                    severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity);
1593                }
1594                else {
1595                    standardDateProps[name_1] = formatSettings[name_1];
1596                    if (name_1 in STANDARD_DATE_PROP_SEVERITIES) {
1597                        severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity);
1598                    }
1599                }
1600            }
1601            this.standardDateProps = standardDateProps;
1602            this.extendedSettings = extendedSettings;
1603            this.severity = severity;
1604            this.buildFormattingFunc = memoize(buildFormattingFunc);
1605        }
1606        NativeFormatter.prototype.format = function (date, context) {
1607            return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
1608        };
1609        NativeFormatter.prototype.formatRange = function (start, end, context) {
1610            var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings;
1611            var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
1612            if (!diffSeverity) {
1613                return this.format(start, context);
1614            }
1615            var biggestUnitForPartial = diffSeverity;
1616            if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time
1617                (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&
1618                (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&
1619                (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
1620                biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time
1621            }
1622            var full0 = this.format(start, context);
1623            var full1 = this.format(end, context);
1624            if (full0 === full1) {
1625                return full0;
1626            }
1627            var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForParti
1627al);
1628            var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
1629            var partial0 = partialFormattingFunc(start);
1630            var partial1 = partialFormattingFunc(end);
1631            var insertion = findCommonInsertion(full0, partial0, full1, partial1);
1632            var separator = extendedSettings.separator || '';
1633            if (insertion) {
1634                return insertion.before + partial0 + separator + partial1 + insertion.after;
1635            }
1636            return full0 + separator + full1;
1637        };
1638        NativeFormatter.prototype.getLargestUnit = function () {
1639            switch (this.severity) {
1640                case 7:
1641                case 6:
1642                case 5:
1643                    return 'year';
1644                case 4:
1645                    return 'month';
1646                case 3:
1647                    return 'week';
1648                default:
1649                    return 'day';
1650            }
1651        };
1652        return NativeFormatter;
1653    }());
1654    function buildFormattingFunc(standardDateProps, extendedSettings, context) {
1655        var standardDatePropCnt = Object.keys(standardDateProps).length;
1656        if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
1657            return function (date) {
1658                return formatTimeZoneOffset(date.timeZoneOffset);
1659            };
1660        }
1661        if (standardDatePropCnt === 0 && extendedSettings.week) {
1662            return function (date) {
1663                return formatWeekNumber(context.computeWeekNumber(date.marker), context.weekLabel, context.locale, extendedSettings.week);
1664            };
1665        }
1666        return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
1667    }
1668    function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
1669        standardDateProps = __assign({}, standardDateProps); // copy
1670        extendedSettings = __assign({}, extendedSettings); // copy
1671        sanitizeSettings(standardDateProps, extendedSettings);
1672        standardDateProps.timeZone = 'UTC'; // we leverage the only guaranteed timeZone for our UTC markers
1673        var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
1674        var zeroFormat; // needed?
1675        if (extendedSettings.omitZeroMinute) {
1676            var zeroProps = __assign({}, standardDateProps);
1677            delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings
1678            zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
1679        }
1680        return function (date) {
1681            var marker = date.marker;
1682            var format;
1683            if (zeroFormat && !marker.getUTCMinutes()) {
1684                format = zeroFormat;
1685            }
1686            else {
1687                format = normalFormat;
1688            }
1689            var s = format.format(marker);
1690            return postProcess(s, date, standardDateProps, extendedSettings, context);
1691        };
1692    }
1693    function sanitizeSettings(standardDateProps, extendedSettings) {
1694        // deal with a browser inconsistency where formatting the timezone
1695        // requires that the hour/minute be present.
1696        if (standardDateProps.timeZoneName) {
1697            if (!standardDateProps.hour) {
1698                standardDateProps.hour = '2-digit';
1699            }
1700            if (!standardDateProps.minute) {
1701                standardDateProps.minute = '2-digit';
1702            }
1703        }
1704        // only support short timezone names
1705        if (standardDateProps.timeZoneName === 'long') {
1706            standardDateProps.timeZoneName = 'short';
1707        }
1708        // if requesting to display seconds, MUST display minutes
1709        if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
1710            delete extendedSettings.omitZeroMinute;
1711        }
1712    }
1713    function postProcess(s, date, standardDateProps, extendedSettings, context) {
1714        s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes
1715        if (standardDateProps.timeZoneName === 'short') {
1716            s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?
1717                'UTC' : // important to normalize for IE, which does "GMT"
1718                formatTimeZoneOffset(date.timeZoneOffset));
1719        }
1720        if (extendedSettings.omitCommas) {
1721            s = s.replace(COMMA_RE, '').trim();
1722        }
1723        if (extendedSettings.omitZeroMinute) {
1724            s = s.replace(':00', ''); // zeroFormat doesn't always achieve this
1725        }
1726        // ^ do anything that might create adjacent spaces before this point,
1727        // because MERIDIEM_RE likes to eat up loading spaces
1728        if (extendedSettings.meridiem === false) {
1729            s = s.replace(MERIDIEM_RE, '').trim();
1730        }
1731        else if (extendedSettings.meridiem === 'narrow') { // a/p
1732            s = s.replace(MERIDIEM_RE, function (m0, m1) {
1733                return m1.toLocaleLowerCase();
1734            });
1735        }
1736        else if (extendedSettings.meridiem === 'short') { // am/pm
1737            s = s.replace(MERIDIEM_RE, function (m0, m1) {
1738                return m1.toLocaleLowerCase() + 'm';
1739            });
1740        }
1741        else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase
1742            s = s.replace(MERIDIEM_RE, function (m0) {
1743                return m0.toLocaleLowerCase();
1744            });
1745        }
1746        s = s.replace(MULTI_SPACE_RE, ' ');
1747        s = s.trim();
1748        return s;
1749    }
1750    function injectTzoStr(s, tzoStr) {
1751        var replaced = false;
1752        s = s.replace(UTC_RE, function () {
1753            replaced = true;
1754            return tzoStr;
1755        });
1756        // IE11 doesn't include UTC/GMT in the original string, so append to end
1757        if (!replaced) {
1758            s += ' ' + tzoStr;
1759        }
1760        return s;
1761    }
1762    function formatWeekNumber(num, weekLabel, locale, display) {
1763        var parts = [];
1764        if (display === 'narrow') {
1765            parts.push(weekLabel);
1766        }
1767        else if (display === 'short') {
1768            parts.push(weekLabel, ' ');
1769        }
1770        // otherwise, considered 'numeric'
1771        parts.push(locale.simpleNumberFormat.format(num));
1772        if (locale.options.isRtl) { // TODO: use control characters instead?
1773            parts.reverse();
1774        }
1775        return parts.join('');
1776    }
1777    // Range Formatting Utils
1778    // 0 = exactly the same
1779    // 1 = different by time
1780    // and bigger
1781    function computeMarkerDiffSeverity(d0, d1, ca) {
1782        if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
1783            return 5;
1784        }
1785        if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
1786            return 4;
1787        }
1788        if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
1789            return 2;
1790        }
1791        if (timeAsMs(d0) !== timeAsMs(d1)) {
1792            return 1;
1793        }
1794        return 0;
1795    }
1796    function computePartialFormattingOptions(options, biggestUnit) {
1797        var partialOptions = {};
1798        for (var name_2 in options) {
1799            if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)
1800                STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) {
1801                partialOptions[name_2] = options[name_2];
1802            }
1803        }
1804        return partialOptions;
1805    }
1806    function findCommonInsertion(full0, partial0, full1, partial1) {
1807        var i0 = 0;
1808        while (i0 < full0.length) {
1809            var found0 = full0.indexOf(partial0, i0);
1810            if (found0 === -1) {
1811                break;
1812            }
1813            var before0 = full0.substr(0, found0);
1814            i0 = found0 + partial0.length;
1815            var after0 = full0.substr(i0);
1816            var i1 = 0;
1817            while (i1 < full1.length) {
1818                var found1 = full1.indexOf(partial1, i1);
1819                if (found1 === -1) {
1820                    break;
1821                }
1822                var before1 = full1.substr(0, found1);
1823                i1 = found1 + partial1.length;
1824                var after1 = full1.substr(i1);
1825                if (before0 === before1 && after0 === after1) {
1826                    return {
1827                        before: before0,
1828                        after: after0
1829                    };
1830                }
1831            }
1832        }
1833        return null;
1834    }
1835
1836    /*
1837    TODO: fix the terminology of "formatter" vs "formatting func"
1838    */
1839    /*
1840    At the time of instantiation, this object does not know which cmd-formatting system it will use.
1841    It receives this at the time of formatting, as a setting.
1842    */
1843    var CmdFormatter = /** @class */ (function () {
1844        function CmdFormatter(cmdStr, separator) {
1845            this.cmdStr = cmdStr;
1846            this.separator = separator;
1847        }
1848        CmdFormatter.prototype.format = function (date, context) {
1849            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, this.separator));
1850        };
1851        CmdFormatter.prototype.formatRange = function (start, end, context) {
1852            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, this.separator));
1853        };
1854        return CmdFormatter;
1855    }());
1856
1857    var FuncFormatter = /** @class */ (function () {
1858        function FuncFormatter(func) {
1859            this.func = func;
1860        }
1861        FuncFormatter.prototype.format = function (date, context) {
1862            return this.func(createVerboseFormattingArg(date, null, context));
1863        };
1864        FuncFormatter.prototype.formatRange = function (start, end, context) {
1865            return this.func(createVerboseFormattingArg(start, end, context));
1866        };
1867        return FuncFormatter;
1868    }());
1869
1870    // Formatter Object Creation
1871    function createFormatter(input, defaultSeparator) {
1872        if (typeof input === 'object' && input) { // non-null object
1873            if (typeof defaultSeparator === 'string') {
1874                input = __assign({ separator: defaultSeparator }, input);
1875            }
1876            return new NativeFormatter(input);
1877        }
1878        else if (typeof input === 'string') {
1879            return new CmdFormatter(input, defaultSeparator);
1880        }
1881        else if (typeof input === 'function') {
1882            return new FuncFormatter(input);
1883        }
1884    }
1885    // String Utils
1886    // timeZoneOffset is in minutes
1887    function buildIsoString(marker, timeZoneOffset, stripZeroTime) {
1888        if (stripZeroTime === void 0) { stripZeroTime = false; }
1889        var s = marker.toISOString();
1890        s = s.replace('.000', '');
1891        if (stripZeroTime) {
1892            s = s.replace('T00:00:00Z', '');
1893        }
1894        if (s.length > 10) { // time part wasn't stripped, can add timezone info
1895            if (timeZoneOffset == null) {
1896                s = s.replace('Z', '');
1897            }
1898            else if (timeZoneOffset !== 0) {
1899                s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
1900            }
1901            // otherwise, its UTC-0 and we want to keep the Z
1902        }
1903        return s;
1904    }
1905    function formatIsoTimeString(marker) {
1906        return padStart(marker.getUTCHours(), 2) + ':' +
1907            padStart(marker.getUTCMinutes(), 2) + ':' +
1908            padStart(marker.getUTCSeconds(), 2);
1909    }
1910    function formatTimeZoneOffset(minutes, doIso) {
1911        if (doIso === void 0) { doIso = false; }
1912        var sign = minutes < 0 ? '-' : '+';
1913        var abs = Math.abs(minutes);
1914        var hours = Math.floor(abs / 60);
1915        var mins = Math.round(abs % 60);
1916        if (doIso) {
1917            return sign + padStart(hours, 2) + ':' + padStart(mins, 2);
1918        }
1919        else {
1920            return 'GMT' + sign + hours + (mins ? ':' + padStart(mins, 2) : '');
1921        }
1922    }
1923    // Arg Utils
1924    function createVerboseFormattingArg(start, end, context, separator) {
1925        var startInfo = expandZonedMarker(start, context.calendarSystem);
1926        var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
1927        return {
1928            date: startInfo,
1929            start: startInfo,
1930            end: endInfo,
1931            timeZone: context.timeZone,
1932            localeCodes: context.locale.codes,
1933            separator: separator
1934        };
1935    }
1936    function expandZonedMarker(dateInfo, calendarSystem) {
1937        var a = calendarSystem.markerToArray(dateInfo.marker);
1938        return {
1939            marker: dateInfo.marker,
1940            timeZoneOffset: dateInfo.timeZoneOffset,
1941            array: a,
1942            year: a[0],
1943            month: a[1],
1944            day: a[2],
1945            hour: a[3],
1946            minute: a[4],
1947            second: a[5],
1948            millisecond: a[6]
1949        };
1950    }
1951
1952    var EventSourceApi = /** @class */ (function () {
1953        function EventSourceApi(calendar, internalEventSource) {
1954            this.calendar = calendar;
1955            this.internalEventSource = internalEventSource;
1956        }
1957        EventSourceApi.prototype.remove = function () {
1958            this.calendar.dispatch({
1959                type: 'REMOVE_EVENT_SOURCE',
1960                sourceId: this.internalEventSource.sourceId
1961            });
1962        };
1963        EventSourceApi.prototype.refetch = function () {
1964            this.calendar.dispatch({
1965                type: 'FETCH_EVENT_SOURCES',
1966                sourceIds: [this.internalEventSource.sourceId]
1967            });
1968        };
1969        Object.defineProperty(EventSourceApi.prototype, "id", {
1970            get: function () {
1971                return this.internalEventSource.publicId;
1972            },
1973            enumerable: true,
1974            configurable: true
1975        });
1976        Object.defineProperty(EventSourceApi.prototype, "url", {
1977            // only relevant to json-feed event sources
1978            get: function () {
1979                return this.internalEventSource.meta.url;
1980            },
1981            enumerable: true,
1982            configurable: true
1983        });
1984        return EventSourceApi;
1985    }());
1986
1987    var EventApi = /** @class */ (function () {
1988        function EventApi(calendar, def, instance) {
1989            this._calendar = calendar;
1990            this._def = def;
1991            this._instance = instance || null;
1992        }
1993        /*
1994        TODO: make event struct more responsible for this
1995        */
1996        EventApi.prototype.setProp = function (name, val) {
1997            var _a, _b;
1998            if (name in DATE_PROPS) ;
1999            else if (name in NON_DATE_PROPS) {
2000                if (typeof NON_DATE_PROPS[name] === 'function') {
2001                    val = NON_DATE_PROPS[name](val);
2002                }
2003                this.mutate({
2004                    standardProps: (_a = {}, _a[name] = val, _a)
2005                });
2006            }
2007            else if (name in UNSCOPED_EVENT_UI_PROPS) {
2008                var ui = void 0;
2009                if (typeof UNSCOPED_EVENT_UI_PROPS[name] === 'function') {
2010                    val = UNSCOPED_EVENT_UI_PROPS[name](val);
2011                }
2012                if (name === 'color') {
2013                    ui = { backgroundColor: val, borderColor: val };
2014                }
2015                else if (name === 'editable') {
2016                    ui = { startEditable: val, durationEditable: val };
2017                }
2018                else {
2019                    ui = (_b = {}, _b[name] = val, _b);
2020                }
2021                this.mutate({
2022                    standardProps: { ui: ui }
2023                });
2024            }
2025        };
2026        EventApi.prototype.setExtendedProp = function (name, val) {
2027            var _a;
2028            this.mutate({
2029                extendedProps: (_a = {}, _a[name] = val, _a)
2030            });
2031        };
2032        EventApi.prototype.setStart = function (startInput, options) {
2033            if (options === void 0) { options = {}; }
2034            var dateEnv = this._calendar.dateEnv;
2035            var start = dateEnv.createMarker(startInput);
2036            if (start && this._instance) { // TODO: warning if parsed bad
2037                var instanceRange = this._instance.range;
2038                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?
2039                var endDelta = null;
2040                if (options.maintainDuration) {
2041                    var origDuration = diffDates(instanceRange.start, instanceRange.end, dateEnv, options.granularity);
2042                    var newDuration = diffDates(start, instanceRange.end, dateEnv, options.granularity);
2043                    endDelta = subtractDurations(origDuration, newDuration);
2044                }
2045                this.mutate({ startDelta: startDelta, endDelta: endDelta });
2046            }
2047        };
2048        EventApi.prototype.setEnd = function (endInput, options) {
2049            if (options === void 0) { options = {}; }
2050            var dateEnv = this._calendar.dateEnv;
2051            var end;
2052            if (endInput != null) {
2053                end = dateEnv.createMarker(endInput);
2054                if (!end) {
2055                    return; // TODO: warning if parsed bad
2056                }
2057            }
2058            if (this._instance) {
2059                if (end) {
2060                    var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
2061                    this.mutate({ endDelta: endDelta });
2062                }
2063                else {
2064                    this.mutate({ standardProps: { hasEnd: false } });
2065                }
2066            }
2067        };
2068        EventApi.prototype.setDates = function (startInput, endInput, options) {
2069            if (options === void 0) { options = {}; }
2070            var dateEnv = this._calendar.dateEnv;
2071            var standardProps = { allDay: options.allDay };
2072            var start = dateEnv.createMarker(startInput);
2073            var end;
2074            if (!start) {
2075                return; // TODO: warning if parsed bad
2076            }
2077            if (endInput != null) {
2078                end = dateEnv.createMarker(endInput);
2079                if (!end) { // TODO: warning if parsed bad
2080                    return;
2081                }
2082            }
2083            if (this._instance) {
2084                var instanceRange = this._instance.range;
2085                // when computing the diff for an event being converted to all-day,
2086                // compute diff off of the all-day values the way event-mutation does.
2087                if (options.allDay === true) {
2088                    instanceRange = computeAlignedDayRange(instanceRange);
2089                }
2090                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
2091                if (end) {
2092                    var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
2093                    this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps });
2094                }
2095                else {
2096                    standardProps.hasEnd = false;
2097                    this.mutate({ startDelta: startDelta, standardProps: standardProps });
2098                }
2099            }
2100        };
2101        EventApi.prototype.moveStart = function (deltaInput) {
2102            var delta = createDuration(deltaInput);
2103            if (delta) { // TODO: warning if parsed bad
2104                this.mutate({ startDelta: delta });
2105            }
2106        };
2107        EventApi.prototype.moveEnd = function (deltaInput) {
2108            var delta = createDuration(deltaInput);
2109            if (delta) { // TODO: warning if parsed bad
2110                this.mutate({ endDelta: delta });
2111            }
2112        };
2113        EventApi.prototype.moveDates = function (deltaInput) {
2114            var delta = createDuration(deltaInput);
2115            if (delta) { // TODO: warning if parsed bad
2116                this.mutate({ startDelta: delta, endDelta: delta });
2117            }
2118        };
2119        EventApi.prototype.setAllDay = function (allDay, options) {
2120            if (options === void 0) { options = {}; }
2121            var standardProps = { allDay: allDay };
2122            var maintainDuration = options.maintainDuration;
2123            if (maintainDuration == null) {
2124                maintainDuration = this._calendar.opt('allDayMaintainDuration');
2125            }
2126            if (this._def.allDay !== allDay) {
2127                standardProps.hasEnd = maintainDuration;
2128            }
2129            this.mutate({ standardProps: standardProps });
2130        };
2131        EventApi.prototype.formatRange = function (formatInput) {
2132            var dateEnv = this._calendar.dateEnv;
2133            var instance = this._instance;
2134            var formatter = createFormatter(formatInput, this._calendar.opt('defaultRangeSeparator'));
2135            if (this._def.hasEnd) {
2136                return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
2137                    forcedStartTzo: instance.forcedStartTzo,
2138                    forcedEndTzo: instance.forcedEndTzo
2139                });
2140            }
2141            else {
2142                return dateEnv.format(instance.range.start, formatter, {
2143                    forcedTzo: instance.forcedStartTzo
2144                });
2145            }
2146        };
2147        EventApi.prototype.mutate = function (mutation) {
2148            var def = this._def;
2149            var instance = this._instance;
2150            if (instance) {
2151                this._calendar.dispatch({
2152                    type: 'MUTATE_EVENTS',
2153                    instanceId: instance.instanceId,
2154                    mutation: mutation,
2155                    fromApi: true
2156                });
2157                var eventStore = this._calendar.state.eventStore;
2158                this._def = eventStore.defs[def.defId];
2159                this._instance = eventStore.instances[instance.instanceId];
2160            }
2161        };
2162        EventApi.prototype.remove = function () {
2163            this._calendar.dispatch({
2164                type: 'REMOVE_EVENT_DEF',
2165                defId: this._def.defId
2166            });
2167        };
2168        Object.defineProperty(EventApi.prototype, "source", {
2169            get: function () {
2170                var sourceId = this._def.sourceId;
2171                if (sourceId) {
2172                    return new EventSourceApi(this._calendar, this._calendar.state.eventSources[sourceId]);
2173                }
2174                return null;
2175            },
2176            enumerable: true,
2177            configurable: true
2178        });
2179        Object.defineProperty(EventApi.prototype, "start", {
2180            get: function () {
2181                return this._instance ?
2182                    this._calendar.dateEnv.toDate(this._instance.range.start) :
2183                    null;
2184            },
2185            enumerable: true,
2186            configurable: true
2187        });
2188        Object.defineProperty(EventApi.prototype, "end", {
2189            get: function () {
2190                return (this._instance && this._def.hasEnd) ?
2191                    this._calendar.dateEnv.toDate(this._instance.range.end) :
2192                    null;
2193            },
2194            enumerable: true,
2195            configurable: true
2196        });
2197        Object.defineProperty(EventApi.prototype, "id", {
2198            // computable props that all access the def
2199            // TODO: find a TypeScript-compatible way to do this at scale
2200            get: function () { return this._def.publicId; },
2201            enumerable: true,
2202            configurable: true
2203        });
2204        Object.defineProperty(EventApi.prototype, "groupId", {
2205            get: function () { return this._def.groupId; },
2206            enumerable: true,
2207            configurable: true
2208        });
2209        Object.defineProperty(EventApi.prototype, "allDay", {
2210            get: function () { return this._def.allDay; },
2211            enumerable: true,
2212            configurable: true
2213        });
2214        Object.defineProperty(EventApi.prototype, "title", {
2215            get: function () { return this._def.title; },
2216            enumerable: true,
2217            configurable: true
2218        });
2219        Object.defineProperty(EventApi.prototype, "url", {
2220            get: function () { return this._def.url; },
2221            enumerable: true,
2222            configurable: true
2223        });
2224        Object.defineProperty(EventApi.prototype, "rendering", {
2225            get: function () { return this._def.rendering; },
2226            enumerable: true,
2227            configurable: true
2228        });
2229        Object.defineProperty(EventApi.prototype, "startEditable", {
2230            get: function () { return this._def.ui.startEditable; },
2231            enumerable: true,
2232            configurable: true
2233        });
2234        Object.defineProperty(EventApi.prototype, "durationEditable", {
2235            get: function () { return this._def.ui.durationEditable; },
2236            enumerable: true,
2237            configurable: true
2238        });
2239        Object.defineProperty(EventApi.prototype, "constraint", {
2240            get: function () { return this._def.ui.constraints[0] || null; },
2241            enumerable: true,
2242            configurable: true
2243        });
2244        Object.defineProperty(EventApi.prototype, "overlap", {
2245            get: function () { return this._def.ui.overlap; },
2246            enumerable: true,
2247            configurable: true
2248        });
2249        Object.defineProperty(EventApi.prototype, "allow", {
2250            get: function () { return this._def.ui.allows[0] || null; },
2251            enumerable: true,
2252            configurable: true
2253        });
2254        Object.defineProperty(EventApi.prototype, "backgroundColor", {
2255            get: function () { return this._def.ui.backgroundColor; },
2256            enumerable: true,
2257            configurable: true
2258        });
2259        Object.defineProperty(EventApi.prototype, "borderColor", {
2260            get: function () { return this._def.ui.borderColor; },
2261            enumerable: true,
2262            configurable: true
2263        });
2264        Object.defineProperty(EventApi.prototype, "textColor", {
2265            get: function () { return this._def.ui.textColor; },
2266            enumerable: true,
2267            configurable: true
2268        });
2269        Object.defineProperty(EventApi.prototype, "classNames", {
2270            // NOTE: user can't modify these because Object.freeze was called in event-def parsing
2271            get: function () { return this._def.ui.classNames; },
2272            enumerable: true,
2273            configurable: true
2274        });
2275        Object.defineProperty(EventApi.prototype, "extendedProps", {
2276            get: function () { return this._def.extendedProps; },
2277            enumerable: true,
2278            configurable: true
2279        });
2280        return EventApi;
2281    }());
2282
2283    /*
2284    Specifying nextDayThreshold signals that all-day ranges should be sliced.
2285    */
2286    function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
2287        var inverseBgByGroupId = {};
2288        var inverseBgByDefId = {};
2289        var defByGroupId = {};
2290        var bgRanges = [];
2291        var fgRanges = [];
2292        var eventUis = compileEventUis(eventStore.defs, eventUiBases);
2293        for (var defId in eventStore.defs) {
2294            var def = eventStore.defs[defId];
2295            if (def.rendering === 'inverse-background') {
2296                if (def.groupId) {
2297                    inverseBgByGroupId[def.groupId] = [];
2298                    if (!defByGroupId[def.groupId]) {
2299                        defByGroupId[def.groupId] = def;
2300                    }
2301                }
2302                else {
2303                    inverseBgByDefId[defId] = [];
2304                }
2305            }
2306        }
2307        for (var instanceId in eventStore.instances) {
2308            var instance = eventStore.instances[instanceId];
2309            var def = eventStore.defs[instance.defId];
2310            var ui = eventUis[def.defId];
2311            var origRange = instance.range;
2312            var normalRange = (!def.allDay && nextDayThreshold) ?
2313                computeVisibleDayRange(origRange, nextDayThreshold) :
2314                origRange;
2315            var slicedRange = intersectRanges(normalRange, framingRange);
2316            if (slicedRange) {
2317                if (def.rendering === 'inverse-background') {
2318                    if (def.groupId) {
2319                        inverseBgByGroupId[def.groupId].push(slicedRange);
2320                    }
2321                    else {
2322                        inverseBgByDefId[instance.defId].push(slicedRange);
2323                    }
2324                }
2325                else {
2326                    (def.rendering === 'background' ? bgRanges : fgRanges).push({
2327                        def: def,
2328                        ui: ui,
2329                        instance: instance,
2330                        range: slicedRange,
2331                        isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
2332                        isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf()
2333                    });
2334                }
2335            }
2336        }
2337        for (var groupId in inverseBgByGroupId) { // BY GROUP
2338            var ranges = inverseBgByGroupId[groupId];
2339            var invertedRanges = invertRanges(ranges, framingRange);
2340            for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) {
2341                var invertedRange = invertedRanges_1[_i];
2342                var def = defByGroupId[groupId];
2343                var ui = eventUis[def.defId];
2344                bgRanges.push({
2345                    def: def,
2346                    ui: ui,
2347                    instance: null,
2348                    range: invertedRange,
2349                    isStart: false,
2350                    isEnd: false
2351                });
2352            }
2353        }
2354        for (var defId in inverseBgByDefId) {
2355            var ranges = inverseBgByDefId[defId];
2356            var invertedRanges = invertRanges(ranges, framingRange);
2357            for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) {
2358                var invertedRange = invertedRanges_2[_a];
2359                bgRanges.push({
2360                    def: eventStore.defs[defId],
2361                    ui: eventUis[defId],
2362                    instance: null,
2363                    range: invertedRange,
2364                    isStart: false,
2365                    isEnd: false
2366                });
2367            }
2368        }
2369        return { bg: bgRanges, fg: fgRanges };
2370    }
2371    function hasBgRendering(def) {
2372        return def.rendering === 'background' || def.rendering === 'inverse-background';
2373    }
2374    function filterSegsViaEls(view, segs, isMirror) {
2375        if (view.hasPublicHandlers('eventRender')) {
2376            segs = segs.filter(function (seg) {
2377                var custom = view.publiclyTrigger('eventRender', [
2378                    {
2379                        event: new EventApi(view.calendar, seg.eventRange.def, seg.eventRange.instance),
2380                        isMirror: isMirror,
2381                        isStart: seg.isStart,
2382                        isEnd: seg.isEnd,
2383                        // TODO: include seg.range once all components consistently generate it
2384                        el: seg.el,
2385                        view: view
2386                    }
2387                ]);
2388                if (custom === false) { // means don't render at all
2389                    return false;
2390                }
2391                else if (custom && custom !== true) {
2392                    seg.el = custom;
2393                }
2394                return true;
2395            });
2396        }
2397        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
2398            var seg = segs_1[_i];
2399            setElSeg(seg.el, seg);
2400        }
2401        return segs;
2402    }
2403    function setElSeg(el, seg) {
2404        el.fcSeg = seg;
2405    }
2406    function getElSeg(el) {
2407        return el.fcSeg || null;
2408    }
2409    // event ui computation
2410    function compileEventUis(eventDefs, eventUiBases) {
2411        return mapHash(eventDefs, function (eventDef) {
2412            return compileEventUi(eventDef, eventUiBases);
2413        });
2414    }
2415    function compileEventUi(eventDef, eventUiBases) {
2416        var uis = [];
2417        if (eventUiBases['']) {
2418            uis.push(eventUiBases['']);
2419        }
2420        if (eventUiBases[eventDef.defId]) {
2421            uis.push(eventUiBases[eventDef.defId]);
2422        }
2423        uis.push(eventDef.ui);
2424        return combineEventUis(uis);
2425    }
2426
2427    // applies the mutation to ALL defs/instances within the event store
2428    function applyMutationToEventStore(eventStore, eventConfigBase, mutation, calendar) {
2429        var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
2430        var dest = createEmptyEventStore();
2431        for (var defId in eventStore.defs) {
2432            var def = eventStore.defs[defId];
2433            dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, calendar.pluginSystem.hooks.eventDefMutationAppliers, calendar);
2434        }
2435        for (var instanceId in eventStore.instances) {
2436            var instance = eventStore.instances[instanceId];
2437            var def = dest.defs[instance.defId]; // important to grab the newly modified def
2438            dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, calendar);
2439        }
2440        return dest;
2441    }
2442    function applyMutationToEventDef(eventDef, eventConfig, mutation, appliers, calendar) {
2443        var standardProps = mutation.standardProps || {};
2444        // if hasEnd has not been specified, guess a good value based on deltas.
2445        // if duration will change, there's no way the default duration will persist,
2446        // and thus, we need to mark the event as having a real end
2447        if (standardProps.hasEnd == null &&
2448            eventConfig.durationEditable &&
2449            willDeltasAffectDuration(eventConfig.startEditable ? mutation.startDelta : null, mutation.endDelta || null)) {
2450            standardProps.hasEnd = true; // TODO: is this mutation okay?
2451        }
2452        var copy = __assign({}, eventDef, standardProps, { ui: __assign({}, eventDef.ui, standardProps.ui) });
2453        if (mutation.extendedProps) {
2454            copy.extendedProps = __assign({}, copy.extendedProps, mutation.extendedProps);
2455        }
2456        for (var _i = 0, appliers_1 = appliers; _i < appliers_1.length; _i++) {
2457            var applier = appliers_1[_i];
2458            applier(copy, mutation, calendar);
2459        }
2460        if (!copy.hasEnd && calendar.opt('forceEventDuration')) {
2461            copy.hasEnd = true;
2462        }
2463        return copy;
2464    }
2465    function willDeltasAffectDuration(startDelta, endDelta) {
2466        if (startDelta && !asRoughMs(startDelta)) {
2467            startDelta = null;
2468        }
2469        if (endDelta && !asRoughMs(endDelta)) {
2470            endDelta = null;
2471        }
2472        if (!startDelta && !endDelta) {
2473            return false;
2474        }
2475        if (Boolean(startDelta) !== Boolean(endDelta)) {
2476            return true;
2477        }
2478        return !durationsEqual(startDelta, endDelta);
2479    }
2480    function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
2481    eventConfig, mutation, calendar) {
2482        var dateEnv = calendar.dateEnv;
2483        var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
2484        var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
2485        var copy = __assign({}, eventInstance);
2486        if (forceAllDay) {
2487            copy.range = computeAlignedDayRange(copy.range);
2488        }
2489        if (mutation.startDelta && eventConfig.startEditable) {
2490            copy.range = {
2491                start: dateEnv.add(copy.range.start, mutation.startDelta),
2492                end: copy.range.end
2493            };
2494        }
2495        if (clearEnd) {
2496            copy.range = {
2497                start: copy.range.start,
2498                end: calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start)
2499            };
2500        }
2501        else if (mutation.endDelta &&
2502            (eventConfig.durationEditable ||
2503                !willDeltasAffectDuration(// TODO: nonDRY logic above
2504                eventConfig.startEditable ? mutation.startDelta : null, mutation.endDelta))) {
2505            copy.range = {
2506                start: copy.range.start,
2507                end: dateEnv.add(copy.range.end, mutation.endDelta)
2508            };
2509        }
2510        // in case event was all-day but the supplied deltas were not
2511        // better util for this?
2512        if (eventDef.allDay) {
2513            copy.range = {
2514                start: startOfDay(copy.range.start),
2515                end: startOfDay(copy.range.end)
2516            };
2517        }
2518        // handle invalid durations
2519        if (copy.range.end < copy.range.start) {
2520            copy.range.end = calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start);
2521        }
2522        return copy;
2523    }
2524
2525    function reduceEventStore (eventStore, action, eventSources, dateProfile, calendar) {
2526        switch (action.type) {
2527            case 'RECEIVE_EVENTS': // raw
2528                return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, calendar);
2529            case 'ADD_EVENTS': // already parsed, but not expanded
2530                return addEvent(eventStore, action.eventStore, // new ones
2531                dateProfile ? dateProfile.activeRange : null, calendar);
2532            case 'MERGE_EVENTS': // already parsed and expanded
2533                return mergeEventStores(eventStore, action.eventStore);
2534            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
2535            case 'NEXT':
2536            case 'SET_DATE':
2537            case 'SET_VIEW_TYPE':
2538                if (dateProfile) {
2539                    return expandRecurring(eventStore, dateProfile.activeRange, calendar);
2540                }
2541                else {
2542                    return eventStore;
2543                }
2544            case 'CHANGE_TIMEZONE':
2545                return rezoneDates(eventStore, action.oldDateEnv, calendar.dateEnv);
2546            case 'MUTATE_EVENTS':
2547                return applyMutationToRelated(eventStore, action.instanceId, action.mutation, action.fromApi, calendar);
2548            case 'REMOVE_EVENT_INSTANCES':
2549                return excludeInstances(eventStore, action.instances);
2550            case 'REMOVE_EVENT_DEF':
2551                return filterEventStoreDefs(eventStore, function (eventDef) {
2552                    return eventDef.defId !== action.defId;
2553                });
2554            case 'REMOVE_EVENT_SOURCE':
2555                return excludeEventsBySourceId(eventStore, action.sourceId);
2556            case 'REMOVE_ALL_EVENT_SOURCES':
2557                return filterEventStoreDefs(eventStore, function (eventDef) {
2558                    return !eventDef.sourceId; // only keep events with no source id
2559                });
2560            case 'REMOVE_ALL_EVENTS':
2561                return createEmptyEventStore();
2562            case 'RESET_EVENTS':
2563                return {
2564                    defs: eventStore.defs,
2565                    instances: eventStore.instances
2566                };
2567            default:
2568                return eventStore;
2569        }
2570    }
2571    function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, calendar) {
2572        if (eventSource && // not already removed
2573            fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
2574        ) {
2575            var subset = parseEvents(transformRawEvents(rawEvents, eventSource, calendar), eventSource.sourceId, calendar);
2576            if (fetchRange) {
2577                subset = expandRecurring(subset, fetchRange, calendar);
2578            }
2579            return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
2580        }
2581        return eventStore;
2582    }
2583    function addEvent(eventStore, subset, expandRange, calendar) {
2584        if (expandRange) {
2585            subset = expandRecurring(subset, expandRange, calendar);
2586        }
2587        return mergeEventStores(eventStore, subset);
2588    }
2589    function rezoneDates(eventStore, oldDateEnv, newDateEnv) {
2590        var defs = eventStore.defs;
2591        var instances = mapHash(eventStore.instances, function (instance) {
2592            var def = defs[instance.defId];
2593            if (def.allDay || def.recurringDef) {
2594                return instance; // isn't dependent on timezone
2595            }
2596            else {
2597                return __assign({}, instance, { range: {
2598                        start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
2599                        end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo))
2600                    }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
2601            }
2602        });
2603        return { defs: defs, instances: instances };
2604    }
2605    function applyMutationToRelated(eventStore, instanceId, mutation, fromApi, calendar) {
2606        var relevant = getRelevantEvents(eventStore, instanceId);
2607        var eventConfigBase = fromApi ?
2608            { '': {
2609                    startEditable: true,
2610                    durationEditable: true,
2611                    constraints: [],
2612                    overlap: null,
2613                    allows: [],
2614                    backgroundColor: '',
2615                    borderColor: '',
2616                    textColor: '',
2617                    classNames: []
2618                } } :
2619            calendar.eventUiBases;
2620        relevant = applyMutationToEventStore(relevant, eventConfigBase, mutation, calendar);
2621        return mergeEventStores(eventStore, relevant);
2622    }
2623    function excludeEventsBySourceId(eventStore, sourceId) {
2624        return filterEventStoreDefs(eventStore, function (eventDef) {
2625            return eventDef.sourceId !== sourceId;
2626        });
2627    }
2628    // QUESTION: why not just return instances? do a general object-property-exclusion util
2629    function excludeInstances(eventStore, removals) {
2630        return {
2631            defs: eventStore.defs,
2632            instances: filterHash(eventStore.instances, function (instance) {
2633                return !removals[instance.instanceId];
2634            })
2635        };
2636    }
2637
2638    // high-level segmenting-aware tester functions
2639    // ------------------------------------------------------------------------------------------------------------------------
2640    function isInteractionValid(interaction, calendar) {
2641        return isNewPropsValid({ eventDrag: interaction }, calendar); // HACK: the eventDrag props is used for ALL interactions
2642    }
2643    function isDateSelectionValid(dateSelection, calendar) {
2644        return isNewPropsValid({ dateSelection: dateSelection }, calendar);
2645    }
2646    function isNewPropsValid(newProps, calendar) {
2647        var view = calendar.view;
2648        var props = __assign({ businessHours: view ? view.props.businessHours : createEmptyEventStore(), dateSelection: '', eventStore: calendar.state.eventStore, eventUiBases: calendar.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
2649        return (calendar.pluginSystem.hooks.isPropsValid || isPropsValid)(props, calendar);
2650    }
2651    function isPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2652        if (dateSpanMeta === void 0) { dateSpanMeta = {}; }
2653        if (state.eventDrag && !isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
2654            return false;
2655        }
2656        if (state.dateSelection && !isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
2657            return false;
2658        }
2659        return true;
2660    }
2661    // Moving Event Validation
2662    // ------------------------------------------------------------------------------------------------------------------------
2663    function isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2664        var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
2665        var subjectEventStore = interaction.mutatedEvents;
2666        var subjectDefs = subjectEventStore.defs;
2667        var subjectInstances = subjectEventStore.instances;
2668        var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
2669            state.eventUiBases :
2670            { '': calendar.selectionConfig } // if not a real event, validate as a selection
2671        );
2672        if (filterConfig) {
2673            subjectConfigs = mapHash(subjectConfigs, filterConfig);
2674        }
2675        var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); // exclude the subject events. TODO: exclude defs too?
2676        var otherDefs = otherEventStore.defs;
2677        var otherInstances = otherEventStore.instances;
2678        var otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
2679        for (var subjectInstanceId in subjectInstances) {
2680            var subjectInstance = subjectInstances[subjectInstanceId];
2681            var subjectRange = subjectInstance.range;
2682            var subjectConfig = subjectConfigs[subjectInstance.defId];
2683            var subjectDef = subjectDefs[subjectInstance.defId];
2684            // constraint
2685            if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, calendar)) {
2686                return false;
2687            }
2688            // overlap
2689            var overlapFunc = calendar.opt('eventOverlap');
2690            if (typeof overlapFunc !== 'function') {
2691                overlapFunc = null;
2692            }
2693            for (var otherInstanceId in otherInstances) {
2694                var otherInstance = otherInstances[otherInstanceId];
2695                // intersect! evaluate
2696                if (rangesIntersect(subjectRange, otherInstance.range)) {
2697                    var otherOverlap = otherConfigs[otherInstance.defId].overlap;
2698                    // consider the other event's overlap. only do this if the subject event is a "real" event
2699                    if (otherOverlap === false && interaction.isEvent) {
2700                        return false;
2701                    }
2702                    if (subjectConfig.overlap === false) {
2703                        return false;
2704                    }
2705                    if (overlapFunc && !overlapFunc(new EventApi(calendar, otherDefs[otherInstance.defId], otherInstance), // still event
2706                    new EventApi(calendar, subjectDef, subjectInstance) // moving event
2707                    )) {
2708                        return false;
2709                    }
2710                }
2711            }
2712            // allow (a function)
2713            for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) {
2714                var subjectAllow = _a[_i];
2715                var subjectDateSpan = __assign({}, dateSpanMeta, { range: subjectInstance.range, allDay: subjectDef.allDay });
2716                var origDef = state.eventStore.defs[subjectDef.defId];
2717                var origInstance = state.eventStore.instances[subjectInstanceId];
2718                var eventApi = void 0;
2719                if (origDef) { // was previously in the calendar
2720                    eventApi = new EventApi(calendar, origDef, origInstance);
2721                }
2722                else { // was an external event
2723                    eventApi = new EventApi(calendar, subjectDef); // no instance, because had no dates
2724                }
2725                if (!subjectAllow(calendar.buildDateSpanApi(subjectDateSpan), eventApi)) {
2726                    return false;
2727                }
2728            }
2729        }
2730        return true;
2731    }
2732    // Date Selection Validation
2733    // ------------------------------------------------------------------------------------------------------------------------
2734    function isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2735        var relevantEventStore = state.eventStore;
2736        var relevantDefs = relevantEventStore.defs;
2737        var relevantInstances = relevantEventStore.instances;
2738        var selection = state.dateSelection;
2739        var selectionRange = selection.range;
2740        var selectionConfig = calendar.selectionConfig;
2741        if (filterConfig) {
2742            selectionConfig = filterConfig(selectionConfig);
2743        }
2744        // constraint
2745        if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, calendar)) {
2746            return false;
2747        }
2748        // overlap
2749        var overlapFunc = calendar.opt('selectOverlap');
2750        if (typeof overlapFunc !== 'function') {
2751            overlapFunc = null;
2752        }
2753        for (var relevantInstanceId in relevantInstances) {
2754            var relevantInstance = relevantInstances[relevantInstanceId];
2755            // intersect! evaluate
2756            if (rangesIntersect(selectionRange, relevantInstance.range)) {
2757                if (selectionConfig.overlap === false) {
2758                    return false;
2759                }
2760                if (overlapFunc && !overlapFunc(new EventApi(calendar, relevantDefs[relevantInstance.defId], relevantInstance))) {
2761                    return false;
2762                }
2763            }
2764        }
2765        // allow (a function)
2766        for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) {
2767            var selectionAllow = _a[_i];
2768            var fullDateSpan = __assign({}, dateSpanMeta, selection);
2769            if (!selectionAllow(calendar.buildDateSpanApi(fullDateSpan), null)) {
2770                return false;
2771            }
2772        }
2773        return true;
2774    }
2775    // Constraint Utils
2776    // ------------------------------------------------------------------------------------------------------------------------
2777    function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, calendar) {
2778        for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
2779            var constraint = constraints_1[_i];
2780            if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, calendar), subjectRange)) {
2781                return false;
2782            }
2783        }
2784        return true;
2785    }
2786    function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
2787    otherEventStore, // for if constraint is an even group ID
2788    businessHoursUnexpanded, // for if constraint is 'businessHours'
2789    calendar // for expanding businesshours
2790    ) {
2791        if (constraint === 'businessHours') {
2792            return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, calendar));
2793        }
2794        else if (typeof constraint === 'string') { // an group ID
2795            return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) {
2796                return eventDef.groupId === constraint;
2797            }));
2798        }
2799        else if (typeof constraint === 'object' && constraint) { // non-null object
2800            return eventStoreToRanges(expandRecurring(constraint, subjectRange, calendar));
2801        }
2802        return []; // if it's false
2803    }
2804    // TODO: move to event-store file?
2805    function eventStoreToRanges(eventStore) {
2806        var instances = eventStore.instances;
2807        var ranges = [];
2808        for (var instanceId in instances) {
2809            ranges.push(instances[instanceId].range);
2810        }
2811        return ranges;
2812    }
2813    // TODO: move to geom file?
2814    function anyRangesContainRange(outerRanges, innerRange) {
2815        for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) {
2816            var outerRange = outerRanges_1[_i];
2817            if (rangeContainsRange(outerRange, innerRange)) {
2818                return true;
2819            }
2820        }
2821        return false;
2822    }
2823    // Parsing
2824    // ------------------------------------------------------------------------------------------------------------------------
2825    function normalizeConstraint(input, calendar) {
2826        if (Array.isArray(input)) {
2827            return parseEvents(input, '', calendar, true); // allowOpenRange=true
2828        }
2829        else if (typeof input === 'object' && input) { // non-null object
2830            return parseEvents([input], '', calendar, true); // allowOpenRange=true
2831        }
2832        else if (input != null) {
2833            return String(input);
2834        }
2835        else {
2836            return null;
2837        }
2838    }
2839
2840    function htmlEscape(s) {
2841        return (s + '').replace(/&/g, '&amp;')
2842            .replace(/</g, '&lt;')
2843            .replace(/>/g, '&gt;')
2844            .replace(/'/g, '&#039;')
2845            .replace(/"/g, '&quot;')
2846            .replace(/\n/g, '<br />');
2847    }
2848    // Given a hash of CSS properties, returns a string of CSS.
2849    // Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.
2850    function cssToStr(cssProps) {
2851        var statements = [];
2852        for (var name_1 in cssProps) {
2853            var val = cssProps[name_1];
2854            if (val != null && val !== '') {
2855                statements.push(name_1 + ':' + val);
2856            }
2857        }
2858        return statements.join(';');
2859    }
2860    // Given an object hash of HTML attribute names to values,
2861    // generates a string that can be injected between < > in HTML
2862    function attrsToStr(attrs) {
2863        var parts = [];
2864        for (var name_2 in attrs) {
2865            var val = attrs[name_2];
2866            if (val != null) {
2867                parts.push(name_2 + '="' + htmlEscape(val) + '"');
2868            }
2869        }
2870        return parts.join(' ');
2871    }
2872    function parseClassName(raw) {
2873        if (Array.isArray(raw)) {
2874            return raw;
2875        }
2876        else if (typeof raw === 'string') {
2877            return raw.split(/\s+/);
2878        }
2879        else {
2880            return [];
2881        }
2882    }
2883
2884    var UNSCOPED_EVENT_UI_PROPS = {
2885        editable: Boolean,
2886        startEditable: Boolean,
2887        durationEditable: Boolean,
2888        constraint: null,
2889        overlap: null,
2890        allow: null,
2891        className: parseClassName,
2892        classNames: parseClassName,
2893        color: String,
2894        backgroundColor: String,
2895        borderColor: String,
2896        textColor: String
2897    };
2898    function processUnscopedUiProps(rawProps, calendar, leftovers) {
2899        var props = refineProps(rawProps, UNSCOPED_EVENT_UI_PROPS, {}, leftovers);
2900        var constraint = normalizeConstraint(props.constraint, calendar);
2901        return {
2902            startEditable: props.startEditable != null ? props.startEditable : props.editable,
2903            durationEditable: props.durationEditable != null ? props.durationEditable : props.editable,
2904            constraints: constraint != null ? [constraint] : [],
2905            overlap: props.overlap,
2906            allows: props.allow != null ? [props.allow] : [],
2907            backgroundColor: props.backgroundColor || props.color,
2908            borderColor: props.borderColor || props.color,
2909            textColor: props.textColor,
2910            classNames: props.classNames.concat(props.className)
2911        };
2912    }
2913    function processScopedUiProps(prefix, rawScoped, calendar, leftovers) {
2914        var rawUnscoped = {};
2915        var wasFound = {};
2916        for (var key in UNSCOPED_EVENT_UI_PROPS) {
2917            var scopedKey = prefix + capitaliseFirstLetter(key);
2918            rawUnscoped[key] = rawScoped[scopedKey];
2919            wasFound[scopedKey] = true;
2920        }
2921        if (prefix === 'event') {
2922            rawUnscoped.editable = rawScoped.editable; // special case. there is no 'eventEditable', just 'editable'
2923        }
2924        if (leftovers) {
2925            for (var key in rawScoped) {
2926                if (!wasFound[key]) {
2927                    leftovers[key] = rawScoped[key];
2928                }
2929            }
2930        }
2931        return processUnscopedUiProps(rawUnscoped, calendar);
2932    }
2933    var EMPTY_EVENT_UI = {
2934        startEditable: null,
2935        durationEditable: null,
2936        constraints: [],
2937        overlap: null,
2938        allows: [],
2939        backgroundColor: '',
2940        borderColor: '',
2941        textColor: '',
2942        classNames: []
2943    };
2944    // prevent against problems with <2 args!
2945    function combineEventUis(uis) {
2946        return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
2947    }
2948    function combineTwoEventUis(item0, item1) {
2949        return {
2950            startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
2951            durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
2952            constraints: item0.constraints.concat(item1.constraints),
2953            overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
2954            allows: item0.allows.concat(item1.allows),
2955            backgroundColor: item1.backgroundColor || item0.backgroundColor,
2956            borderColor: item1.borderColor || item0.borderColor,
2957            textColor: item1.textColor || item0.textColor,
2958            classNames: item0.classNames.concat(item1.classNames)
2959        };
2960    }
2961
2962    var NON_DATE_PROPS = {
2963        id: String,
2964        groupId: String,
2965        title: String,
2966        url: String,
2967        rendering: String,
2968        extendedProps: null
2969    };
2970    var DATE_PROPS = {
2971        start: null,
2972        date: null,
2973        end: null,
2974        allDay: null
2975    };
2976    var uid = 0;
2977    function parseEvent(raw, sourceId, calendar, allowOpenRange) {
2978        var allDayDefault = computeIsAllDayDefault(sourceId, calendar);
2979        var leftovers0 = {};
2980        var recurringRes = parseRecurring(raw, // raw, but with single-event stuff stripped out
2981        allDayDefault, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes, leftovers0 // will populate with non-recurring props
2982        );
2983        if (recurringRes) {
2984            var def = parseEventDef(leftovers0, sourceId, recurringRes.allDay, Boolean(recurringRes.duration), calendar);
2985            def.recurringDef = {
2986                typeId: recurringRes.typeId,
2987                typeData: recurringRes.typeData,
2988                duration: recurringRes.duration
2989            };
2990            return { def: def, instance: null };
2991        }
2992        else {
2993            var leftovers1 = {};
2994            var singleRes = parseSingle(raw, allDayDefault, calendar, leftovers1, allowOpenRange);
2995            if (singleRes) {
2996                var def = parseEventDef(leftovers1, sourceId, singleRes.allDay, singleRes.hasEnd, calendar);
2997                var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
2998                return { def: def, instance: instance };
2999            }
3000        }
3001        return null;
3002    }
3003    /*
3004    Will NOT populate extendedProps with the leftover properties.
3005    Will NOT populate date-related props.
3006    The EventNonDateInput has been normalized (id => publicId, etc).
3007    */
3008    function parseEventDef(raw, sourceId, allDay, hasEnd, calendar) {
3009        var leftovers = {};
3010        var def = pluckNonDateProps(raw, calendar, leftovers);
3011        def.defId = String(uid++);
3012        def.sourceId = sourceId;
3013        def.allDay = allDay;
3014        def.hasEnd = hasEnd;
3015        for (var _i = 0, _a = calendar.pluginSystem.hooks.eventDefParsers; _i < _a.length; _i++) {
3016            var eventDefParser = _a[_i];
3017            var newLeftovers = {};
3018            eventDefParser(def, leftovers, newLeftovers);
3019            leftovers = newLeftovers;
3020        }
3021        def.extendedProps = __assign(leftovers, def.extendedProps || {});
3022        // help out EventApi from having user modify props
3023        Object.freeze(def.ui.classNames);
3024        Object.freeze(def.extendedProps);
3025        return def;
3026    }
3027    function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
3028        return {
3029            instanceId: String(uid++),
3030            defId: defId,
3031            range: range,
3032            forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
3033            forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo
3034        };
3035    }
3036    function parseSingle(raw, allDayDefault, calendar, leftovers, allowOpenRange) {
3037        var props = pluckDateProps(raw, leftovers);
3038        var allDay = props.allDay;
3039        var startMeta;
3040        var startMarker = null;
3041        var hasEnd = false;
3042        var endMeta;
3043        var endMarker = null;
3044        startMeta = calendar.dateEnv.createMarkerMeta(props.start);
3045        if (startMeta) {
3046            startMarker = startMeta.marker;
3047        }
3048        else if (!allowOpenRange) {
3049            return null;
3050        }
3051        if (props.end != null) {
3052            endMeta = calendar.dateEnv.createMarkerMeta(props.end);
3053        }
3054        if (allDay == null) {
3055            if (allDayDefault != null) {
3056                allDay = allDayDefault;
3057            }
3058            else {
3059                // fall back to the date props LAST
3060                allDay = (!startMeta || startMeta.isTimeUnspecified) &&
3061                    (!endMeta || endMeta.isTimeUnspecified);
3062            }
3063        }
3064        if (allDay && startMarker) {
3065            startMarker = startOfDay(startMarker);
3066        }
3067        if (endMeta) {
3068            endMarker = endMeta.marker;
3069            if (allDay) {
3070                endMarker = startOfDay(endMarker);
3071            }
3072            if (startMarker && endMarker <= startMarker) {
3073                endMarker = null;
3074            }
3075        }
3076        if (endMarker) {
3077            hasEnd = true;
3078        }
3079        else if (!allowOpenRange) {
3080            hasEnd = calendar.opt('forceEventDuration') || false;
3081            endMarker = calendar.dateEnv.add(startMarker, allDay ?
3082                calendar.defaultAllDayEventDuration :
3083                calendar.defaultTimedEventDuration);
3084        }
3085        return {
3086            allDay: allDay,
3087            hasEnd: hasEnd,
3088            range: { start: startMarker, end: endMarker },
3089            forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
3090            forcedEndTzo: endMeta ? endMeta.forcedTzo : null
3091        };
3092    }
3093    function pluckDateProps(raw, leftovers) {
3094        var props = refineProps(raw, DATE_PROPS, {}, leftovers);
3095        props.start = (props.start !== null) ? props.start : props.date;
3096        delete props.date;
3097        return props;
3098    }
3099    function pluckNonDateProps(raw, calendar, leftovers) {
3100        var preLeftovers = {};
3101        var props = refineProps(raw, NON_DATE_PROPS, {}, preLeftovers);
3102        var ui = processUnscopedUiProps(preLeftovers, calendar, leftovers);
3103        props.publicId = props.id;
3104        delete props.id;
3105        props.ui = ui;
3106        return props;
3107    }
3108    function computeIsAllDayDefault(sourceId, calendar) {
3109        var res = null;
3110        if (sourceId) {
3111            var source = calendar.state.eventSources[sourceId];
3112            res = source.allDayDefault;
3113        }
3114        if (res == null) {
3115            res = calendar.opt('allDayDefault');
3116        }
3117        return res;
3118    }
3119
3120    var DEF_DEFAULTS = {
3121        startTime: '09:00',
3122        endTime: '17:00',
3123        daysOfWeek: [1, 2, 3, 4, 5],
3124        rendering: 'inverse-background',
3125        classNames: 'fc-nonbusiness',
3126        groupId: '_businessHours' // so multiple defs get grouped
3127    };
3128    /*
3129    TODO: pass around as EventDefHash!!!
3130    */
3131    function parseBusinessHours(input, calendar) {
3132        return parseEvents(refineInputs(input), '', calendar);
3133    }
3134    function refineInputs(input) {
3135        var rawDefs;
3136        if (input === true) {
3137            rawDefs = [{}]; // will get DEF_DEFAULTS verbatim
3138        }
3139        else if (Array.isArray(input)) {
3140            // if specifying an array, every sub-definition NEEDS a day-of-week
3141            rawDefs = input.filter(function (rawDef) {
3142                return rawDef.daysOfWeek;
3143            });
3144        }
3145        else if (typeof input === 'object' && input) { // non-null object
3146            rawDefs = [input];
3147        }
3148        else { // is probably false
3149            rawDefs = [];
3150        }
3151        rawDefs = rawDefs.map(function (rawDef) {
3152            return __assign({}, DEF_DEFAULTS, rawDef);
3153        });
3154        return rawDefs;
3155    }
3156
3157    function memoizeRendering(renderFunc, unrenderFunc, dependencies) {
3158        if (dependencies === void 0) { dependencies = []; }
3159        var dependents = [];
3160        var thisContext;
3161        var prevArgs;
3162        function unrender() {
3163            if (prevArgs) {
3164                for (var _i = 0, dependents_1 = dependents; _i < dependents_1.length; _i++) {
3165                    var dependent = dependents_1[_i];
3166                    dependent.unrender();
3167                }
3168                if (unrenderFunc) {
3169                    unrenderFunc.apply(thisContext, prevArgs);
3170                }
3171                prevArgs = null;
3172            }
3173        }
3174        function res() {
3175            if (!prevArgs || !isArraysEqual(prevArgs, arguments)) {
3176                unrender();
3177                thisContext = this;
3178                prevArgs = arguments;
3179                renderFunc.apply(this, arguments);
3180            }
3181        }
3182        res.dependents = dependents;
3183        res.unrender = unrender;
3184        for (var _i = 0, dependencies_1 = dependencies; _i < dependencies_1.length; _i++) {
3185            var dependency = dependencies_1[_i];
3186            dependency.dependents.push(res);
3187        }
3188        return res;
3189    }
3190
3191    function isValuesSimilar(val0, val1, depth) {
3192        if (depth === void 0) { depth = 1; }
3193        if (val0 === val1) {
3194            return true;
3195        }
3196        else if (Array.isArray(val0) && Array.isArray(val1)) {
3197            return isArraysSimilar(val0, val1, depth);
3198        }
3199        else if (typeof val0 === 'object' && val0 && typeof val1 === 'object' && val1) { // non-null objects
3200            return isObjectsSimilar(val0, val1, depth);
3201        }
3202        else {
3203            return false;
3204        }
3205    }
3206    function isArraysSimilar(a0, a1, depth) {
3207        if (depth === void 0) { depth = 1; }
3208        if (a0 === a1) {
3209            return true;
3210        }
3211        else if (depth > 0) {
3212            if (a0.length !== a1.length) {
3213                return false;
3214            }
3215            else {
3216                for (var i = 0; i < a0.length; i++) {
3217                    if (!isValuesSimilar(a0[i], a1[i], depth - 1)) {
3218                        return false;
3219                    }
3220                }
3221                return true;
3222            }
3223        }
3224        else {
3225            return false;
3226        }
3227    }
3228    function isObjectsSimilar(obj0, obj1, depth) {
3229        if (depth === void 0) { depth = 1; }
3230        if (obj0 === obj1) {
3231            return true;
3232        }
3233        else if (depth > 0) {
3234            for (var prop in obj0) {
3235                if (!(prop in obj1)) {
3236                    return false;
3237                }
3238            }
3239            for (var prop in obj1) {
3240                if (!(prop in obj0)) {
3241                    return false;
3242                }
3243                else {
3244                    if (!isValuesSimilar(obj0[prop], obj1[prop], depth - 1)) {
3245                        return false;
3246                    }
3247                }
3248            }
3249            return true;
3250        }
3251        else {
3252            return false;
3253        }
3254    }
3255    function computeChangedProps(obj0, obj1, depth) {
3256        if (depth === void 0) { depth = 1; }
3257        var res = {};
3258        for (var prop in obj1) {
3259            if (!(prop in obj0) ||
3260                !isValuesSimilar(obj0[prop], obj1[prop], depth - 1)) {
3261                res[prop] = obj1[prop];
3262            }
3263        }
3264        return res;
3265    }
3266    function anyKeysRemoved(obj0, obj1) {
3267        for (var prop in obj0) {
3268            if (!(prop in obj1)) {
3269                return true;
3270            }
3271        }
3272        return false;
3273    }
3274
3275    var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
3276    var Splitter = /** @class */ (function () {
3277        function Splitter() {
3278            this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
3279            this.splitDateSelection = memoize(this._splitDateSpan);
3280            this.splitEventStore = memoize(this._splitEventStore);
3281            this.splitIndividualUi = memoize(this._splitIndividualUi);
3282            this.splitEventDrag = memoize(this._splitInteraction);
3283            this.splitEventResize = memoize(this._splitInteraction);
3284            this.eventUiBuilders = {}; // TODO: typescript protection
3285        }
3286        Splitter.prototype.splitProps = function (props) {
3287            var _this = this;
3288            var keyInfos = this.getKeyInfo(props);
3289            var defKeys = this.getKeysForEventDefs(props.eventStore);
3290            var dateSelections = this.splitDateSelection(props.dateSelection);
3291            var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
3292            var eventStores = this.splitEventStore(props.eventStore, defKeys);
3293            var eventDrags = this.splitEventDrag(props.eventDrag);
3294            var eventResizes = this.splitEventResize(props.eventResize);
3295            var splitProps = {};
3296            this.eventUiBuilders = mapHash(keyInfos, function (info, key) {
3297                return _this.eventUiBuilders[key] || memoize(buildEventUiForKey);
3298            });
3299            for (var key in keyInfos) {
3300                var keyInfo = keyInfos[key];
3301                var eventStore = eventStores[key] || EMPTY_EVENT_STORE;
3302                var buildEventUi = this.eventUiBuilders[key];
3303                splitProps[key] = {
3304                    businessHours: keyInfo.businessHours || props.businessHours,
3305                    dateSelection: dateSelections[key] || null,
3306                    eventStore: eventStore,
3307                    eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
3308                    eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
3309                    eventDrag: eventDrags[key] || null,
3310                    eventResize: eventResizes[key] || null
3311                };
3312            }
3313            return splitProps;
3314        };
3315        Splitter.prototype._splitDateSpan = function (dateSpan) {
3316            var dateSpans = {};
3317            if (dateSpan) {
3318                var keys = this.getKeysForDateSpan(dateSpan);
3319                for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
3320                    var key = keys_1[_i];
3321                    dateSpans[key] = dateSpan;
3322                }
3323            }
3324            return dateSpans;
3325        };
3326        Splitter.prototype._getKeysForEventDefs = function (eventStore) {
3327            var _this = this;
3328            return mapHash(eventStore.defs, function (eventDef) {
3329                return _this.getKeysForEventDef(eventDef);
3330            });
3331        };
3332        Splitter.prototype._splitEventStore = function (eventStore, defKeys) {
3333            var defs = eventStore.defs, instances = eventStore.instances;
3334            var splitStores = {};
3335            for (var defId in defs) {
3336                for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
3337                    var key = _a[_i];
3338                    if (!splitStores[key]) {
3339                        splitStores[key] = createEmptyEventStore();
3340                    }
3341                    splitStores[key].defs[defId] = defs[defId];
3342                }
3343            }
3344            for (var instanceId in instances) {
3345                var instance = instances[instanceId];
3346                for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) {
3347                    var key = _c[_b];
3348                    if (splitStores[key]) { // must have already been created
3349                        splitStores[key].instances[instanceId] = instance;
3350                    }
3351                }
3352            }
3353            return splitStores;
3354        };
3355        Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) {
3356            var splitHashes = {};
3357            for (var defId in eventUiBases) {
3358                if (defId) { // not the '' key
3359                    for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
3360                        var key = _a[_i];
3361                        if (!splitHashes[key]) {
3362                            splitHashes[key] = {};
3363                        }
3364                        splitHashes[key][defId] = eventUiBases[defId];
3365                    }
3366                }
3367            }
3368            return splitHashes;
3369        };
3370        Splitter.prototype._splitInteraction = function (interaction) {
3371            var splitStates = {};
3372            if (interaction) {
3373                var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeys
3373ForEventDefs(interaction.affectedEvents) // can't use cached. might be events from other calendar
3374                );
3375                // can't rely on defKeys because event data is mutated
3376                var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
3377                var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
3378                var populate = function (key) {
3379                    if (!splitStates[key]) {
3380                        splitStates[key] = {
3381                            affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE,
3382                            mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE,
3383                            isEvent: interaction.isEvent,
3384                            origSeg: interaction.origSeg
3385                        };
3386                    }
3387                };
3388                for (var key in affectedStores_1) {
3389                    populate(key);
3390                }
3391                for (var key in mutatedStores_1) {
3392                    populate(key);
3393                }
3394            }
3395            return splitStates;
3396        };
3397        return Splitter;
3398    }());
3399    function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
3400        var baseParts = [];
3401        if (allUi) {
3402            baseParts.push(allUi);
3403        }
3404        if (eventUiForKey) {
3405            baseParts.push(eventUiForKey);
3406        }
3407        var stuff = {
3408            '': combineEventUis(baseParts)
3409        };
3410        if (individualUi) {
3411            __assign(stuff, individualUi);
3412        }
3413        return stuff;
3414    }
3415
3416    // Generates HTML for an anchor to another view into the calendar.
3417    // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings.
3418    // `gotoOptions` can either be a DateMarker, or an object with the form:
3419    // { date, type, forceOff }
3420    // `type` is a view-type like "day" or "week". default value is "day".
3421    // `attrs` and `innerHtml` are use to generate the rest of the HTML tag.
3422    function buildGotoAnchorHtml(component, gotoOptions, attrs, innerHtml) {
3423        var dateEnv = component.dateEnv;
3424        var date;
3425        var type;
3426        var forceOff;
3427        var finalOptions;
3428        if (gotoOptions instanceof Date) {
3429            date = gotoOptions; // a single date-like input
3430        }
3431        else {
3432            date = gotoOptions.date;
3433            type = gotoOptions.type;
3434            forceOff = gotoOptions.forceOff;
3435        }
3436        finalOptions = {
3437            date: dateEnv.formatIso(date, { omitTime: true }),
3438            type: type || 'day'
3439        };
3440        if (typeof attrs === 'string') {
3441            innerHtml = attrs;
3442            attrs = null;
3443        }
3444        attrs = attrs ? ' ' + attrsToStr(attrs) : ''; // will have a leading space
3445        innerHtml = innerHtml || '';
3446        if (!forceOff && component.opt('navLinks')) {
3447            return '<a' + attrs +
3448                ' data-goto="' + htmlEscape(JSON.stringify(finalOptions)) + '">' +
3449                innerHtml +
3450                '</a>';
3451        }
3452        else {
3453            return '<span' + attrs + '>' +
3454                innerHtml +
3455                '</span>';
3456        }
3457    }
3458    function getAllDayHtml(component) {
3459        return component.opt('allDayHtml') || htmlEscape(component.opt('allDayText'));
3460    }
3461    // Computes HTML classNames for a single-day element
3462    function getDayClasses(date, dateProfile, context, noThemeHighlight) {
3463        var calendar = context.calendar, view = context.view, theme = context.theme, dateEnv = context.dateEnv;
3464        var classes = [];
3465        var todayStart;
3466        var todayEnd;
3467        if (!rangeContainsMarker(dateProfile.activeRange, date)) {
3468            classes.push('fc-disabled-day');
3469        }
3470        else {
3471            classes.push('fc-' + DAY_IDS[date.getUTCDay()]);
3472            if (view.opt('monthMode') &&
3473                dateEnv.getMonth(date) !== dateEnv.getMonth(dateProfile.currentRange.start)) {
3474                classes.push('fc-other-month');
3475            }
3476            todayStart = startOfDay(calendar.getNow());
3477            todayEnd = addDays(todayStart, 1);
3478            if (date < todayStart) {
3479                classes.push('fc-past');
3480            }
3481            else if (date >= todayEnd) {
3482                classes.push('fc-future');
3483            }
3484            else {
3485                classes.push('fc-today');
3486                if (noThemeHighlight !== true) {
3487                    classes.push(theme.getClass('today'));
3488                }
3489            }
3490        }
3491        return classes;
3492    }
3493
3494    // given a function that resolves a result asynchronously.
3495    // the function can either call passed-in success and failure callbacks,
3496    // or it can return a promise.
3497    // if you need to pass additional params to func, bind them first.
3498    function unpromisify(func, success, failure) {
3499        // guard against success/failure callbacks being called more than once
3500        // and guard against a promise AND callback being used together.
3501        var isResolved = false;
3502        var wrappedSuccess = function () {
3503            if (!isResolved) {
3504                isResolved = true;
3505                success.apply(this, arguments);
3506            }
3507        };
3508        var wrappedFailure = function () {
3509            if (!isResolved) {
3510                isResolved = true;
3511                if (failure) {
3512                    failure.apply(this, arguments);
3513                }
3514            }
3515        };
3516        var res = func(wrappedSuccess, wrappedFailure);
3517        if (res && typeof res.then === 'function') {
3518            res.then(wrappedSuccess, wrappedFailure);
3519        }
3520    }
3521
3522    var Mixin = /** @class */ (function () {
3523        function Mixin() {
3524        }
3525        // mix into a CLASS
3526        Mixin.mixInto = function (destClass) {
3527            this.mixIntoObj(destClass.prototype);
3528        };
3529        // mix into ANY object
3530        Mixin.mixIntoObj = function (destObj) {
3531            var _this = this;
3532            Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
3533                if (!destObj[name]) { // if destination doesn't already define it
3534                    destObj[name] = _this.prototype[name];
3535                }
3536            });
3537        };
3538        /*
3539        will override existing methods
3540        TODO: remove! not used anymore
3541        */
3542        Mixin.mixOver = function (destClass) {
3543            var _this = this;
3544            Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
3545                destClass.prototype[name] = _this.prototype[name];
3546            });
3547        };
3548        return Mixin;
3549    }());
3550
3551    /*
3552    USAGE:
3553      import { default as EmitterMixin, EmitterInterface } from './EmitterMixin'
3554    in class:
3555      on: EmitterInterface['on']
3556      one: EmitterInterface['one']
3557      off: EmitterInterface['off']
3558      trigger: EmitterInterface['trigger']
3559      triggerWith: EmitterInterface['triggerWith']
3560      hasHandlers: EmitterInterface['hasHandlers']
3561    after class:
3562      EmitterMixin.mixInto(TheClass)
3563    */
3564    var EmitterMixin = /** @class */ (function (_super) {
3565        __extends(EmitterMixin, _super);
3566        function EmitterMixin() {
3567            return _super !== null && _super.apply(this, arguments) || this;
3568        }
3569        EmitterMixin.prototype.on = function (type, handler) {
3570            addToHash(this._handlers || (this._handlers = {}), type, handler);
3571            return this; // for chaining
3572        };
3573        // todo: add comments
3574        EmitterMixin.prototype.one = function (type, handler) {
3575            addToHash(this._oneHandlers || (this._oneHandlers = {}), type, handler);
3576            return this; // for chaining
3577        };
3578        EmitterMixin.prototype.off = function (type, handler) {
3579            if (this._handlers) {
3580                removeFromHash(this._handlers, type, handler);
3581            }
3582            if (this._oneHandlers) {
3583                removeFromHash(this._oneHandlers, type, handler);
3584            }
3585            return this; // for chaining
3586        };
3587        EmitterMixin.prototype.trigger = function (type) {
3588            var args = [];
3589            for (var _i = 1; _i < arguments.length; _i++) {
3590                args[_i - 1] = arguments[_i];
3591            }
3592            this.triggerWith(type, this, args);
3593            return this; // for chaining
3594        };
3595        EmitterMixin.prototype.triggerWith = function (type, context, args) {
3596            if (this._handlers) {
3597                applyAll(this._handlers[type], context, args);
3598            }
3599            if (this._oneHandlers) {
3600                applyAll(this._oneHandlers[type], context, args);
3601                delete this._oneHandlers[type]; // will never fire again
3602            }
3603            return this; // for chaining
3604        };
3605        EmitterMixin.prototype.hasHandlers = function (type) {
3606            return (this._handlers && this._handlers[type] && this._handlers[type].length) ||
3607                (this._oneHandlers && this._oneHandlers[type] && this._oneHandlers[type].length);
3608        };
3609        return EmitterMixin;
3610    }(Mixin));
3611    function addToHash(hash, type, handler) {
3612        (hash[type] || (hash[type] = []))
3613            .push(handler);
3614    }
3615    function removeFromHash(hash, type, handler) {
3616        if (handler) {
3617            if (hash[type]) {
3618                hash[type] = hash[type].filter(function (func) {
3619                    return func !== handler;
3620                });
3621            }
3622        }
3623        else {
3624            delete hash[type]; // remove all handler funcs for this type
3625        }
3626    }
3627
3628    /*
3629    Records offset information for a set of elements, relative to an origin element.
3630    Can record the left/right OR the top/bottom OR both.
3631    Provides methods for querying the cache by position.
3632    */
3633    var PositionCache = /** @class */ (function () {
3634        function PositionCache(originEl, els, isHorizontal, isVertical) {
3635            this.originEl = originEl;
3636            this.els = els;
3637            this.isHorizontal = isHorizontal;
3638            this.isVertical = isVertical;
3639        }
3640        // Queries the els for coordinates and stores them.
3641        // Call this method before using and of the get* methods below.
3642        PositionCache.prototype.build = function () {
3643            var originEl = this.originEl;
3644            var originClientRect = this.originClientRect =
3645                originEl.getBoundingClientRect(); // relative to viewport top-left
3646            if (this.isHorizontal) {
3647                this.buildElHorizontals(originClientRect.left);
3648            }
3649            if (this.isVertical) {
3650                this.buildElVerticals(originClientRect.top);
3651            }
3652        };
3653        // Populates the left/right internal coordinate arrays
3654        PositionCache.prototype.buildElHorizontals = function (originClientLeft) {
3655            var lefts = [];
3656            var rights = [];
3657            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
3658                var el = _a[_i];
3659                var rect = el.getBoundingClientRect();
3660                lefts.push(rect.left - originClientLeft);
3661                rights.push(rect.right - originClientLeft);
3662            }
3663            this.lefts = lefts;
3664            this.rights = rights;
3665        };
3666        // Populates the top/bottom internal coordinate arrays
3667        PositionCache.prototype.buildElVerticals = function (originClientTop) {
3668            var tops = [];
3669            var bottoms = [];
3670            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
3671                var el = _a[_i];
3672                var rect = el.getBoundingClientRect();
3673                tops.push(rect.top - originClientTop);
3674                bottoms.push(rect.bottom - originClientTop);
3675            }
3676            this.tops = tops;
3677            this.bottoms = bottoms;
3678        };
3679        // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
3680        // If no intersection is made, returns undefined.
3681        PositionCache.prototype.leftToIndex = function (leftPosition) {
3682            var lefts = this.lefts;
3683            var rights = this.rights;
3684            var len = lefts.length;
3685            var i;
3686            for (i = 0; i < len; i++) {
3687                if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
3688                    return i;
3689                }
3690            }
3691        };
3692        // Given a top offset (from document top), returns the index of the el that it vertically intersects.
3693        // If no intersection is made, returns undefined.
3694        PositionCache.prototype.topToIndex = function (topPosition) {
3695            var tops = this.tops;
3696            var bottoms = this.bottoms;
3697            var len = tops.length;
3698            var i;
3699            for (i = 0; i < len; i++) {
3700                if (topPosition >= tops[i] && topPosition < bottoms[i]) {
3701                    return i;
3702                }
3703            }
3704        };
3705        // Gets the width of the element at the given index
3706        PositionCache.prototype.getWidth = function (leftIndex) {
3707            return this.rights[leftIndex] - this.lefts[leftIndex];
3708        };
3709        // Gets the height of the element at the given index
3710        PositionCache.prototype.getHeight = function (topIndex) {
3711            return this.bottoms[topIndex] - this.tops[topIndex];
3712        };
3713        return PositionCache;
3714    }());
3715
3716    /*
3717    An object for getting/setting scroll-related information for an element.
3718    Internally, this is done very differently for window versus DOM element,
3719    so this object serves as a common interface.
3720    */
3721    var ScrollController = /** @class */ (function () {
3722        function ScrollController() {
3723        }
3724        ScrollController.prototype.getMaxScrollTop = function () {
3725            return this.getScrollHeight() - this.getClientHeight();
3726        };
3727        ScrollController.prototype.getMaxScrollLeft = function () {
3728            return this.getScrollWidth() - this.getClientWidth();
3729        };
3730        ScrollController.prototype.canScrollVertically = function () {
3731            return this.getMaxScrollTop() > 0;
3732        };
3733        ScrollController.prototype.canScrollHorizontally = function () {
3734            return this.getMaxScrollLeft() > 0;
3735        };
3736        ScrollController.prototype.canScrollUp = function () {
3737            return this.getScrollTop() > 0;
3738        };
3739        ScrollController.prototype.canScrollDown = function () {
3740            return this.getScrollTop() < this.getMaxScrollTop();
3741        };
3742        ScrollController.prototype.canScrollLeft = function () {
3743            return this.getScrollLeft() > 0;
3744        };
3745        ScrollController.prototype.canScrollRight = function () {
3746            return this.getScrollLeft() < this.getMaxScrollLeft();
3747        };
3748        return ScrollController;
3749    }());
3750    var ElementScrollController = /** @class */ (function (_super) {
3751        __extends(ElementScrollController, _super);
3752        function ElementScrollController(el) {
3753            var _this = _super.call(this) || this;
3754            _this.el = el;
3755            return _this;
3756        }
3757        ElementScrollController.prototype.getScrollTop = function () {
3758            return this.el.scrollTop;
3759        };
3760        ElementScrollController.prototype.getScrollLeft = function () {
3761            return this.el.scrollLeft;
3762        };
3763        ElementScrollController.prototype.setScrollTop = function (top) {
3764            this.el.scrollTop = top;
3765        };
3766        ElementScrollController.prototype.setScrollLeft = function (left) {
3767            this.el.scrollLeft = left;
3768        };
3769        ElementScrollController.prototype.getScrollWidth = function () {
3770            return this.el.scrollWidth;
3771        };
3772        ElementScrollController.prototype.getScrollHeight = function () {
3773            return this.el.scrollHeight;
3774        };
3775        ElementScrollController.prototype.getClientHeight = function () {
3776            return this.el.clientHeight;
3777        };
3778        ElementScrollController.prototype.getClientWidth = function () {
3779            return this.el.clientWidth;
3780        };
3781        return ElementScrollController;
3782    }(ScrollController));
3783    var WindowScrollController = /** @class */ (function (_super) {
3784        __extends(WindowScrollController, _super);
3785        function WindowScrollController() {
3786            return _super !== null && _super.apply(this, arguments) || this;
3787        }
3788        WindowScrollController.prototype.getScrollTop = function () {
3789            return window.pageYOffset;
3790        };
3791        WindowScrollController.prototype.getScrollLeft = function () {
3792            return window.pageXOffset;
3793        };
3794        WindowScrollController.prototype.setScrollTop = function (n) {
3795            window.scroll(window.pageXOffset, n);
3796        };
3797        WindowScrollController.prototype.setScrollLeft = function (n) {
3798            window.scroll(n, window.pageYOffset);
3799        };
3800        WindowScrollController.prototype.getScrollWidth = function () {
3801            return document.documentElement.scrollWidth;
3802        };
3803        WindowScrollController.prototype.getScrollHeight = function () {
3804            return document.documentElement.scrollHeight;
3805        };
3806        WindowScrollController.prototype.getClientHeight = function () {
3807            return document.documentElement.clientHeight;
3808        };
3809        WindowScrollController.prototype.getClientWidth = function () {
3810            return document.documentElement.clientWidth;
3811        };
3812        return WindowScrollController;
3813    }(ScrollController));
3814
3815    /*
3816    Embodies a div that has potential scrollbars
3817    */
3818    var ScrollComponent = /** @class */ (function (_super) {
3819        __extends(ScrollComponent, _super);
3820        function ScrollComponent(overflowX, overflowY) {
3821            var _this = _super.call(this, createElement('div', {
3822                className: 'fc-scroller'
3823            })) || this;
3824            _this.overflowX = overflowX;
3825            _this.overflowY = overflowY;
3826            _this.applyOverflow();
3827            return _this;
3828        }
3829        // sets to natural height, unlocks overflow
3830        ScrollComponent.prototype.clear = function () {
3831            this.setHeight('auto');
3832            this.applyOverflow();
3833        };
3834        ScrollComponent.prototype.destroy = function () {
3835            removeElement(this.el);
3836        };
3837        // Overflow
3838        // -----------------------------------------------------------------------------------------------------------------
3839        ScrollComponent.prototype.applyOverflow = function () {
3840            applyStyle(this.el, {
3841                overflowX: this.overflowX,
3842                overflowY: this.overflowY
3843            });
3844        };
3845        // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
3846        // Useful for preserving scrollbar widths regardless of future resizes.
3847        // Can pass in scrollbarWidths for optimization.
3848        ScrollComponent.prototype.lockOverflow = function (scrollbarWidths) {
3849            var overflowX = this.overflowX;
3850            var overflowY = this.overflowY;
3851            scrollbarWidths = scrollbarWidths || this.getScrollbarWidths();
3852            if (overflowX === 'auto') {
3853                overflowX = (scrollbarWidths.bottom || // horizontal scrollbars?
3854                    this.canScrollHorizontally() // OR scrolling pane with massless scrollbars?
3855                ) ? 'scroll' : 'hidden';
3856            }
3857            if (overflowY === 'auto') {
3858                overflowY = (scrollbarWidths.left || scrollbarWidths.right || // horizontal scrollbars?
3859                    this.canScrollVertically() // OR scrolling pane with massless scrollbars?
3860                ) ? 'scroll' : 'hidden';
3861            }
3862            applyStyle(this.el, { overflowX: overflowX, overflowY: overflowY });
3863        };
3864        ScrollComponent.prototype.setHeight = function (height) {
3865            applyStyleProp(this.el, 'height', height);
3866        };
3867        ScrollComponent.prototype.getScrollbarWidths = function () {
3868            var edges = computeEdges(this.el);
3869            return {
3870                left: edges.scrollbarLeft,
3871                right: edges.scrollbarRight,
3872                bottom: edges.scrollbarBottom
3873            };
3874        };
3875        return ScrollComponent;
3876    }(ElementScrollController));
3877
3878    var Theme = /** @class */ (function () {
3879        function Theme(calendarOptions) {
3880            this.calendarOptions = calendarOptions;
3881            this.processIconOverride();
3882        }
3883        Theme.prototype.processIconOverride = function () {
3884            if (this.iconOverrideOption) {
3885                this.setIconOverride(this.calendarOptions[this.iconOverrideOption]);
3886            }
3887        };
3888        Theme.prototype.setIconOverride = function (iconOverrideHash) {
3889            var iconClassesCopy;
3890            var buttonName;
3891            if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object
3892                iconClassesCopy = __assign({}, this.iconClasses);
3893                for (buttonName in iconOverrideHash) {
3894                    iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
3895                }
3896                this.iconClasses = iconClassesCopy;
3897            }
3898            else if (iconOverrideHash === false) {
3899                this.iconClasses = {};
3900            }
3901        };
3902        Theme.prototype.applyIconOverridePrefix = function (className) {
3903            var prefix = this.iconOverridePrefix;
3904            if (prefix && className.indexOf(prefix) !== 0) { // if not already present
3905                className = prefix + className;
3906            }
3907            return className;
3908        };
3909        Theme.prototype.getClass = function (key) {
3910            return this.classes[key] || '';
3911        };
3912        Theme.prototype.getIconClass = function (buttonName) {
3913            var className = this.iconClasses[buttonName];
3914            if (className) {
3915                return this.baseIconClass + ' ' + className;
3916            }
3917            return '';
3918        };
3919        Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
3920            var className;
3921            if (this.iconOverrideCustomButtonOption) {
3922                className = customButtonProps[this.iconOverrideCustomButtonOption];
3923                if (className) {
3924                    return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className);
3925                }
3926            }
3927            return '';
3928        };
3929        return Theme;
3930    }());
3931    Theme.prototype.classes = {};
3932    Theme.prototype.iconClasses = {};
3933    Theme.prototype.baseIconClass = '';
3934    Theme.prototype.iconOverridePrefix = '';
3935
3936    var guid = 0;
3937    var Component = /** @class */ (function () {
3938        function Component(context, isView) {
3939            // HACK to populate view at top of component instantiation call chain
3940            if (isView) {
3941                context.view = this;
3942            }
3943            this.uid = String(guid++);
3944            this.context = context;
3945            this.dateEnv = context.dateEnv;
3946            this.theme = context.theme;
3947            this.view = context.view;
3948            this.calendar = context.calendar;
3949            this.isRtl = this.opt('dir') === 'rtl';
3950        }
3951        Component.addEqualityFuncs = function (newFuncs) {
3952            this.prototype.equalityFuncs = __assign({}, this.prototype.equalityFuncs, newFuncs);
3953        };
3954        Component.prototype.opt = function (name) {
3955            return this.context.options[name];
3956        };
3957        Component.prototype.receiveProps = function (props) {
3958            var _a = recycleProps(this.props || {}, props, this.equalityFuncs), anyChanges = _a.anyChanges, comboProps = _a.comboProps;
3959            this.props = comboProps;
3960            if (anyChanges) {
3961                this.render(comboProps);
3962            }
3963        };
3964        Component.prototype.render = function (props) {
3965        };
3966        // after destroy is called, this component won't ever be used again
3967        Component.prototype.destroy = function () {
3968        };
3969        return Component;
3970    }());
3971    Component.prototype.equalityFuncs = {};
3972    /*
3973    Reuses old values when equal. If anything is unequal, returns newProps as-is.
3974    Great for PureComponent, but won't be feasible with React, so just eliminate and use React's DOM diffing.
3975    */
3976    function recycleProps(oldProps, newProps, equalityFuncs) {
3977        var comboProps = {}; // some old, some new
3978        var anyChanges = false;
3979        for (var key in newProps) {
3980            if (key in oldProps && (oldProps[key] === newProps[key] ||
3981                (equalityFuncs[key] && equalityFuncs[key](oldProps[key], newProps[key])))) {
3982                // equal to old? use old prop
3983                comboProps[key] = oldProps[key];
3984            }
3985            else {
3986                comboProps[key] = newProps[key];
3987                anyChanges = true;
3988            }
3989        }
3990        for (var key in oldProps) {
3991            if (!(key in newProps)) {
3992                anyChanges = true;
3993                break;
3994            }
3995        }
3996        return { anyChanges: anyChanges, comboProps: comboProps };
3997    }
3998
3999    /*
4000    PURPOSES:
4001    - hook up to fg, fill, and mirror renderers
4002    - interface for dragging and hits
4003    */
4004    var DateComponent = /** @class */ (function (_super) {
4005        __extends(DateComponent, _super);
4006        function DateComponent(context, el, isView) {
4007            var _this = _super.call(this, context, isView) || this;
4008            _this.el = el;
4009            return _this;
4010        }
4011        DateComponent.prototype.destroy = function () {
4012            _super.prototype.destroy.call(this);
4013            removeElement(this.el);
4014        };
4015        // TODO: WHAT ABOUT (sourceSeg && sourceSeg.component.doesDragMirror)
4016        //
4017        // Event Drag-n-Drop Rendering (for both events and external elements)
4018        // ---------------------------------------------------------------------------------------------------------------
4019        /*
4020        renderEventDragSegs(state: EventSegUiInteractionState) {
4021          if (state) {
4022            let { isEvent, segs, sourceSeg } = state
4023      
4024            if (this.eventRenderer) {
4025              this.eventRenderer.hideByHash(state.affectedInstances)
4026            }
4027      
4028            // if the user is dragging something that is considered an event with real event data,
4029            // and this component likes to do drag mirrors OR the component where the seg came from
4030            // likes to do drag mirrors, then render a drag mirror.
4031            if (isEvent && (this.doesDragMirror || sourceSeg && sourceSeg.component.doesDragMirror)) {
4032              if (this.mirrorRenderer) {
4033                this.mirrorRenderer.renderSegs(segs, { isDragging: true, sourceSeg })
4034              }
4035            }
4036      
4037            // if it would be impossible to render a drag mirror OR this component likes to render
4038            // highlights, then render a highlight.
4039            if (!isEvent || this.doesDragHighlight) {
4040              if (this.fillRenderer) {
4041                this.fillRenderer.renderSegs('highlight', segs)
4042              }
4043            }
4044          }
4045        }
4046        */
4047        // Hit System
4048        // -----------------------------------------------------------------------------------------------------------------
4049        DateComponent.prototype.buildPositionCaches = function () {
4050        };
4051        DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
4052            return null; // this should be abstract
4053        };
4054        // Validation
4055        // -----------------------------------------------------------------------------------------------------------------
4056        DateComponent.prototype.isInteractionValid = function (interaction) {
4057            var calendar = this.calendar;
4058            var dateProfile = this.props.dateProfile; // HACK
4059            var instances = interaction.mutatedEvents.instances;
4060            if (dateProfile) { // HACK for DayTile
4061                for (var instanceId in instances) {
4062                    if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
4063                        return false;
4064                    }
4065                }
4066            }
4067            return isInteractionValid(interaction, calendar);
4068        };
4069        DateComponent.prototype.isDateSelectionValid = function (selection) {
4070            var dateProfile = this.props.dateProfile; // HACK
4071            if (dateProfile && // HACK for DayTile
4072                !rangeContainsRange(dateProfile.validRange, selection.range)) {
4073                return false;
4074            }
4075            return isDateSelectionValid(selection, this.calendar);
4076        };
4077        // Triggering
4078        // -----------------------------------------------------------------------------------------------------------------
4079        // TODO: move to Calendar
4080        DateComponent.prototype.publiclyTrigger = function (name, args) {
4081            var calendar = this.calendar;
4082            return calendar.publiclyTrigger(name, args);
4083        };
4084        DateComponent.prototype.publiclyTriggerAfterSizing = function (name, args) {
4085            var calendar = this.calendar;
4086            return calendar.publiclyTriggerAfterSizing(name, args);
4087        };
4088        DateComponent.prototype.hasPublicHandlers = function (name) {
4089            var calendar = this.calendar;
4090            return calendar.hasPublicHandlers(name);
4091        };
4092        DateComponent.prototype.triggerRenderedSegs = function (segs, isMirrors) {
4093            var calendar = this.calendar;
4094            if (this.hasPublicHandlers('eventPositioned')) {
4095                for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
4096                    var seg = segs_1[_i];
4097                    this.publiclyTriggerAfterSizing('eventPositioned', [
4098                        {
4099                            event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
4100                            isMirror: isMirrors,
4101                            isStart: seg.isStart,
4102                            isEnd: seg.isEnd,
4103                            el: seg.el,
4104                            view: this // ?
4105                        }
4106                    ]);
4107                }
4108            }
4109            if (!calendar.state.loadingLevel) { // avoid initial empty state while pending
4110                calendar.afterSizingTriggers._eventsPositioned = [null]; // fire once
4111            }
4112        };
4113        DateComponent.prototype.triggerWillRemoveSegs = function (segs, isMirrors) {
4114            var calendar = this.calendar;
4115            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
4116                var seg = segs_2[_i];
4117                calendar.trigger('eventElRemove', seg.el);
4118            }
4119            if (this.hasPublicHandlers('eventDestroy')) {
4120                for (var _a = 0, segs_3 = segs; _a < segs_3.length; _a++) {
4121                    var seg = segs_3[_a];
4122                    this.publiclyTrigger('eventDestroy', [
4123                        {
4124                            event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
4125                            isMirror: isMirrors,
4126                            el: seg.el,
4127                            view: this // ?
4128                        }
4129                    ]);
4130                }
4131            }
4132        };
4133        // Pointer Interaction Utils
4134        // -----------------------------------------------------------------------------------------------------------------
4135        DateComponent.prototype.isValidSegDownEl = function (el) {
4136            return !this.props.eventDrag && // HACK
4137                !this.props.eventResize && // HACK
4138                !elementClosest(el, '.fc-mirror') &&
4139                (this.isPopover() || !this.isInPopover(el));
4140            // ^above line ensures we don't detect a seg interaction within a nested component.
4141            // it's a HACK because it only supports a popover as the nested component.
4142        };
4143        DateComponent.prototype.isValidDateDownEl = function (el) {
4144            var segEl = elementClosest(el, this.fgSegSelector);
4145            return (!segEl || segEl.classList.contains('fc-mirror')) &&
4146                !elementClosest(el, '.fc-more') && // a "more.." link
4147                !elementClosest(el, 'a[data-goto]') && // a clickable nav link
4148                !this.isInPopover(el);
4149        };
4150        DateComponent.prototype.isPopover = function () {
4151            return this.el.classList.contains('fc-popover');
4152        };
4153        DateComponent.prototype.isInPopover = function (el) {
4154            return Boolean(elementClosest(el, '.fc-popover'));
4155        };
4156        return DateComponent;
4157    }(Component));
4158    DateComponent.prototype.fgSegSelector = '.fc-event-container > *';
4159    DateComponent.prototype.bgSegSelector = '.fc-bgevent:not(.fc-nonbusiness)';
4160
4161    var uid$1 = 0;
4162    function createPlugin(input) {
4163        return {
4164            id: String(uid$1++),
4165            deps: input.deps || [],
4166            reducers: input.reducers || [],
4167            eventDefParsers: input.eventDefParsers || [],
4168            eventDragMutationMassagers: input.eventDragMutationMassagers || [],
4169            eventDefMutationAppliers: input.eventDefMutationAppliers || [],
4170            dateSelectionTransformers: input.dateSelectionTransformers || [],
4171            datePointTransforms: input.datePointTransforms || [],
4172            dateSpanTransforms: input.dateSpanTransforms || [],
4173            views: input.views || {},
4174            viewPropsTransformers: input.viewPropsTransformers || [],
4175            isPropsValid: input.isPropsValid || null,
4176            externalDefTransforms: input.externalDefTransforms || [],
4177            eventResizeJoinTransforms: input.eventResizeJoinTransforms || [],
4178            viewContainerModifiers: input.viewContainerModifiers || [],
4179            eventDropTransformers: input.eventDropTransformers || [],
4180            componentInteractions: input.componentInteractions || [],
4181            calendarInteractions: input.calendarInteractions || [],
4182            themeClasses: input.themeClasses || {},
4183            eventSourceDefs: input.eventSourceDefs || [],
4184            cmdFormatter: input.cmdFormatter,
4185            recurringTypes: input.recurringTypes || [],
4186            namedTimeZonedImpl: input.namedTimeZonedImpl,
4187            defaultView: input.defaultView || '',
4188            elementDraggingImpl: input.elementDraggingImpl,
4189            optionChangeHandlers: input.optionChangeHandlers || {}
4190        };
4191    }
4192    var PluginSystem = /** @class */ (function () {
4193        function PluginSystem() {
4194            this.hooks = {
4195                reducers: [],
4196                eventDefParsers: [],
4197                eventDragMutationMassagers: [],
4198                eventDefMutationAppliers: [],
4199                dateSelectionTransformers: [],
4200                datePointTransforms: [],
4201                dateSpanTransforms: [],
4202                views: {},
4203                viewPropsTransformers: [],
4204                isPropsValid: null,
4205                externalDefTransforms: [],
4206                eventResizeJoinTransforms: [],
4207                viewContainerModifiers: [],
4208                eventDropTransformers: [],
4209                componentInteractions: [],
4210                calendarInteractions: [],
4211                themeClasses: {},
4212                eventSourceDefs: [],
4213                cmdFormatter: null,
4214                recurringTypes: [],
4215                namedTimeZonedImpl: null,
4216                defaultView: '',
4217                elementDraggingImpl: null,
4218                optionChangeHandlers: {}
4219            };
4220            this.addedHash = {};
4221        }
4222        PluginSystem.prototype.add = function (plugin) {
4223            if (!this.addedHash[plugin.id]) {
4224                this.addedHash[plugin.id] = true;
4225                for (var _i = 0, _a = plugin.deps; _i < _a.length; _i++) {
4226                    var dep = _a[_i];
4227                    this.add(dep);
4228                }
4229                this.hooks = combineHooks(this.hooks, plugin);
4230            }
4231        };
4232        return PluginSystem;
4233    }());
4234    function combineHooks(hooks0, hooks1) {
4235        return {
4236            reducers: hooks0.reducers.concat(hooks1.reducers),
4237            eventDefParsers: hooks0.eventDefParsers.concat(hooks1.eventDefParsers),
4238            eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
4239            eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
4240            dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
4241            datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
4242            dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
4243            views: __assign({}, hooks0.views, hooks1.views),
4244            viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
4245            isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
4246            externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
4247            eventResizeJoinTransforms: hooks0.eventResizeJoinTransforms.concat(hooks1.eventResizeJoinTransforms),
4248            viewContainerModifiers: hooks0.viewContainerModifiers.concat(hooks1.viewContainerModifiers),
4249            eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
4250            calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
4251            componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
4252            themeClasses: __assign({}, hooks0.themeClasses, hooks1.themeClasses),
4253            eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
4254            cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
4255            recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
4256            namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
4257            defaultView: hooks0.defaultView || hooks1.defaultView,
4258            elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
4259            optionChangeHandlers: __assign({}, hooks0.optionChangeHandlers, hooks1.optionChangeHandlers)
4260        };
4261    }
4262
4263    var eventSourceDef = {
4264        ignoreRange: true,
4265        parseMeta: function (raw) {
4266            if (Array.isArray(raw)) { // short form
4267                return raw;
4268            }
4269            else if (Array.isArray(raw.events)) {
4270                return raw.events;
4271            }
4272            return null;
4273        },
4274        fetch: function (arg, success) {
4275            success({
4276                rawEvents: arg.eventSource.meta
4277            });
4278        }
4279    };
4280    var ArrayEventSourcePlugin = createPlugin({
4281        eventSourceDefs: [eventSourceDef]
4282    });
4283
4284    var eventSourceDef$1 = {
4285        parseMeta: function (raw) {
4286            if (typeof raw === 'function') { // short form
4287                return raw;
4288            }
4289            else if (typeof raw.events === 'function') {
4290                return raw.events;
4291            }
4292            return null;
4293        },
4294        fetch: function (arg, success, failure) {
4295            var dateEnv = arg.calendar.dateEnv;
4296            var func = arg.eventSource.meta;
4297            unpromisify(func.bind(null, {
4298                start: dateEnv.toDate(arg.range.start),
4299                end: dateEnv.toDate(arg.range.end),
4300                startStr: dateEnv.formatIso(arg.range.start),
4301                endStr: dateEnv.formatIso(arg.range.end),
4302                timeZone: dateEnv.timeZone
4303            }), function (rawEvents) {
4304                success({ rawEvents: rawEvents }); // needs an object response
4305            }, failure // send errorObj directly to failure callback
4306            );
4307        }
4308    };
4309    var FuncEventSourcePlugin = createPlugin({
4310        eventSourceDefs: [eventSourceDef$1]
4311    });
4312
4313    function requestJson(method, url, params, successCallback, failureCallback) {
4314        method = method.toUpperCase();
4315        var body = null;
4316        if (method === 'GET') {
4317            url = injectQueryStringParams(url, params);
4318        }
4319        else {
4320            body = encodeParams(params);
4321        }
4322        var xhr = new XMLHttpRequest();
4323        xhr.open(method, url, true);
4324        if (method !== 'GET') {
4325            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
4326        }
4327        xhr.onload = function () {
4328            if (xhr.status >= 200 && xhr.status < 400) {
4329                try {
4330                    var res = JSON.parse(xhr.responseText);
4331                    successCallback(res, xhr);
4332                }
4333                catch (err) {
4334                    failureCallback('Failure parsing JSON', xhr);
4335                }
4336            }
4337            else {
4338                failureCallback('Request failed', xhr);
4339            }
4340        };
4341        xhr.onerror = function () {
4342            failureCallback('Request failed', xhr);
4343        };
4344        xhr.send(body);
4345    }
4346    function injectQueryStringParams(url, params) {
4347        return url +
4348            (url.indexOf('?') === -1 ? '?' : '&') +
4349            encodeParams(params);
4350    }
4351    function encodeParams(params) {
4352        var parts = [];
4353        for (var key in params) {
4354            parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
4355        }
4356        return parts.join('&');
4357    }
4358
4359    var eventSourceDef$2 = {
4360        parseMeta: function (raw) {
4361            if (typeof raw === 'string') { // short form
4362                raw = { url: raw };
4363            }
4364            else if (!raw || typeof raw !== 'object' || !raw.url) {
4365                return null;
4366            }
4367            return {
4368                url: raw.url,
4369                method: (raw.method || 'GET').toUpperCase(),
4370                extraParams: raw.extraParams,
4371                startParam: raw.startParam,
4372                endParam: raw.endParam,
4373                timeZoneParam: raw.timeZoneParam
4374            };
4375        },
4376        fetch: function (arg, success, failure) {
4377            var meta = arg.eventSource.meta;
4378            var requestParams = buildRequestParams(meta, arg.range, arg.calendar);
4379            requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) {
4380                success({ rawEvents: rawEvents, xhr: xhr });
4381            }, function (errorMessage, xhr) {
4382                failure({ message: errorMessage, xhr: xhr });
4383            });
4384        }
4385    };
4386    var JsonFeedEventSourcePlugin = createPlugin({
4387        eventSourceDefs: [eventSourceDef$2]
4388    });
4389    function buildRequestParams(meta, range, calendar) {
4390        var dateEnv = calendar.dateEnv;
4391        var startParam;
4392        var endParam;
4393        var timeZoneParam;
4394        var customRequestParams;
4395        var params = {};
4396        startParam = meta.startParam;
4397        if (startParam == null) {
4398            startParam = calendar.opt('startParam');
4399        }
4400        endParam = meta.endParam;
4401        if (endParam == null) {
4402            endParam = calendar.opt('endParam');
4403        }
4404        timeZoneParam = meta.timeZoneParam;
4405        if (timeZoneParam == null) {
4406            timeZoneParam = calendar.opt('timeZoneParam');
4407        }
4408        // retrieve any outbound GET/POST data from the options
4409        if (typeof meta.extraParams === 'function') {
4410            // supplied as a function that returns a key/value object
4411            customRequestParams = meta.extraParams();
4412        }
4413        else {
4414            // probably supplied as a straight key/value object
4415            customRequestParams = meta.extraParams || {};
4416        }
4417        __assign(params, customRequestParams);
4418        params[startParam] = dateEnv.formatIso(range.start);
4419        params[endParam] = dateEnv.formatIso(range.end);
4420        if (dateEnv.timeZone !== 'local') {
4421            params[timeZoneParam] = dateEnv.timeZone;
4422        }
4423        return params;
4424    }
4425
4426    var recurring = {
4427        parse: function (rawEvent, leftoverProps, dateEnv) {
4428            var createMarker = dateEnv.createMarker.bind(dateEnv);
4429            var processors = {
4430                daysOfWeek: null,
4431                startTime: createDuration,
4432                endTime: createDuration,
4433                startRecur: createMarker,
4434                endRecur: createMarker
4435            };
4436            var props = refineProps(rawEvent, processors, {}, leftoverProps);
4437            var anyValid = false;
4438            for (var propName in props) {
4439                if (props[propName] != null) {
4440                    anyValid = true;
4441                    break;
4442                }
4443            }
4444            if (anyValid) {
4445                return {
4446                    allDayGuess: Boolean(!props.startTime && !props.endTime),
4447                    duration: (props.startTime && props.endTime) ?
4448                        subtractDurations(props.endTime, props.startTime) :
4449                        null,
4450                    typeData: props // doesn't need endTime anymore but oh well
4451                };
4452            }
4453            return null;
4454        },
4455        expand: function (typeData, framingRange, dateEnv) {
4456            var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
4457            if (clippedFramingRange) {
4458                return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
4459            }
4460            else {
4461                return [];
4462            }
4463        }
4464    };
4465    var SimpleRecurrencePlugin = createPlugin({
4466        recurringTypes: [recurring]
4467    });
4468    function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
4469        var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
4470        var dayMarker = startOfDay(framingRange.start);
4471        var endMarker = framingRange.end;
4472        var instanceStarts = [];
4473        while (dayMarker < endMarker) {
4474            var instanceStart 
4475            // if everyday, or this particular day-of-week
4476            = void 0;
4477            // if everyday, or this particular day-of-week
4478            if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
4479                if (startTime) {
4480                    instanceStart = dateEnv.add(dayMarker, startTime);
4481                }
4482                else {
4483                    instanceStart = dayMarker;
4484                }
4485                instanceStarts.push(instanceStart);
4486            }
4487            dayMarker = addDays(dayMarker, 1);
4488        }
4489        return instanceStarts;
4490    }
4491
4492    var DefaultOptionChangeHandlers = createPlugin({
4493        optionChangeHandlers: {
4494            events: function (events, calendar) {
4495                handleEventSources([events], calendar);
4496            },
4497            eventSources: handleEventSources,
4498            plugins: handlePlugins
4499        }
4500    });
4501    function handleEventSources(inputs, calendar) {
4502        var unfoundSources = hashValuesToArray(calendar.state.eventSources);
4503        var newInputs = [];
4504        for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
4505            var input = inputs_1[_i];
4506            var inputFound = false;
4507            for (var i = 0; i < unfoundSources.length; i++) {
4508                if (isValuesSimilar(unfoundSources[i]._raw, input, 2)) {
4509                    unfoundSources.splice(i, 1); // delete
4510                    inputFound = true;
4511                    break;
4512                }
4513            }
4514            if (!inputFound) {
4515                newInputs.push(input);
4516            }
4517        }
4518        for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) {
4519            var unfoundSource = unfoundSources_1[_a];
4520            calendar.dispatch({
4521                type: 'REMOVE_EVENT_SOURCE',
4522                sourceId: unfoundSource.sourceId
4523            });
4524        }
4525        for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) {
4526            var newInput = newInputs_1[_b];
4527            calendar.addEventSource(newInput);
4528        }
4529    }
4530    // shortcoming: won't remove plugins
4531    function handlePlugins(inputs, calendar) {
4532        calendar.addPluginInputs(inputs); // will gracefully handle duplicates
4533    }
4534
4535    var config = {}; // TODO: make these options
4536    var globalDefaults = {
4537        defaultRangeSeparator: ' - ',
4538        titleRangeSeparator: ' \u2013 ',
4539        defaultTimedEventDuration: '01:00:00',
4540        defaultAllDayEventDuration: { day: 1 },
4541        forceEventDuration: false,
4542        nextDayThreshold: '00:00:00',
4543        // display
4544        columnHeader: true,
4545        defaultView: '',
4546        aspectRatio: 1.35,
4547        header: {
4548            left: 'title',
4549            center: '',
4550            right: 'today prev,next'
4551        },
4552        weekends: true,
4553        weekNumbers: false,
4554        weekNumberCalculation: 'local',
4555        editable: false,
4556        // nowIndicator: false,
4557        scrollTime: '06:00:00',
4558        minTime: '00:00:00',
4559        maxTime: '24:00:00',
4560        showNonCurrentDates: true,
4561        // event ajax
4562        lazyFetching: true,
4563        startParam: 'start',
4564        endParam: 'end',
4565        timeZoneParam: 'timeZone',
4566        timeZone: 'local',
4567        // allDayDefault: undefined,
4568        // locale
4569        locales: [],
4570        locale: '',
4571        // dir: will get this from the default locale
4572        // buttonIcons: null,
4573        // allows setting a min-height to the event segment to prevent short events overlapping each other
4574        timeGridEventMinHeight: 0,
4575        themeSystem: 'standard',
4576        // eventResizableFromStart: false,
4577        dragRevertDuration: 500,
4578        dragScroll: true,
4579        allDayMaintainDuration: false,
4580        // selectable: false,
4581        unselectAuto: true,
4582        // selectMinDistance: 0,
4583        dropAccept: '*',
4584        eventOrder: 'start,-duration,allDay,title',
4585        // ^ if start tie, longer events go before shorter. final tie-breaker is title text
4586        // rerenderDelay: null,
4587        eventLimit: false,
4588        eventLimitClick: 'popover',
4589        dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
4590        handleWindowResize: true,
4591        windowResizeDelay: 100,
4592        longPressDelay: 1000,
4593        eventDragMinDistance: 5 // only applies to mouse
4594    };
4595    var rtlDefaults = {
4596        header: {
4597            left: 'next,prev today',
4598            center: '',
4599            right: 'title'
4600        },
4601        buttonIcons: {
4602            // TODO: make RTL support the responibility of the theme
4603            prev: 'fc-icon-chevron-right',
4604            next: 'fc-icon-chevron-left',
4605            prevYear: 'fc-icon-chevrons-right',
4606            nextYear: 'fc-icon-chevrons-left'
4607        }
4608    };
4609    var complexOptions = [
4610        'header',
4611        'footer',
4612        'buttonText',
4613        'buttonIcons'
4614    ];
4615    // Merges an array of option objects into a single object
4616    function mergeOptions(optionObjs) {
4617        return mergeProps(optionObjs, complexOptions);
4618    }
4619    // TODO: move this stuff to a "plugin"-related file...
4620    var INTERNAL_PLUGINS = [
4621        ArrayEventSourcePlugin,
4622        FuncEventSourcePlugin,
4623        JsonFeedEventSourcePlugin,
4624        SimpleRecurrencePlugin,
4625        DefaultOptionChangeHandlers
4626    ];
4627    function refinePluginDefs(pluginInputs) {
4628        var plugins = [];
4629        for (var _i = 0, pluginInputs_1 = pluginInputs; _i < pluginInputs_1.length; _i++) {
4630            var pluginInput = pluginInputs_1[_i];
4631            if (typeof pluginInput === 'string') {
4632                var globalName = 'FullCalendar' + capitaliseFirstLetter(pluginInput);
4633                if (!window[globalName]) {
4634                    console.warn('Plugin file not loaded for ' + pluginInput);
4635                }
4636                else {
4637                    plugins.push(window[globalName].default); // is an ES6 module
4638                }
4639            }
4640            else {
4641                plugins.push(pluginInput);
4642            }
4643        }
4644        return INTERNAL_PLUGINS.concat(plugins);
4645    }
4646
4647    var RAW_EN_LOCALE = {
4648        code: 'en',
4649        week: {
4650            dow: 0,
4651            doy: 4 // 4 days need to be within the year to be considered the first week
4652        },
4653        dir: 'ltr',
4654        buttonText: {
4655            prev: 'prev',
4656            next: 'next',
4657            prevYear: 'prev year',
4658            nextYear: 'next year',
4659            year: 'year',
4660            today: 'today',
4661            month: 'month',
4662            week: 'week',
4663            day: 'day',
4664            list: 'list'
4665        },
4666        weekLabel: 'W',
4667        allDayText: 'all-day',
4668        eventLimitText: 'more',
4669        noEventsMessage: 'No events to display'
4670    };
4671    function parseRawLocales(explicitRawLocales) {
4672        var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
4673        var globalArray = window['FullCalendarLocalesAll'] || []; // from locales-all.js
4674        var globalObject = window['FullCalendarLocales'] || {}; // from locales/*.js. keys are meaningless
4675        var allRawLocales = globalArray.concat(// globalArray is low prio
4676        hashValuesToArray(globalObject), // medium prio
4677        explicitRawLocales // highest prio
4678        );
4679        var rawLocaleMap = {
4680            en: RAW_EN_LOCALE // necessary?
4681        };
4682        for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) {
4683            var rawLocale = allRawLocales_1[_i];
4684            rawLocaleMap[rawLocale.code] = rawLocale;
4685        }
4686        return {
4687            map: rawLocaleMap,
4688            defaultCode: defaultCode
4689        };
4690    }
4691    function buildLocale(inputSingular, available) {
4692        if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
4693            return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
4694        }
4695        else {
4696            return queryLocale(inputSingular, available);
4697        }
4698    }
4699    function queryLocale(codeArg, available) {
4700        var codes = [].concat(codeArg || []); // will convert to array
4701        var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
4702        return parseLocale(codeArg, codes, raw);
4703    }
4704    function queryRawLocale(codes, available) {
4705        for (var i = 0; i < codes.length; i++) {
4706            var parts = codes[i].toLocaleLowerCase().split('-');
4707            for (var j = parts.length; j > 0; j--) {
4708                var simpleId = parts.slice(0, j).join('-');
4709                if (available[simpleId]) {
4710                    return available[simpleId];
4711                }
4712            }
4713        }
4714        return null;
4715    }
4716    function parseLocale(codeArg, codes, raw) {
4717        var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']);
4718        delete merged.code; // don't want this part of the options
4719        var week = merged.week;
4720        delete merged.week;
4721        return {
4722            codeArg: codeArg,
4723            codes: codes,
4724            week: week,
4725            simpleNumberFormat: new Intl.NumberFormat(codeArg),
4726            options: merged
4727        };
4728    }
4729
4730    var OptionsManager = /** @class */ (function () {
4731        function OptionsManager(overrides) {
4732            this.overrides = __assign({}, overrides); // make a copy
4733            this.dynamicOverrides = {};
4734            this.compute();
4735        }
4736        OptionsManager.prototype.add = function (props) {
4737            __assign(this.overrides, props);
4738            this.compute();
4739        };
4740        OptionsManager.prototype.addDynamic = function (props) {
4741            __assign(this.dynamicOverrides, props);
4742            this.compute();
4743        };
4744        OptionsManager.prototype.reset = function (props) {
4745            this.overrides = props;
4746            this.compute();
4747        };
4748        // Computes the flattened options hash for the calendar and assigns to `this.options`.
4749        // Assumes this.overrides and this.dynamicOverrides have already been initialized.
4750        OptionsManager.prototype.compute = function () {
4751            // TODO: not a very efficient system
4752            var locales = firstDefined(// explicit locale option given?
4753            this.dynamicOverrides.locales, this.overrides.locales, globalDefaults.locales);
4754            var locale = firstDefined(// explicit locales option given?
4755            this.dynamicOverrides.locale, this.overrides.locale, globalDefaults.locale);
4756            var available = parseRawLocales(locales);
4757            var localeDefaults = buildLocale(locale || available.defaultCode, available.map).options;
4758            var dir = firstDefined(// based on options computed so far, is direction RTL?
4759            this.dynamicOverrides.dir, this.overrides.dir, localeDefaults.dir);
4760            var dirDefaults = dir === 'rtl' ? rtlDefaults : {};
4761            this.dirDefaults = dirDefaults;
4762            this.localeDefaults = localeDefaults;
4763            this.computed = mergeOptions([
4764                globalDefaults,
4765                dirDefaults,
4766                localeDefaults,
4767                this.overrides,
4768                this.dynamicOverrides
4769            ]);
4770        };
4771        return OptionsManager;
4772    }());
4773
4774    var calendarSystemClassMap = {};
4775    function registerCalendarSystem(name, theClass) {
4776        calendarSystemClassMap[name] = theClass;
4777    }
4778    function createCalendarSystem(name) {
4779        return new calendarSystemClassMap[name]();
4780    }
4781    var GregorianCalendarSystem = /** @class */ (function () {
4782        function GregorianCalendarSystem() {
4783        }
4784        GregorianCalendarSystem.prototype.getMarkerYear = function (d) {
4785            return d.getUTCFullYear();
4786        };
4787        GregorianCalendarSystem.prototype.getMarkerMonth = function (d) {
4788            return d.getUTCMonth();
4789        };
4790        GregorianCalendarSystem.prototype.getMarkerDay = function (d) {
4791            return d.getUTCDate();
4792        };
4793        GregorianCalendarSystem.prototype.arrayToMarker = function (arr) {
4794            return arrayToUtcDate(arr);
4795        };
4796        GregorianCalendarSystem.prototype.markerToArray = function (marker) {
4797            return dateToUtcArray(marker);
4798        };
4799        return GregorianCalendarSystem;
4800    }());
4801    registerCalendarSystem('gregory', GregorianCalendarSystem);
4802
4803    var ISO_RE = /^\s*(\d{4})(-(\d{2})(-(\d{2})([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
4804    function parse(str) {
4805        var m = ISO_RE.exec(str);
4806        if (m) {
4807            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));
4808            if (isValidDate(marker)) {
4809                var timeZoneOffset = null;
4810                if (m[13]) {
4811                    timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
4812                        Number(m[18] || 0));
4813                }
4814                return {
4815                    marker: marker,
4816                    isTimeUnspecified: !m[6],
4817                    timeZoneOffset: timeZoneOffset
4818                };
4819            }
4820        }
4821        return null;
4822    }
4823
4824    var DateEnv = /** @class */ (function () {
4825        function DateEnv(settings) {
4826            var timeZone = this.timeZone = settings.timeZone;
4827            var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
4828            if (settings.namedTimeZoneImpl && isNamedTimeZone) {
4829                this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
4830            }
4831            this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
4832            this.calendarSystem = createCalendarSystem(settings.calendarSystem);
4833            this.locale = settings.locale;
4834            this.weekDow = settings.locale.week.dow;
4835            this.weekDoy = settings.locale.week.doy;
4836            if (settings.weekNumberCalculation === 'ISO') {
4837                this.weekDow = 1;
4838                this.weekDoy = 4;
4839            }
4840            else if (typeof settings.firstDay === 'number') {
4841                this.weekDow = settings.firstDay;
4842            }
4843            if (typeof settings.weekNumberCalculation === 'function') {
4844                this.weekNumberFunc = settings.weekNumberCalculation;
4845            }
4846            this.weekLabel = settings.weekLabel != null ? settings.weekLabel : settings.locale.options.weekLabel;
4847            this.cmdFormatter = settings.cmdFormatter;
4848        }
4849        // Creating / Parsing
4850        DateEnv.prototype.createMarker = function (input) {
4851            var meta = this.createMarkerMeta(input);
4852            if (meta === null) {
4853                return null;
4854            }
4855            return meta.marker;
4856        };
4857        DateEnv.prototype.createNowMarker = function () {
4858            if (this.canComputeOffset) {
4859                return this.timestampToMarker(new Date().valueOf());
4860            }
4861            else {
4862                // if we can't compute the current date val for a timezone,
4863                // better to give the current local date vals than UTC
4864                return arrayToUtcDate(dateToLocalArray(new Date()));
4865            }
4866        };
4867        DateEnv.prototype.createMarkerMeta = function (input) {
4868            if (typeof input === 'string') {
4869                return this.parse(input);
4870            }
4871            var marker = null;
4872            if (typeof input === 'number') {
4873                marker = this.timestampToMarker(input);
4874            }
4875            else if (input instanceof Date) {
4876                input = input.valueOf();
4877                if (!isNaN(input)) {
4878                    marker = this.timestampToMarker(input);
4879                }
4880            }
4881            else if (Array.isArray(input)) {
4882                marker = arrayToUtcDate(input);
4883            }
4884            if (marker === null || !isValidDate(marker)) {
4885                return null;
4886            }
4887            return { marker: marker, isTimeUnspecified: false, forcedTzo: null };
4888        };
4889        DateEnv.prototype.parse = function (s) {
4890            var parts = parse(s);
4891            if (parts === null) {
4892                return null;
4893            }
4894            var marker = parts.marker;
4895            var forcedTzo = null;
4896            if (parts.timeZoneOffset !== null) {
4897                if (this.canComputeOffset) {
4898                    marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
4899                }
4900                else {
4901                    forcedTzo = parts.timeZoneOffset;
4902                }
4903            }
4904            return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo };
4905        };
4906        // Accessors
4907        DateEnv.prototype.getYear = function (marker) {
4908            return this.calendarSystem.getMarkerYear(marker);
4909        };
4910        DateEnv.prototype.getMonth = function (marker) {
4911            return this.calendarSystem.getMarkerMonth(marker);
4912        };
4913        // Adding / Subtracting
4914        DateEnv.prototype.add = function (marker, dur) {
4915            var a = this.calendarSystem.markerToArray(marker);
4916            a[0] += dur.years;
4917            a[1] += dur.months;
4918            a[2] += dur.days;
4919            a[6] += dur.milliseconds;
4920            return this.calendarSystem.arrayToMarker(a);
4921        };
4922        DateEnv.prototype.subtract = function (marker, dur) {
4923            var a = this.calendarSystem.markerToArray(marker);
4924            a[0] -= dur.years;
4925            a[1] -= dur.months;
4926            a[2] -= dur.days;
4927            a[6] -= dur.milliseconds;
4928            return this.calendarSystem.arrayToMarker(a);
4929        };
4930        DateEnv.prototype.addYears = function (marker, n) {
4931            var a = this.calendarSystem.markerToArray(marker);
4932            a[0] += n;
4933            return this.calendarSystem.arrayToMarker(a);
4934        };
4935        DateEnv.prototype.addMonths = function (marker, n) {
4936            var a = this.calendarSystem.markerToArray(marker);
4937            a[1] += n;
4938            return this.calendarSystem.arrayToMarker(a);
4939        };
4940        // Diffing Whole Units
4941        DateEnv.prototype.diffWholeYears = function (m0, m1) {
4942            var calendarSystem = this.calendarSystem;
4943            if (timeAsMs(m0) === timeAsMs(m1) &&
4944                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
4945                calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
4946                return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
4947            }
4948            return null;
4949        };
4950        DateEnv.prototype.diffWholeMonths = function (m0, m1) {
4951            var calendarSystem = this.calendarSystem;
4952            if (timeAsMs(m0) === timeAsMs(m1) &&
4953                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
4954                return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
4955                    (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
4956            }
4957            return null;
4958        };
4959        // Range / Duration
4960        DateEnv.prototype.greatestWholeUnit = function (m0, m1) {
4961            var n = this.diffWholeYears(m0, m1);
4962            if (n !== null) {
4963                return { unit: 'year', value: n };
4964            }
4965            n = this.diffWholeMonths(m0, m1);
4966            if (n !== null) {
4967                return { unit: 'month', value: n };
4968            }
4969            n = diffWholeWeeks(m0, m1);
4970            if (n !== null) {
4971                return { unit: 'week', value: n };
4972            }
4973            n = diffWholeDays(m0, m1);
4974            if (n !== null) {
4975                return { unit: 'day', value: n };
4976            }
4977            n = diffHours(m0, m1);
4978            if (isInt(n)) {
4979                return { unit: 'hour', value: n };
4980            }
4981            n = diffMinutes(m0, m1);
4982            if (isInt(n)) {
4983                return { unit: 'minute', value: n };
4984            }
4985            n = diffSeconds(m0, m1);
4986            if (isInt(n)) {
4987                return { unit: 'second', value: n };
4988            }
4989            return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
4990        };
4991        DateEnv.prototype.countDurationsBetween = function (m0, m1, d) {
4992            // TODO: can use greatestWholeUnit
4993            var diff;
4994            if (d.years) {
4995                diff = this.diffWholeYears(m0, m1);
4996                if (diff !== null) {
4997                    return diff / asRoughYears(d);
4998                }
4999            }
5000            if (d.months) {
5001                diff = this.diffWholeMonths(m0, m1);
5002                if (diff !== null) {
5003                    return diff / asRoughMonths(d);
5004                }
5005            }
5006            if (d.days) {
5007                diff = diffWholeDays(m0, m1);
5008                if (diff !== null) {
5009                    return diff / asRoughDays(d);
5010                }
5011            }
5012            return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
5013        };
5014        // Start-Of
5015        DateEnv.prototype.startOf = function (m, unit) {
5016            if (unit === 'year') {
5017                return this.startOfYear(m);
5018            }
5019            else if (unit === 'month') {
5020                return this.startOfMonth(m);
5021            }
5022            else if (unit === 'week') {
5023                return this.startOfWeek(m);
5024            }
5025            else if (unit === 'day') {
5026                return startOfDay(m);
5027            }
5028            else if (unit === 'hour') {
5029                return startOfHour(m);
5030            }
5031            else if (unit === 'minute') {
5032                return startOfMinute(m);
5033            }
5034            else if (unit === 'second') {
5035                return startOfSecond(m);
5036            }
5037        };
5038        DateEnv.prototype.startOfYear = function (m) {
5039            return this.calendarSystem.arrayToMarker([
5040                this.calendarSystem.getMarkerYear(m)
5041            ]);
5042        };
5043        DateEnv.prototype.startOfMonth = function (m) {
5044            return this.calendarSystem.arrayToMarker([
5045                this.calendarSystem.getMarkerYear(m),
5046                this.calendarSystem.getMarkerMonth(m)
5047            ]);
5048        };
5049        DateEnv.prototype.startOfWeek = function (m) {
5050            return this.calendarSystem.arrayToMarker([
5051                this.calendarSystem.getMarkerYear(m),
5052                this.calendarSystem.getMarkerMonth(m),
5053                m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7)
5054            ]);
5055        };
5056        // Week Number
5057        DateEnv.prototype.computeWeekNumber = function (marker) {
5058            if (this.weekNumberFunc) {
5059                return this.weekNumberFunc(this.toDate(marker));
5060            }
5061            else {
5062                return weekOfYear(marker, this.weekDow, this.weekDoy);
5063            }
5064        };
5065        // TODO: choke on timeZoneName: long
5066        DateEnv.prototype.format = function (marker, formatter, dateOptions) {
5067            if (dateOptions === void 0) { dateOptions = {}; }
5068            return formatter.format({
5069                marker: marker,
5070                timeZoneOffset: dateOptions.forcedTzo != null ?
5071                    dateOptions.forcedTzo :
5072                    this.offsetForMarker(marker)
5073            }, this);
5074        };
5075        DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) {
5076            if (dateOptions === void 0) { dateOptions = {}; }
5077            if (dateOptions.isEndExclusive) {
5078                end = addMs(end, -1);
5079            }
5080            return formatter.formatRange({
5081                marker: start,
5082                timeZoneOffset: dateOptions.forcedStartTzo != null ?
5083                    dateOptions.forcedStartTzo :
5084                    this.offsetForMarker(start)
5085            }, {
5086                marker: end,
5087                timeZoneOffset: dateOptions.forcedEndTzo != null ?
5088                    dateOptions.forcedEndTzo :
5089                    this.offsetForMarker(end)
5090            }, this);
5091        };
5092        DateEnv.prototype.formatIso = function (marker, extraOptions) {
5093            if (extraOptions === void 0) { extraOptions = {}; }
5094            var timeZoneOffset = null;
5095            if (!extraOptions.omitTimeZoneOffset) {
5096                if (extraOptions.forcedTzo != null) {
5097                    timeZoneOffset = extraOptions.forcedTzo;
5098                }
5099                else {
5100                    timeZoneOffset = this.offsetForMarker(marker);
5101                }
5102            }
5103            return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
5104        };
5105        // TimeZone
5106        DateEnv.prototype.timestampToMarker = function (ms) {
5107            if (this.timeZone === 'local') {
5108                return arrayToUtcDate(dateToLocalArray(new Date(ms)));
5109            }
5110            else if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
5111                return new Date(ms);
5112            }
5113            else {
5114                return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
5115            }
5116        };
5117        DateEnv.prototype.offsetForMarker = function (m) {
5118            if (this.timeZone === 'local') {
5119                return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
5120            }
5121            else if (this.timeZone === 'UTC') {
5122                return 0;
5123            }
5124            else if (this.namedTimeZoneImpl) {
5125                return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
5126            }
5127            return null;
5128        };
5129        // Conversion
5130        DateEnv.prototype.toDate = function (m, forcedTzo) {
5131            if (this.timeZone === 'local') {
5132                return arrayToLocalDate(dateToUtcArray(m));
5133            }
5134            else if (this.timeZone === 'UTC') {
5135                return new Date(m.valueOf()); // make sure it's a copy
5136            }
5137            else if (!this.namedTimeZoneImpl) {
5138                return new Date(m.valueOf() - (forcedTzo || 0));
5139            }
5140            else {
5141                return new Date(m.valueOf() -
5142                    this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60 // convert minutes -> ms
5143                );
5144            }
5145        };
5146        return DateEnv;
5147    }());
5148
5149    var SIMPLE_SOURCE_PROPS = {
5150        id: String,
5151        allDayDefault: Boolean,
5152        eventDataTransform: Function,
5153        success: Function,
5154        failure: Function
5155    };
5156    var uid$2 = 0;
5157    function doesSourceNeedRange(eventSource, calendar) {
5158        var defs = calendar.pluginSystem.hooks.eventSourceDefs;
5159        return !defs[eventSource.sourceDefId].ignoreRange;
5160    }
5161    function parseEventSource(raw, calendar) {
5162        var defs = calendar.pluginSystem.hooks.eventSourceDefs;
5163        for (var i = defs.length - 1; i >= 0; i--) { // later-added plugins take precedence
5164            var def = defs[i];
5165            var meta = def.parseMeta(raw);
5166            if (meta) {
5167                var res = parseEventSourceProps(typeof raw === 'object' ? raw : {}, meta, i, calendar);
5168                res._raw = freezeRaw(raw);
5169                return res;
5170            }
5171        }
5172        return null;
5173    }
5174    function parseEventSourceProps(raw, meta, sourceDefId, calendar) {
5175        var leftovers0 = {};
5176        var props = refineProps(raw, SIMPLE_SOURCE_PROPS, {}, leftovers0);
5177        var leftovers1 = {};
5178        var ui = processUnscopedUiProps(leftovers0, calendar, leftovers1);
5179        props.isFetching = false;
5180        props.latestFetchId = '';
5181        props.fetchRange = null;
5182        props.publicId = String(raw.id || '');
5183        props.sourceId = String(uid$2++);
5184        props.sourceDefId = sourceDefId;
5185        props.meta = meta;
5186        props.ui = ui;
5187        props.extendedProps = leftovers1;
5188        return props;
5189    }
5190
5191    function reduceEventSources (eventSources, action, dateProfile, calendar) {
5192        switch (action.type) {
5193            case 'ADD_EVENT_SOURCES': // already parsed
5194                return addSources(eventSources, action.sources, dateProfile ? dateProfile.activeRange : null, calendar);
5195            case 'REMOVE_EVENT_SOURCE':
5196                return removeSource(eventSources, action.sourceId);
5197            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
5198            case 'NEXT':
5199            case 'SET_DATE':
5200            case 'SET_VIEW_TYPE':
5201                if (dateProfile) {
5202                    return fetchDirtySources(eventSources, dateProfile.activeRange, calendar);
5203                }
5204                else {
5205                    return eventSources;
5206                }
5207            case 'FETCH_EVENT_SOURCES':
5208            case 'CHANGE_TIMEZONE':
5209                return fetchSourcesByIds(eventSources, action.sourceIds ?
5210                    arrayToHash(action.sourceIds) :
5211                    excludeStaticSources(eventSources, calendar), dateProfile ? dateProfile.activeRange : null, calendar);
5212            case 'RECEIVE_EVENTS':
5213            case 'RECEIVE_EVENT_ERROR':
5214                return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
5215            case 'REMOVE_ALL_EVENT_SOURCES':
5216                return {};
5217            default:
5218                return eventSources;
5219        }
5220    }
5221    var uid$3 = 0;
5222    function addSources(eventSourceHash, sources, fetchRange, calendar) {
5223        var hash = {};
5224        for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
5225            var source = sources_1[_i];
5226            hash[source.sourceId] = source;
5227        }
5228        if (fetchRange) {
5229            hash = fetchDirtySources(hash, fetchRange, calendar);
5230        }
5231        return __assign({}, eventSourceHash, hash);
5232    }
5233    function removeSource(eventSourceHash, sourceId) {
5234        return filterHash(eventSourceHash, function (eventSource) {
5235            return eventSource.sourceId !== sourceId;
5236        });
5237    }
5238    function fetchDirtySources(sourceHash, fetchRange, calendar) {
5239        return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) {
5240            return isSourceDirty(eventSource, fetchRange, calendar);
5241        }), fetchRange, calendar);
5242    }
5243    function isSourceDirty(eventSource, fetchRange, calendar) {
5244        if (!doesSourceNeedRange(eventSource, calendar)) {
5245            return !eventSource.latestFetchId;
5246        }
5247        else {
5248            return !calendar.opt('lazyFetching') ||
5249                !eventSource.fetchRange ||
5250                fetchRange.start < eventSource.fetchRange.start ||
5251                fetchRange.end > eventSource.fetchRange.end;
5252        }
5253    }
5254    function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, calendar) {
5255        var nextSources = {};
5256        for (var sourceId in prevSources) {
5257            var source = prevSources[sourceId];
5258            if (sourceIdHash[sourceId]) {
5259                nextSources[sourceId] = fetchSource(source, fetchRange, calendar);
5260            }
5261            else {
5262                nextSources[sourceId] = source;
5263            }
5264        }
5265        return nextSources;
5266    }
5267    function fetchSource(eventSource, fetchRange, calendar) {
5268        var sourceDef = calendar.pluginSystem.hooks.eventSourceDefs[eventSource.sourceDefId];
5269        var fetchId = String(uid$3++);
5270        sourceDef.fetch({
5271            eventSource: eventSource,
5272            calendar: calendar,
5273            range: fetchRange
5274        }, function (res) {
5275            var rawEvents = res.rawEvents;
5276            var calSuccess = calendar.opt('eventSourceSuccess');
5277            var calSuccessRes;
5278            var sourceSuccessRes;
5279            if (eventSource.success) {
5280                sourceSuccessRes = eventSource.success(rawEvents, res.xhr);
5281            }
5282            if (calSuccess) {
5283                calSuccessRes = calSuccess(rawEvents, res.xhr);
5284            }
5285            rawEvents = sourceSuccessRes || calSuccessRes || rawEvents;
5286            calendar.dispatch({
5287                type: 'RECEIVE_EVENTS',
5288                sourceId: eventSource.sourceId,
5289                fetchId: fetchId,
5290                fetchRange: fetchRange,
5291                rawEvents: rawEvents
5292            });
5293        }, function (error) {
5294            var callFailure = calendar.opt('eventSourceFailure');
5295            console.warn(error.message, error);
5296            if (eventSource.failure) {
5297                eventSource.failure(error);
5298            }
5299            if (callFailure) {
5300                callFailure(error);
5301            }
5302            calendar.dispatch({
5303                type: 'RECEIVE_EVENT_ERROR',
5304                sourceId: eventSource.sourceId,
5305                fetchId: fetchId,
5306                fetchRange: fetchRange,
5307                error: error
5308            });
5309        });
5310        return __assign({}, eventSource, { isFetching: true, latestFetchId: fetchId });
5311    }
5312    function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
5313        var _a;
5314        var eventSource = sourceHash[sourceId];
5315        if (eventSource && // not already removed
5316            fetchId === eventSource.latestFetchId) {
5317            return __assign({}, sourceHash, (_a = {}, _a[sourceId] = __assign({}, eventSource, { isFetching: false, fetchRange: fetchRange }), _a));
5318        }
5319        return sourceHash;
5320    }
5321    function excludeStaticSources(eventSources, calendar) {
5322        return filterHash(eventSources, function (eventSource) {
5323            return doesSourceNeedRange(eventSource, calendar);
5324        });
5325    }
5326
5327    var DateProfileGenerator = /** @class */ (function () {
5328        function DateProfileGenerator(viewSpec, calendar) {
5329            this.viewSpec = viewSpec;
5330            this.options = viewSpec.options;
5331            this.dateEnv = calendar.dateEnv;
5332            this.calendar = calendar;
5333            this.initHiddenDays();
5334        }
5335        /* Date Range Computation
5336        ------------------------------------------------------------------------------------------------------------------*/
5337        // Builds a structure with info about what the dates/ranges will be for the "prev" view.
5338        DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate) {
5339            var dateEnv = this.dateEnv;
5340            var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5341            currentDateProfile.dateIncrement);
5342            return this.build(prevDate, -1);
5343        };
5344        // Builds a structure with info about what the dates/ranges will be for the "next" view.
5345        DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate) {
5346            var dateEnv = this.dateEnv;
5347            var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5348            currentDateProfile.dateIncrement);
5349            return this.build(nextDate, 1);
5350        };
5351        // Builds a structure holding dates/ranges for rendering around the given date.
5352        // Optional direction param indicates whether the date is being incremented/decremented
5353        // from its previous value. decremented = -1, incremented = 1 (default).
5354        DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) {
5355            if (forceToValid === void 0) { forceToValid = false; }
5356            var validRange;
5357            var minTime = null;
5358            var maxTime = null;
5359            var currentInfo;
5360            var isRangeAllDay;
5361            var renderRange;
5362            var activeRange;
5363            var isValid;
5364            validRange = this.buildValidRange();
5365            validRange = this.trimHiddenDays(validRange);
5366            if (forceToValid) {
5367                currentDate = constrainMarkerToRange(currentDate, validRange);
5368            }
5369            currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
5370            isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
5371            renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
5372            renderRange = this.trimHiddenDays(renderRange);
5373            activeRange = renderRange;
5374            if (!this.options.showNonCurrentDates) {
5375                activeRange = intersectRanges(activeRange, currentInfo.range);
5376            }
5377            minTime = createDuration(this.options.minTime);
5378            maxTime = createDuration(this.options.maxTime);
5379            activeRange = this.adjustActiveRange(activeRange, minTime, maxTime);
5380            activeRange = intersectRanges(activeRange, validRange); // might return null
5381            // it's invalid if the originally requested date is not contained,
5382            // or if the range is completely outside of the valid range.
5383            isValid = rangesIntersect(currentInfo.range, validRange);
5384            return {
5385                // constraint for where prev/next operations can go and where events can be dragged/resized to.
5386                // an object with optional start and end properties.
5387                validRange: validRange,
5388                // range the view is formally responsible for.
5389                // for example, a month view might have 1st-31st, excluding padded dates
5390                currentRange: currentInfo.range,
5391                // name of largest unit being displayed, like "month" or "week"
5392                currentRangeUnit: currentInfo.unit,
5393                isRangeAllDay: isRangeAllDay,
5394                // dates that display events and accept drag-n-drop
5395                // will be `null` if no dates accept events
5396                activeRange: activeRange,
5397                // date range with a rendered skeleton
5398                // includes not-active days that need some sort of DOM
5399                renderRange: renderRange,
5400                // Duration object that denotes the first visible time of any given day
5401                minTime: minTime,
5402                // Duration object that denotes the exclusive visible end time of any given day
5403                maxTime: maxTime,
5404                isValid: isValid,
5405                // how far the current date will move for a prev/next operation
5406                dateIncrement: this.buildDateIncrement(currentInfo.duration)
5407                // pass a fallback (might be null) ^
5408            };
5409        };
5410        // Builds an object with optional start/end properties.
5411        // Indicates the minimum/maximum dates to display.
5412        // not responsible for trimming hidden days.
5413        DateProfileGenerator.prototype.buildValidRange = function () {
5414            return this.getRangeOption('validRange', this.calendar.getNow()) ||
5415                { start: null, end: null }; // completely open-ended
5416        };
5417        // Builds a structure with info about the "current" range, the range that is
5418        // highlighted as being the current month for example.
5419        // See build() for a description of `direction`.
5420        // Guaranteed to have `range` and `unit` properties. `duration` is optional.
5421        DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
5422            var _a = this, viewSpec = _a.viewSpec, dateEnv = _a.dateEnv;
5423            var duration = null;
5424            var unit = null;
5425            var range = null;
5426            var dayCount;
5427            if (viewSpec.duration) {
5428                duration = viewSpec.duration;
5429                unit = viewSpec.durationUnit;
5430                range = this.buildRangeFromDuration(date, direction, duration, unit);
5431            }
5432            else if ((dayCount = this.options.dayCount)) {
5433                unit = 'day';
5434                range = this.buildRangeFromDayCount(date, direction, dayCount);
5435            }
5436            else if ((range = this.buildCustomVisibleRange(date))) {
5437                unit = dateEnv.greatestWholeUnit(range.start, range.end).unit;
5438            }
5439            else {
5440                duration = this.getFallbackDuration();
5441                unit = greatestDurationDenominator(duration).unit;
5442                range = this.buildRangeFromDuration(date, direction, duration, unit);
5443            }
5444            return { duration: duration, unit: unit, range: range };
5445        };
5446        DateProfileGenerator.prototype.getFallbackDuration = function () {
5447            return createDuration({ day: 1 });
5448        };
5449        // Returns a new activeRange to have time values (un-ambiguate)
5450        // minTime or maxTime causes the range to expand.
5451        DateProfileGenerator.prototype.adjustActiveRange = function (range, minTime, maxTime) {
5452            var dateEnv = this.dateEnv;
5453            var start = range.start;
5454            var end = range.end;
5455            if (this.viewSpec.class.prototype.usesMinMaxTime) {
5456                // expand active range if minTime is negative (why not when positive?)
5457                if (asRoughDays(minTime) < 0) {
5458                    start = startOfDay(start); // necessary?
5459                    start = dateEnv.add(start, minTime);
5460                }
5461                // expand active range if maxTime is beyond one day (why not when positive?)
5462                if (asRoughDays(maxTime) > 1) {
5463                    end = startOfDay(end); // necessary?
5464                    end = addDays(end, -1);
5465                    end = dateEnv.add(end, maxTime);
5466                }
5467            }
5468            return { start: start, end: end };
5469        };
5470        // Builds the "current" range when it is specified as an explicit duration.
5471        // `unit` is the already-computed greatestDurationDenominator unit of duration.
5472        DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
5473            var dateEnv = this.dateEnv;
5474            var alignment = this.options.dateAlignment;
5475            var dateIncrementInput;
5476            var dateIncrementDuration;
5477            var start;
5478            var end;
5479            var res;
5480            // compute what the alignment should be
5481            if (!alignment) {
5482                dateIncrementInput = this.options.dateIncrement;
5483                if (dateIncrementInput) {
5484                    dateIncrementDuration = createDuration(dateIncrementInput);
5485                    // use the smaller of the two units
5486                    if (asRoughMs(dateIncrementDuration) < asRoughMs(duration)) {
5487                        alignment = greatestDurationDenominator(dateIncrementDuration, !getWeeksFromInput(dateIncrementInput)).unit;
5488                    }
5489                    else {
5490                        alignment = unit;
5491                    }
5492                }
5493                else {
5494                    alignment = unit;
5495                }
5496            }
5497            // if the view displays a single day or smaller
5498            if (asRoughDays(duration) <= 1) {
5499                if (this.isHiddenDay(start)) {
5500                    start = this.skipHiddenDays(start, direction);
5501                    start = startOfDay(start);
5502                }
5503            }
5504            function computeRes() {
5505                start = dateEnv.startOf(date, alignment);
5506                end = dateEnv.add(start, duration);
5507                res = { start: start, end: end };
5508            }
5509            computeRes();
5510            // if range is completely enveloped by hidden days, go past the hidden days
5511            if (!this.trimHiddenDays(res)) {
5512                date = this.skipHiddenDays(date, direction);
5513                computeRes();
5514            }
5515            return res;
5516        };
5517        // Builds the "current" range when a dayCount is specified.
5518        DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
5519            var dateEnv = this.dateEnv;
5520            var customAlignment = this.options.dateAlignment;
5521            var runningCount = 0;
5522            var start = date;
5523            var end;
5524            if (customAlignment) {
5525                start = dateEnv.startOf(start, customAlignment);
5526            }
5527            start = startOfDay(start);
5528            start = this.skipHiddenDays(start, direction);
5529            end = start;
5530            do {
5531                end = addDays(end, 1);
5532                if (!this.isHiddenDay(end)) {
5533                    runningCount++;
5534                }
5535            } while (runningCount < dayCount);
5536            return { start: start, end: end };
5537        };
5538        // Builds a normalized range object for the "visible" range,
5539        // which is a way to define the currentRange and activeRange at the same time.
5540        DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
5541            var dateEnv = this.dateEnv;
5542            var visibleRange = this.getRangeOption('visibleRange', dateEnv.toDate(date));
5543            if (visibleRange && (visibleRange.start == null || visibleRange.end == null)) {
5544                return null;
5545            }
5546            return visibleRange;
5547        };
5548        // Computes the range that will represent the element/cells for *rendering*,
5549        // but which may have voided days/times.
5550        // not responsible for trimming hidden days.
5551        DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
5552            return currentRange;
5553        };
5554        // Compute the duration value that should be added/substracted to the current date
5555        // when a prev/next operation happens.
5556        DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
5557            var dateIncrementInput = this.options.dateIncrement;
5558            var customAlignment;
5559            if (dateIncrementInput) {
5560                return createDuration(dateIncrementInput);
5561            }
5562            else if ((customAlignment = this.options.dateAlignment)) {
5563                return createDuration(1, customAlignment);
5564            }
5565            else if (fallback) {
5566                return fallback;
5567            }
5568            else {
5569                return createDuration({ days: 1 });
5570            }
5571        };
5572        // Arguments after name will be forwarded to a hypothetical function value
5573        // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects.
5574        // Always clone your objects if you fear mutation.
5575        DateProfileGenerator.prototype.getRangeOption = function (name) {
5576            var otherArgs = [];
5577            for (var _i = 1; _i < arguments.length; _i++) {
5578                otherArgs[_i - 1] = arguments[_i];
5579            }
5580            var val = this.options[name];
5581            if (typeof val === 'function') {
5582                val = val.apply(null, otherArgs);
5583            }
5584            if (val) {
5585                val = parseRange(val, this.dateEnv);
5586            }
5587            if (val) {
5588                val = computeVisibleDayRange(val);
5589            }
5590            return val;
5591        };
5592        /* Hidden Days
5593        ------------------------------------------------------------------------------------------------------------------*/
5594        // Initializes internal variables related to calculating hidden days-of-week
5595        DateProfileGenerator.prototype.initHiddenDays = function () {
5596            var hiddenDays = this.options.hiddenDays || []; // array of day-of-week indices that are hidden
5597            var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
5598            var dayCnt = 0;
5599            var i;
5600            if (this.options.weekends === false) {
5601                hiddenDays.push(0, 6); // 0=sunday, 6=saturday
5602            }
5603            for (i = 0; i < 7; i++) {
5604                if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
5605                    dayCnt++;
5606                }
5607            }
5608            if (!dayCnt) {
5609                throw new Error('invalid hiddenDays'); // all days were hidden? bad.
5610            }
5611            this.isHiddenDayHash = isHiddenDayHash;
5612        };
5613        // Remove days from the beginning and end of the range that are computed as hidden.
5614        // If the whole range is trimmed off, returns null
5615        DateProfileGenerator.prototype.trimHiddenDays = function (range) {
5616            var start = range.start;
5617            var end = range.end;
5618            if (start) {
5619                start = this.skipHiddenDays(start);
5620            }
5621            if (end) {
5622                end = this.skipHiddenDays(end, -1, true);
5623            }
5624            if (start == null || end == null || start < end) {
5625                return { start: start, end: end };
5626            }
5627            return null;
5628        };
5629        // Is the current day hidden?
5630        // `day` is a day-of-week index (0-6), or a Date (used for UTC)
5631        DateProfileGenerator.prototype.isHiddenDay = function (day) {
5632            if (day instanceof Date) {
5633                day = day.getUTCDay();
5634            }
5635            return this.isHiddenDayHash[day];
5636        };
5637        // Incrementing the current day until it is no longer a hidden day, returning a copy.
5638        // DOES NOT CONSIDER validRange!
5639        // If the initial value of `date` is not a hidden day, don't do anything.
5640        // Pass `isExclusive` as `true` if you are dealing with an end date.
5641        // `inc` defaults to `1` (increment one day forward each time)
5642        DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) {
5643            if (inc === void 0) { inc = 1; }
5644            if (isExclusive === void 0) { isExclusive = false; }
5645            while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
5646                date = addDays(date, inc);
5647            }
5648            return date;
5649        };
5650        return DateProfileGenerator;
5651    }());
5652    // TODO: find a way to avoid comparing DateProfiles. it's tedious
5653    function isDateProfilesEqual(p0, p1) {
5654        return rangesEqual(p0.activeRange, p1.activeRange) &&
5655            rangesEqual(p0.validRange, p1.validRange) &&
5656            durationsEqual(p0.minTime, p1.minTime) &&
5657            durationsEqual(p0.maxTime, p1.maxTime);
5658    }
5659
5660    function reduce (state, action, calendar) {
5661        var viewType = reduceViewType(state.viewType, action);
5662        var dateProfile = reduceDateProfile(state.dateProfile, action, state.currentDate, viewType, calendar);
5663        var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendar);
5664        var nextState = __assign({}, state, { viewType: viewType,
5665            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) });
5666        for (var _i = 0, _a = calendar.pluginSystem.hooks.reducers; _i < _a.length; _i++) {
5667            var reducerFunc = _a[_i];
5668            nextState = reducerFunc(nextState, action, calendar);
5669        }
5670        // console.log(action.type, nextState)
5671        return nextState;
5672    }
5673    function reduceViewType(currentViewType, action) {
5674        switch (action.type) {
5675            case 'SET_VIEW_TYPE':
5676                return action.viewType;
5677            default:
5678                return currentViewType;
5679        }
5680    }
5681    function reduceDateProfile(currentDateProfile, action, currentDate, viewType, calendar) {
5682        var newDateProfile;
5683        switch (action.type) {
5684            case 'PREV':
5685                newDateProfile = calendar.dateProfileGenerators[viewType].buildPrev(currentDateProfile, currentDate);
5686                break;
5687            case 'NEXT':
5688                newDateProfile = calendar.dateProfileGenerators[viewType].buildNext(currentDateProfile, currentDate);
5689                break;
5690            case 'SET_DATE':
5691                if (!currentDateProfile.activeRange ||
5692                    !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker)) {
5693                    newDateProfile = calendar.dateProfileGenerators[viewType].build(action.dateMarker, undefined, true // forceToValid
5694                    );
5695                }
5696                break;
5697            case 'SET_VIEW_TYPE':
5698                var generator = calendar.dateProfileGenerators[viewType];
5699                if (!generator) {
5700                    throw new Error(viewType ?
5701                        'The FullCalendar view "' + viewType + '" does not exist. Make sure your plugins are loaded correctly.' :
5702                        'No available FullCalendar view plugins.');
5703                }
5704                newDateProfile = generator.build(action.dateMarker || currentDate, undefined, true // forceToValid
5705                );
5706                break;
5707        }
5708        if (newDateProfile &&
5709            newDateProfile.isValid &&
5710            !(currentDateProfile && isDateProfilesEqual(currentDateProfile, newDateProfile))) {
5711            return newDateProfile;
5712        }
5713        else {
5714            return currentDateProfile;
5715        }
5716    }
5717    function reduceCurrentDate(currentDate, action, dateProfile) {
5718        switch (action.type) {
5719            case 'PREV':
5720            case 'NEXT':
5721                if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) {
5722                    return dateProfile.currentRange.start;
5723                }
5724                else {
5725                    return currentDate;
5726                }
5727            case 'SET_DATE':
5728            case 'SET_VIEW_TYPE':
5729                var newDate = action.dateMarker || currentDate;
5730                if (dateProfile.activeRange && !rangeContainsMarker(dateProfile.activeRange, newD
5730ate)) {
5731                    return dateProfile.currentRange.start;
5732                }
5733                else {
5734                    return newDate;
5735                }
5736            default:
5737                return currentDate;
5738        }
5739    }
5740    function reduceDateSelection(currentSelection, action, calendar) {
5741        switch (action.type) {
5742            case 'SELECT_DATES':
5743                return action.selection;
5744            case 'UNSELECT_DATES':
5745                return null;
5746            default:
5747                return currentSelection;
5748        }
5749    }
5750    function reduceSelectedEvent(currentInstanceId, action) {
5751        switch (action.type) {
5752            case 'SELECT_EVENT':
5753                return action.eventInstanceId;
5754            case 'UNSELECT_EVENT':
5755                return '';
5756            default:
5757                return currentInstanceId;
5758        }
5759    }
5760    function reduceEventDrag(currentDrag, action, sources, calendar) {
5761        switch (action.type) {
5762            case 'SET_EVENT_DRAG':
5763                var newDrag = action.state;
5764                return {
5765                    affectedEvents: newDrag.affectedEvents,
5766                    mutatedEvents: newDrag.mutatedEvents,
5767                    isEvent: newDrag.isEvent,
5768                    origSeg: newDrag.origSeg
5769                };
5770            case 'UNSET_EVENT_DRAG':
5771                return null;
5772            default:
5773                return currentDrag;
5774        }
5775    }
5776    function reduceEventResize(currentResize, action, sources, calendar) {
5777        switch (action.type) {
5778            case 'SET_EVENT_RESIZE':
5779                var newResize = action.state;
5780                return {
5781                    affectedEvents: newResize.affectedEvents,
5782                    mutatedEvents: newResize.mutatedEvents,
5783                    isEvent: newResize.isEvent,
5784                    origSeg: newResize.origSeg
5785                };
5786            case 'UNSET_EVENT_RESIZE':
5787                return null;
5788            default:
5789                return currentResize;
5790        }
5791    }
5792    function computeLoadingLevel(eventSources) {
5793        var cnt = 0;
5794        for (var sourceId in eventSources) {
5795            if (eventSources[sourceId].isFetching) {
5796                cnt++;
5797            }
5798        }
5799        return cnt;
5800    }
5801
5802    var STANDARD_PROPS = {
5803        start: null,
5804        end: null,
5805        allDay: Boolean
5806    };
5807    function parseDateSpan(raw, dateEnv, defaultDuration) {
5808        var span = parseOpenDateSpan(raw, dateEnv);
5809        var range = span.range;
5810        if (!range.start) {
5811            return null;
5812        }
5813        if (!range.end) {
5814            if (defaultDuration == null) {
5815                return null;
5816            }
5817            else {
5818                range.end = dateEnv.add(range.start, defaultDuration);
5819            }
5820        }
5821        return span;
5822    }
5823    /*
5824    TODO: somehow combine with parseRange?
5825    Will return null if the start/end props were present but parsed invalidly.
5826    */
5827    function parseOpenDateSpan(raw, dateEnv) {
5828        var leftovers = {};
5829        var standardProps = refineProps(raw, STANDARD_PROPS, {}, leftovers);
5830        var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
5831        var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
5832        var allDay = standardProps.allDay;
5833        if (allDay == null) {
5834            allDay = (startMeta && startMeta.isTimeUnspecified) &&
5835                (!endMeta || endMeta.isTimeUnspecified);
5836        }
5837        // use this leftover object as the selection object
5838        leftovers.range = {
5839            start: startMeta ? startMeta.marker : null,
5840            end: endMeta ? endMeta.marker : null
5841        };
5842        leftovers.allDay = allDay;
5843        return leftovers;
5844    }
5845    function isDateSpansEqual(span0, span1) {
5846        return rangesEqual(span0.range, span1.range) &&
5847            span0.allDay === span1.allDay &&
5848            isSpanPropsEqual(span0, span1);
5849    }
5850    // the NON-DATE-RELATED props
5851    function isSpanPropsEqual(span0, span1) {
5852        for (var propName in span1) {
5853            if (propName !== 'range' && propName !== 'allDay') {
5854                if (span0[propName] !== span1[propName]) {
5855                    return false;
5856                }
5857            }
5858        }
5859        // are there any props that span0 has that span1 DOESN'T have?
5860        // both have range/allDay, so no need to special-case.
5861        for (var propName in span0) {
5862            if (!(propName in span1)) {
5863                return false;
5864            }
5865        }
5866        return true;
5867    }
5868    function buildDateSpanApi(span, dateEnv) {
5869        return {
5870            start: dateEnv.toDate(span.range.start),
5871            end: dateEnv.toDate(span.range.end),
5872            startStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
5873            endStr: dateEnv.formatIso(span.range.end, { omitTime: span.allDay }),
5874            allDay: span.allDay
5875        };
5876    }
5877    function buildDatePointApi(span, dateEnv) {
5878        return {
5879            date: dateEnv.toDate(span.range.start),
5880            dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
5881            allDay: span.allDay
5882        };
5883    }
5884    function fabricateEventRange(dateSpan, eventUiBases, calendar) {
5885        var def = parseEventDef({ editable: false }, '', // sourceId
5886        dateSpan.allDay, true, // hasEnd
5887        calendar);
5888        return {
5889            def: def,
5890            ui: compileEventUi(def, eventUiBases),
5891            instance: createEventInstance(def.defId, dateSpan.range),
5892            range: dateSpan.range,
5893            isStart: true,
5894            isEnd: true
5895        };
5896    }
5897
5898    function compileViewDefs(defaultConfigs, overrideConfigs) {
5899        var hash = {};
5900        var viewType;
5901        for (viewType in defaultConfigs) {
5902            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5903        }
5904        for (viewType in overrideConfigs) {
5905            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5906        }
5907        return hash;
5908    }
5909    function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5910        if (hash[viewType]) {
5911            return hash[viewType];
5912        }
5913        var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5914        if (viewDef) {
5915            hash[viewType] = viewDef;
5916        }
5917        return viewDef;
5918    }
5919    function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5920        var defaultConfig = defaultConfigs[viewType];
5921        var overrideConfig = overrideConfigs[viewType];
5922        var queryProp = function (name) {
5923            return (defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
5924                ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null);
5925        };
5926        var theClass = queryProp('class');
5927        var superType = queryProp('superType');
5928        if (!superType && theClass) {
5929            superType =
5930                findViewNameBySubclass(theClass, overrideConfigs) ||
5931                    findViewNameBySubclass(theClass, defaultConfigs);
5932        }
5933        var superDef = superType ? ensureViewDef(superType, hash, defaultConfigs, overrideConfigs) : null;
5934        if (!theClass && superDef) {
5935            theClass = superDef.class;
5936        }
5937        if (!theClass) {
5938            return null; // don't throw a warning, might be settings for a single-unit view
5939        }
5940        return {
5941            type: viewType,
5942            class: theClass,
5943            defaults: __assign({}, (superDef ? superDef.defaults : {}), (defaultConfig ? defaultConfig.options : {})),
5944            overrides: __assign({}, (superDef ? superDef.overrides : {}), (overrideConfig ? overrideConfig.options : {}))
5945        };
5946    }
5947    function findViewNameBySubclass(viewSubclass, configs) {
5948        var superProto = Object.getPrototypeOf(viewSubclass.prototype);
5949        for (var viewType in configs) {
5950            var parsed = configs[viewType];
5951            // need DIRECT subclass, so instanceof won't do it
5952            if (parsed.class && parsed.class.prototype === superProto) {
5953                return viewType;
5954            }
5955        }
5956        return '';
5957    }
5958
5959    function parseViewConfigs(inputs) {
5960        return mapHash(inputs, parseViewConfig);
5961    }
5962    var VIEW_DEF_PROPS = {
5963        type: String,
5964        class: null
5965    };
5966    function parseViewConfig(input) {
5967        if (typeof input === 'function') {
5968            input = { class: input };
5969        }
5970        var options = {};
5971        var props = refineProps(input, VIEW_DEF_PROPS, {}, options);
5972        return {
5973            superType: props.type,
5974            class: props.class,
5975            options: options
5976        };
5977    }
5978
5979    function buildViewSpecs(defaultInputs, optionsManager) {
5980        var defaultConfigs = parseViewConfigs(defaultInputs);
5981        var overrideConfigs = parseViewConfigs(optionsManager.overrides.views);
5982        var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
5983        return mapHash(viewDefs, function (viewDef) {
5984            return buildViewSpec(viewDef, overrideConfigs, optionsManager);
5985        });
5986    }
5987    function buildViewSpec(viewDef, overrideConfigs, optionsManager) {
5988        var durationInput = viewDef.overrides.duration ||
5989            viewDef.defaults.duration ||
5990            optionsManager.dynamicOverrides.duration ||
5991            optionsManager.overrides.duration;
5992        var duration = null;
5993        var durationUnit = '';
5994        var singleUnit = '';
5995        var singleUnitOverrides = {};
5996        if (durationInput) {
5997            duration = createDuration(durationInput);
5998            if (duration) { // valid?
5999                var denom = greatestDurationDenominator(duration, !getWeeksFromInput(durationInput));
6000                durationUnit = denom.unit;
6001                if (denom.value === 1) {
6002                    singleUnit = durationUnit;
6003                    singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].options : {};
6004                }
6005            }
6006        }
6007        var queryButtonText = function (options) {
6008            var buttonTextMap = options.buttonText || {};
6009            var buttonTextKey = viewDef.defaults.buttonTextKey;
6010            if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
6011                return buttonTextMap[buttonTextKey];
6012            }
6013            if (buttonTextMap[viewDef.type] != null) {
6014                return buttonTextMap[viewDef.type];
6015            }
6016            if (buttonTextMap[singleUnit] != null) {
6017                return buttonTextMap[singleUnit];
6018            }
6019        };
6020        return {
6021            type: viewDef.type,
6022            class: viewDef.class,
6023            duration: duration,
6024            durationUnit: durationUnit,
6025            singleUnit: singleUnit,
6026            options: __assign({}, globalDefaults, viewDef.defaults, optionsManager.dirDefaults, optionsManager.localeDefaults, optionsManager.overrides, singleUnitOverrides, viewDef.overrides, optionsManager.dynamicOverrides),
6027            buttonTextOverride: queryButtonText(optionsManager.dynamicOverrides) ||
6028                queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence
6029                viewDef.overrides.buttonText,
6030            buttonTextDefault: queryButtonText(optionsManager.localeDefaults) ||
6031                queryButtonText(optionsManager.dirDefaults) ||
6032                viewDef.defaults.buttonText ||
6033                queryButtonText(globalDefaults) ||
6034                viewDef.type // fall back to given view name
6035        };
6036    }
6037
6038    var Toolbar = /** @class */ (function (_super) {
6039        __extends(Toolbar, _super);
6040        function Toolbar(context, extraClassName) {
6041            var _this = _super.call(this, context) || this;
6042            _this._renderLayout = memoizeRendering(_this.renderLayout, _this.unrenderLayout);
6043            _this._updateTitle = memoizeRendering(_this.updateTitle, null, [_this._renderLayout]);
6044            _this._updateActiveButton = memoizeRendering(_this.updateActiveButton, null, [_this._renderLayout]);
6045            _this._updateToday = memoizeRendering(_this.updateToday, null, [_this._renderLayout]);
6046            _this._updatePrev = memoizeRendering(_this.updatePrev, null, [_this._renderLayout]);
6047            _this._updateNext = memoizeRendering(_this.updateNext, null, [_this._renderLayout]);
6048            _this.el = createElement('div', { className: 'fc-toolbar ' + extraClassName });
6049            return _this;
6050        }
6051        Toolbar.prototype.destroy = function () {
6052            _super.prototype.destroy.call(this);
6053            this._renderLayout.unrender(); // should unrender everything else
6054            removeElement(this.el);
6055        };
6056        Toolbar.prototype.render = function (props) {
6057            this._renderLayout(props.layout);
6058            this._updateTitle(props.title);
6059            this._updateActiveButton(props.activeButton);
6060            this._updateToday(props.isTodayEnabled);
6061            this._updatePrev(props.isPrevEnabled);
6062            this._updateNext(props.isNextEnabled);
6063        };
6064        Toolbar.prototype.renderLayout = function (layout) {
6065            var el = this.el;
6066            this.viewsWithButtons = [];
6067            appendToElement(el, this.renderSection('left', layout.left));
6068            appendToElement(el, this.renderSection('center', layout.center));
6069            appendToElement(el, this.renderSection('right', layout.right));
6070        };
6071        Toolbar.prototype.unrenderLayout = function () {
6072            this.el.innerHTML = '';
6073        };
6074        Toolbar.prototype.renderSection = function (position, buttonStr) {
6075            var _this = this;
6076            var _a = this, theme = _a.theme, calendar = _a.calendar;
6077            var optionsManager = calendar.optionsManager;
6078            var viewSpecs = calendar.viewSpecs;
6079            var sectionEl = createElement('div', { className: 'fc-' + position });
6080            var calendarCustomButtons = optionsManager.computed.customButtons || {};
6081            var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {};
6082            var calendarButtonText = optionsManager.computed.buttonText || {};
6083            if (buttonStr) {
6084                buttonStr.split(' ').forEach(function (buttonGroupStr, i) {
6085                    var groupChildren = [];
6086                    var isOnlyButtons = true;
6087                    var groupEl;
6088                    buttonGroupStr.split(',').forEach(function (buttonName, j) {
6089                        var customButtonProps;
6090                        var viewSpec;
6091                        var buttonClick;
6092                        var buttonIcon; // only one of these will be set
6093                        var buttonText; // "
6094                        var buttonInnerHtml;
6095                        var buttonClasses;
6096                        var buttonEl;
6097                        var buttonAriaAttr;
6098                        if (buttonName === 'title') {
6099                            groupChildren.push(htmlToElement('<h2>&nbsp;</h2>')); // we always want it to take up height
6100                            isOnlyButtons = false;
6101                        }
6102                        else {
6103                            if ((customButtonProps = calendarCustomButtons[buttonName])) {
6104                                buttonClick = function (ev) {
6105                                    if (customButtonProps.click) {
6106                                        customButtonProps.click.call(buttonEl, ev);
6107                                    }
6108                                };
6109                                (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
6110                                    (buttonIcon = theme.getIconClass(buttonName)) ||
6111                                    (buttonText = customButtonProps.text);
6112                            }
6113                            else if ((viewSpec = viewSpecs[buttonName])) {
6114                                _this.viewsWithButtons.push(buttonName);
6115                                buttonClick = function () {
6116                                    calendar.changeView(buttonName);
6117                                };
6118                                (buttonText = viewSpec.buttonTextOverride) ||
6119                                    (buttonIcon = theme.getIconClass(buttonName)) ||
6120                                    (buttonText = viewSpec.buttonTextDefault);
6121                            }
6122                            else if (calendar[buttonName]) { // a calendar method
6123                                buttonClick = function () {
6124                                    calendar[buttonName]();
6125                                };
6126                                (buttonText = calendarButtonTextOverrides[buttonName]) ||
6127                                    (buttonIcon = theme.getIconClass(buttonName)) ||
6128                                    (buttonText = calendarButtonText[buttonName]);
6129                                //            ^ everything else is considered default
6130                            }
6131                            if (buttonClick) {
6132                                buttonClasses = [
6133                                    'fc-' + buttonName + '-button',
6134                                    theme.getClass('button')
6135                                ];
6136                                if (buttonText) {
6137                                    buttonInnerHtml = htmlEscape(buttonText);
6138                                    buttonAriaAttr = '';
6139                                }
6140                                else if (buttonIcon) {
6141                                    buttonInnerHtml = "<span class='" + buttonIcon + "'></span>";
6142                                    buttonAriaAttr = ' aria-label="' + buttonName + '"';
6143                                }
6144                                buttonEl = htmlToElement(// type="button" so that it doesn't submit a form
6145                                '<button type="button" class="' + buttonClasses.join(' ') + '"' +
6146                                    buttonAriaAttr +
6147                                    '>' + buttonInnerHtml + '</button>');
6148                                buttonEl.addEventListener('click', buttonClick);
6149                                groupChildren.push(buttonEl);
6150                            }
6151                        }
6152                    });
6153                    if (groupChildren.length > 1) {
6154                        groupEl = document.createElement('div');
6155                        var buttonGroupClassName = theme.getClass('buttonGroup');
6156                        if (isOnlyButtons && buttonGroupClassName) {
6157                            groupEl.classList.add(buttonGroupClassName);
6158                        }
6159                        appendToElement(groupEl, groupChildren);
6160                        sectionEl.appendChild(groupEl);
6161                    }
6162                    else {
6163                        appendToElement(sectionEl, groupChildren); // 1 or 0 children
6164                    }
6165                });
6166            }
6167            return sectionEl;
6168        };
6169        Toolbar.prototype.updateToday = function (isTodayEnabled) {
6170            this.toggleButtonEnabled('today', isTodayEnabled);
6171        };
6172        Toolbar.prototype.updatePrev = function (isPrevEnabled) {
6173            this.toggleButtonEnabled('prev', isPrevEnabled);
6174        };
6175        Toolbar.prototype.updateNext = function (isNextEnabled) {
6176            this.toggleButtonEnabled('next', isNextEnabled);
6177        };
6178        Toolbar.prototype.updateTitle = function (text) {
6179            findElements(this.el, 'h2').forEach(function (titleEl) {
6180                titleEl.innerText = text;
6181            });
6182        };
6183        Toolbar.prototype.updateActiveButton = function (buttonName) {
6184            var className = this.theme.getClass('buttonActive');
6185            findElements(this.el, 'button').forEach(function (buttonEl) {
6186                if (buttonName && buttonEl.classList.contains('fc-' 
6186+ buttonName + '-button')) {
6187                    buttonEl.classList.add(className);
6188                }
6189                else {
6190                    buttonEl.classList.remove(className);
6191                }
6192            });
6193        };
6194        Toolbar.prototype.toggleButtonEnabled = function (buttonName, bool) {
6195            findElements(this.el, '.fc-' + buttonName + '-button').forEach(function (buttonEl) {
6196                buttonEl.disabled = !bool;
6197            });
6198        };
6199        return Toolbar;
6200    }(Component));
6201
6202    var CalendarComponent = /** @class */ (function (_super) {
6203        __extends(CalendarComponent, _super);
6204        function CalendarComponent(context, el) {
6205            var _this = _super.call(this, context) || this;
6206            _this._renderToolbars = memoizeRendering(_this.renderToolbars);
6207            _this.buildViewPropTransformers = memoize(buildViewPropTransformers);
6208            _this.el = el;
6209            prependToElement(el, _this.contentEl = createElement('div', { className: 'fc-view-container' }));
6210            var calendar = _this.calendar;
6211            for (var _i = 0, _a = calendar.pluginSystem.hooks.viewContainerModifiers; _i < _a.length; _i++) {
6212                var modifyViewContainer = _a[_i];
6213                modifyViewContainer(_this.contentEl, calendar);
6214            }
6215            _this.toggleElClassNames(true);
6216            _this.computeTitle = memoize(computeTitle);
6217            _this.parseBusinessHours = memoize(function (input) {
6218                return parseBusinessHours(input, _this.calendar);
6219            });
6220            return _this;
6221        }
6222        CalendarComponent.prototype.destroy = function () {
6223            if (this.header) {
6224                this.header.destroy();
6225            }
6226            if (this.footer) {
6227                this.footer.destroy();
6228            }
6229            if (this.view) {
6230                this.view.destroy();
6231            }
6232            removeElement(this.contentEl);
6233            this.toggleElClassNames(false);
6234            _super.prototype.destroy.call(this);
6235        };
6236        CalendarComponent.prototype.toggleElClassNames = function (bool) {
6237            var classList = this.el.classList;
6238            var dirClassName = 'fc-' + this.opt('dir');
6239            var themeClassName = this.theme.getClass('widget');
6240            if (bool) {
6241                classList.add('fc');
6242                classList.add(dirClassName);
6243                classList.add(themeClassName);
6244            }
6245            else {
6246                classList.remove('fc');
6247                classList.remove(dirClassName);
6248                classList.remove(themeClassName);
6249            }
6250        };
6251        CalendarComponent.prototype.render = function (props) {
6252            this.freezeHeight();
6253            var title = this.computeTitle(props.dateProfile, props.viewSpec.options);
6254            this._renderToolbars(props.viewSpec, props.dateProfile, props.currentDate, props.dateProfileGenerator, title);
6255            this.renderView(props, title);
6256            this.updateSize();
6257            this.thawHeight();
6258        };
6259        CalendarComponent.prototype.renderToolbars = function (viewSpec, dateProfile, currentDate, dateProfileGenerator, title) {
6260            var headerLayout = this.opt('header');
6261            var footerLayout = this.opt('footer');
6262            var now = this.calendar.getNow();
6263            var todayInfo = dateProfileGenerator.build(now);
6264            var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate);
6265            var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate);
6266            var toolbarProps = {
6267                title: title,
6268                activeButton: viewSpec.type,
6269                isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now),
6270                isPrevEnabled: prevInfo.isValid,
6271                isNextEnabled: nextInfo.isValid
6272            };
6273            if (headerLayout) {
6274                if (!this.header) {
6275                    this.header = new Toolbar(this.context, 'fc-header-toolbar');
6276                    prependToElement(this.el, this.header.el);
6277                }
6278                this.header.receiveProps(__assign({ layout: headerLayout }, toolbarProps));
6279            }
6280            else if (this.header) {
6281                this.header.destroy();
6282                this.header = null;
6283            }
6284            if (footerLayout) {
6285                if (!this.footer) {
6286                    this.footer = new Toolbar(this.context, 'fc-footer-toolbar');
6287                    appendToElement(this.el, this.footer.el);
6288                }
6289                this.footer.receiveProps(__assign({ layout: footerLayout }, toolbarProps));
6290            }
6291            else if (this.footer) {
6292                this.footer.destroy();
6293                this.footer = null;
6294            }
6295        };
6296        CalendarComponent.prototype.renderView = function (props, title) {
6297            var view = this.view;
6298            var viewSpec = props.viewSpec, dateProfileGenerator = props.dateProfileGenerator;
6299            if (!view || view.viewSpec !== viewSpec) {
6300                if (view) {
6301                    view.destroy();
6302                }
6303                view = this.view = new viewSpec['class']({
6304                    calendar: this.calendar,
6305                    view: null,
6306                    dateEnv: this.dateEnv,
6307                    theme: this.theme,
6308                    options: viewSpec.options
6309                }, viewSpec, dateProfileGenerator, this.contentEl);
6310            }
6311            else {
6312                view.addScroll(view.queryScroll());
6313            }
6314            view.title = title; // for the API
6315            var viewProps = {
6316                dateProfile: props.dateProfile,
6317                businessHours: this.parseBusinessHours(viewSpec.options.businessHours),
6318                eventStore: props.eventStore,
6319                eventUiBases: props.eventUiBases,
6320                dateSelection: props.dateSelection,
6321                eventSelection: props.eventSelection,
6322                eventDrag: props.eventDrag,
6323                eventResize: props.eventResize
6324            };
6325            var transformers = this.buildViewPropTransformers(this.calendar.pluginSystem.hooks.viewPropsTransformers);
6326            for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
6327                var transformer = transformers_1[_i];
6328                __assign(viewProps, transformer.transform(viewProps, viewSpec, props, view));
6329            }
6330            view.receiveProps(viewProps);
6331        };
6332        // Sizing
6333        // -----------------------------------------------------------------------------------------------------------------
6334        CalendarComponent.prototype.updateSize = function (isResize) {
6335            if (isResize === void 0) { isResize = false; }
6336            var view = this.view;
6337            if (isResize) {
6338                view.addScroll(view.queryScroll());
6339            }
6340            if (isResize || this.isHeightAuto == null) {
6341                this.computeHeightVars();
6342            }
6343            view.updateSize(isResize, this.viewHeight, this.isHeightAuto);
6344            view.updateNowIndicator(); // we need to guarantee this will run after updateSize
6345            view.popScroll(isResize);
6346        };
6347        CalendarComponent.prototype.computeHeightVars = function () {
6348            var calendar = this.calendar; // yuck. need to handle dynamic options
6349            var heightInput = calendar.opt('height');
6350            var contentHeightInput = calendar.opt('contentHeight');
6351            this.isHeightAuto = heightInput === 'auto' || contentHeightInput === 'auto';
6352            if (typeof contentHeightInput === 'number') { // exists and not 'auto'
6353                this.viewHeight = contentHeightInput;
6354            }
6355            else if (typeof contentHeightInput === 'function') { // exists and is a function
6356                this.viewHeight = contentHeightInput();
6357            }
6358            else if (typeof heightInput === 'number') { // exists and not 'auto'
6359                this.viewHeight = heightInput - this.queryToolbarsHeight();
6360            }
6361            else if (typeof heightInput === 'function') { // exists and is a function
6362                this.viewHeight = heightInput() - this.queryToolbarsHeight();
6363            }
6364            else if (heightInput === 'parent') { // set to height of parent element
6365                this.viewHeight = this.el.parentNode.offsetHeight - this.queryToolbarsHeight();
6366            }
6367            else {
6368                this.viewHeight = Math.round(this.contentEl.offsetWidth /
6369                    Math.max(calendar.opt('aspectRatio'), .5));
6370            }
6371        };
6372        CalendarComponent.prototype.queryToolbarsHeight = function () {
6373            var height = 0;
6374            if (this.header) {
6375                height += computeHeightAndMargins(this.header.el);
6376            }
6377            if (this.footer) {
6378                height += computeHeightAndMargins(this.footer.el);
6379            }
6380            return height;
6381        };
6382        // Height "Freezing"
6383        // -----------------------------------------------------------------------------------------------------------------
6384        CalendarComponent.prototype.freezeHeight = function () {
6385            applyStyle(this.el, {
6386                height: this.el.offsetHeight,
6387                overflow: 'hidden'
6388            });
6389        };
6390        CalendarComponent.prototype.thawHeight = function () {
6391            applyStyle(this.el, {
6392                height: '',
6393                overflow: ''
6394            });
6395        };
6396        return CalendarComponent;
6397    }(Component));
6398    // Title and Date Formatting
6399    // -----------------------------------------------------------------------------------------------------------------
6400    // Computes what the title at the top of the calendar should be for this view
6401    function computeTitle(dateProfile, viewOptions) {
6402        var range;
6403        // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
6404        if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
6405            range = dateProfile.currentRange;
6406        }
6407        else { // for day units or smaller, use the actual day range
6408            range = dateProfile.activeRange;
6409        }
6410        return this.dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || computeTitleFormat(dateProfile), viewOptions.titleRangeSeparator), { isEndExclusive: dateProfile.isRangeAllDay });
6411    }
6412    // Generates the format string that should be used to generate the title for the current date range.
6413    // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
6414    function computeTitleFormat(dateProfile) {
6415        var currentRangeUnit = dateProfile.currentRangeUnit;
6416        if (currentRangeUnit === 'year') {
6417            return { year: 'numeric' };
6418        }
6419        else if (currentRangeUnit === 'month') {
6420            return { year: 'numeric', month: 'long' }; // like "September 2014"
6421        }
6422        else {
6423            var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
6424            if (days !== null && days > 1) {
6425                // multi-day range. shorter, like "Sep 9 - 10 2014"
6426                return { year: 'numeric', month: 'short', day: 'numeric' };
6427            }
6428            else {
6429                // one day. longer, like "September 9 2014"
6430                return { year: 'numeric', month: 'long', day: 'numeric' };
6431            }
6432        }
6433    }
6434    // Plugin
6435    // -----------------------------------------------------------------------------------------------------------------
6436    function buildViewPropTransformers(theClasses) {
6437        return theClasses.map(function (theClass) {
6438            return new theClass();
6439        });
6440    }
6441
6442    var Interaction = /** @class */ (function () {
6443        function Interaction(settings) {
6444            this.component = settings.component;
6445        }
6446        Interaction.prototype.destroy = function () {
6447        };
6448        return Interaction;
6449    }());
6450    function parseInteractionSettings(component, input) {
6451        return {
6452            component: component,
6453            el: input.el,
6454            useEventCenter: input.useEventCenter != null ? input.useEventCenter : true
6455        };
6456    }
6457    function interactionSettingsToStore(settings) {
6458        var _a;
6459        return _a = {},
6460            _a[settings.component.uid] = settings,
6461            _a;
6462    }
6463    // global state
6464    var interactionSettingsStore = {};
6465
6466    /*
6467    Detects when the user clicks on an event within a DateComponent
6468    */
6469    var EventClicking = /** @class */ (function (_super) {
6470        __extends(EventClicking, _super);
6471        function EventClicking(settings) {
6472            var _this = _super.call(this, settings) || this;
6473            _this.handleSegClick = function (ev, segEl) {
6474                var component = _this.component;
6475                var seg = getElSeg(segEl);
6476                if (seg && // might be the <div> surrounding the more link
6477                    component.isValidSegDownEl(ev.target)) {
6478                    // our way to simulate a link click for elements that can't be <a> tags
6479                    // grab before trigger fired in case trigger trashes DOM thru rerendering
6480                    var hasUrlContainer = elementClosest(ev.target, '.fc-has-url');
6481                    var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
6482                    component.publiclyTrigger('eventClick', [
6483                        {
6484                            el: segEl,
6485                            event: new EventApi(component.calendar, seg.eventRange.def, seg.eventRange.instance),
6486                            jsEvent: ev,
6487                            view: component.view
6488                        }
6489                    ]);
6490                    if (url && !ev.defaultPrevented) {
6491                        window.location.href = url;
6492                    }
6493                }
6494            };
6495            var component = settings.component;
6496            _this.destroy = listenBySelector(component.el, 'click', component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegClick);
6497            return _this;
6498        }
6499        return EventClicking;
6500    }(Interaction));
6501
6502    /*
6503    Triggers events and adds/removes core classNames when the user's pointer
6504    enters/leaves event-elements of a component.
6505    */
6506    var EventHovering = /** @class */ (function (_super) {
6507        __extends(EventHovering, _super);
6508        function EventHovering(settings) {
6509            var _this = _super.call(this, settings) || this;
6510            // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
6511            _this.handleEventElRemove = function (el) {
6512                if (el === _this.currentSegEl) {
6513                    _this.handleSegLeave(null, _this.currentSegEl);
6514                }
6515            };
6516            _this.handleSegEnter = function (ev, segEl) {
6517                if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
6518                    segEl.classList.add('fc-allow-mouse-resize');
6519                    _this.currentSegEl = segEl;
6520                    _this.triggerEvent('eventMouseEnter', ev, segEl);
6521                }
6522            };
6523            _this.handleSegLeave = function (ev, segEl) {
6524                if (_this.currentSegEl) {
6525                    segEl.classList.remove('fc-allow-mouse-resize');
6526                    _this.currentSegEl = null;
6527                    _this.triggerEvent('eventMouseLeave', ev, segEl);
6528                }
6529            };
6530            var component = settings.component;
6531            _this.removeHoverListeners = listenToHoverBySelector(component.el, component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegEnter, _this.handleSegLeave);
6532            component.calendar.on('eventElRemove', _this.handleEventElRemove);
6533            return _this;
6534        }
6535        EventHovering.prototype.destroy = function () {
6536            this.removeHoverListeners();
6537            this.component.calendar.off('eventElRemove', this.handleEventElRemove);
6538        };
6539        EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) {
6540            var component = this.component;
6541            var seg = getElSeg(segEl);
6542            if (!ev || component.isValidSegDownEl(ev.target)) {
6543                component.publiclyTrigger(publicEvName, [
6544                    {
6545                        el: segEl,
6546                        event: new EventApi(this.component.calendar, seg.eventRange.def, seg.eventRange.instance),
6547                        jsEvent: ev,
6548                        view: component.view
6549                    }
6550                ]);
6551            }
6552        };
6553        return EventHovering;
6554    }(Interaction));
6555
6556    var StandardTheme = /** @class */ (function (_super) {
6557        __extends(StandardTheme, _super);
6558        function StandardTheme() {
6559            return _super !== null && _super.apply(this, arguments) || this;
6560        }
6561        return StandardTheme;
6562    }(Theme));
6563    StandardTheme.prototype.classes = {
6564        widget: 'fc-unthemed',
6565        widgetHeader: 'fc-widget-header',
6566        widgetContent: 'fc-widget-content',
6567        buttonGroup: 'fc-button-group',
6568        button: 'fc-button fc-button-primary',
6569        buttonActive: 'fc-button-active',
6570        popoverHeader: 'fc-widget-header',
6571        popoverContent: 'fc-widget-content',
6572        // day grid
6573        headerRow: 'fc-widget-header',
6574        dayRow: 'fc-widget-content',
6575        // list view
6576        listView: 'fc-widget-content'
6577    };
6578    StandardTheme.prototype.baseIconClass = 'fc-icon';
6579    StandardTheme.prototype.iconClasses = {
6580        close: 'fc-icon-x',
6581        prev: 'fc-icon-chevron-left',
6582        next: 'fc-icon-chevron-right',
6583        prevYear: 'fc-icon-chevrons-left',
6584        nextYear: 'fc-icon-chevrons-right'
6585    };
6586    StandardTheme.prototype.iconOverrideOption = 'buttonIcons';
6587    StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
6588    StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
6589
6590    var Calendar = /** @class */ (function () {
6591        function Calendar(el, overrides) {
6592            var _this = this;
6593            this.parseRawLocales = memoize(parseRawLocales);
6594            this.buildLocale = memoize(buildLocale);
6595            this.buildDateEnv = memoize(buildDateEnv);
6596            this.buildTheme = memoize(buildTheme);
6597            this.buildEventUiSingleBase = memoize(this._buildEventUiSingleBase);
6598            this.buildSelectionConfig = memoize(this._buildSelectionConfig);
6599            this.buildEventUiBySource = memoizeOutput(buildEventUiBySource, isObjectsSimilar);
6600            this.buildEventUiBases = memoize(buildEventUiBases);
6601            this.interactionsStore = {};
6602            this.actionQueue = [];
6603            this.isReducing = false;
6604            // isDisplaying: boolean = false // installed in DOM? accepting renders?
6605            this.needsRerender = false; // needs a render?
6606            this.needsFullRerender = false;
6607            this.isRendering = false; // currently in the executeRender function?
6608            this.renderingPauseDepth = 0;
6609            this.buildDelayedRerender = memoize(buildDelayedRerender);
6610            this.afterSizingTriggers = {};
6611            this.isViewUpdated = false;
6612            this.isDatesUpdated = false;
6613            this.isEventsUpdated = false;
6614            this.el = el;
6615            this.optionsManager = new OptionsManager(overrides || {});
6616            this.pluginSystem = new PluginSystem();
6617            // only do once. don't do in handleOptions. because can't remove plugins
6618            this.addPluginInputs(this.optionsManager.computed.plugins || []);
6619            this.handleOptions(this.optionsManager.computed);
6620            this.publiclyTrigger('_init'); // for tests
6621            this.hydrate();
6622            this.calendarInteractions = this.pluginSystem.hooks.calendarInteractions
6623                .map(function (calendarInteractionClass) {
6624                return new calendarInteractionClass(_this);
6625            });
6626        }
6627        Calendar.prototype.addPluginInputs = function (pluginInputs) {
6628            var pluginDefs = refinePluginDefs(pluginInputs);
6629            for (var _i = 0, pluginDefs_1 = pluginDefs; _i < pluginDefs_1.length; _i++) {
6630                var pluginDef = pluginDefs_1[_i];
6631                this.pluginSystem.add(pluginDef);
6632            }
6633        };
6634        Object.defineProperty(Calendar.prototype, "view", {
6635            // public API
6636            get: function () {
6637                return this.component ? this.component.view : null;
6638            },
6639            enumerable: true,
6640            configurable: true
6641        });
6642        // Public API for rendering
6643        // -----------------------------------------------------------------------------------------------------------------
6644        Calendar.prototype.render = function () {
6645            if (!this.component) {
6646                this.renderableEventStore = createEmptyEventStore();
6647                this.bindHandlers();
6648                this.executeRender();
6649            }
6650            else {
6651                this.requestRerender(true);
6652            }
6653        };
6654        Calendar.prototype.destroy = function () {
6655            if (this.component) {
6656                this.unbindHandlers();
6657                this.component.destroy(); // don't null-out. in case API needs access
6658                this.component = null; // umm ???
6659                for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) {
6660                    var interaction = _a[_i];
6661                    interaction.destroy();
6662                }
6663                this.publiclyTrigger('_destroyed');
6664            }
6665        };
6666        // Handlers
6667        // -----------------------------------------------------------------------------------------------------------------
6668        Calendar.prototype.bindHandlers = function () {
6669            var _this = this;
6670            // event delegation for nav links
6671            this.removeNavLinkListener = listenBySelector(this.el, 'click', 'a[data-goto]', function (ev, anchorEl) {
6672                var gotoOptions = anchorEl.getAttribute('data-goto');
6673                gotoOptions = gotoOptions ? JSON.parse(gotoOptions) : {};
6674                var dateEnv = _this.dateEnv;
6675                var dateMarker = dateEnv.createMarker(gotoOptions.date);
6676                var viewType = gotoOptions.type;
6677                // property like "navLinkDayClick". might be a string or a function
6678                var customAction = _this.viewOpt('navLink' + capitaliseFirstLetter(viewType) + 'Click');
6679                if (typeof customAction === 'function') {
6680                    customAction(dateEnv.toDate(dateMarker), ev);
6681                }
6682                else {
6683                    if (typeof customAction === 'string') {
6684                        viewType = customAction;
6685                    }
6686                    _this.zoomTo(dateMarker, viewType);
6687                }
6688            });
6689            if (this.opt('handleWindowResize')) {
6690                window.addEventListener('resize', this.windowResizeProxy = debounce(// prevents rapid calls
6691                this.windowResize.bind(this), this.opt('windowResizeDelay')));
6692            }
6693        };
6694        Calendar.prototype.unbindHandlers = function () {
6695            this.removeNavLinkListener();
6696            if (this.windowResizeProxy) {
6697                window.removeEventListener('resize', this.windowResizeProxy);
6698                this.windowResizeProxy = null;
6699            }
6700        };
6701        // Dispatcher
6702        // -----------------------------------------------------------------------------------------------------------------
6703        Calendar.prototype.hydrate = function () {
6704            var _this = this;
6705            this.state = this.buildInitialState();
6706            var rawSources = this.opt('eventSources') || [];
6707            var singleRawSource = this.opt('events');
6708            var sources = []; // parsed
6709            if (singleRawSource) {
6710                rawSources.unshift(singleRawSource);
6711            }
6712            for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) {
6713                var rawSource = rawSources_1[_i];
6714                var source = parseEventSource(rawSource, this);
6715                if (source) {
6716                    sources.push(source);
6717                }
6718            }
6719            this.batchRendering(function () {
6720                _this.dispatch({ type: 'INIT' }); // pass in sources here?
6721                _this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: sources });
6722                _this.dispatch({
6723                    type: 'SET_VIEW_TYPE',
6724                    viewType: _this.opt('defaultView') || _this.pluginSystem.hooks.defaultView
6725                });
6726            });
6727        };
6728        Calendar.prototype.buildInitialState = function () {
6729            return {
6730                viewType: null,
6731                loadingLevel: 0,
6732                eventSourceLoadingLevel: 0,
6733                currentDate: this.getInitialDate(),
6734                dateProfile: null,
6735                eventSources: {},
6736                eventStore: createEmptyEventStore(),
6737                dateSelection: null,
6738                eventSelection: '',
6739                eventDrag: null,
6740                eventResize: null
6741            };
6742        };
6743        Calendar.prototype.dispatch = function (action) {
6744            this.actionQueue.push(action);
6745            if (!this.isReducing) {
6746                this.isReducing = true;
6747                var oldState = this.state;
6748                while (this.actionQueue.length) {
6749                    this.state = this.reduce(this.state, this.actionQueue.shift(), this);
6750                }
6751                var newState = this.state;
6752                this.isReducing = false;
6753                if (!oldState.loadingLevel && newState.loadingLevel) {
6754                    this.publiclyTrigger('loading', [true]);
6755                }
6756                else if (oldState.loadingLevel && !newState.loadingLevel) {
6757                    this.publiclyTrigger('loading', [false]);
6758                }
6759                var view = this.component && this.component.view;
6760                if (oldState.eventStore !== newState.eventStore || this.needsFullRerender) {
6761                    if (oldState.eventStore) {
6762                        this.isEventsUpdated = true;
6763                    }
6764                }
6765                if (oldState.dateProfile !== newState.dateProfile || this.needsFullRerender) {
6766                    if (oldState.dateProfile && view) { // why would view be null!?
6767                        this.publiclyTrigger('datesDestroy', [
6768                            {
6769                                view: view,
6770                                el: view.el
6771                            }
6772                        ]);
6773                    }
6774                    this.isDatesUpdated = true;
6775                }
6776                if (oldState.viewType !== newState.viewType || this.needsFullRerender) {
6777                    if (oldState.viewType && view) { // why would view be null!?
6778                        this.publiclyTrigger('viewSkeletonDestroy', [
6779                            {
6780                                view: view,
6781                                el: view.el
6782                            }
6783                        ]);
6784                    }
6785                    this.isViewUpdated = true;
6786                }
6787                this.requestRerender();
6788            }
6789        };
6790        Calendar.prototype.reduce = function (state, action, calendar) {
6791            return reduce(state, action, calendar);
6792        };
6793        // Render Queue
6794        // -----------------------------------------------------------------------------------------------------------------
6795        Calendar.prototype.requestRerender = function (needsFull) {
6796            if (needsFull === void 0) { needsFull = false; }
6797            this.needsRerender = true;
6798            this.needsFullRerender = this.needsFullRerender || needsFull;
6799            this.delayedRerender(); // will call a debounced-version of tryRerender
6800        };
6801        Calendar.prototype.tryRerender = function () {
6802            if (this.component && // must be accepting renders
6803                this.needsRerender && // indicates that a rerender was requested
6804                !this.renderingPauseDepth && // not paused
6805                !this.isRendering // not currently in the render loop
6806            ) {
6807                this.executeRender();
6808            }
6809        };
6810        Calendar.prototype.batchRendering = function (func) {
6811            this.renderingPauseDepth++;
6812            func();
6813            this.renderingPauseDepth--;
6814            if (this.needsRerender) {
6815                this.requestRerender();
6816            }
6817        };
6818        // Rendering
6819        // -----------------------------------------------------------------------------------------------------------------
6820        Calendar.prototype.executeRender = function () {
6821            var needsFullRerender = this.needsFullRerender; // save before clearing
6822            // clear these BEFORE the render so that new values will accumulate during render
6823            this.needsRerender = false;
6824            this.needsFullRerender = false;
6825            this.isRendering = true;
6826            this.renderComponent(needsFullRerender);
6827            this.isRendering = false;
6828            // received a rerender request while rendering
6829            if (this.needsRerender) {
6830                this.delayedRerender();
6831            }
6832        };
6833        /*
6834        don't call this directly. use executeRender instead
6835        */
6836        Calendar.prototype.renderComponent = function (needsFull) {
6837            var _a = this, state = _a.state, component = _a.component;
6838            var viewType = state.viewType;
6839            var viewSpec = this.viewSpecs[viewType];
6840            var savedScroll = (needsFull && component) ? component.view.queryScroll() : null;
6841            if (!viewSpec) {
6842                throw new Error("View type \"" + viewType + "\" is not valid");
6843            }
6844            // if event sources are still loading and progressive rendering hasn't been enabled,
6845            // keep rendering the last fully loaded set of events
6846            var renderableEventStore = this.renderableEventStore =
6847                (state.eventSourceLoadingLevel && !this.opt('progressiveEventRendering')) ?
6848                    this.renderableEventStore :
6849                    state.eventStore;
6850            var eventUiSingleBase = this.buildEventUiSingleBase(viewSpec.options);
6851            var eventUiBySource = this.buildEventUiBySource(state.eventSources);
6852            var eventUiBases = this.eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
6853            if (needsFull || !component) {
6854                if (component) {
6855                    component.freezeHeight(); // next component will unfreeze it
6856                    component.destroy();
6857                }
6858                component = this.component = new CalendarComponent({
6859                    calendar: this,
6860                    view: null,
6861                    dateEnv: this.dateEnv,
6862                    theme: this.theme,
6863                    options: this.optionsManager.computed
6864                }, this.el);
6865            }
6866            component.receiveProps(__assign({}, state, { viewSpec: viewSpec, dateProfile: state.dateProfile, dateProfileGenerator: this.dateProfileGenerators[viewType], eventStore: renderableEventStore, eventUiBases: eventUiBases, dateSelection: state.dateSelection, eventSelection: state.eventSelection, eventDrag: state.eventDrag, eventResize: state.eventResize }));
6867            if (savedScroll) {
6868                component.view.applyScroll(savedScroll, false);
6869            }
6870            if (this.isViewUpdated) {
6871                this.isViewUpdated = false;
6872                this.publiclyTrigger('viewSkeletonRender', [
6873                    {
6874                        view: component.view,
6875                        el: component.view.el
6876                    }
6877                ]);
6878            }
6879            if (this.isDatesUpdated) {
6880                this.isDatesUpdated = false;
6881                this.publiclyTrigger('datesRender', [
6882                    {
6883                        view: component.view,
6884                        el: component.view.el
6885                    }
6886                ]);
6887            }
6888            if (this.isEventsUpdated) {
6889                this.isEventsUpdated = false;
6890            }
6891            this.releaseAfterSizingTriggers();
6892        };
6893        // Options
6894        // -----------------------------------------------------------------------------------------------------------------
6895        /*
6896        Not meant for public API
6897        */
6898        Calendar.prototype.resetOptions = function (options) {
6899            var _this = this;
6900            var changeHandlers = this.pluginSystem.hooks.optionChangeHandlers;
6901            var oldOptions = this.optionsManager.overrides;
6902            var oldNormalOptions = {};
6903            var normalOptions = {};
6904            var specialOptions = {};
6905            for (var name_1 in oldOptions) {
6906                if (!changeHandlers[name_1]) {
6907                    oldNormalOptions[name_1] = oldOptions[name_1];
6908                }
6909            }
6910            for (var name_2 in options) {
6911                if (changeHandlers[name_2]) {
6912                    specialOptions[name_2] = options[name_2];
6913                }
6914                else {
6915                    normalOptions[name_2] = options[name_2];
6916                }
6917            }
6918            this.batchRendering(function () {
6919                if (anyKeysRemoved(oldNormalOptions, normalOptions)) {
6920                    _this.processOptions(options, 'reset');
6921                }
6922                else {
6923                    _this.processOptions(computeChangedProps(oldNormalOptions, normalOptions));
6924                }
6925                // handle special options last
6926                for (var name_3 in specialOptions) {
6927                    changeHandlers[name_3](specialOptions[name_3], _this);
6928                }
6929            });
6930        };
6931        /*
6932        Not meant for public API. Won't give the same precedence that setOption does
6933        */
6934        Calendar.prototype.setOptions = function (options) {
6935            var _this = this;
6936            var changeHandlers = this.pluginSystem.hooks.optionChangeHandlers;
6937            var normalOptions = {};
6938            var specialOptions = {};
6939            for (var name_4 in options) {
6940                if (changeHandlers[name_4]) {
6941                    specialOptions[name_4] = options[name_4];
6942                }
6943                else {
6944                    normalOptions[name_4] = options[name_4];
6945                }
6946            }
6947            this.batchRendering(function () {
6948                _this.processOptions(normalOptions);
6949                // handle special options last
6950                for (var name_5 in specialOptions) {
6951                    changeHandlers[name_5](specialOptions[name_5], _this);
6952                }
6953            });
6954        };
6955        Calendar.prototype.processOptions = function (options, mode) {
6956            var _this = this;
6957            var oldDateEnv = this.dateEnv; // do this before handleOptions
6958            var isTimeZoneDirty = false;
6959            var isSizeDirty = false;
6960            var anyDifficultOptions = false;
6961            for (var name_6 in options) {
6962                if (/^(height|contentHeight|aspectRatio)$/.test(name_6)) {
6963                    isSizeDirty = true;
6964                }
6965                else if (/^(defaultDate|defaultView)$/.test(name_6)) ;
6966                else {
6967                    anyDifficultOptions = true;
6968                    if (name_6 === 'timeZone') {
6969                        isTimeZoneDirty = true;
6970                    }
6971                }
6972            }
6973            if (mode === 'reset') {
6974                anyDifficultOptions = true;
6975                this.optionsManager.reset(options);
6976            }
6977            else if (mode === 'dynamic') {
6978                this.optionsManager.addDynamic(options); // takes higher precedence
6979            }
6980            else {
6981                this.optionsManager.add(options);
6982            }
6983            if (anyDifficultOptions) {
6984                this.handleOptions(this.optionsManager.computed); // only for "difficult" options
6985                this.needsFullRerender = true;
6986                this.batchRendering(function () {
6987                    if (isTimeZoneDirty) {
6988                        _this.dispatch({
6989                            type: 'CHANGE_TIMEZONE',
6990                            oldDateEnv: oldDateEnv
6991                        });
6992                    }
6993                    /* HACK
6994                    has the same effect as calling this.requestRerender(true)
6995                    but recomputes the state's dateProfile
6996                    */
6997                    _this.dispatch({
6998                        type: 'SET_VIEW_TYPE',
6999                        viewType: _this.state.viewType
7000                    });
7001                });
7002            }
7003            if (isSizeDirty) {
7004                this.updateSize();
7005            }
7006        };
7007        Calendar.prototype.setOption = function (name, val) {
7008            var _a;
7009            this.processOptions((_a = {}, _a[name] = val, _a), 'dynamic');
7010        };
7011        Calendar.prototype.getOption = function (name) {
7012            return this.optionsManager.computed[name];
7013        };
7014        Calendar.prototype.opt = function (name) {
7015            return this.optionsManager.computed[name];
7016        };
7017        Calendar.prototype.viewOpt = function (name) {
7018            return this.viewOpts()[name];
7019        };
7020        Calendar.prototype.viewOpts = function () {
7021            return this.viewSpecs[this.state.viewType].options;
7022        };
7023        /*
7024        rebuilds things based off of a complete set of refined options
7025        */
7026        Calendar.prototype.handleOptions = function (options) {
7027            var _this = this;
7028            var pluginHooks = this.pluginSystem.hooks;
7029            this.defaultAllDayEventDuration = createDuration(options.defaultAllDayEventDuration);
7030            this.defaultTimedEventDuration = createDuration(options.defaultTimedEventDuration);
7031            this.delayedRerender = this.buildDelayedRerender(options.rerenderDelay);
7032            this.theme = this.buildTheme(options);
7033            var available = this.parseRawLocales(options.locales);
7034            this.availableRawLocales = available.map;
7035            var locale = this.buildLocale(options.locale || available.defaultCode, available.map);
7036            this.dateEnv = this.buildDateEnv(locale, options.timeZone, pluginHooks.namedTimeZonedImpl, options.firstDay, options.weekNumberCalculation, options.weekLabel, pluginHooks.cmdFormatter);
7037            this.selectionConfig = this.buildSelectionConfig(options); // needs dateEnv. do after :(
7038            // ineffecient to do every time?
7039            this.viewSpecs = buildViewSpecs(pluginHooks.views, this.optionsManager);
7040            // ineffecient to do every time?
7041            this.dateProfileGenerators = mapHash(this.viewSpecs, function (viewSpec) {
7042                return new viewSpec.class.prototype.dateProfileGeneratorClass(viewSpec, _this);
7043            });
7044        };
7045        Calendar.prototype.getAvailableLocaleCodes = function () {
7046            return Object.keys(this.availableRawLocales);
7047        };
7048        Calendar.prototype._buildSelectionConfig = function (rawOpts) {
7049            return processScopedUiProps('select', rawOpts, this);
7050        };
7051        Calendar.prototype._buildEventUiSingleBase = function (rawOpts) {
7052            if (rawOpts.editable) { // so 'editable' affected events
7053                rawOpts = __assign({}, rawOpts, { eventEditable: true });
7054            }
7055            return processScopedUiProps('event', rawOpts, this);
7056        };
7057        // Trigger
7058        // -----------------------------------------------------------------------------------------------------------------
7059        Calendar.prototype.hasPublicHandlers = function (name) {
7060            return this.hasHandlers(name) ||
7061                this.opt(name); // handler specified in options
7062        };
7063        Calendar.prototype.publiclyTrigger = function (name, args) {
7064            var optHandler = this.opt(name);
7065            this.triggerWith(name, this, args);
7066            if (optHandler) {
7067                return optHandler.apply(this, args);
7068            }
7069        };
7070        Calendar.prototype.publiclyTriggerAfterSizing = function (name, args) {
7071            var afterSizingTriggers = this.afterSizingTriggers;
7072            (afterSizingTriggers[name] || (afterSizingTriggers[name] = [])).push(args);
7073        };
7074        Calendar.prototype.releaseAfterSizingTriggers = function () {
7075            var afterSizingTriggers = this.afterSizingTriggers;
7076            for (var name_7 in afterSizingTriggers) {
7077                for (var _i = 0, _a = afterSizingTriggers[name_7]; _i < _a.length; _i++) {
7078                    var args = _a[_i];
7079                    this.publiclyTrigger(name_7, args);
7080                }
7081            }
7082            this.afterSizingTriggers = {};
7083        };
7084        // View
7085        // -----------------------------------------------------------------------------------------------------------------
7086        // Returns a boolean about whether the view is okay to instantiate at some point
7087        Calendar.prototype.isValidViewType = function (viewType) {
7088            return Boolean(this.viewSpecs[viewType]);
7089        };
7090        Calendar.prototype.changeView = function (viewType, dateOrRange) {
7091            var dateMarker = null;
7092            if (dateOrRange) {
7093                if (dateOrRange.start && dateOrRange.end) { // a range
7094                    this.optionsManager.addDynamic({ visibleRange: dateOrRange }); // will not rerender
7095                    this.handleOptions(this.optionsManager.computed); // ...but yuck
7096                }
7097                else { // a date
7098                    dateMarker = this.dateEnv.createMarker(dateOrRange); // just like gotoDate
7099                }
7100            }
7101            this.unselect();
7102            this.dispatch({
7103                type: 'SET_VIEW_TYPE',
7104                viewType: viewType,
7105                dateMarker: dateMarker
7106            });
7107        };
7108        // Forces navigation to a view for the given date.
7109        // `viewType` can be a specific view name or a generic one like "week" or "day".
7110        // needs to change
7111        Calendar.prototype.zoomTo = function (dateMarker, viewType) {
7112            var spec;
7113            viewType = viewType || 'day'; // day is default zoom
7114            spec = this.viewSpecs[viewType] ||
7115                this.getUnitViewSpec(viewType);
7116            this.unselect();
7117            if (spec) {
7118                this.dispatch({
7119                    type: 'SET_VIEW_TYPE',
7120                    viewType: spec.type,
7121                    dateMarker: dateMarker
7122                });
7123            }
7124            else {
7125                this.dispatch({
7126                    type: 'SET_DATE',
7127                    dateMarker: dateMarker
7128                });
7129            }
7130        };
7131        // Given a duration singular unit, like "week" or "day", finds a matching view spec.
7132        // Preference is given to views that have corresponding buttons.
7133        Calendar.prototype.getUnitViewSpec = function (unit) {
7134            var component = this.component;
7135            var viewTypes = [];
7136            var i;
7137            var spec;
7138            // put views that have buttons first. there will be duplicates, but oh
7139            if (component.header) {
7140                viewTypes.push.apply(viewTypes, component.header.viewsWithButtons);
7141            }
7142            if (component.footer) {
7143                viewTypes.push.apply(viewTypes, component.footer.viewsWithButtons);
7144            }
7145            for (var viewType in this.viewSpecs) {
7146                viewTypes.push(viewType);
7147            }
7148            for (i = 0; i < viewTypes.length; i++) {
7149                spec = this.viewSpecs[viewTypes[i]];
7150                if (spec) {
7151                    if (spec.singleUnit === unit) {
7152                        return spec;
7153                    }
7154                }
7155            }
7156        };
7157        // Current Date
7158        // -----------------------------------------------------------------------------------------------------------------
7159        Calendar.prototype.getInitialDate = function () {
7160            var defaultDateInput = this.opt('defaultDate');
7161            // compute the initial ambig-timezone date
7162            if (defaultDateInput != null) {
7163                return this.dateEnv.createMarker(defaultDateInput);
7164            }
7165            else {
7166                return this.getNow(); // getNow already returns unzoned
7167            }
7168        };
7169        Calendar.prototype.prev = function () {
7170            this.unselect();
7171            this.dispatch({ type: 'PREV' });
7172        };
7173        Calendar.prototype.next = function () {
7174            this.unselect();
7175            this.dispatch({ type: 'NEXT' });
7176        };
7177        Calendar.prototype.prevYear = function () {
7178            this.unselect();
7179            this.dispatch({
7180                type: 'SET_DATE',
7181                dateMarker: this.dateEnv.addYears(this.state.currentDate, -1)
7182            });
7183        };
7184        Calendar.prototype.nextYear = function () {
7185            this.unselect();
7186            this.dispatch({
7187                type: 'SET_DATE',
7188                dateMarker: this.dateEnv.addYears(this.state.currentDate, 1)
7189            });
7190        };
7191        Calendar.prototype.today = function () {
7192            this.unselect();
7193            this.dispatch({
7194                type: 'SET_DATE',
7195                dateMarker: this.getNow()
7196            });
7197        };
7198        Calendar.prototype.gotoDate = function (zonedDateInput) {
7199            this.unselect();
7200            this.dispatch({
7201                type: 'SET_DATE',
7202                dateMarker: this.dateEnv.createMarker(zonedDateInput)
7203            });
7204        };
7205        Calendar.prototype.incrementDate = function (deltaInput) {
7206            var delta = createDuration(deltaInput);
7207            if (delta) { // else, warn about invalid input?
7208                this.unselect();
7209                this.dispatch({
7210                    type: 'SET_DATE',
7211                    dateMarker: this.dateEnv.add(this.state.currentDate, delta)
7212                });
7213            }
7214        };
7215        // for external API
7216        Calendar.prototype.getDate = function () {
7217            return this.dateEnv.toDate(this.state.currentDate);
7218        };
7219        // Date Formatting Utils
7220        // -----------------------------------------------------------------------------------------------------------------
7221        Calendar.prototype.formatDate = function (d, formatter) {
7222            var dateEnv = this.dateEnv;
7223            return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
7224        };
7225        // `settings` is for formatter AND isEndExclusive
7226        Calendar.prototype.formatRange = function (d0, d1, settings) {
7227            var dateEnv = this.dateEnv;
7228            return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings, this.opt('defaultRangeSeparator')), settings);
7229        };
7230        Calendar.prototype.formatIso = function (d, omitTime) {
7231            var dateEnv = this.dateEnv;
7232            return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime });
7233        };
7234        // Sizing
7235        // -----------------------------------------------------------------------------------------------------------------
7236        Calendar.prototype.windowResize = function (ev) {
7237            if (!this.isHandlingWindowResize &&
7238                this.component && // why?
7239                ev.target === window // not a jqui resize event
7240            ) {
7241                this.isHandlingWindowResize = true;
7242                this.updateSize();
7243                this.publiclyTrigger('windowResize', [this.view]);
7244                this.isHandlingWindowResize = false;
7245            }
7246        };
7247        Calendar.prototype.updateSize = function () {
7248            if (this.component) { // when?
7249                this.component.updateSize(true);
7250            }
7251        };
7252        // Component Registration
7253        // -----------------------------------------------------------------------------------------------------------------
7254        Calendar.prototype.registerInteractiveComponent = function (component, settingsInput) {
7255            var settings = parseInteractionSettings(component, settingsInput);
7256            var DEFAULT_INTERACTIONS = [
7257                EventClicking,
7258                EventHovering
7259            ];
7260            var interactionClasses = DEFAULT_INTERACTIONS.concat(this.pluginSystem.hooks.componentInteractions);
7261            var interactions = interactionClasses.map(function (interactionClass) {
7262                return new interactionClass(settings);
7263            });
7264            this.interactionsStore[component.uid] = interactions;
7265            interactionSettingsStore[component.uid] = settings;
7266        };
7267        Calendar.prototype.unregisterInteractiveComponent = function (component) {
7268            for (var _i = 0, _a = this.interactionsStore[component.uid]; _i < _a.length; _i++) {
7269                var listener = _a[_i];
7270                listener.destroy();
7271            }
7272            delete this.interactionsStore[component.uid];
7273            delete interactionSettingsStore[component.uid];
7274        };
7275        // Date Selection / Event Selection / DayClick
7276        // -----------------------------------------------------------------------------------------------------------------
7277        // this public method receives start/end dates in any format, with any timezone
7278        // NOTE: args were changed from v3
7279        Calendar.prototype.select = function (dateOrObj, endDate) {
7280            var selectionInput;
7281            if (endDate == null) {
7282                if (dateOrObj.start != null) {
7283                    selectionInput = dateOrObj;
7284                }
7285                else {
7286                    selectionInput = {
7287                        start: dateOrObj,
7288                        end: null
7289                    };
7290                }
7291            }
7292            else {
7293                selectionInput = {
7294                    start: dateOrObj,
7295                    end: endDate
7296                };
7297            }
7298            var selection = parseDateSpan(selectionInput, this.dateEnv, createDuration({ days: 1 }) // TODO: cache this?
7299            );
7300            if (selection) { // throw parse error otherwise?
7301                this.dispatch({ type: 'SELECT_DATES', selection: selection });
7302                this.triggerDateSelect(selection);
7303            }
7304        };
7305        // public method
7306        Calendar.prototype.unselect = function (pev) {
7307            if (this.state.dateSelection) {
7308                this.dispatch({ type: 'UNSELECT_DATES' });
7309                this.triggerDateUnselect(pev);
7310            }
7311        };
7312        Calendar.prototype.triggerDateSelect = function (selection, pev) {
7313            var arg = this.buildDateSpanApi(selection);
7314            arg.jsEvent = pev ? pev.origEvent : null;
7315            arg.view = this.view;
7316            this.publiclyTrigger('select', [arg]);
7317        };
7318        Calendar.prototype.triggerDateUnselect = function (pev) {
7319            this.publiclyTrigger('unselect', [
7320                {
7321                    jsEvent: pev ? pev.origEvent : null,
7322                    view: this.view
7323                }
7324            ]);
7325        };
7326        // TODO: receive pev?
7327        Calendar.prototype.triggerDateClick = function (dateSpan, dayEl, view, ev) {
7328            var arg = this.buildDatePointApi(dateSpan);
7329            arg.dayEl = dayEl;
7330            arg.jsEvent = ev;
7331            arg.view = view;
7332            this.publiclyTrigger('dateClick', [arg]);
7333        };
7334        Calendar.prototype.buildDatePointApi = function (dateSpan) {
7335            var props = {};
7336            for (var _i = 0, _a = this.pluginSystem.hooks.datePointTransforms; _i < _a.length; _i++) {
7337                var transform = _a[_i];
7338                __assign(props, transform(dateSpan, this));
7339            }
7340            __assign(props, buildDatePointApi(dateSpan, this.dateEnv));
7341            return props;
7342        };
7343        Calendar.prototype.buildDateSpanApi = function (dateSpan) {
7344            var props = {};
7345            for (var _i = 0, _a = this.pluginSystem.hooks.dateSpanTransforms; _i < _a.length; _i++) {
7346                var transform = _a[_i];
7347                __assign(props, transform(dateSpan, this));
7348            }
7349            __assign(props, buildDateSpanApi(dateSpan, this.dateEnv));
7350            return props;
7351        };
7352        // Date Utils
7353        // -----------------------------------------------------------------------------------------------------------------
7354        // Returns a DateMarker for the current date, as defined by the client's computer or from the `now` option
7355        Calendar.prototype.getNow = function () {
7356            var now = this.opt('now');
7357            if (typeof now === 'function') {
7358                now = now();
7359            }
7360            if (now == null) {
7361                return this.dateEnv.createNowMarker();
7362            }
7363            return this.dateEnv.createMarker(now);
7364        };
7365        // Event-Date Utilities
7366        // -----------------------------------------------------------------------------------------------------------------
7367        // Given an event's allDay status and start date, return what its fallback end date should be.
7368        // TODO: rename to computeDefaultEventEnd
7369        Calendar.prototype.getDefaultEventEnd = function (allDay, marker) {
7370            var end = marker;
7371            if (allDay) {
7372                end = startOfDay(end);
7373                end = this.dateEnv.add(end, this.defaultAllDayEventDuration);
7374            }
7375            else {
7376                end = this.dateEnv.add(end, this.defaultTimedEventDuration);
7377            }
7378            return end;
7379        };
7380        // Public Events API
7381        // -----------------------------------------------------------------------------------------------------------------
7382        Calendar.prototype.addEvent = function (eventInput, sourceIn
7382put) {
7383            if (eventInput instanceof EventApi) {
7384                var def = eventInput._def;
7385                var instance = eventInput._instance;
7386                // not already present? don't want to add an old snapshot
7387                if (!this.state.eventStore.defs[def.defId]) {
7388                    this.dispatch({
7389                        type: 'ADD_EVENTS',
7390                        eventStore: eventTupleToStore({ def: def, instance: instance }) // TODO: better util for two args?
7391                    });
7392                }
7393                return eventInput;
7394            }
7395            var sourceId;
7396            if (sourceInput instanceof EventSourceApi) {
7397                sourceId = sourceInput.internalEventSource.sourceId;
7398            }
7399            else if (sourceInput != null) {
7400                var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
7401                if (!sourceApi) {
7402                    console.warn('Could not find an event source with ID "' + sourceInput + '"'); // TODO: test
7403                    return null;
7404                }
7405                else {
7406                    sourceId = sourceApi.internalEventSource.sourceId;
7407                }
7408            }
7409            var tuple = parseEvent(eventInput, sourceId, this);
7410            if (tuple) {
7411                this.dispatch({
7412                    type: 'ADD_EVENTS',
7413                    eventStore: eventTupleToStore(tuple)
7414                });
7415                return new EventApi(this, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
7416            }
7417            return null;
7418        };
7419        // TODO: optimize
7420        Calendar.prototype.getEventById = function (id) {
7421            var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
7422            id = String(id);
7423            for (var defId in defs) {
7424                var def = defs[defId];
7425                if (def.publicId === id) {
7426                    if (def.recurringDef) {
7427                        return new EventApi(this, def, null);
7428                    }
7429                    else {
7430                        for (var instanceId in instances) {
7431                            var instance = instances[instanceId];
7432                            if (instance.defId === def.defId) {
7433                                return new EventApi(this, def, instance);
7434                            }
7435                        }
7436                    }
7437                }
7438            }
7439            return null;
7440        };
7441        Calendar.prototype.getEvents = function () {
7442            var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
7443            var eventApis = [];
7444            for (var id in instances) {
7445                var instance = instances[id];
7446                var def = defs[instance.defId];
7447                eventApis.push(new EventApi(this, def, instance));
7448            }
7449            return eventApis;
7450        };
7451        Calendar.prototype.removeAllEvents = function () {
7452            this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
7453        };
7454        Calendar.prototype.rerenderEvents = function () {
7455            this.dispatch({ type: 'RESET_EVENTS' });
7456        };
7457        // Public Event Sources API
7458        // -----------------------------------------------------------------------------------------------------------------
7459        Calendar.prototype.getEventSources = function () {
7460            var sourceHash = this.state.eventSources;
7461            var sourceApis = [];
7462            for (var internalId in sourceHash) {
7463                sourceApis.push(new EventSourceApi(this, sourceHash[internalId]));
7464            }
7465            return sourceApis;
7466        };
7467        Calendar.prototype.getEventSourceById = function (id) {
7468            var sourceHash = this.state.eventSources;
7469            id = String(id);
7470            for (var sourceId in sourceHash) {
7471                if (sourceHash[sourceId].publicId === id) {
7472                    return new EventSourceApi(this, sourceHash[sourceId]);
7473                }
7474            }
7475            return null;
7476        };
7477        Calendar.prototype.addEventSource = function (sourceInput) {
7478            if (sourceInput instanceof EventSourceApi) {
7479                // not already present? don't want to add an old snapshot
7480                if (!this.state.eventSources[sourceInput.internalEventSource.sourceId]) {
7481                    this.dispatch({
7482                        type: 'ADD_EVENT_SOURCES',
7483                        sources: [sourceInput.internalEventSource]
7484                    });
7485                }
7486                return sourceInput;
7487            }
7488            var eventSource = parseEventSource(sourceInput, this);
7489            if (eventSource) { // TODO: error otherwise?
7490                this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
7491                return new EventSourceApi(this, eventSource);
7492            }
7493            return null;
7494        };
7495        Calendar.prototype.removeAllEventSources = function () {
7496            this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
7497        };
7498        Calendar.prototype.refetchEvents = function () {
7499            this.dispatch({ type: 'FETCH_EVENT_SOURCES' });
7500        };
7501        // Scroll
7502        // -----------------------------------------------------------------------------------------------------------------
7503        Calendar.prototype.scrollToTime = function (timeInput) {
7504            var time = createDuration(timeInput);
7505            if (time) {
7506                this.component.view.scrollToTime(time);
7507            }
7508        };
7509        return Calendar;
7510    }());
7511    EmitterMixin.mixInto(Calendar);
7512    // for memoizers
7513    // -----------------------------------------------------------------------------------------------------------------
7514    function buildDateEnv(locale, timeZone, namedTimeZoneImpl, firstDay, weekNumberCalculation, weekLabel, cmdFormatter) {
7515        return new DateEnv({
7516            calendarSystem: 'gregory',
7517            timeZone: timeZone,
7518            namedTimeZoneImpl: namedTimeZoneImpl,
7519            locale: locale,
7520            weekNumberCalculation: weekNumberCalculation,
7521            firstDay: firstDay,
7522            weekLabel: weekLabel,
7523            cmdFormatter: cmdFormatter
7524        });
7525    }
7526    function buildTheme(calendarOptions) {
7527        var themeClass = this.pluginSystem.hooks.themeClasses[calendarOptions.themeSystem] || StandardTheme;
7528        return new themeClass(calendarOptions);
7529    }
7530    function buildDelayedRerender(wait) {
7531        var func = this.tryRerender.bind(this);
7532        if (wait != null) {
7533            func = debounce(func, wait);
7534        }
7535        return func;
7536    }
7537    function buildEventUiBySource(eventSources) {
7538        return mapHash(eventSources, function (eventSource) {
7539            return eventSource.ui;
7540        });
7541    }
7542    function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
7543        var eventUiBases = { '': eventUiSingleBase };
7544        for (var defId in eventDefs) {
7545            var def = eventDefs[defId];
7546            if (def.sourceId && eventUiBySource[def.sourceId]) {
7547                eventUiBases[defId] = eventUiBySource[def.sourceId];
7548            }
7549        }
7550        return eventUiBases;
7551    }
7552
7553    var View = /** @class */ (function (_super) {
7554        __extends(View, _super);
7555        function View(context, viewSpec, dateProfileGenerator, parentEl) {
7556            var _this = _super.call(this, context, createElement('div', { className: 'fc-view fc-' + viewSpec.type + '-view' }), true // isView (HACK)
7557            ) || this;
7558            _this.renderDatesMem = memoizeRendering(_this.renderDatesWrap, _this.unrenderDatesWrap);
7559            _this.renderBusinessHoursMem = memoizeRendering(_this.renderBusinessHours, _this.unrenderBusinessHours, [_this.renderDatesMem]);
7560            _this.renderDateSelectionMem = memoizeRendering(_this.renderDateSelectionWrap, _this.unrenderDateSelectionWrap, [_this.renderDatesMem]);
7561            _this.renderEventsMem = memoizeRendering(_this.renderEvents, _this.unrenderEvents, [_this.renderDatesMem]);
7562            _this.renderEventSelectionMem = memoizeRendering(_this.renderEventSelectionWrap, _this.unrenderEventSelectionWrap, [_this.renderEventsMem]);
7563            _this.renderEventDragMem = memoizeRendering(_this.renderEventDragWrap, _this.unrenderEventDragWrap, [_this.renderDatesMem]);
7564            _this.renderEventResizeMem = memoizeRendering(_this.renderEventResizeWrap, _this.unrenderEventResizeWrap, [_this.renderDatesMem]);
7565            _this.viewSpec = viewSpec;
7566            _this.dateProfileGenerator = dateProfileGenerator;
7567            _this.type = viewSpec.type;
7568            _this.eventOrderSpecs = parseFieldSpecs(_this.opt('eventOrder'));
7569            _this.nextDayThreshold = createDuration(_this.opt('nextDayThreshold'));
7570            parentEl.appendChild(_this.el);
7571            _this.initialize();
7572            return _this;
7573        }
7574        View.prototype.initialize = function () {
7575        };
7576        Object.defineProperty(View.prototype, "activeStart", {
7577            // Date Setting/Unsetting
7578            // -----------------------------------------------------------------------------------------------------------------
7579            get: function () {
7580                return this.dateEnv.toDate(this.props.dateProfile.activeRange.start);
7581            },
7582            enumerable: true,
7583            configurable: true
7584        });
7585        Object.defineProperty(View.prototype, "activeEnd", {
7586            get: function () {
7587                return this.dateEnv.toDate(this.props.dateProfile.activeRange.end);
7588            },
7589            enumerable: true,
7590            configurable: true
7591        });
7592        Object.defineProperty(View.prototype, "currentStart", {
7593            get: function () {
7594                return this.dateEnv.toDate(this.props.dateProfile.currentRange.start);
7595            },
7596            enumerable: true,
7597            configurable: true
7598        });
7599        Object.defineProperty(View.prototype, "currentEnd", {
7600            get: function () {
7601                return this.dateEnv.toDate(this.props.dateProfile.currentRange.end);
7602            },
7603            enumerable: true,
7604            configurable: true
7605        });
7606        // General Rendering
7607        // -----------------------------------------------------------------------------------------------------------------
7608        View.prototype.render = function (props) {
7609            this.renderDatesMem(props.dateProfile);
7610            this.renderBusinessHoursMem(props.businessHours);
7611            this.renderDateSelectionMem(props.dateSelection);
7612            this.renderEventsMem(props.eventStore);
7613            this.renderEventSelectionMem(props.eventSelection);
7614            this.renderEventDragMem(props.eventDrag);
7615            this.renderEventResizeMem(props.eventResize);
7616        };
7617        View.prototype.destroy = function () {
7618            _super.prototype.destroy.call(this);
7619            this.renderDatesMem.unrender(); // should unrender everything else
7620        };
7621        // Sizing
7622        // -----------------------------------------------------------------------------------------------------------------
7623        View.prototype.updateSize = function (isResize, viewHeight, isAuto) {
7624            var calendar = this.calendar;
7625            if (isResize || calendar.isViewUpdated || calendar.isDatesUpdated || calendar.isEventsUpdated) {
7626                // sort of the catch-all sizing
7627                // anything that might cause dimension changes
7628                this.updateBaseSize(isResize, viewHeight, isAuto);
7629            }
7630        };
7631        View.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
7632        };
7633        // Date Rendering
7634        // -----------------------------------------------------------------------------------------------------------------
7635        View.prototype.renderDatesWrap = function (dateProfile) {
7636            this.renderDates(dateProfile);
7637            this.addScroll({
7638                timeMs: createDuration(this.opt('scrollTime')).milliseconds
7639            });
7640            this.startNowIndicator(dateProfile); // shouldn't render yet because updateSize will be called soon
7641        };
7642        View.prototype.unrenderDatesWrap = function () {
7643            this.stopNowIndicator();
7644            this.unrenderDates();
7645        };
7646        View.prototype.renderDates = function (dateProfile) { };
7647        View.prototype.unrenderDates = function () { };
7648        // Business Hours
7649        // -----------------------------------------------------------------------------------------------------------------
7650        View.prototype.renderBusinessHours = function (businessHours) { };
7651        View.prototype.unrenderBusinessHours = function () { };
7652        // Date Selection
7653        // -----------------------------------------------------------------------------------------------------------------
7654        View.prototype.renderDateSelectionWrap = function (selection) {
7655            if (selection) {
7656                this.renderDateSelection(selection);
7657            }
7658        };
7659        View.prototype.unrenderDateSelectionWrap = function (selection) {
7660            if (selection) {
7661                this.unrenderDateSelection(selection);
7662            }
7663        };
7664        View.prototype.renderDateSelection = function (selection) { };
7665        View.prototype.unrenderDateSelection = function (selection) { };
7666        // Event Rendering
7667        // -----------------------------------------------------------------------------------------------------------------
7668        View.prototype.renderEvents = function (eventStore) { };
7669        View.prototype.unrenderEvents = function () { };
7670        // util for subclasses
7671        View.prototype.sliceEvents = function (eventStore, allDay) {
7672            var props = this.props;
7673            return sliceEventStore(eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? this.nextDayThreshold : null).fg;
7674        };
7675        // Event Selection
7676        // -----------------------------------------------------------------------------------------------------------------
7677        View.prototype.renderEventSelectionWrap = function (instanceId) {
7678            if (instanceId) {
7679                this.renderEventSelection(instanceId);
7680            }
7681        };
7682        View.prototype.unrenderEventSelectionWrap = function (instanceId) {
7683            if (instanceId) {
7684                this.unrenderEventSelection(instanceId);
7685            }
7686        };
7687        View.prototype.renderEventSelection = function (instanceId) { };
7688        View.prototype.unrenderEventSelection = function (instanceId) { };
7689        // Event Drag
7690        // -----------------------------------------------------------------------------------------------------------------
7691        View.prototype.renderEventDragWrap = function (state) {
7692            if (state) {
7693                this.renderEventDrag(state);
7694            }
7695        };
7696        View.prototype.unrenderEventDragWrap = function (state) {
7697            if (state) {
7698                this.unrenderEventDrag(state);
7699            }
7700        };
7701        View.prototype.renderEventDrag = function (state) { };
7702        View.prototype.unrenderEventDrag = function (state) { };
7703        // Event Resize
7704        // -----------------------------------------------------------------------------------------------------------------
7705        View.prototype.renderEventResizeWrap = function (state) {
7706            if (state) {
7707                this.renderEventResize(state);
7708            }
7709        };
7710        View.prototype.unrenderEventResizeWrap = function (state) {
7711            if (state) {
7712                this.unrenderEventResize(state);
7713            }
7714        };
7715        View.prototype.renderEventResize = function (state) { };
7716        View.prototype.unrenderEventResize = function (state) { };
7717        /* Now Indicator
7718        ------------------------------------------------------------------------------------------------------------------*/
7719        // Immediately render the current time indicator and begins re-rendering it at an interval,
7720        // which is defined by this.getNowIndicatorUnit().
7721        // TODO: somehow do this for the current whole day's background too
7722        View.prototype.startNowIndicator = function (dateProfile) {
7723            var _this = this;
7724            var dateEnv = this.dateEnv;
7725            var unit;
7726            var update;
7727            var delay; // ms wait value
7728            if (this.opt('nowIndicator')) {
7729                unit = this.getNowIndicatorUnit(dateProfile);
7730                if (unit) {
7731                    update = this.updateNowIndicator.bind(this);
7732                    this.initialNowDate = this.calendar.getNow();
7733                    this.initialNowQueriedMs = new Date().valueOf();
7734                    // wait until the beginning of the next interval
7735                    delay = dateEnv.add(dateEnv.startOf(this.initialNowDate, unit), createDuration(1, unit)).valueOf() - this.initialNowDate.valueOf();
7736                    // TODO: maybe always use setTimeout, waiting until start of next unit
7737                    this.nowIndicatorTimeoutID = setTimeout(function () {
7738                        _this.nowIndicatorTimeoutID = null;
7739                        update();
7740                        if (unit === 'second') {
7741                            delay = 1000; // every second
7742                        }
7743                        else {
7744                            delay = 1000 * 60; // otherwise, every minute
7745                        }
7746                        _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval
7747                    }, delay);
7748                }
7749                // rendering will be initiated in updateSize
7750            }
7751        };
7752        // rerenders the now indicator, computing the new current time from the amount of time that has passed
7753        // since the initial getNow call.
7754        View.prototype.updateNowIndicator = function () {
7755            if (this.props.dateProfile && // a way to determine if dates were rendered yet
7756                this.initialNowDate // activated before?
7757            ) {
7758                this.unrenderNowIndicator(); // won't unrender if unnecessary
7759                this.renderNowIndicator(addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs));
7760                this.isNowIndicatorRendered = true;
7761            }
7762        };
7763        // Immediately unrenders the view's current time indicator and stops any re-rendering timers.
7764        // Won't cause side effects if indicator isn't rendered.
7765        View.prototype.stopNowIndicator = function () {
7766            if (this.isNowIndicatorRendered) {
7767                if (this.nowIndicatorTimeoutID) {
7768                    clearTimeout(this.nowIndicatorTimeoutID);
7769                    this.nowIndicatorTimeoutID = null;
7770                }
7771                if (this.nowIndicatorIntervalID) {
7772                    clearInterval(this.nowIndicatorIntervalID);
7773                    this.nowIndicatorIntervalID = null;
7774                }
7775                this.unrenderNowIndicator();
7776                this.isNowIndicatorRendered = false;
7777            }
7778        };
7779        View.prototype.getNowIndicatorUnit = function (dateProfile) {
7780            // subclasses should implement
7781        };
7782        // Renders a current time indicator at the given datetime
7783        View.prototype.renderNowIndicator = function (date) {
7784            // SUBCLASSES MUST PASS TO CHILDREN!
7785        };
7786        // Undoes the rendering actions from renderNowIndicator
7787        View.prototype.unrenderNowIndicator = function () {
7788            // SUBCLASSES MUST PASS TO CHILDREN!
7789        };
7790        /* Scroller
7791        ------------------------------------------------------------------------------------------------------------------*/
7792        View.prototype.addScroll = function (scroll) {
7793            var queuedScroll = this.queuedScroll || (this.queuedScroll = {});
7794            __assign(queuedScroll, scroll);
7795        };
7796        View.prototype.popScroll = function (isResize) {
7797            this.applyQueuedScroll(isResize);
7798            this.queuedScroll = null;
7799        };
7800        View.prototype.applyQueuedScroll = function (isResize) {
7801            this.applyScroll(this.queuedScroll || {}, isResize);
7802        };
7803        View.prototype.queryScroll = function () {
7804            var scroll = {};
7805            if (this.props.dateProfile) { // dates rendered yet?
7806                __assign(scroll, this.queryDateScroll());
7807            }
7808            return scroll;
7809        };
7810        View.prototype.applyScroll = function (scroll, isResize) {
7811            var timeMs = scroll.timeMs;
7812            if (timeMs != null) {
7813                delete scroll.timeMs;
7814                if (this.props.dateProfile) { // dates rendered yet?
7815                    __assign(scroll, this.computeDateScroll(timeMs));
7816                }
7817            }
7818            if (this.props.dateProfile) { // dates rendered yet?
7819                this.applyDateScroll(scroll);
7820            }
7821        };
7822        View.prototype.computeDateScroll = function (timeMs) {
7823            return {}; // subclasses must implement
7824        };
7825        View.prototype.queryDateScroll = function () {
7826            return {}; // subclasses must implement
7827        };
7828        View.prototype.applyDateScroll = function (scroll) {
7829            // subclasses must implement
7830        };
7831        // for API
7832        View.prototype.scrollToTime = function (time) {
7833            this.applyScroll({
7834                timeMs: time.milliseconds
7835            }, false);
7836        };
7837        return View;
7838    }(DateComponent));
7839    EmitterMixin.mixInto(View);
7840    View.prototype.usesMinMaxTime = false;
7841    View.prototype.dateProfileGeneratorClass = DateProfileGenerator;
7842
7843    var FgEventRenderer = /** @class */ (function () {
7844        function FgEventRenderer(context) {
7845            this.segs = [];
7846            this.isSizeDirty = false;
7847            this.context = context;
7848        }
7849        FgEventRenderer.prototype.renderSegs = function (segs, mirrorInfo) {
7850            this.rangeUpdated(); // called too frequently :(
7851            // render an `.el` on each seg
7852            // returns a subset of the segs. segs that were actually rendered
7853            segs = this.renderSegEls(segs, mirrorInfo);
7854            this.segs = segs;
7855            this.attachSegs(segs, mirrorInfo);
7856            this.isSizeDirty = true;
7857            this.context.view.triggerRenderedSegs(this.segs, Boolean(mirrorInfo));
7858        };
7859        FgEventRenderer.prototype.unrender = function (_segs, mirrorInfo) {
7860            this.context.view.triggerWillRemoveSegs(this.segs, Boolean(mirrorInfo));
7861            this.detachSegs(this.segs);
7862            this.segs = [];
7863        };
7864        // Updates values that rely on options and also relate to range
7865        FgEventRenderer.prototype.rangeUpdated = function () {
7866            var options = this.context.options;
7867            var displayEventTime;
7868            var displayEventEnd;
7869            this.eventTimeFormat = createFormatter(options.eventTimeFormat || this.computeEventTimeFormat(), options.defaultRangeSeparator);
7870            displayEventTime = options.displayEventTime;
7871            if (displayEventTime == null) {
7872                displayEventTime = this.computeDisplayEventTime(); // might be based off of range
7873            }
7874            displayEventEnd = options.displayEventEnd;
7875            if (displayEventEnd == null) {
7876                displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range
7877            }
7878            this.displayEventTime = displayEventTime;
7879            this.displayEventEnd = displayEventEnd;
7880        };
7881        // Renders and assigns an `el` property for each foreground event segment.
7882        // Only returns segments that successfully rendered.
7883        FgEventRenderer.prototype.renderSegEls = function (segs, mirrorInfo) {
7884            var html = '';
7885            var i;
7886            if (segs.length) { // don't build an empty html string
7887                // build a large concatenation of event segment HTML
7888                for (i = 0; i < segs.length; i++) {
7889                    html += this.renderSegHtml(segs[i], mirrorInfo);
7890                }
7891                // Grab individual elements from the combined HTML string. Use each as the default rendering.
7892                // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
7893                htmlToElements(html).forEach(function (el, i) {
7894                    var seg = segs[i];
7895                    if (el) {
7896                        seg.el = el;
7897                    }
7898                });
7899                segs = filterSegsViaEls(this.context.view, segs, Boolean(mirrorInfo));
7900            }
7901            return segs;
7902        };
7903        // Generic utility for generating the HTML classNames for an event segment's element
7904        FgEventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable, mirrorInfo) {
7905            var classes = [
7906                'fc-event',
7907                seg.isStart ? 'fc-start' : 'fc-not-start',
7908                seg.isEnd ? 'fc-end' : 'fc-not-end'
7909            ].concat(seg.eventRange.ui.classNames);
7910            if (isDraggable) {
7911                classes.push('fc-draggable');
7912            }
7913            if (isResizable) {
7914                classes.push('fc-resizable');
7915            }
7916            if (mirrorInfo) {
7917                classes.push('fc-mirror');
7918                if (mirrorInfo.isDragging) {
7919                    classes.push('fc-dragging');
7920                }
7921                if (mirrorInfo.isResizing) {
7922                    classes.push('fc-resizing');
7923                }
7924            }
7925            return classes;
7926        };
7927        // Compute the text that should be displayed on an event's element.
7928        // `range` can be the Event object itself, or something range-like, with at least a `start`.
7929        // If event times are disabled, or the event has no time, will return a blank string.
7930        // If not specified, formatter will default to the eventTimeFormat setting,
7931        // and displayEnd will default to the displayEventEnd setting.
7932        FgEventRenderer.prototype.getTimeText = function (eventRange, formatter, displayEnd) {
7933            var def = eventRange.def, instance = eventRange.instance;
7934            return this._getTimeText(instance.range.start, def.hasEnd ? instance.range.end : null, def.allDay, formatter, displayEnd, instance.forcedStartTzo, instance.forcedEndTzo);
7935        };
7936        FgEventRenderer.prototype._getTimeText = function (start, end, allDay, formatter, displayEnd, forcedStartTzo, forcedEndTzo) {
7937            var dateEnv = this.context.dateEnv;
7938            if (formatter == null) {
7939                formatter = this.eventTimeFormat;
7940            }
7941            if (displayEnd == null) {
7942                displayEnd = this.displayEventEnd;
7943            }
7944            if (this.displayEventTime && !allDay) {
7945                if (displayEnd && end) {
7946                    return dateEnv.formatRange(start, end, formatter, {
7947                        forcedStartTzo: forcedStartTzo,
7948                        forcedEndTzo: forcedEndTzo
7949                    });
7950                }
7951                else {
7952                    return dateEnv.format(start, formatter, {
7953                        forcedTzo: forcedStartTzo
7954                    });
7955                }
7956            }
7957            return '';
7958        };
7959        FgEventRenderer.prototype.computeEventTimeFormat = function () {
7960            return {
7961                hour: 'numeric',
7962                minute: '2-digit',
7963                omitZeroMinute: true
7964            };
7965        };
7966        FgEventRenderer.prototype.computeDisplayEventTime = function () {
7967            return true;
7968        };
7969        FgEventRenderer.prototype.computeDisplayEventEnd = function () {
7970            return true;
7971        };
7972        // Utility for generating event skin-related CSS properties
7973        FgEventRenderer.prototype.getSkinCss = function (ui) {
7974            return {
7975                'background-color': ui.backgroundColor,
7976                'border-color': ui.borderColor,
7977                color: ui.textColor
7978            };
7979        };
7980        FgEventRenderer.prototype.sortEventSegs = function (segs) {
7981            var specs = this.context.view.eventOrderSpecs;
7982            var objs = segs.map(buildSegCompareObj);
7983            objs.sort(function (obj0, obj1) {
7984                return compareByFieldSpecs(obj0, obj1, specs);
7985            });
7986            return objs.map(function (c) {
7987                return c._seg;
7988            });
7989        };
7990        FgEventRenderer.prototype.computeSizes = function (force) {
7991            if (force || this.isSizeDirty) {
7992                this.computeSegSizes(this.segs);
7993            }
7994        };
7995        FgEventRenderer.prototype.assignSizes = function (force) {
7996            if (force || this.isSizeDirty) {
7997                this.assignSegSizes(this.segs);
7998                this.isSizeDirty = false;
7999            }
8000        };
8001        FgEventRenderer.prototype.computeSegSizes = function (segs) {
8002        };
8003        FgEventRenderer.prototype.assignSegSizes = function (segs) {
8004        };
8005        // Manipulation on rendered segs
8006        FgEventRenderer.prototype.hideByHash = function (hash) {
8007            if (hash) {
8008                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
8009                    var seg = _a[_i];
8010                    if (hash[seg.eventRange.instance.instanceId]) {
8011                        seg.el.style.visibility = 'hidden';
8012                    }
8013                }
8014            }
8015        };
8016        FgEventRenderer.prototype.showByHash = function (hash) {
8017            if (hash) {
8018                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
8019                    var seg = _a[_i];
8020                    if (hash[seg.eventRange.instance.instanceId]) {
8021                        seg.el.style.visibility = '';
8022                    }
8023                }
8024            }
8025        };
8026        FgEventRenderer.prototype.selectByInstanceId = function (instanceId) {
8027            if (instanceId) {
8028                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
8029                    var seg = _a[_i];
8030                    var eventInstance = seg.eventRange.instance;
8031                    if (eventInstance && eventInstance.instanceId === instanceId &&
8032                        seg.el // necessary?
8033                    ) {
8034                        seg.el.classList.add('fc-selected');
8035                    }
8036                }
8037            }
8038        };
8039        FgEventRenderer.prototype.unselectByInstanceId = function (instanceId) {
8040            if (instanceId) {
8041                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
8042                    var seg = _a[_i];
8043                    if (seg.el) { // necessary?
8044                        seg.el.classList.remove('fc-selected');
8045                    }
8046                }
8047            }
8048        };
8049        return FgEventRenderer;
8050    }());
8051    // returns a object with all primitive props that can be compared
8052    function buildSegCompareObj(seg) {
8053        var eventDef = seg.eventRange.def;
8054        var range = seg.eventRange.instance.range;
8055        var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
8056        var end = range.end ? range.end.valueOf() : 0; // "
8057        return __assign({}, eventDef.extendedProps, eventDef, { id: eventDef.publicId, start: start,
8058            end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg // for later retrieval
8059         });
8060    }
8061
8062    var FillRenderer = /** @class */ (function () {
8063        function FillRenderer(context) {
8064            this.fillSegTag = 'div';
8065            this.dirtySizeFlags = {};
8066            this.context = context;
8067            this.containerElsByType = {};
8068            this.segsByType = {};
8069        }
8070        FillRenderer.prototype.getSegsByType = function (type) {
8071            return this.segsByType[type] || [];
8072        };
8073        FillRenderer.prototype.renderSegs = function (type, segs) {
8074            var _a;
8075            var renderedSegs = this.renderSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs
8076            var containerEls = this.attachSegs(type, renderedSegs);
8077            if (containerEls) {
8078                (_a = (this.containerElsByType[type] || (this.containerElsByType[type] = []))).push.apply(_a, containerEls);
8079            }
8080            this.segsByType[type] = renderedSegs;
8081            if (type === 'bgEvent') {
8082                this.context.view.triggerRenderedSegs(renderedSegs, false); // isMirror=false
8083            }
8084            this.dirtySizeFlags[type] = true;
8085        };
8086        // Unrenders a specific type of fill that is currently rendered on the grid
8087        FillRenderer.prototype.unrender = function (type) {
8088            var segs = this.segsByType[type];
8089            if (segs) {
8090                if (type === 'bgEvent') {
8091                    this.context.view.triggerWillRemoveSegs(segs, false); // isMirror=false
8092                }
8093                this.detachSegs(type, segs);
8094            }
8095        };
8096        // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
8097        // Only returns segments that successfully rendered.
8098        FillRenderer.prototype.renderSegEls = function (type, segs) {
8099            var _this = this;
8100            var html = '';
8101            var i;
8102            if (segs.length) {
8103                // build a large concatenation of segment HTML
8104                for (i = 0; i < segs.length; i++) {
8105                    html += this.renderSegHtml(type, segs[i]);
8106                }
8107                // Grab individual elements from the combined HTML string. Use each as the default rendering.
8108                // Then, compute the 'el' for each segment.
8109                htmlToElements(html).forEach(function (el, i) {
8110                    var seg = segs[i];
8111                    if (el) {
8112                        seg.el = el;
8113                    }
8114                });
8115                if (type === 'bgEvent') {
8116                    segs = filterSegsViaEls(this.context.view, segs, false // isMirror. background events can never be mirror elements
8117                    );
8118                }
8119                // correct element type? (would be bad if a non-TD were inserted into a table for example)
8120                segs = segs.filter(function (seg) {
8121                    return elementMatches(seg.el, _this.fillSegTag);
8122                });
8123            }
8124            return segs;
8125        };
8126        // Builds the HTML needed for one fill segment. Generic enough to work with different types.
8127        FillRenderer.prototype.renderSegHtml = function (type, seg) {
8128            var css = null;
8129            var classNames = [];
8130            if (type !== 'highlight' && type !== 'businessHours') {
8131                css = {
8132                    'background-color': seg.eventRange.ui.backgroundColor
8133                };
8134            }
8135            if (type !== 'highlight') {
8136                classNames = classNames.concat(seg.eventRange.ui.classNames);
8137            }
8138            if (type === 'businessHours') {
8139                classNames.push('fc-bgevent');
8140            }
8141            else {
8142                classNames.push('fc-' + type.toLowerCase());
8143            }
8144            return '<' + this.fillSegTag +
8145                (classNames.length ? ' class="' + classNames.join(' ') + '"' : '') +
8146                (css ? ' style="' + cssToStr(css) + '"' : '') +
8147                '></' + this.fillSegTag + '>';
8148        };
8149        FillRenderer.prototype.detachSegs = function (type, segs) {
8150            var containerEls = this.containerElsByType[type];
8151            if (containerEls) {
8152                containerEls.forEach(removeElement);
8153                delete this.containerElsByType[type];
8154            }
8155        };
8156        FillRenderer.prototype.computeSizes = function (force) {
8157            for (var type in this.segsByType) {
8158                if (force || this.dirtySizeFlags[type]) {
8159                    this.computeSegSizes(this.segsByType[type]);
8160                }
8161            }
8162        };
8163        FillRenderer.prototype.assignSizes = function (force) {
8164            for (var type in this.segsByType) {
8165                if (force || this.dirtySizeFlags[type]) {
8166                    this.assignSegSizes(this.segsByType[type]);
8167                }
8168            }
8169            this.dirtySizeFlags = {};
8170        };
8171        FillRenderer.prototype.computeSegSizes = function (segs) {
8172        };
8173        FillRenderer.prototype.assignSegSizes = function (segs) {
8174        };
8175        return FillRenderer;
8176    }());
8177
8178    var NamedTimeZoneImpl = /** @class */ (function () {
8179        function NamedTimeZoneImpl(timeZoneName) {
8180            this.timeZoneName = timeZoneName;
8181        }
8182        return NamedTimeZoneImpl;
8183    }());
8184
8185    /*
8186    An abstraction for a dragging interaction originating on an event.
8187    Does higher-level things than PointerDragger, such as possibly:
8188    - a "mirror" that moves with the pointer
8189    - a minimum number of pixels or other criteria for a true drag to begin
8190
8191    subclasses must emit:
8192    - pointerdown
8193    - dragstart
8194    - dragmove
8195    - pointerup
8196    - dragend
8197    */
8198    var ElementDragging = /** @class */ (function () {
8199        function ElementDragging(el) {
8200            this.emitter = new EmitterMixin();
8201        }
8202        ElementDragging.prototype.destroy = function () {
8203        };
8204        ElementDragging.prototype.setMirrorIsVisible = function (bool) {
8205            // optional if subclass doesn't want to support a mirror
8206        };
8207        ElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
8208            // optional if subclass doesn't want to support a mirror
8209        };
8210        ElementDragging.prototype.setAutoScrollEnabled = function (bool) {
8211            // optional
8212        };
8213        return ElementDragging;
8214    }());
8215
8216    function formatDate(dateInput, settings) {
8217        if (settings === void 0) { settings = {}; }
8218        var dateEnv = buildDateEnv$1(settings);
8219        var formatter = createFormatter(settings);
8220        var dateMeta = dateEnv.createMarkerMeta(dateInput);
8221        if (!dateMeta) { // TODO: warning?
8222            return '';
8223        }
8224        return dateEnv.format(dateMeta.marker, formatter, {
8225            forcedTzo: dateMeta.forcedTzo
8226        });
8227    }
8228    function formatRange(startInput, endInput, settings // mixture of env and formatter settings
8229    ) {
8230        var dateEnv = buildDateEnv$1(typeof settings === 'object' && settings ? settings : {}); // pass in if non-null object
8231        var formatter = createFormatter(settings, globalDefaults.defaultRangeSeparator);
8232        var startMeta = dateEnv.createMarkerMeta(startInput);
8233        var endMeta = dateEnv.createMarkerMeta(endInput);
8234        if (!startMeta || !endMeta) { // TODO: warning?
8235            return '';
8236        }
8237        return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
8238            forcedStartTzo: startMeta.forcedTzo,
8239            forcedEndTzo: endMeta.forcedTzo,
8240            isEndExclusive: settings.isEndExclusive
8241        });
8242    }
8243    // TODO: more DRY and optimized
8244    function buildDateEnv$1(settings) {
8245        var locale = buildLocale(settings.locale || 'en', parseRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
8246        // ensure required settings
8247        settings = __assign({ timeZone: globalDefaults.timeZone, calendarSystem: 'gregory' }, settings, { locale: locale });
8248        return new DateEnv(settings);
8249    }
8250
8251    var DRAG_META_PROPS = {
8252        startTime: createDuration,
8253        duration: createDuration,
8254        create: Boolean,
8255        sourceId: String
8256    };
8257    var DRAG_META_DEFAULTS = {
8258        create: true
8259    };
8260    function parseDragMeta(raw) {
8261        var leftoverProps = {};
8262        var refined = refineProps(raw, DRAG_META_PROPS, DRAG_META_DEFAULTS, leftoverProps);
8263        refined.leftoverProps = leftoverProps;
8264        return refined;
8265    }
8266
8267    // Computes a default column header formatting string if `colFormat` is not explicitly defined
8268    function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
8269        // if more than one week row, or if there are a lot of columns with not much space,
8270        // put just the day numbers will be in each cell
8271        if (!datesRepDistinctDays || dayCnt > 10) {
8272            return { weekday: 'short' }; // "Sat"
8273        }
8274        else if (dayCnt > 1) {
8275            return { weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }; // "Sat 11/12"
8276        }
8277        else {
8278            return { weekday: 'long' }; // "Saturday"
8279        }
8280    }
8281    function renderDateCell(dateMarker, dateProfile, datesRepDistinctDays, colCnt, colHeadFormat, context, colspan, otherAttrs) {
8282        var view = context.view, dateEnv = context.dateEnv, theme = context.theme, options = context.options;
8283        var isDateValid = rangeContainsMarker(dateProfile.activeRange, dateMarker); // TODO: called too frequently. cache somehow.
8284        var classNames = [
8285            'fc-day-header',
8286            theme.getClass('widgetHeader')
8287        ];
8288        var innerHtml;
8289        if (typeof options.columnHeaderHtml === 'function') {
8290            innerHtml = options.columnHeaderHtml(dateEnv.toDate(dateMarker));
8291        }
8292        else if (typeof options.columnHeaderText === 'function') {
8293            innerHtml = htmlEscape(options.columnHeaderText(dateEnv.toDate(dateMarker)));
8294        }
8295        else {
8296            innerHtml = htmlEscape(dateEnv.format(dateMarker, colHeadFormat));
8297        }
8298        // if only one row of days, the classNames on the header can represent the specific days beneath
8299        if (datesRepDistinctDays) {
8300            classNames = classNames.concat(
8301            // includes the day-of-week class
8302            // noThemeHighlight=true (don't highlight the header)
8303            getDayClasses(dateMarker, dateProfile, context, true));
8304        }
8305        else {
8306            classNames.push('fc-' + DAY_IDS[dateMarker.getUTCDay()]); // only add the day-of-week class
8307        }
8308        return '' +
8309            '<th class="' + classNames.join(' ') + '"' +
8310            ((isDateValid && datesRepDistinctDays) ?
8311                ' data-date="' + dateEnv.formatIso(dateMarker, { omitTime: true }) + '"' :
8312                '') +
8313            (colspan > 1 ?
8314                ' colspan="' + colspan + '"' :
8315                '') +
8316            (otherAttrs ?
8317                ' ' + otherAttrs :
8318                '') +
8319            '>' +
8320            (isDateValid ?
8321                // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff)
8322                buildGotoAnchorHtml(view, { date: dateMarker, forceOff: !datesRepDistinctDays || colCnt === 1 }, innerHtml) :
8323                // if not valid, display text, but no link
8324                innerHtml) +
8325            '</th>';
8326    }
8327
8328    var DayHeader = /** @class */ (function (_super) {
8329        __extends(DayHeader, _super);
8330        function DayHeader(context, parentEl) {
8331            var _this = _super.call(this, context) || this;
8332            parentEl.innerHTML = ''; // because might be nbsp
8333            parentEl.appendChild(_this.el = htmlToElement('<div class="fc-row ' + _this.theme.getClass('headerRow') + '">' +
8334                '<table class="' + _this.theme.getClass('tableGrid') + '">' +
8335                '<thead></thead>' +
8336                '</table>' +
8337                '</div>'));
8338            _this.thead = _this.el.querySelector('thead');
8339            return _this;
8340        }
8341        DayHeader.prototype.destroy = function () {
8342            removeElement(this.el);
8343        };
8344        DayHeader.prototype.render = function (props) {
8345            var dates = props.dates, datesRepDistinctDays = props.datesRepDistinctDays;
8346            var parts = [];
8347            if (props.renderIntroHtml) {
8348                parts.push(props.renderIntroHtml());
8349            }
8350            var colHeadFormat = createFormatter(this.opt('columnHeaderFormat') ||
8351                computeFallbackHeaderFormat(datesRepDistinctDays, dates.length));
8352            for (var _i = 0, dates_1 = dates; _i < dates_1.length; _i++) {
8353                var date = dates_1[_i];
8354                parts.push(renderDateCell(date, props.dateProfile, datesRepDistinctDays, dates.length, colHeadFormat, this.context));
8355            }
8356            if (this.isRtl) {
8357                parts.reverse();
8358            }
8359            this.thead.innerHTML = '<tr>' + parts.join('') + '</tr>';
8360        };
8361        return DayHeader;
8362    }(Component));
8363
8364    var DaySeries = /** @class */ (function () {
8365        function DaySeries(range, dateProfileGenerator) {
8366            var date = range.start;
8367            var end = range.end;
8368            var indices = [];
8369            var dates = [];
8370            var dayIndex = -1;
8371            while (date < end) { // loop each day from start to end
8372                if (dateProfileGenerator.isHiddenDay(date)) {
8373                    indices.push(dayIndex + 0.5); // mark that it's between indices
8374                }
8375                else {
8376                    dayIndex++;
8377                    indices.push(dayIndex);
8378                    dates.push(date);
8379                }
8380                date = addDays(date, 1);
8381            }
8382            this.dates = dates;
8383            this.indices = indices;
8384            this.cnt = dates.length;
8385        }
8386        DaySeries.prototype.sliceRange = function (range) {
8387            var firstIndex = this.getDateDayIndex(range.start); // inclusive first index
8388            var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
8389            var clippedFirstIndex = Math.max(0, firstIndex);
8390            var clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
8391            // deal with in-between indices
8392            clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
8393            clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
8394            if (clippedFirstIndex <= clippedLastIndex) {
8395                return {
8396                    firstIndex: clippedFirstIndex,
8397                    lastIndex: clippedLastIndex,
8398                    isStart: firstIndex === clippedFirstIndex,
8399                    isEnd: lastIndex === clippedLastIndex
8400                };
8401            }
8402            else {
8403                return null;
8404            }
8405        };
8406        // Given a date, returns its chronolocial cell-index from the first cell of the grid.
8407        // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
8408        // If before the first offset, returns a negative number.
8409        // If after the last offset, returns an offset past the last cell offset.
8410        // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
8411        DaySeries.prototype.getDateDayIndex = function (date) {
8412            var indices = this.indices;
8413            var dayOffset = Math.floor(diffDays(this.dates[0], date));
8414            if (dayOffset < 0) {
8415                return indices[0] - 1;
8416            }
8417            else if (dayOffset >= indices.length) {
8418                return indices[indices.length - 1] + 1;
8419            }
8420            else {
8421                return indices[dayOffset];
8422            }
8423        };
8424        return DaySeries;
8425    }());
8426
8427    var DayTable = /** @class */ (function () {
8428        function DayTable(daySeries, breakOnWeeks) {
8429            var dates = daySeries.dates;
8430            var daysPerRow;
8431            var firstDay;
8432            var rowCnt;
8433            if (breakOnWeeks) {
8434                // count columns until the day-of-week repeats
8435                firstDay = dates[0].getUTCDay();
8436                for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow++) {
8437                    if (dates[daysPerRow].getUTCDay() === firstDay) {
8438                        break;
8439                    }
8440                }
8441                rowCnt = Math.ceil(dates.length / daysPerRow);
8442            }
8443            else {
8444                rowCnt = 1;
8445                daysPerRow = dates.length;
8446            }
8447            this.rowCnt = rowCnt;
8448            this.colCnt = daysPerRow;
8449            this.daySeries = daySeries;
8450            this.cells = this.buildCells();
8451            this.headerDates = this.buildHeaderDates();
8452        }
8453        DayTable.prototype.buildCells = function () {
8454            var rows = [];
8455            for (var row = 0; row < this.rowCnt; row++) {
8456                var cells = [];
8457                for (var col = 0; col < this.colCnt; col++) {
8458                    cells.push(this.buildCell(row, col));
8459                }
8460                rows.push(cells);
8461            }
8462            return rows;
8463        };
8464        DayTable.prototype.buildCell = function (row, col) {
8465            return {
8466                date: this.daySeries.dates[row * this.colCnt + col]
8467            };
8468        };
8469        DayTable.prototype.buildHeaderDates = function () {
8470            var dates = [];
8471            for (var col = 0; col < this.colCnt; col++) {
8472                dates.push(this.cells[0][col].date);
8473            }
8474            return dates;
8475        };
8476        DayTable.prototype.sliceRange = function (range) {
8477            var colCnt = this.colCnt;
8478            var seriesSeg = this.daySeries.sliceRange(range);
8479            var segs = [];
8480            if (seriesSeg) {
8481                var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex;
8482                var index = firstIndex;
8483                while (index <= lastIndex) {
8484                    var row = Math.floor(index / colCnt);
8485                    var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
8486                    segs.push({
8487                        row: row,
8488                        firstCol: index % colCnt,
8489                        lastCol: (nextIndex - 1) % colCnt,
8490                        isStart: seriesSeg.isStart && index === firstIndex,
8491                        isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex
8492                    });
8493                    index = nextIndex;
8494                }
8495            }
8496            return segs;
8497        };
8498        return DayTable;
8499    }());
8500
8501    var Slicer = /** @class */ (function () {
8502        function Slicer() {
8503            this.sliceBusinessHours = memoize(this._sliceBusinessHours);
8504            this.sliceDateSelection = memoize(this._sliceDateSpan);
8505            this.sliceEventStore = memoize(this._sliceEventStore);
8506            this.sliceEventDrag = memoize(this._sliceInteraction);
8507            this.sliceEventResize = memoize(this._sliceInteraction);
8508        }
8509        Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, component) {
8510            var extraArgs = [];
8511            for (var _i = 4; _i < arguments.length; _i++) {
8512                extraArgs[_i - 4] = arguments[_i];
8513            }
8514            var eventUiBases = props.eventUiBases;
8515            var eventSegs = this.sliceEventStore.apply(this, [props.eventStore, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs));
8516            return {
8517                dateSelectionSegs: this.sliceDateSelection.apply(this, [props.dateSelection, eventUiBases, component].concat(extraArgs)),
8518                businessHourSegs: this.sliceBusinessHours.apply(this, [props.businessHours, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8519                fgEventSegs: eventSegs.fg,
8520                bgEventSegs: eventSegs.bg,
8521                eventDrag: this.sliceEventDrag.apply(this, [props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8522                eventResize: this.sliceEventResize.apply(this, [props.eventResize, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8523                eventSelection: props.eventSelection
8524            }; // TODO: give interactionSegs?
8525        };
8526        Slicer.prototype.sliceNowDate = function (// does not memoize
8527        date, component) {
8528            var extraArgs = [];
8529            for (var _i = 2; _i < arguments.length; _i++) {
8530                extraArgs[_i - 2] = arguments[_i];
8531            }
8532            return this._sliceDateSpan.apply(this, [{ range: { start: date, end: addMs(date, 1) }, allDay: false },
8533                {},
8534                component].concat(extraArgs));
8535        };
8536        Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, component) {
8537            var extraArgs = [];
8538            for (var _i = 4; _i < arguments.length; _i++) {
8539                extraArgs[_i - 4] = arguments[_i];
8540            }
8541            if (!businessHours) {
8542                return [];
8543            }
8544            return this._sliceEventStore.apply(this, [expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), component.calendar),
8545                {},
8546                dateProfile,
8547                nextDayThreshold,
8548                component].concat(extraArgs)).bg;
8549        };
8550        Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold, component) {
8551            var extraArgs = [];
8552            for (var _i = 5; _i < arguments.length; _i++) {
8553                extraArgs[_i - 5] = arguments[_i];
8554            }
8555            if (eventStore) {
8556                var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8557                return {
8558                    bg: this.sliceEventRanges(rangeRes.bg, component, extraArgs),
8559                    fg: this.sliceEventRanges(rangeRes.fg, component, extraArgs)
8560                };
8561            }
8562            else {
8563                return { bg: [], fg: [] };
8564            }
8565        };
8566        Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold, component) {
8567            var extraArgs = [];
8568            for (var _i = 5; _i < arguments.length; _i++) {
8569                extraArgs[_i - 5] = arguments[_i];
8570            }
8571            if (!interaction) {
8572                return null;
8573            }
8574            var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8575            return {
8576                segs: this.sliceEventRanges(rangeRes.fg, component, extraArgs),
8577                affectedInstances: interaction.affectedEvents.instances,
8578                isEvent: interaction.isEvent,
8579                sourceSeg: interaction.origSeg
8580            };
8581        };
8582        Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, component) {
8583            var extraArgs = [];
8584            for (var _i = 3; _i < arguments.length; _i++) {
8585                extraArgs[_i - 3] = arguments[_i];
8586            }
8587            if (!dateSpan) {
8588                return [];
8589            }
8590            var eventRange = fabricateEventRange(dateSpan, eventUiBases, component.calendar);
8591            var segs = this.sliceRange.apply(this, [dateSpan.range].concat(extraArgs));
8592            for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) {
8593                var seg = segs_1[_a];
8594                seg.component = component;
8595                seg.eventRange = eventRange;
8596            }
8597            return segs;
8598        };
8599        /*
8600        "complete" seg means it has component and eventRange
8601        */
8602        Slicer.prototype.sliceEventRanges = function (eventRanges, component, // TODO: kill
8603        extraArgs) {
8604            var segs = [];
8605            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
8606                var eventRange = eventRanges_1[_i];
8607                segs.push.apply(segs, this.sliceEventRange(eventRange, component, extraArgs));
8608            }
8609            return segs;
8610        };
8611        /*
8612        "complete" seg means it has component and eventRange
8613        */
8614        Slicer.prototype.sliceEventRange = function (eventRange, component, // TODO: kill
8615        extraArgs) {
8616            var segs = this.sliceRange.apply(this, [eventRange.range].concat(extraArgs));
8617            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
8618                var seg = segs_2[_i];
8619                seg.component = component;
8620                seg.eventRange = eventRange;
8621                seg.isStart = eventRange.isStart && seg.isStart;
8622                seg.isEnd = eventRange.isEnd && seg.isEnd;
8623            }
8624            return segs;
8625        };
8626        return Slicer;
8627    }());
8628    /*
8629    for incorporating minTime/maxTime if appropriate
8630    TODO: should be part of DateProfile!
8631    TimelineDateProfile already does this btw
8632    */
8633    function computeActiveRange(dateProfile, isComponentAllDay) {
8634        var range = dateProfile.activeRange;
8635        if (isComponentAllDay) {
8636            return range;
8637        }
8638        return {
8639            start: addMs(range.start, dateProfile.minTime.milliseconds),
8640            end: addMs(range.end, dateProfile.maxTime.milliseconds - 864e5) // 864e5 = ms in a day
8641        };
8642    }
8643
8644    // exports
8645    // --------------------------------------------------------------------------------------------------
8646    var version = '4.1.0';
8647
8648    exports.Calendar = Calendar;
8649    exports.Component = Component;
8650    exports.DateComponent = DateComponent;
8651    exports.DateEnv = DateEnv;
8652    exports.DateProfileGenerator = DateProfileGenerator;
8653    exports.DayHeader = DayHeader;
8654    exports.DaySeries = DaySeries;
8655    exports.DayTable = DayTable;
8656    exports.ElementDragging = ElementDragging;
8657    exports.ElementScrollController = ElementScrollController;
8658    exports.EmitterMixin = EmitterMixin;
8659    exports.EventApi = EventApi;
8660    exports.FgEventRenderer = FgEventRenderer;
8661    exports.FillRenderer = FillRenderer;
8662    exports.Interaction = Interaction;
8663    exports.Mixin = Mixin;
8664    exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
8665    exports.PositionCache = PositionCache;
8666    exports.ScrollComponent = ScrollComponent;
8667    exports.ScrollController = ScrollController;
8668    exports.Slicer = Slicer;
8669    exports.Splitter = Splitter;
8670    exports.Theme = Theme;
8671    exports.View = View;
8672    exports.WindowScrollController = WindowScrollController;
8673    exports.addDays = addDays;
8674    exports.addDurations = addDurations;
8675    exports.addMs = addMs;
8676    exports.addWeeks = addWeeks;
8677    exports.allowContextMenu = allowContextMenu;
8678    exports.allowSelection = allowSelection;
8679    exports.appendToElement = appendToElement;
8680    exports.applyAll = applyAll;
8681    exports.applyMutationToEventStore = applyMutationToEventStore;
8682    exports.applyStyle = applyStyle;
8683    exports.applyStyleProp = applyStyleProp;
8684    exports.asRoughMinutes = asRoughMinutes;
8685    exports.asRoughMs = asRoughMs;
8686    exports.asRoughSeconds = asRoughSeconds;
8687    exports.buildGotoAnchorHtml = buildGotoAnchorHtml;
8688    exports.buildSegCompareObj = buildSegCompareObj;
8689    exports.capitaliseFirstLetter = capitaliseFirstLetter;
8690    exports.combineEventUis = combineEventUis;
8691    exports.compareByFieldSpec = compareByFieldSpec;
8692    exports.compareByFieldSpecs = compareByFieldSpecs;
8693    exports.compareNumbers = compareNumbers;
8694    exports.compensateScroll = compensateScroll;
8695    exports.computeClippingRect = computeClippingRect;
8696    exports.computeEdges = computeEdges;
8697    exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat;
8698    exports.computeHeightAndMargins = computeHeightAndMargins;
8699    exports.computeInnerRect = computeInnerRect;
8700    exports.computeRect = computeRect;
8701    exports.computeVisibleDayRange = computeVisibleDayRange;
8702    exports.config = config;
8703    exports.constrainPoint = constrainPoint;
8704    exports.createDuration = createDuration;
8705    exports.createElement = createElement;
8706    exports.createEmptyEventStore = createEmptyEventStore;
8707    exports.createEventInstance = createEventInstance;
8708    exports.createFormatter = createFormatter;
8709    exports.createPlugin = createPlugin;
8710    exports.cssToStr = cssToStr;
8711    exports.debounce = debounce;
8712    exports.diffDates = diffDates;
8713    exports.diffDayAndTime = diffDayAndTime;
8714    exports.diffDays = diffDays;
8715    exports.diffPoints = diffPoints;
8716    exports.diffWeeks = diffWeeks;
8717    exports.diffWholeDays = diffWholeDays;
8718    exports.diffWholeWeeks = diffWholeWeeks;
8719    exports.disableCursor = disableCursor;
8720    exports.distributeHeight = distributeHeight;
8721    exports.elementClosest = elementClosest;
8722    exports.elementMatches = elementMatches;
8723    exports.enableCursor = enableCursor;
8724    exports.eventTupleToStore = eventTupleToStore;
8725    exports.filterEventStoreDefs = filterEventStoreDefs;
8726    exports.filterHash = filterHash;
8727    exports.findChildren = findChildren;
8728    exports.findElements = findElements;
8729    exports.flexibleCompare = flexibleCompare;
8730    exports.forceClassName = forceClassName;
8731    exports.formatDate = formatDate;
8732    exports.formatIsoTimeString = formatIsoTimeString;
8733    exports.formatRange = formatRange;
8734    exports.freezeRaw = freezeRaw;
8735    exports.getAllDayHtml = getAllDayHtml;
8736    exports.getClippingParents = getClippingParents;
8737    exports.getDayClasses = getDayClasses;
8738    exports.getElSeg = getElSeg;
8739    exports.getRectCenter = getRectCenter;
8740    exports.getRelevantEvents = getRelevantEvents;
8741    exports.globalDefaults = globalDefaults;
8742    exports.greatestDurationDenominator = greatestDurationDenominator;
8743    exports.hasBgRendering = hasBgRendering;
8744    exports.htmlEscape = htmlEscape;
8745    exports.htmlToElement = htmlToElement;
8746    exports.insertAfterElement = insertAfterElement;
8747    exports.interactionSettingsStore = interactionSettingsStore;
8748    exports.interactionSettingsToStore = interactionSettingsToStore;
8749    exports.intersectRanges = intersectRanges;
8750    exports.intersectRects = intersectRects;
8751    exports.isArraysEqual = isArraysEqual;
8752    exports.isDateSpansEqual = isDateSpansEqual;
8753    exports.isInt = isInt;
8754    exports.isInteractionValid = isInteractionValid;
8755    exports.isMultiDayRange = isMultiDayRange;
8756    exports.isObjectsSimilar = isObjectsSimilar;
8757    exports.isPropsValid = isPropsValid;
8758    exports.isSingleDay = isSingleDay;
8759    exports.isValidDate = isValidDate;
8760    exports.isValuesSimilar = isValuesSimilar;
8761    exports.listenBySelector = listenBySelector;
8762    exports.mapHash = mapHash;
8763    exports.matchCellWidths = matchCellWidths;
8764    exports.memoize = memoize;
8765    exports.memoizeOutput = memoizeOutput;
8766    exports.memoizeRendering = memoizeRendering;
8767    exports.mergeEventStores = mergeEventStores;
8768    exports.multiplyDuration = multiplyDuration;
8769    exports.padStart = padStart;
8770    exports.parseBusinessHours = parseBusinessHours;
8771    exports.parseDragMeta = parseDragMeta;
8772    exports.parseEventDef = parseEventDef;
8773    exports.parseFieldSpecs = parseFieldSpecs;
8774    exports.parseMarker = parse;
8775    exports.pointInsideRect = pointInsideRect;
8776    exports.prependToElement = prependToElement;
8777    exports.preventContextMenu = preventContextMenu;
8778    exports.preventDefault = preventDefault;
8779    exports.preventSelection = preventSelection;
8780    exports.processScopedUiProps = processScopedUiProps;
8781    exports.rangeContainsMarker = rangeContainsMarker;
8782    exports.rangeContainsRange = rangeContainsRange;
8783    exports.rangesEqual = rangesEqual;
8784    exports.rangesIntersect = rangesIntersect;
8785    exports.refineProps = refineProps;
8786    exports.removeElement = removeElement;
8787    exports.removeExact = removeExact;
8788    exports.renderDateCell = renderDateCell;
8789    exports.requestJson = requestJson;
8790    exports.sliceEventStore = sliceEventStore;
8791    exports.startOfDay = startOfDay;
8792    exports.subtractInnerElHeight = subtractInnerElHeight;
8793    exports.translateRect = translateRect;
8794    exports.uncompensateScroll = uncompensateScroll;
8795    exports.undistributeHeight = undistributeHeight;
8796    exports.unpromisify = unpromisify;
8797    exports.version = version;
8798    exports.whenTransitionDone = whenTransitionDone;
8799    exports.wholeDivideDurations = wholeDivideDurations;
8800
8801    Object.defineProperty(exports, '__esModule', { value: true });
8802
8803}));
8804
8805/*!
8806FullCalendar Day Grid Plugin v4.1.0
8807Docs & License: https://fullcalendar.io/
8808(c) 2019 Adam Shaw
8809*/
8810(function (global, factory) {
8811    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
8812    typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
8813    (global = global || self, factory(global.FullCalendarDayGrid = {}, global.FullCalendar));
8814}(this, function (exports, core) { 'use strict';
8815
8816    /*! *****************************************************************************
8817    Copyright (c) Microsoft Corporation. All rights reserved.
8818    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
8819    this file except in compliance with the License. You may obtain a copy of the
8820    License at http://www.apache.org/licenses/LICENSE-2.0
8821
8822    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8823    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
8824    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
8825    MERCHANTABLITY OR NON-INFRINGEMENT.
8826
8827    See the Apache Version 2.0 License for specific language governing permissions
8828    and limitations under the License.
8829    ***************************************************************************** */
8830    /* global Reflect, Promise */
8831
8832    var extendStatics = function(d, b) {
8833        extendStatics = Object.setPrototypeOf ||
8834            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
8835            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
8836        return extendStatics(d, b);
8837    };
8838
8839    function __extends(d, b) {
8840        extendStatics(d, b);
8841        function __() { this.constructor = d; }
8842        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
8843    }
8844
8845    var __assign = function() {
8846        __assign = Object.assign || function __assign(t) {
8847            for (var s, i = 1, n = arguments.length; i < n; i++) {
8848                s = arguments[i];
8849                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
8850            }
8851            return t;
8852        };
8853        return __assign.apply(this, arguments);
8854    };
8855
8856    var DayGridDateProfileGenerator = /** @class */ (function (_super) {
8857        __extends(DayGridDateProfileGenerator, _super);
8858        function DayGridDateProfileGenerator() {
8859            return _super !== null && _super.apply(this, arguments) || this;
8860        }
8861        // Computes the date range that will be rendered.
8862        DayGridDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
8863            var dateEnv = this.dateEnv;
8864            var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay);
8865            var start = renderRange.start;
8866            var end = renderRange.end;
8867            var endOfWeek;
8868            // year and month views should be aligned with weeks. this is already done for week
8869            if (/^(year|month)$/.test(currentRangeUnit)) {
8870                start = dateEnv.startOfWeek(start);
8871                // make end-of-week if not already
8872                endOfWeek = dateEnv.startOfWeek(end);
8873                if (endOfWeek.valueOf() !== end.valueOf()) {
8874                    end = core.addWeeks(endOfWeek, 1);
8875                }
8876            }
8877            // ensure 6 weeks
8878            if (this.options.monthMode &&
8879                this.options.fixedWeekCount) {
8880                var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
8881                core.diffWeeks(start, end));
8882                end = core.addWeeks(end, 6 - rowCnt);
8883            }
8884            return { start: start, end: end };
8885        };
8886        return DayGridDateProfileGenerator;
8887    }(core.DateProfileGenerator));
8888
8889    /* A rectangular panel that is absolutely positioned over other content
8890    ------------------------------------------------------------------------------------------------------------------------
8891    Options:
8892      - className (string)
8893      - content (HTML string, element, or element array)
8894      - parentEl
8895      - top
8896      - left
8897      - right (the x coord of where the right edge should be. not a "CSS" right)
8898      - autoHide (boolean)
8899      - show (callback)
8900      - hide (callback)
8901    */
8902    var Popover = /** @class */ (function () {
8903        function Popover(options) {
8904            var _this = this;
8905            this.isHidden = true;
8906            this.margin = 10; // the space required between the popover and the edges of the scroll container
8907            // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
8908            this.documentMousedown = function (ev) {
8909                // only hide the popover if the click happened outside the popover
8910                if (_this.el && !_this.el.contains(ev.target)) {
8911                    _this.hide();
8912                }
8913            };
8914            this.options = options;
8915        }
8916        // Shows the popover on the specified position. Renders it if not already
8917        Popover.prototype.show = function () {
8918            if (this.isHidden) {
8919                if (!this.el) {
8920                    this.render();
8921                }
8922                this.el.style.display = '';
8923                this.position();
8924                this.isHidden = false;
8925                this.trigger('show');
8926            }
8927        };
8928        // Hides the popover, through CSS, but does not remove it from the DOM
8929        Popover.prototype.hide = function () {
8930            if (!this.isHidden) {
8931                this.el.style.display = 'none';
8932                this.isHidden = true;
8933                this.trigger('hide');
8934            }
8935        };
8936        // Creates `this.el` and renders content inside of it
8937        Popover.prototype.render = function () {
8938            var _this = this;
8939            var options = this.options;
8940            var el = this.el = core.createElement('div', {
8941                className: 'fc-popover ' + (options.className || ''),
8942                style: {
8943                    top: '0',
8944                    left: '0'
8945                }
8946            });
8947            if (typeof options.content === 'function') {
8948                options.content(el);
8949            }
8950            options.parentEl.appendChild(el);
8951            // when a click happens on anything inside with a 'fc-close' className, hide the popover
8952            core.listenBySelector(el, 'click', '.fc-close', function (ev) {
8953                _this.hide();
8954            });
8955            if (options.autoHide) {
8956                document.addEventListener('mousedown', this.documentMousedown);
8957            }
8958        };
8959        // Hides and unregisters any handlers
8960        Popover.prototype.destroy = function () {
8961            this.hide();
8962            if (this.el) {
8963                core.removeElement(this.el);
8964                this.el = null;
8965            }
8966            document.removeEventListener('mousedown', this.documentMousedown);
8967        };
8968        // Positions the popover optimally, using the top/left/right options
8969        Popover.prototype.position = function () {
8970            var options = this.options;
8971            var el = this.el;
8972            var elDims = el.getBoundingClientRect(); // only used for width,height
8973            var origin = core.computeRect(el.offsetParent);
8974            var clippingRect = core.computeClippingRect(options.parentEl);
8975            var top; // the "position" (not "offset") values for the popover
8976            var left; //
8977            // compute top and left
8978            top = options.top || 0;
8979            if (options.left !== undefined) {
8980                left = options.left;
8981            }
8982            else if (options.right !== undefined) {
8983                left = options.right - elDims.width; // derive the left value from the right value
8984            }
8985            else {
8986                left = 0;
8987            }
8988            // constrain to the view port. if constrained by two edges, give precedence to top/left
8989            top = Math.min(top, clippingRect.bottom - elDims.height - this.margin);
8990            top = Math.max(top, clippingRect.top + this.margin);
8991            left = Math.min(left, clippingRect.right - elDims.width - this.margin);
8992            left = Math.max(left, clippingRect.left + this.margin);
8993            core.applyStyle(el, {
8994                top: top - origin.top,
8995                left: left - origin.left
8996            });
8997        };
8998        // Triggers a callback. Calls a function in the option hash of the same name.
8999        // Arguments beyond the first `name` are forwarded on.
9000        // TODO: better code reuse for this. Repeat code
9001        // can kill this???
9002        Popover.prototype.trigger = function (name) {
9003            if (this.options[name]) {
9004                this.options[name].apply(this, Array.prototype.slice.call(arguments, 1));
9005            }
9006        };
9007        return Popover;
9008    }());
9009
9010    /* Event-rendering methods for the DayGrid class
9011    ----------------------------------------------------------------------------------------------------------------------*/
9012    // "Simple" is bad a name. has nothing to do with SimpleDayGrid
9013    var SimpleDayGridEventRenderer = /** @class */ (function (_super) {
9014        __extends(SimpleDayGridEventRenderer, _super);
9015        function SimpleDayGridEventRenderer() {
9016            return _super !== null && _super.apply(this, arguments) || this;
9017        }
9018        // Builds the HTML to be used for the default element for an individual segment
9019        SimpleDayGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) {
9020            var options = this.context.options;
9021            var eventRange = seg.eventRange;
9022            var eventDef = eventRange.def;
9023            var eventUi = eventRange.ui;
9024            var allDay = eventDef.allDay;
9025            var isDraggable = eventUi.startEditable;
9026            var isResizableFromStart = allDay && seg.isStart && eventUi.durationEditable && options.eventResizableFromStart;
9027            var isResizableFromEnd = allDay && seg.isEnd && eventUi.durationEditable;
9028            var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo);
9029            var skinCss = core.cssToStr(this.getSkinCss(eventUi));
9030            var timeHtml = '';
9031            var timeText;
9032            var titleHtml;
9033            classes.unshift('fc-day-grid-event', 'fc-h-event');
9034            // Only display a timed events time if it is the starting segment
9035            if (seg.isStart) {
9036                timeText = this.getTimeText(eventRange);
9037                if (timeText) {
9038                    timeHtml = '<span class="fc-time">' + core.htmlEscape(timeText) + '</span>';
9039                }
9040            }
9041            titleHtml =
9042                '<span class="fc-title">' +
9043                    (core.htmlEscape(eventDef.title || '') || '&nbsp;') + // we always want one line of height
9044                    '</span>';
9045            return '<a class="' + classes.join(' ') + '"' +
9046                (eventDef.url ?
9047                    ' href="' + core.htmlEscape(eventDef.url) + '"' :
9048                    '') +
9049                (skinCss ?
9050                    ' style="' + skinCss + '"' :
9051                    '') +
9052                '>' +
9053                '<div class="fc-content">' +
9054                (options.dir === 'rtl' ?
9055                    titleHtml + ' ' + timeHtml : // put a natural space in between
9056                    timeHtml + ' ' + titleHtml //
9057                ) +
9058                '</div>' +
9059                (isResizableFromStart ?
9060                    '<div class="fc-resizer fc-start-resizer"></div>' :
9061                    '') +
9062                (isResizableFromEnd ?
9063                    '<div class="fc-resizer fc-end-resizer"></div>' :
9064                    '') +
9065                '</a>';
9066        };
9067        // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined
9068        SimpleDayGridEventRenderer.prototype.computeEventTimeFormat = function () {
9069            return {
9070                hour: 'numeric',
9071                minute: '2-digit',
9072                omitZeroMinute: true,
9073                meridiem: 'narrow'
9074            };
9075        };
9076        SimpleDayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
9077            return false; // TODO: somehow consider the originating DayGrid's column count
9078        };
9079        return SimpleDayGridEventRenderer;
9080    }(core.FgEventRenderer));
9081
9082    /* Event-rendering methods for the DayGrid class
9083    ----------------------------------------------------------------------------------------------------------------------*/
9084    var DayGridEventRenderer = /** @class */ (function (_super) {
9085        __extends(DayGridEventRenderer, _super);
9086        function DayGridEventRenderer(dayGrid) {
9087            var _this = _super.call(this, dayGrid.context) || this;
9088            _this.dayGrid = dayGrid;
9089            return _this;
9090        }
9091        // Renders the given foreground event segments onto the grid
9092        DayGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
9093            var rowStructs = this.rowStructs = this.renderSegRows(segs);
9094            // append to each row's content skeleton
9095            this.dayGrid.rowEls.forEach(function (rowNode, i) {
9096                rowNode.querySelector('.fc-content-skeleton > table').appendChild(rowStructs[i].tbodyEl);
9097            });
9098            // removes the "more.." events popover
9099            if (!mirrorInfo) {
9100                this.dayGrid.removeSegPopover();
9101            }
9102        };
9103        // Unrenders all currently rendered foreground event segments
9104        DayGridEventRenderer.prototype.detachSegs = function () {
9105            var rowStructs = this.rowStructs || [];
9106            var rowStruct;
9107            while ((rowStruct = rowStructs.pop())) {
9108                core.removeElement(rowStruct.tbodyEl);
9109            }
9110            this.rowStructs = null;
9111        };
9112        // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.
9113        // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
9114        // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
9115        DayGridEventRenderer.prototype.renderSegRows = function (segs) {
9116            var rowStructs = [];
9117            var segRows;
9118            var row;
9119            segRows = this.groupSegRows(segs); // group into nested arrays
9120            // iterate each row of segment groupings
9121            for (row = 0; row < segRows.length; row++) {
9122                rowStructs.push(this.renderSegRow(row, segRows[row]));
9123            }
9124            return rowStructs;
9125        };
9126        // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains
9127        // the segments. Returns object with a bunch of internal data about how the render was calculated.
9128        // NOTE: modifies rowSegs
9129        DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) {
9130            var dayGrid = this.dayGrid;
9131            var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl;
9132            var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels
9133            var levelCnt = Math.max(1, segLevels.length); // ensure at least one level
9134            var tbody = document.createElement('tbody');
9135            var segMatrix = []; // lookup for which segments are rendered into which level+col cells
9136            var cellMatrix = []; // lookup for all <td> elements of the level+col matrix
9137            var loneCellMatrix = []; // lookup for <td> elements that only take up a single column
9138            var i;
9139            var levelSegs;
9140            var col;
9141            var tr;
9142            var j;
9143            var seg;
9144            var td;
9145            // populates empty cells from the current column (`col`) to `endCol`
9146            function emptyCellsUntil(endCol) {
9147                while (col < endCol) {
9148                    // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell
9149                    td = (loneCellMatrix[i - 1] || [])[col];
9150                    if (td) {
9151                        td.rowSpan = (td.rowSpan || 1) + 1;
9152                    }
9153                    else {
9154                        td = document.createElement('td');
9155                        tr.appendChild(td);
9156                    }
9157                    cellMatrix[i][col] = td;
9158                    loneCellMatrix[i][col] = td;
9159                    col++;
9160                }
9161            }
9162            for (i = 0; i < levelCnt; i++) { // iterate through all levels
9163                levelSegs = segLevels[i];
9164                col = 0;
9165                tr = document.createElement('tr');
9166                segMatrix.push([]);
9167                cellMatrix.push([]);
9168                loneCellMatrix.push([]);
9169                // levelCnt might be 1 even though there are no actual levels. protect against this.
9170                // this single empty row is useful for styling.
9171                if (levelSegs) {
9172                    for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level
9173                        seg = levelSegs[j];
9174                        var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
9175                        var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
9176                        emptyCellsUntil(leftCol);
9177                        // create a container that occupies or more columns. append the event element.
9178                        td = core.createElement('td', { className: 'fc-event-container' }, seg.el);
9179                        if (leftCol !== rightCol) {
9180                            td.colSpan = rightCol - leftCol + 1;
9181                        }
9182                        else { // a single-column segment
9183                            loneCellMatrix[i][col] = td;
9184                        }
9185                        while (col <= rightCol) {
9186                            cellMatrix[i][col] = td;
9187                            segMatrix[i][col] = seg;
9188                            col++;
9189                        }
9190                        tr.appendChild(td);
9191                    }
9192                }
9193                emptyCellsUntil(colCnt); // finish off the row
9194                var introHtml = dayGrid.renderProps.renderIntroHtml();
9195                if (introHtml) {
9196                    if (dayGrid.isRtl) {
9197                        core.appendToElement(tr, introHtml);
9198                    }
9199                    else {
9200                        core.prependToElement(tr, introHtml);
9201                    }
9202                }
9203                tbody.appendChild(tr);
9204            }
9205            return {
9206                row: row,
9207                tbodyEl: tbody,
9208                cellMatrix: cellMatrix,
9209                segMatrix: segMatrix,
9210                segLevels: segLevels,
9211                segs: rowSegs
9212            };
9213        };
9214        // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
9215        // NOTE: modifies segs
9216        DayGridEventRenderer.prototype.buildSegLevels = function (segs) {
9217            var _a = this.dayGrid, isRtl = _a.isRtl, colCnt = _a.colCnt;
9218            var levels = [];
9219            var i;
9220            var seg;
9221            var j;
9222            // Give preference to elements with certain criteria, so they have
9223            // a chance to be closer to the top.
9224            segs = this.sortEventSegs(segs);
9225            for (i = 0; i < segs.length; i++) {
9226                seg = segs[i];
9227                // loop through levels, starting with the topmost, until the segment doesn't collide with other segments
9228                for (j = 0; j < levels.length; j++) {
9229                    if (!isDaySegCollision(seg, levels[j])) {
9230                        break;
9231                    }
9232                }
9233                // `j` now holds the desired subrow index
9234                seg.level = j;
9235                seg.leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol; // for sorting only
9236                seg.rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol // for sorting only
9237                ;
9238                (levels[j] || (levels[j] = [])).push(seg);
9239            }
9240            // order segments left-to-right. very important if calendar is RTL
9241            for (j = 0; j < levels.length; j++) {
9242                levels[j].sort(compareDaySegCols);
9243            }
9244            return levels;
9245        };
9246        // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
9247        DayGridEventRenderer.prototype.groupSegRows = function (segs) {
9248            var segRows = [];
9249            var i;
9250            for (i = 0; i < this.dayGrid.rowCnt; i++) {
9251                segRows.push([]);
9252            }
9253            for (i = 0; i < segs.length; i++) {
9254                segRows[segs[i].row].push(segs[i]);
9255            }
9256            return segRows;
9257        };
9258        // Computes a default `displayEventEnd` value if one is not expliclty defined
9259        DayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
9260            return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day
9261        };
9262        return DayGridEventRenderer;
9263    }(SimpleDayGridEventRenderer));
9264    // Computes whether two segments' columns collide. They are assumed to be in the same row.
9265    function isDaySegCollision(seg, otherSegs) {
9266        var i;
9267        var otherSeg;
9268        for (i = 0; i < otherSegs.length; i++) {
9269            otherSeg = otherSegs[i];
9270            if (otherSeg.firstCol <= seg.lastCol &&
9271                otherSeg.lastCol >= seg.firstCol) {
9272                return true;
9273            }
9274        }
9275        return false;
9276    }
9277    // A cmp function for determining the leftmost event
9278    function compareDaySegCols(a, b) {
9279        return a.leftCol - b.leftCol;
9280    }
9281
9282    var DayGridMirrorRenderer = /** @class */ (function (_super) {
9283        __extends(DayGridMirrorRenderer, _super);
9284        function DayGridMirrorRenderer() {
9285            return _super !== null && _super.apply(this, arguments) || this;
9286        }
9287        DayGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
9288            var sourceSeg = mirrorInfo.sourceSeg;
9289            var rowStructs = this.rowStructs = this.renderSegRows(segs);
9290            // inject each new event skeleton into each associated row
9291            this.dayGrid.rowEls.forEach(function (rowNode, row) {
9292                var skeletonEl = core.htmlToElement('<div class="fc-mirror-skeleton"><table></table></div>'); // will be absolutely positioned
9293                var skeletonTopEl;
9294                var skeletonTop;
9295                // If there is an original segment, match the top position. Otherwise, put it at the row's top level
9296                if (sourceSeg && sourceSeg.row === row) {
9297                    skeletonTopEl = sourceSeg.el;
9298                }
9299                else {
9300                    skeletonTopEl = rowNode.querySelector('.fc-content-skeleton tbody');
9301                    if (!skeletonTopEl) { // when no events
9302                        skeletonTopEl = rowNode.querySelector('.fc-content-skeleton table');
9303                    }
9304                }
9305                skeletonTop = skeletonTopEl.getBoundingClientRect().top -
9306                    rowNode.getBoundingClientRect().top; // the offsetParent origin
9307                skeletonEl.style.top = skeletonTop + 'px';
9308                skeletonEl.querySelector('table').appendChild(rowStructs[row].tbodyEl);
9309                rowNode.appendChild(skeletonEl);
9310            });
9311        };
9312        return DayGridMirrorRenderer;
9313    }(DayGridEventRenderer));
9314
9315    var DayGridFillRenderer = /** @class */ (function (_super) {
9316        __extends(DayGridFillRenderer, _super);
9317        function DayGridFillRenderer(dayGrid) {
9318            var _this = _super.call(this, dayGrid.context) || this;
9319            _this.fillSegTag = 'td'; // override the default tag name
9320            _this.dayGrid = dayGrid;
9321            return _this;
9322        }
9323        DayGridFillRenderer.prototype.renderSegs = function (type, segs) {
9324            // don't render timed background events
9325            if (type === 'bgEvent') {
9326                segs = segs.filter(function (seg) {
9327                    return seg.eventRange.def.allDay;
9328                });
9329            }
9330            _super.prototype.renderSegs.call(this, type, segs);
9331        };
9332        DayGridFillRenderer.prototype.attachSegs = function (type, segs) {
9333            var els = [];
9334            var i;
9335            var seg;
9336            var skeletonEl;
9337            for (i = 0; i < segs.length; i++) {
9338                seg = segs[i];
9339                skeletonEl = this.renderFillRow(type, seg);
9340                this.dayGrid.rowEls[seg.row].appendChild(skeletonEl);
9341                els.push(skeletonEl);
9342            }
9343            return els;
9344        };
9345        // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
9346        DayGridFillRenderer.prototype.renderFillRow = function (type, seg) {
9347            var dayGrid = this.dayGrid;
9348            var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl;
9349            var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
9350            var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
9351            var startCol = leftCol;
9352            var endCol = rightCol + 1;
9353            var className;
9354            var skeletonEl;
9355            var trEl;
9356            if (type === 'businessHours') {
9357                className = 'bgevent';
9358            }
9359            else {
9360                className = type.toLowerCase();
9361            }
9362            skeletonEl = core.htmlToElement('<div class="fc-' + className + '-skeleton">' +
9363                '<table><tr></tr></table>' +
9364                '</div>');
9365            trEl = skeletonEl.getElementsByTagName('tr')[0];
9366            if (startCol > 0) {
9367                core.appendToElement(trEl, 
9368                // will create (startCol + 1) td's
9369                new Array(startCol + 1).join('<td></td>'));
9370            }
9371            seg.el.colSpan = endCol - startCol;
9372            trEl.appendChild(seg.el);
9373            if (endCol < colCnt) {
9374                core.appendToElement(trEl, 
9375                // will create (colCnt - endCol) td's
9376                new Array(colCnt - endCol + 1).join('<td></td>'));
9377            }
9378            var introHtml = dayGrid.renderProps.renderIntroHtml();
9379            if (introHtml) {
9380                if (dayGrid.isRtl) {
9381                    core.appendToElement(trEl, introHtml);
9382                }
9383                else {
9384                    core.prependToElement(trEl, introHtml);
9385                }
9386            }
9387            return skeletonEl;
9388        };
9389        return DayGridFillRenderer;
9390    }(core.FillRenderer));
9391
9392    var DayTile = /** @class */ (function (_super) {
9393        __extends(DayTile, _super);
9394        function DayTile(context, el) {
9395            var _this = _super.call(this, context, el) || this;
9396            var eventRenderer = _this.eventRenderer = new DayTileEventRenderer(_this);
9397            var renderFrame = _this.renderFrame = core.memoizeRendering(_this._renderFrame);
9398            _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderFrame]);
9399            _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
9400            _this.renderEventDrag = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]);
9401            _this.renderEventResize = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]);
9402            context.calendar.registerInteractiveComponent(_this, {
9403                el: _this.el,
9404                useEventCenter: false
9405            });
9406            return _this;
9407        }
9408        DayTile.prototype.render = function (props) {
9409            this.renderFrame(props.date);
9410            this.renderFgEvents(props.fgSegs);
9411            this.renderEventSelection(props.eventSelection);
9412            this.renderEventDrag(props.eventDragInstances);
9413            this.renderEventResize(props.eventResizeInstances);
9414        };
9415        DayTile.prototype.destroy = function () {
9416            _super.prototype.destroy.call(this);
9417            this.renderFrame.unrender(); // should unrender everything else
9418            this.calendar.unregisterInteractiveComponent(this);
9419        };
9420        DayTile.prototype._renderFrame = function (date) {
9421            var _a = this, theme = _a.theme, dateEnv = _a.dateEnv;
9422            var title = dateEnv.format(date, core.createFormatter(this.opt('dayPopoverFormat')) // TODO: cache
9423            );
9424            this.el.innerHTML =
9425                '<div class="fc-header ' + theme.getClass('popoverHeader') + '">' +
9426                    '<span class="fc-title">' +
9427                    core.htmlEscape(title) +
9428                    '</span>' +
9429                    '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' +
9430                    '</div>' +
9431                    '<div class="fc-body ' + theme.getClass('popoverContent') + '">' +
9432                    '<div class="fc-event-container"></div>' +
9433                    '</div>';
9434            this.segContainerEl = this.el.querySelector('.fc-event-container');
9435        };
9436        DayTile.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
9437            var date = this.props.date; // HACK
9438            if (positionLeft < elWidth && positionTop < elHeight) {
9439                return {
9440                    component: this,
9441                    dateSpan: {
9442                        allDay: true,
9443                        range: { start: date, end: core.addDays(date, 1) }
9444                    },
9445                    dayEl: this.el,
9446                    rect: {
9447                        left: 0,
9448                        top: 0,
9449                        right: elWidth,
9450                        bottom: elHeight
9451                    },
9452                    layer: 1
9453                };
9454            }
9455        };
9456        return DayTile;
9457    }(core.DateComponent));
9458    var DayTileEventRenderer = /** @class */ (function (_super) {
9459        __extends(DayTileEventRenderer, _super);
9460        function DayTileEventRenderer(dayTile) {
9461            var _this = _super.call(this, dayTile.context) || this;
9462            _this.dayTile = dayTile;
9463            return _this;
9464        }
9465        DayTileEventRenderer.prototype.attachSegs = function (segs) {
9466            for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
9467                var seg = segs_1[_i];
9468                this.dayTile.segContainerEl.appendChild(seg.el);
9469            }
9470        };
9471        DayTileEventRenderer.prototype.detachSegs = function (segs) {
9472            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
9473                var seg = segs_2[_i];
9474                core.removeElement(seg.el);
9475            }
9476        };
9477        return DayTileEventRenderer;
9478    }(SimpleDayGridEventRenderer));
9479
9480    var DayBgRow = /** @class */ (function () {
9481        function DayBgRow(context) {
9482            this.context = context;
9483        }
9484        DayBgRow.prototype.renderHtml = function (props) {
9485            var parts = [];
9486            if (props.renderIntroHtml) {
9487                parts.push(props.renderIntroHtml());
9488            }
9489            for (var _i = 0, _a = props.cells; _i < _a.length; _i++) {
9490                var cell = _a[_i];
9491                parts.push(renderCellHtml(cell.date, props.dateProfile, this.context, cell.htmlAttrs));
9492            }
9493            if (!props.cells.length) {
9494                parts.push('<td class="fc-day ' + this.context.theme.getClass('widgetContent') + '"></td>');
9495            }
9496            if (this.context.options.dir === 'rtl') {
9497                parts.reverse();
9498            }
9499            return '<tr>' + parts.join('') + '</tr>';
9500        };
9501        return DayBgRow;
9502    }());
9503    function renderCellHtml(date, dateProfile, context, otherAttrs) {
9504        var dateEnv = context.dateEnv, theme = context.theme;
9505        var isDateValid = core.rangeContainsMarker(dateProfile.activeRange, date); // TODO: called too frequently. cache somehow.
9506        var classes = core.getDayClasses(date, dateProfile, context);
9507        classes.unshift('fc-day', theme.getClass('widgetContent'));
9508        return '<td class="' + classes.join(' ') + '"' +
9509            (isDateValid ?
9510                ' data-date="' + dateEnv.formatIso(date, { omitTime: true }) + '"' :
9511                '') +
9512            (otherAttrs ?
9513                ' ' + otherAttrs :
9514                '') +
9515            '></td>';
9516    }
9517
9518    var DAY_NUM_FORMAT = core.createFormatter({ day: 'numeric' });
9519    var WEEK_NUM_FORMAT = core.createFormatter({ week: 'numeric' });
9520    var DayGrid = /** @class */ (function (_super) {
9521        __extends(DayGrid, _super);
9522        function DayGrid(context, el, renderProps) {
9523            var _this = _super.call(this, context, el) || this;
9524            _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid
9525            _this.isCellSizesDirty = false;
9526            var eventRenderer = _this.eventRenderer = new DayGridEventRenderer(_this);
9527            var fillRenderer = _this.fillRenderer = new DayGridFillRenderer(_this);
9528            _this.mirrorRenderer = new DayGridMirrorRenderer(_this);
9529            var renderCells = _this.renderCells = core.memoizeRendering(_this._renderCells, _this._unrenderCells);
9530            _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderCells]);
9531            _this.renderDateSelection = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'highlight'), fillRenderer.unrender.bind(fillRenderer, 'highlight'), [renderCells]);
9532            _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderCells]);
9533            _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderCells]);
9534            _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
9535            _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderCells]);
9536            _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderCells]);
9537            _this.renderProps = renderProps;
9538            return _this;
9539        }
9540        DayGrid.prototype.render = function (props) {
9541            var cells = props.cells;
9542            this.rowCnt = cells.length;
9543            this.colCnt = cells[0].length;
9544            this.renderCells(cells, props.isRigid);
9545            this.renderBusinessHours(props.businessHourSegs);
9546            this.renderDateSelection(props.dateSelectionSegs);
9547            this.renderBgEvents(props.bgEventSegs);
9548            this.renderFgEvents(props.fgEventSegs);
9549            this.renderEventSelection(props.eventSelection);
9550            this.renderEventDrag(props.eventDrag);
9551            this.renderEventResize(props.eventResize);
9552            if (this.segPopoverTile) {
9553                this.updateSegPopoverTile();
9554            }
9555        };
9556        DayGrid.prototype.destroy = function () {
9557            _super.prototype.destroy.call(this);
9558            this.renderCells.unrender(); // will unrender everything else
9559        };
9560        DayGrid.prototype.getCellRange = function (row, col) {
9561            var start = this.props.cells[row][col].date;
9562            var end = core.addDays(start, 1);
9563            return { start: start, end: end };
9564        };
9565        DayGrid.prototype.updateSegPopoverTile = function (date, segs) {
9566            var ownProps = this.props;
9567            this.segPopoverTile.receiveProps({
9568                date: date || this.segPopoverTile.props.date,
9569                fgSegs: segs || this.segPopoverTile.props.fgSegs,
9570                eventSelection: ownProps.eventSelection,
9571                eventDragInstances: ownProps.eventDrag ? ownProps.eventDrag.affectedInstances : null,
9572                eventResizeInstances: ownProps.eventResize ? ownProps.eventResize.affectedInstances : null
9573            });
9574        };
9575        /* Date Rendering
9576        ------------------------------------------------------------------------------------------------------------------*/
9577        DayGrid.prototype._renderCells = function (cells, isRigid) {
9578            var _a = this, view = _a.view, dateEnv = _a.dateEnv;
9579            var _b = this, rowCnt = _b.rowCnt, colCnt = _b.colCnt;
9580            var html = '';
9581            var row;
9582            var col;
9583            for (row = 0; row < rowCnt; row++) {
9584                html += this.renderDayRowHtml(row, isRigid);
9585            }
9586            this.el.innerHTML = html;
9587            this.rowEls = core.findElements(this.el, '.fc-row');
9588            this.cellEls = core.findElements(this.el, '.fc-day, .fc-disabled-day');
9589            if (this.isRtl) {
9590                this.cellEls.reverse();
9591            }
9592            this.rowPositions = new core.PositionCache(this.el, this.rowEls, false, true // vertical
9593            );
9594            this.colPositions = new core.PositionCache(this.el, this.cellEls.slice(0, colCnt), // only the first row
9595            true, false // horizontal
9596            );
9597            // trigger dayRender with each cell's element
9598            for (row = 0; row < rowCnt; row++) {
9599                for (col = 0; col < colCnt; col++) {
9600                    this.publiclyTrigger('dayRender', [
9601                        {
9602                            date: dateEnv.toDate(cells[row][col].date),
9603                            el: this.getCellEl(row, col),
9604                            view: view
9605                        }
9606                    ]);
9607                }
9608            }
9609            this.isCellSizesDirty = true;
9610        };
9611        DayGrid.prototype._unrenderCells = function () {
9612            this.removeSegPopover();
9613        };
9614        // Generates the HTML for a single row, which is a div that wraps a table.
9615        // `row` is the row number.
9616        DayGrid.prototype.renderDayRowHtml = function (row, isRigid) {
9617            var theme = this.theme;
9618            var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')];
9619            if (isRigid) {
9620                classes.push('fc-rigid');
9621            }
9622            var bgRow = new DayBgRow(this.context);
9623            return '' +
9624                '<div class="' + classes.join(' ') + '">' +
9625                '<div class="fc-bg">' +
9626                '<table class="' + theme.getClass('tableGrid') + '">' +
9627                bgRow.renderHtml({
9628                    cells: this.props.cells[row],
9629                    dateProfile: this.props.dateProfile,
9630                    renderIntroHtml: this.renderProps.renderBgIntroHtml
9631                }) +
9632                '</table>' +
9633                '</div>' +
9634                '<div class="fc-content-skeleton">' +
9635                '<table>' +
9636                (this.getIsNumbersVisible() ?
9637                    '<thead>' +
9638                        this.renderNumberTrHtml(row) +
9639                        '</thead>' :
9640                    '') +
9641                '</table>' +
9642                '</div>' +
9643                '</div>';
9644        };
9645        DayGrid.prototype.getIsNumbersVisible = function () {
9646            return this.getIsDayNumbersVisible() ||
9647                this.renderProps.cellWeekNumbersVisible ||
9648                this.renderProps.colWeekNumbersVisible;
9649        };
9650        DayGrid.prototype.getIsDayNumbersVisible = function () {
9651            return this.rowCnt > 1;
9652        };
9653        /* Grid Number Rendering
9654        ------------------------------------------------------------------------------------------------------------------*/
9655        DayGrid.prototype.renderNumberTrHtml = function (row) {
9656            var intro = this.renderProps.renderNumberIntroHtml(row, this);
9657            return '' +
9658                '<tr>' +
9659                (this.isRtl ? '' : intro) +
9660                this.renderNumberCellsHtml(row) +
9661                (this.isRtl ? intro : '') +
9662                '</tr>';
9663        };
9664        DayGrid.prototype.renderNumberCellsHtml = function (row) {
9665            var htmls = [];
9666            var col;
9667            var date;
9668            for (col = 0; col < this.colCnt; col++) {
9669                date = this.props.cells[row][col].date;
9670                htmls.push(this.renderNumberCellHtml(date));
9671            }
9672            if (this.isRtl) {
9673                htmls.reverse();
9674            }
9675            return htmls.join('');
9676        };
9677        // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
9678        // The number row will only exist if either day numbers or week numbers are turned on.
9679        DayGrid.prototype.renderNumberCellHtml = function (date) {
9680            var _a = this, view = _a.view, dateEnv = _a.dateEnv;
9681            var html = '';
9682            var isDateValid = core.rangeContainsMarker(this.props.dateProfile.activeRange, date); // TODO: called too frequently. cache somehow.
9683            var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid;
9684            var classes;
9685            var weekCalcFirstDow;
9686            if (!isDayNumberVisible && !this.renderProps.cellWeekNumbersVisible) {
9687                // no numbers in day cell (week number must be along the side)
9688                return '<td></td>'; //  will create an empty space above events :(
9689            }
9690            classes = core.getDayClasses(date, this.props.dateProfile, this.context);
9691            classes.unshift('fc-day-top');
9692            if (this.renderProps.cellWeekNumbersVisible) {
9693                weekCalcFirstDow = dateEnv.weekDow;
9694            }
9695            html += '<td class="' + classes.join(' ') + '"' +
9696                (isDateValid ?
9697                    ' data-date="' + dateEnv.formatIso(date, { omitTime: true }) + '"' :
9698                    '') +
9699                '>';
9700            if (this.renderProps.cellWeekNumbersVisible && (date.getUTCDay() === weekCalcFirstDow)) {
9701                html += core.buildGotoAnchorHtml(view, { date: date, type: 'week' }, { 'class': 'fc-week-number' }, dateEnv.format(date, WEEK_NUM_FORMAT) // inner HTML
9702                );
9703            }
9704            if (isDayNumberVisible) {
9705                html += core.buildGotoAnchorHtml(view, date, { 'class': 'fc-day-number' }, dateEnv.format(date, DAY_NUM_FORMAT) // inner HTML
9706                );
9707            }
9708            html += '</td>';
9709            return html;
9710        };
9711        /* Sizing
9712        ------------------------------------------------------------------------------------------------------------------*/
9713        DayGrid.prototype.updateSize = function (isResize) {
9714            var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer;
9715            if (isResize ||
9716                this.isCellSizesDirty ||
9717                this.view.calendar.isEventsUpdated // hack
9718            ) {
9719                this.buildPositionCaches();
9720                this.isCellSizesDirty = false;
9721            }
9722            fillRenderer.computeSizes(isResize);
9723            eventRenderer.computeSizes(isResize);
9724            mirrorRenderer.computeSizes(isResize);
9725            fillRenderer.assignSizes(isResize);
9726            eventRenderer.assignSizes(isResize);
9727            mirrorRenderer.assignSizes(isResize);
9728        };
9729        DayGrid.prototype.buildPositionCaches = function () {
9730            this.buildColPositions();
9731            this.buildRowPositions();
9732        };
9733        DayGrid.prototype.buildColPositions = function () {
9734            this.colPositions.build();
9735        };
9736        DayGrid.prototype.buildRowPositions = function () {
9737            this.rowPositions.build();
9738            this.rowPositions.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack
9739        };
9740        /* Hit System
9741        ------------------------------------------------------------------------------------------------------------------*/
9742        DayGrid.prototype.positionToHit = function (leftPosition, topPosition) {
9743            var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions;
9744            var col = colPositions.leftToIndex(leftPosition);
9745            var row = rowPositions.topToIndex(topPosition);
9746            if (row != null && col != null) {
9747                return {
9748                    row: row,
9749                    col: col,
9750                    dateSpan: {
9751                        range: this.getCellRange(row, col),
9752                        allDay: true
9753                    },
9754                    dayEl: this.getCellEl(row, col),
9755                    relativeRect: {
9756                        left: colPositions.lefts[col],
9757                        right: colPositions.rights[col],
9758                        top: rowPositions.tops[row],
9759                        bottom: rowPositions.bottoms[row]
9760                    }
9761                };
9762            }
9763        };
9764        /* Cell System
9765        ------------------------------------------------------------------------------------------------------------------*/
9766        // FYI: the first column is the leftmost column, regardless of date
9767        DayGrid.prototype.getCellEl = function (row, col) {
9768            return this.cellEls[row * this.colCnt + col];
9769        };
9770        /* Event Drag Visualization
9771        ------------------------------------------------------------------------------------------------------------------*/
9772        DayGrid.prototype._renderEventDrag = function (state) {
9773            if (state) {
9774                this.eventRenderer.hideByHash(state.affectedInstances);
9775                this.fillRenderer.renderSegs('highlight', state.segs);
9776            }
9777        };
9778        DayGrid.prototype._unrenderEventDrag = function (state) {
9779            if (state) {
9780                this.eventRenderer.showByHash(state.affectedInstances);
9781                this.fillRenderer.unrender('highlight');
9782            }
9783        };
9784        /* Event Resize Visualization
9785        ------------------------------------------------------------------------------------------------------------------*/
9786        DayGrid.prototype._renderEventResize = function (state) {
9787            if (state) {
9788                this.eventRenderer.hideByHash(state.affectedInstances);
9789                this.fillRenderer.renderSegs('highlight', state.segs);
9790                this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
9791            }
9792        };
9793        DayGrid.prototype._unrenderEventResize = function (state) {
9794            if (state) {
9795                this.eventRenderer.showByHash(state.affectedInstances);
9796                this.fillRenderer.unrender('highlight');
9797                this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
9798            }
9799        };
9800        /* More+ Link Popover
9801        ------------------------------------------------------------------------------------------------------------------*/
9802        DayGrid.prototype.removeSegPopover = function () {
9803            if (this.segPopover) {
9804                this.segPopover.hide(); // in handler, will call segPopover's removeElement
9805            }
9806        };
9807        // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid.
9808        // `levelLimit` can be false (don't limit), a number, or true (should be computed).
9809        DayGrid.prototype.limitRows = function (levelLimit) {
9810            var rowStructs = this.eventRenderer.rowStructs || [];
9811            var row; // row #
9812            var rowLevelLimit;
9813            for (row = 0; row < rowStructs.length; row++) {
9814                this.unlimitRow(row);
9815                if (!levelLimit) {
9816                    rowLevelLimit = false;
9817                }
9818                else if (typeof levelLimit === 'number') {
9819                    rowLevelLimit = levelLimit;
9820                }
9821                else {
9822                    rowLevelLimit = this.computeRowLevelLimit(row);
9823                }
9824                if (rowLevelLimit !== false) {
9825                    this.limitRow(row, rowLevelLimit);
9826                }
9827            }
9828        };
9829        // Computes the number of levels a row will accomodate without going outside its bounds.
9830        // Assumes the row is "rigid" (maintains a constant height regardless of what is inside).
9831        // `row` is the row number.
9832        DayGrid.prototype.computeRowLevelLimit = function (row) {
9833            var rowEl = this.rowEls[row]; // the containing "fake" row div
9834            var rowBottom = rowEl.getBoundingClientRect().bottom; // relative to viewport!
9835            var trEls = core.findChildren(this.eventRenderer.rowStructs[row].tbodyEl);
9836            var i;
9837            var trEl;
9838            // Reveal one level <tr> at a time and stop when we find one out of bounds
9839            for (i = 0; i < trEls.length; i++) {
9840                trEl = trEls[i];
9841                trEl.classList.remove('fc-limited'); // reset to original state (reveal)
9842                if (trEl.getBoundingClientRect().bottom > rowBottom) {
9843                    return i;
9844                }
9845            }
9846            return false; // should not limit at all
9847        };
9848        // Limits the given grid row to the maximum number of levels and injects "more" links if necessary.
9849        // `row` is the row number.
9850        // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
9851        DayGrid.prototype.limitRow = function (row, levelLimit) {
9852            var _this = this;
9853            var _a = this, colCnt = _a.colCnt, isRtl = _a.isRtl;
9854            var rowStruct = this.eventRenderer.rowStructs[row];
9855            var moreNodes = []; // array of "more" <a> links and <td> DOM nodes
9856            var col = 0; // col #, left-to-right (not chronologically)
9857            var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right
9858            var cellMatrix; // a matrix (by level, then column) of all <td> elements in the row
9859            var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes
9860            var i;
9861            var seg;
9862            var segsBelow; // array of segment objects below `seg` in the current `col`
9863            var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies
9864            var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)
9865            var td;
9866            var rowSpan;
9867            var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell
9868            var j;
9869            var moreTd;
9870            var moreWrap;
9871            var moreLink;
9872            // Iterates through empty level cells and places "more" links inside if need be
9873            var emptyCellsUntil = function (endCol) {
9874                while (col < endCol) {
9875                    segsBelow = _this.getCellSegs(row, col, levelLimit);
9876                    if (segsBelow.length) {
9877                        td = cellMatrix[levelLimit - 1][col];
9878                        moreLink = _this.renderMoreLink(row, col, segsBelow);
9879                        moreWrap = core.createElement('div', null, moreLink);
9880                        td.appendChild(moreWrap);
9881                        moreNodes.push(moreWrap);
9882                    }
9883                    col++;
9884                }
9885            };
9886            if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?
9887                levelSegs = rowStruct.segLevels[levelLimit - 1];
9888                cellMatrix = rowStruct.cellMatrix;
9889                limitedNodes = core.findChildren(rowStruct.tbodyEl).slice(levelLimit); // get level <tr> elements past the limit
9890                limitedNodes.forEach(function (node) {
9891                    node.classList.add('fc-limited'); // hide elements and get a simple DOM-nodes array
9892                });
9893                // iterate though segments in the last allowable level
9894                for (i = 0; i < levelSegs.length; i++) {
9895                    seg = levelSegs[i];
9896                    var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
9897                    var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
9898                    emptyCellsUntil(leftCol); // process empty cells before the segment
9899                    // determine *all* segments below `seg` that occupy the same columns
9900                    colSegsBelow = [];
9901                    totalSegsBelow = 0;
9902                    while (col <= rightCol) {
9903                        segsBelow = this.getCellSegs(row, col, levelLimit);
9904                        colSegsBelow.push(segsBelow);
9905                        totalSegsBelow += segsBelow.length;
9906                        col++;
9907                    }
9908                    if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links?
9909                        td = cellMatrix[levelLimit - 1][leftCol]; // the segment's parent cell
9910                        rowSpan = td.rowSpan || 1;
9911                        segMoreNodes = [];
9912                        // make a replacement <td> for each column the segment occupies. will be one for each colspan
9913                        for (j = 0; j < colSegsBelow.length; j++) {
9914                            moreTd = core.createElement('td', { className: 'fc-more-cell', rowSpan: rowSpan });
9915                            segsBelow = colSegsBelow[j];
9916                            moreLink = this.renderMoreLink(row, leftCol + j, [seg].concat(segsBelow) // count seg as hidden too
9917                            );
9918                            moreWrap = core.createElement('div', null, moreLink);
9919                            moreTd.appendChild(moreWrap);
9920                            segMoreNodes.push(moreTd);
9921                            moreNodes.push(moreTd);
9922                        }
9923                        td.classList.add('fc-limited');
9924                        core.insertAfterElement(td, segMoreNodes);
9925                        limitedNodes.push(td);
9926                    }
9927                }
9928                emptyCellsUntil(this.colCnt); // finish off the level
9929                rowStruct.moreEls = moreNodes; // for easy undoing later
9930                rowStruct.limitedEls = limitedNodes; // for easy undoing later
9931            }
9932        };
9933        // Reveals all levels and removes all "more"-related elements for a grid's row.
9934        // `row` is a row number.
9935        DayGrid.prototype.unlimitRow = function (row) {
9936            var rowStruct = this.eventRenderer.rowStructs[row];
9937            if (rowStruct.moreEls) {
9938                rowStruct.moreEls.forEach(core.removeElement);
9939                rowStruct.moreEls = null;
9940            }
9941            if (rowStruct.limitedEls) {
9942                rowStruct.limitedEls.forEach(function (limitedEl) {
9943                    limitedEl.classList.remove('fc-limited');
9944                });
9945                rowStruct.limitedEls = null;
9946            }
9947        };
9948        // Renders an <a> element that represents hidden event element for a cell.
9949        // Responsible for attaching click handler as well.
9950        DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) {
9951            var _this = this;
9952            var _a = this, view = _a.view, dateEnv = _a.dateEnv;
9953            var a = core.createElement('a', { className: 'fc-more' });
9954            a.innerText = this.getMoreLinkText(hiddenSegs.length);
9955            a.addEventListener('click', function (ev) {
9956                var clickOption = _this.opt('eventLimitClick');
9957                var _col = _this.isRtl ? _this.colCnt - col - 1 : col; // HACK: props.cells has different dir system?
9958                var date = _this.props.cells[row][_col].date;
9959                var moreEl = ev.currentTarget;
9960                var dayEl = _this.getCellEl(row, col);
9961                var allSegs = _this.getCellSegs(row, col);
9962                // rescope the segments to be within the cell's date
9963                var reslicedAllSegs = _this.resliceDaySegs(allSegs, date);
9964                var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);
9965                if (typeof clickOption === 'function') {
9966                    // the returned value can be an atomic option
9967                    clickOption = _this.publiclyTrigger('eventLimitClick', [
9968                        {
9969                            date: dateEnv.toDate(date),
9970                            allDay: true,
9971                            dayEl: dayEl,
9972                            moreEl: moreEl,
9973                            segs: reslicedAllSegs,
9974                            hiddenSegs: reslicedHiddenSegs,
9975                            jsEvent: ev,
9976                            view: view
9977                        }
9978                    ]);
9979                }
9980                if (clickOption === 'popover') {
9981                    _this.showSegPopover(row, col, moreEl, reslicedAllSegs);
9982                }
9983                else if (typeof clickOption === 'string') { // a view name
9984                    view.calendar.zoomTo(date, clickOption);
9985                }
9986            });
9987            return a;
9988        };
9989        // Reveals the popover that displays all events within a cell
9990        DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) {
9991            var _this = this;
9992            var _a = this, calendar = _a.calendar, view = _a.view, theme = _a.theme;
9993            var _col = this.isRtl ? this.colCnt - col - 1 : col; // HACK: props.cells has different dir system?
9994            var moreWrap = moreLink.parentNode; // the <div> wrapper around the <a>
9995            var topEl; // the element we want to match the top coordinate of
9996            var options;
9997            if (this.rowCnt === 1) {
9998                topEl = view.el; // will cause the popover to cover any sort of header
9999            }
10000            else {
10001                topEl = this.rowEls[row]; // will align with top of row
10002            }
10003            options = {
10004                className: 'fc-more-popover ' + theme.getClass('popover'),
10005                parentEl: view.el,
10006                top: core.computeRect(topEl).top,
10007                autoHide: true,
10008                content: function (el) {
10009                    _this.segPopoverTile = new DayTile(_this.context, el);
10010                    _this.updateSegPopoverTile(_this.props.cells[row][_col].date, segs);
10011                },
10012                hide: function () {
10013                    _this.segPopoverTile.destroy();
10014                    _this.segPopoverTile = null;
10015                    _this.segPopover.destroy();
10016                    _this.segPopover = null;
10017                }
10018            };
10019            // Determine horizontal coordinate.
10020            // We use the moreWrap instead of the <td> to avoid border confusion.
10021            if (this.isRtl) {
10022                options.right = core.computeRect(moreWrap).right + 1; // +1 to be over cell border
10023            }
10024            else {
10025                options.left = core.computeRect(moreWrap).left - 1; // -1 to be over cell border
10026            }
10027            this.segPopover = new Popover(options);
10028            this.segPopover.show();
10029            calendar.releaseAfterSizingTriggers(); // hack for eventPositioned
10030        };
10031        // Given the events within an array of segment objects, reslice them to be in a single day
10032        DayGrid.prototype.resliceDaySegs = function (segs, dayDate) {
10033            var dayStart = dayDate;
10034            var dayEnd = core.addDays(dayStart, 1);
10035            var dayRange = { start: dayStart, end: dayEnd };
10036            var newSegs = [];
10037            for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
10038                var seg = segs_1[_i];
10039                var eventRange = seg.eventRange;
10040                var origRange = eventRange.range;
10041                var slicedRange = core.intersectRanges(origRange, dayRange);
10042                if (slicedRange) {
10043                    newSegs.push(__assign({}, seg, { eventRange: {
10044                            def: eventRange.def,
10045                            ui: __assign({}, eventRange.ui, { durationEditable: false }),
10046                            instance: eventRange.instance,
10047                            range: slicedRange
10048                        }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }));
10049                }
10050            }
10051            return newSegs;
10052        };
10053        // Generates the text that should be inside a "more" link, given the number of events it represents
10054        DayGrid.prototype.getMoreLinkText = function (num) {
10055            var opt = this.opt('eventLimitText');
10056            if (typeof opt === 'function') {
10057                return opt(num);
10058            }
10059            else {
10060                return '+' + num + ' ' + opt;
10061            }
10062        };
10063        // Returns segments within a given cell.
10064        // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.
10065        DayGrid.prototype.getCellSegs = function (row, col, startLevel) {
10066            var segMatrix = this.eventRenderer.rowStructs[row].segMatrix;
10067            var level = startLevel || 0;
10068            var segs = [];
10069            var seg;
10070            while (level < segMatrix.length) {
10071                seg = segMatrix[level][col];
10072                if (seg) {
10073                    segs.push(seg);
10074                }
10075                level++;
10076            }
10077            return segs;
10078        };
10079        return DayGrid;
10080    }(core.DateComponent));
10081
10082    var WEEK_NUM_FORMAT$1 = core.createFormatter({ week: 'numeric' });
10083    /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
10084    ----------------------------------------------------------------------------------------------------------------------*/
10085    // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
10086    // It is responsible for managing width/height.
10087    var DayGridView = /** @class */ (function (_super) {
10088        __extends(DayGridView, _super);
10089        function DayGridView(context, viewSpec, dateProfileGenerator, parentEl) {
10090            var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
10091            /* Header Rendering
10092            ------------------------------------------------------------------------------------------------------------------*/
10093            // Generates the HTML that will go before the day-of week header cells
10094            _this.renderHeadIntroHtml = function () {
10095                var theme = _this.theme;
10096                if (_this.colWeekNumbersVisible) {
10097                    return '' +
10098                        '<th class="fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.weekNumberStyleAttr() + '>' +
10099                        '<span>' + // needed for matchCellWidths
10100                        core.htmlEscape(_this.opt('weekLabel')) +
10101                        '</span>' +
10102                        '</th>';
10103                }
10104                return '';
10105            };
10106            /* Day Grid Rendering
10107            ------------------------------------------------------------------------------------------------------------------*/
10108            // Generates the HTML that will go before content-skeleton cells that display the day/week numbers
10109            _this.renderDayGridNumberIntroHtml = function (row, dayGrid) {
10110                var dateEnv = _this.dateEnv;
10111                var weekStart = dayGrid.props.cells[row][0].date;
10112                if (_this.colWeekNumbersVisible) {
10113                    return '' +
10114                        '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '>' +
10115                        core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
10116                        _this, { date: weekStart, type: 'week', forceOff: dayGrid.colCnt === 1 }, dateEnv.format(weekStart, WEEK_NUM_FORMAT$1) // inner HTML
10117                        ) +
10118                        '</td>';
10119                }
10120                return '';
10121            };
10122            // Generates the HTML that goes before the day bg cells for each day-row
10123            _this.renderDayGridBgIntroHtml = function () {
10124                var theme = _this.theme;
10125                if (_this.colWeekNumbersVisible) {
10126                    return '<td class="fc-week-number ' + theme.getClass('widgetContent') + '" ' + _this.weekNumberStyleAttr() + '></td>';
10127                }
10128                return '';
10129            };
10130            // Generates the HTML that goes before every other type of row generated by DayGrid.
10131            // Affects mirror-skeleton and highlight-skeleton rows.
10132            _this.renderDayGridIntroHtml = function () {
10133                if (_this.colWeekNumbersVisible) {
10134                    return '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '></td>';
10135                }
10136                return '';
10137            };
10138            _this.el.classList.add('fc-dayGrid-view');
10139            _this.el.innerHTML = _this.renderSkeletonHtml();
10140            _this.scroller = new core.ScrollComponent('hidden', // overflow x
10141            'auto' // overflow y
10142            );
10143            var dayGridContainerEl = _this.scroller.el;
10144            _this.el.querySelector('.fc-body > tr > td').appendChild(dayGridContainerEl);
10145            dayGridContainerEl.classList.add('fc-day-grid-container');
10146            var dayGridEl = core.createElement('div', { className: 'fc-day-grid' });
10147            dayGridContainerEl.appendChild(dayGridEl);
10148            var cellWeekNumbersVisible;
10149            if (_this.opt('weekNumbers')) {
10150                if (_this.opt('weekNumbersWithinDays')) {
10151                    cellWeekNumbersVisible = true;
10152                    _this.colWeekNumbersVisible = false;
10153                }
10154                else {
10155                    cellWeekNumbersVisible = false;
10156                    _this.colWeekNumbersVisible = true;
10157                }
10158            }
10159            else {
10160                _this.colWeekNumbersVisible = false;
10161                cellWeekNumbersVisible = false;
10162            }
10163            _this.dayGrid = new DayGrid(_this.context, dayGridEl, {
10164                renderNumberIntroHtml: _this.renderDayGridNumberIntroHtml,
10165                renderBgIntroHtml: _this.renderDayGridBgIntroHtml,
10166                renderIntroHtml: _this.renderDayGridIntroHtml,
10167                colWeekNumbersVisible: _this.colWeekNumbersVisible,
10168                cellWeekNumbersVisible: cellWeekNumbersVisible
10169            });
10170            return _this;
10171        }
10172        DayGridView.prototype.destroy = function () {
10173            _super.prototype.destroy.call(this);
10174            this.dayGrid.destroy();
10175            this.scroller.destroy();
10176        };
10177        // Builds the HTML skeleton for the view.
10178        // The day-grid component will render inside of a container defined by this HTML.
10179        DayGridView.prototype.renderSkeletonHtml = function () {
10180            var theme = this.theme;
10181            return '' +
10182                '<table class="' + theme.getClass('tableGrid') + '">' +
10183                (this.opt('columnHeader') ?
10184                    '<thead class="fc-head">' +
10185                        '<tr>' +
10186                        '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
10187                        '</tr>' +
10188                        '</thead>' :
10189                    '') +
10190                '<tbody class="fc-body">' +
10191                '<tr>' +
10192                '<td class="' + theme.getClass('widgetContent') + '"></td>' +
10193                '</tr>' +
10194                '</tbody>' +
10195                '</table>';
10196        };
10197        // Generates an HTML attribute string for setting the width of the week number column, if it is known
10198        DayGridView.prototype.weekNumberStyleAttr = function () {
10199            if (this.weekNumberWidth != null) {
10200                return 'style="width:' + this.weekNumberWidth + 'px"';
10201            }
10202            return '';
10203        };
10204        // Determines whether each row should have a constant height
10205        DayGridView.prototype.hasRigidRows = function () {
10206            var eventLimit = this.opt('eventLimit');
10207            return eventLimit && typeof eventLimit !== 'number';
10208        };
10209        /* Dimensions
10210        ------------------------------------------------------------------------------------------------------------------*/
10211        DayGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
10212            _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first
10213            this.dayGrid.updateSize(isResize);
10214        };
10215        // Refreshes the horizontal dimensions of the view
10216        DayGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
10217            var dayGrid = this.dayGrid;
10218            var eventLimit = this.opt('eventLimit');
10219            var headRowEl = this.header ? this.header.el : null; // HACK
10220            var scrollerHeight;
10221            var scrollbarWidths;
10222            // hack to give the view some height prior to dayGrid's columns being rendered
10223            // TODO: separate setting height from scroller VS dayGrid.
10224            if (!dayGrid.rowEls) {
10225                if (!isAuto) {
10226                    scrollerHeight = this.computeScrollerHeight(viewHeight);
10227                    this.scroller.setHeight(scrollerHeight);
10228                }
10229                return;
10230            }
10231            if (this.colWeekNumbersVisible) {
10232                // Make sure all week number cells running down the side have the same width.
10233                this.weekNumberWidth = core.matchCellWidths(core.findElements(this.el, '.fc-week-number'));
10234            }
10235            // reset all heights to be natural
10236            this.scroller.clear();
10237            if (headRowEl) {
10238                core.uncompensateScroll(headRowEl);
10239            }
10240            dayGrid.removeSegPopover(); // kill the "more" popover if displayed
10241            // is the event limit a constant level number?
10242            if (eventLimit && typeof eventLimit === 'number') {
10243                dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after
10244            }
10245            // distribute the height to the rows
10246            // (viewHeight is a "recommended" value if isAuto)
10247            scrollerHeight = this.computeScrollerHeight(viewHeight);
10248            this.setGridHeight(scrollerHeight, isAuto);
10249            // is the event limit dynamically calculated?
10250            if (eventLimit && typeof eventLimit !== 'number') {
10251                dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set
10252            }
10253            if (!isAuto) { // should we force dimensions of the scroll container?
10254                this.scroller.setHeight(scrollerHeight);
10255                scrollbarWidths = this.scroller.getScrollbarWidths();
10256                if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
10257                    if (headRowEl) {
10258                        core.compensateScroll(headRowEl, scrollbarWidths);
10259                    }
10260                    // doing the scrollbar compensation might have created text overflow which created more height. redo
10261                    scrollerHeight = this.computeScrollerHeight(viewHeight);
10262                    this.scroller.setHeight(scrollerHeight);
10263                }
10264                // guarantees the same scrollbar widths
10265                this.scroller.lockOverflow(scrollbarWidths);
10266            }
10267        };
10268        // given a desired total height of the view, returns what the height of the scroller should be
10269        DayGridView.prototype.computeScrollerHeight = function (viewHeight) {
10270            return viewHeight -
10271                core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
10272        };
10273        // Sets the height of just the DayGrid component in this view
10274        DayGridView.prototype.setGridHeight = function (height, isAuto) {
10275            if (this.opt('monthMode')) {
10276                // if auto, make the height of each row the height that it would be if there were 6 weeks
10277                if (isAuto) {
10278                    height *= this.dayGrid.rowCnt / 6;
10279                }
10280                core.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows
10281            }
10282            else {
10283                if (isAuto) {
10284                    core.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding
10285                }
10286                else {
10287                    core.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows
10288                }
10289            }
10290        };
10291        /* Scroll
10292        ------------------------------------------------------------------------------------------------------------------*/
10293        DayGridView.prototype.computeDateScroll = function (timeMs) {
10294            return { top: 0 };
10295        };
10296        DayGridView.prototype.queryDateScroll = function () {
10297            return { top: this.scroller.getScrollTop() };
10298        };
10299        DayGridView.prototype.applyDateScroll = function (scroll) {
10300            if (scroll.top !== undefined) {
10301                this.scroller.setScrollTop(scroll.top);
10302            }
10303        };
10304        return DayGridView;
10305    }(core.View));
10306    DayGridView.prototype.dateProfileGeneratorClass = DayGridDateProfileGenerator;
10307
10308    var SimpleDayGrid = /** @class */ (function (_super) {
10309        __extends(SimpleDayGrid, _super);
10310        function SimpleDayGrid(context, dayGrid) {
10311            var _this = _super.call(this, context, dayGrid.el) || this;
10312            _this.slicer = new DayGridSlicer();
10313            _this.dayGrid = dayGrid;
10314            context.calendar.registerInteractiveComponent(_this, { el: _this.dayGrid.el });
10315            return _this;
10316        }
10317        SimpleDayGrid.prototype.destroy = function () {
10318            _super.prototype.destroy.call(this);
10319            this.calendar.unregisterInteractiveComponent(this);
10320        };
10321        SimpleDayGrid.prototype.render = function (props) {
10322            var dayGrid = this.dayGrid;
10323            var dateProfile = props.dateProfile, dayTable = props.dayTable;
10324            dayGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, props.nextDayThreshold, dayGrid, dayTable), { dateProfile: dateProfile, cells: dayTable.cells, isRigid: props.isRigid }));
10325        };
10326        SimpleDayGrid.prototype.buildPositionCaches = function () {
10327            this.dayGrid.buildPositionCaches();
10328        };
10329        SimpleDayGrid.prototype.queryHit = function (positionLeft, positionTop) {
10330            var rawHit = this.dayGrid.positionToHit(positionLeft, positionTop);
10331            if (rawHit) {
10332                return {
10333                    component: this.dayGrid,
10334                    dateSpan: rawHit.dateSpan,
10335                    dayEl: rawHit.dayEl,
10336                    rect: {
10337                        left: rawHit.relativeRect.left,
10338                        right: rawHit.relativeRect.right,
10339                        top: rawHit.relativeRect.top,
10340                        bottom: rawHit.relativeRect.bottom
10341                    },
10342                    layer: 0
10343                };
10344            }
10345        };
10346        return SimpleDayGrid;
10347    }(core.DateComponent));
10348    var DayGridSlicer = /** @class */ (function (_super) {
10349        __extends(DayGridSlicer, _super);
10350        function DayGridSlicer() {
10351            return _super !== null && _super.apply(this, arguments) || this;
10352        }
10353        DayGridSlicer.prototype.sliceRange = function (dateRange, dayTable) {
10354            return dayTable.sliceRange(dateRange);
10355        };
10356        return DayGridSlicer;
10357    }(core.Slicer));
10358
10359    var DayGridView$1 = /** @class */ (function (_super) {
10360        __extends(DayGridView, _super);
10361        function DayGridView(_context, viewSpec, dateProfileGenerator, parentEl) {
10362            var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this;
10363            _this.buildDayTable = core.memoize(buildDayTable);
10364            if (_this.opt('columnHeader')) {
10365                _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container'));
10366            }
10367            _this.simpleDayGrid = new SimpleDayGrid(_this.context, _this.dayGrid);
10368            return _this;
10369        }
10370        DayGridView.prototype.destroy = function () {
10371            _super.prototype.destroy.call(this);
10372            if (this.header) {
10373                this.header.destroy();
10374            }
10375            this.simpleDayGrid.destroy();
10376        };
10377        DayGridView.prototype.render = function (props) {
10378            _super.prototype.render.call(this, props);
10379            var dateProfile = this.props.dateProfile;
10380            var dayTable = this.dayTable =
10381                this.buildDayTable(dateProfile, this.dateProfileGenerator);
10382            if (this.header) {
10383                this.header.receiveProps({
10384                    dateProfile: dateProfile,
10385                    dates: dayTable.headerDates,
10386                    datesRepDistinctDays: dayTable.rowCnt === 1,
10387                    renderIntroHtml: this.renderHeadIntroHtml
10388                });
10389            }
10390            this.simpleDayGrid.receiveProps({
10391                dateProfile: dateProfile,
10392                dayTable: dayTable,
10393                businessHours: props.businessHours,
10394                dateSelection: props.dateSelection,
10395                eventStore: props.eventStore,
10396                eventUiBases: props.eventUiBases,
10397                eventSelection: props.eventSelection,
10398                eventDrag: props.eventDrag,
10399                eventResize: props.eventResize,
10400                isRigid: this.hasRigidRows(),
10401                nextDayThreshold: this.nextDayThreshold
10402            });
10403        };
10404        return DayGridView;
10405    }(DayGridView));
10406    function buildDayTable(dateProfile, dateProfileGenerator) {
10407        var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator);
10408        return new core.DayTable(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
10409    }
10410
10411    var main = core.createPlugin({
10412        defaultView: 'dayGridMonth',
10413        views: {
10414            dayGrid: DayGridView$1,
10415            dayGridDay: {
10416                type: 'dayGrid',
10417                duration: { days: 1 }
10418            },
10419            dayGridWeek: {
10420                type: 'dayGrid',
10421                duration: { weeks: 1 }
10422            },
10423            dayGridMonth: {
10424                type: 'dayGrid',
10425                duration: { months: 1 },
10426                monthMode: true,
10427                fixedWeekCount: true
10428            }
10429        }
10430    });
10431
10432    exports.AbstractDayGridView = DayGridView;
10433    exports.DayBgRow = DayBgRow;
10434    exports.DayGrid = DayGrid;
10435    exports.DayGridSlicer = DayGridSlicer;
10436    exports.DayGridView = DayGridView$1;
10437    exports.SimpleDayGrid = SimpleDayGrid;
10438    exports.buildBasicDayTable = buildDayTable;
10439    exports.default = main;
10440
10441    Object.defineProperty(exports, '__esModule', { value: true });
10442
10443}));
10444
10445/*!
10446FullCalendar Time Grid Plugin v4.1.0
10447Docs & License: https://fullcalendar.io/
10448(c) 2019 Adam Shaw
10449*/
10450(function (global, factory) {
10451    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core'), require('@fullcalendar/daygrid')) :
10452    typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core', '@fullcalendar/daygri
10452d'], factory) :
10453    (global = global || self, factory(global.FullCalendarTimeGrid = {}, global.FullCalendar, global.FullCalendarDayGrid));
10454}(this, function (exports, core, daygrid) { 'use strict';
10455
10456    /*! *****************************************************************************
10457    Copyright (c) Microsoft Corporation. All rights reserved.
10458    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
10459    this file except in compliance with the License. You may obtain a copy of the
10460    License at http://www.apache.org/licenses/LICENSE-2.0
10461
10462    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
10463    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
10464    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
10465    MERCHANTABLITY OR NON-INFRINGEMENT.
10466
10467    See the Apache Version 2.0 License for specific language governing permissions
10468    and limitations under the License.
10469    ***************************************************************************** */
10470    /* global Reflect, Promise */
10471
10472    var extendStatics = function(d, b) {
10473        extendStatics = Object.setPrototypeOf ||
10474            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
10475            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
10476        return extendStatics(d, b);
10477    };
10478
10479    function __extends(d, b) {
10480        extendStatics(d, b);
10481        function __() { this.constructor = d; }
10482        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10483    }
10484
10485    var __assign = function() {
10486        __assign = Object.assign || function __assign(t) {
10487            for (var s, i = 1, n = arguments.length; i < n; i++) {
10488                s = arguments[i];
10489                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
10490            }
10491            return t;
10492        };
10493        return __assign.apply(this, arguments);
10494    };
10495
10496    /*
10497    Only handles foreground segs.
10498    Does not own rendering. Use for low-level util methods by TimeGrid.
10499    */
10500    var TimeGridEventRenderer = /** @class */ (function (_super) {
10501        __extends(TimeGridEventRenderer, _super);
10502        function TimeGridEventRenderer(timeGrid) {
10503            var _this = _super.call(this, timeGrid.context) || this;
10504            _this.timeGrid = timeGrid;
10505            _this.fullTimeFormat = core.createFormatter({
10506                hour: 'numeric',
10507                minute: '2-digit',
10508                separator: _this.context.options.defaultRangeSeparator
10509            });
10510            return _this;
10511        }
10512        // Given an array of foreground segments, render a DOM element for each, computes position,
10513        // and attaches to the column inner-container elements.
10514        TimeGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
10515            var segsByCol = this.timeGrid.groupSegsByCol(segs);
10516            // order the segs within each column
10517            // TODO: have groupSegsByCol do this?
10518            for (var col = 0; col < segsByCol.length; col++) {
10519                segsByCol[col] = this.sortEventSegs(segsByCol[col]);
10520            }
10521            this.segsByCol = segsByCol;
10522            this.timeGrid.attachSegsByCol(segsByCol, this.timeGrid.fgContainerEls);
10523        };
10524        TimeGridEventRenderer.prototype.detachSegs = function (segs) {
10525            segs.forEach(function (seg) {
10526                core.removeElement(seg.el);
10527            });
10528            this.segsByCol = null;
10529        };
10530        TimeGridEventRenderer.prototype.computeSegSizes = function (allSegs) {
10531            var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
10532            var colCnt = timeGrid.colCnt;
10533            timeGrid.computeSegVerticals(allSegs); // horizontals relies on this
10534            if (segsByCol) {
10535                for (var col = 0; col < colCnt; col++) {
10536                    this.computeSegHorizontals(segsByCol[col]); // compute horizontal coordinates, z-index's, and reorder the array
10537                }
10538            }
10539        };
10540        TimeGridEventRenderer.prototype.assignSegSizes = function (allSegs) {
10541            var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
10542            var colCnt = timeGrid.colCnt;
10543            timeGrid.assignSegVerticals(allSegs); // horizontals relies on this
10544            if (segsByCol) {
10545                for (var col = 0; col < colCnt; col++) {
10546                    this.assignSegCss(segsByCol[col]);
10547                }
10548            }
10549        };
10550        // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined
10551        TimeGridEventRenderer.prototype.computeEventTimeFormat = function () {
10552            return {
10553                hour: 'numeric',
10554                minute: '2-digit',
10555                meridiem: false
10556            };
10557        };
10558        // Computes a default `displayEventEnd` value if one is not expliclty defined
10559        TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () {
10560            return true;
10561        };
10562        // Renders the HTML for a single event segment's default rendering
10563        TimeGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) {
10564            var eventRange = seg.eventRange;
10565            var eventDef = eventRange.def;
10566            var eventUi = eventRange.ui;
10567            var allDay = eventDef.allDay;
10568            var isDraggable = eventUi.startEditable;
10569            var isResizableFromStart = seg.isStart && eventUi.durationEditable && this.context.options.eventResizableFromStart;
10570            var isResizableFromEnd = seg.isEnd && eventUi.durationEditable;
10571            var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo);
10572            var skinCss = core.cssToStr(this.getSkinCss(eventUi));
10573            var timeText;
10574            var fullTimeText; // more verbose time text. for the print stylesheet
10575            var startTimeText; // just the start time text
10576            classes.unshift('fc-time-grid-event');
10577            // if the event appears to span more than one day...
10578            if (core.isMultiDayRange(eventRange.range)) {
10579                // Don't display time text on segments that run entirely through a day.
10580                // That would appear as midnight-midnight and would look dumb.
10581                // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
10582                if (seg.isStart || seg.isEnd) {
10583                    var unzonedStart = seg.start;
10584                    var unzonedEnd = seg.end;
10585                    timeText = this._getTimeText(unzonedStart, unzonedEnd, allDay); // TODO: give the timezones
10586                    fullTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, this.fullTimeFormat);
10587                    startTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, null, false); // displayEnd=false
10588                }
10589            }
10590            else {
10591                // Display the normal time text for the *event's* times
10592                timeText = this.getTimeText(eventRange);
10593                fullTimeText = this.getTimeText(eventRange, this.fullTimeFormat);
10594                startTimeText = this.getTimeText(eventRange, null, false); // displayEnd=false
10595            }
10596            return '<a class="' + classes.join(' ') + '"' +
10597                (eventDef.url ?
10598                    ' href="' + core.htmlEscape(eventDef.url) + '"' :
10599                    '') +
10600                (skinCss ?
10601                    ' style="' + skinCss + '"' :
10602                    '') +
10603                '>' +
10604                '<div class="fc-content">' +
10605                (timeText ?
10606                    '<div class="fc-time"' +
10607                        ' data-start="' + core.htmlEscape(startTimeText) + '"' +
10608                        ' data-full="' + core.htmlEscape(fullTimeText) + '"' +
10609                        '>' +
10610                        '<span>' + core.htmlEscape(timeText) + '</span>' +
10611                        '</div>' :
10612                    '') +
10613                (eventDef.title ?
10614                    '<div class="fc-title">' +
10615                        core.htmlEscape(eventDef.title) +
10616                        '</div>' :
10617                    '') +
10618                '</div>' +
10619                /* TODO: write CSS for this
10620                (isResizableFromStart ?
10621                  '<div class="fc-resizer fc-start-resizer"></div>' :
10622                  ''
10623                  ) +
10624                */
10625                (isResizableFromEnd ?
10626                    '<div class="fc-resizer fc-end-resizer"></div>' :
10627                    '') +
10628                '</a>';
10629        };
10630        // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
10631        // Assumed the segs are already ordered.
10632        // NOTE: Also reorders the given array by date!
10633        TimeGridEventRenderer.prototype.computeSegHorizontals = function (segs) {
10634            var levels;
10635            var level0;
10636            var i;
10637            levels = buildSlotSegLevels(segs);
10638            computeForwardSlotSegs(levels);
10639            if ((level0 = levels[0])) {
10640                for (i = 0; i < level0.length; i++) {
10641                    computeSlotSegPressures(level0[i]);
10642                }
10643                for (i = 0; i < level0.length; i++) {
10644                    this.computeSegForwardBack(level0[i], 0, 0);
10645                }
10646            }
10647        };
10648        // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
10649        // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
10650        // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
10651        //
10652        // The segment might be part of a "series", which means consecutive segments with the same pressure
10653        // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
10654        // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
10655        // coordinate of the first segment in the series.
10656        TimeGridEventRenderer.prototype.computeSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) {
10657            var forwardSegs = seg.forwardSegs;
10658            var i;
10659            if (seg.forwardCoord === undefined) { // not already computed
10660                if (!forwardSegs.length) {
10661                    // if there are no forward segments, this segment should butt up against the edge
10662                    seg.forwardCoord = 1;
10663                }
10664                else {
10665                    // sort highest pressure first
10666                    this.sortForwardSegs(forwardSegs);
10667                    // this segment's forwardCoord will be calculated from the backwardCoord of the
10668                    // highest-pressure forward segment.
10669                    this.computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
10670                    seg.forwardCoord = forwardSegs[0].backwardCoord;
10671                }
10672                // calculate the backwardCoord from the forwardCoord. consider the series
10673                seg.backwardCoord = seg.forwardCoord -
10674                    (seg.forwardCoord - seriesBackwardCoord) / // available width for series
10675                        (seriesBackwardPressure + 1); // # of segments in the series
10676                // use this segment's coordinates to computed the coordinates of the less-pressurized
10677                // forward segments
10678                for (i = 0; i < forwardSegs.length; i++) {
10679                    this.computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
10680                }
10681            }
10682        };
10683        TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) {
10684            var objs = forwardSegs.map(buildTimeGridSegCompareObj);
10685            var specs = [
10686                // put higher-pressure first
10687                { field: 'forwardPressure', order: -1 },
10688                // put segments that are closer to initial edge first (and favor ones with no coords yet)
10689                { field: 'backwardCoord', order: 1 }
10690            ].concat(this.context.view.eventOrderSpecs);
10691            objs.sort(function (obj0, obj1) {
10692                return core.compareByFieldSpecs(obj0, obj1, specs);
10693            });
10694            return objs.map(function (c) {
10695                return c._seg;
10696            });
10697        };
10698        // Given foreground event segments that have already had their position coordinates computed,
10699        // assigns position-related CSS values to their elements.
10700        TimeGridEventRenderer.prototype.assignSegCss = function (segs) {
10701            for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
10702                var seg = segs_1[_i];
10703                core.applyStyle(seg.el, this.generateSegCss(seg));
10704                if (seg.level > 0) {
10705                    seg.el.classList.add('fc-time-grid-event-inset');
10706                }
10707                // if the event is short that the title will be cut off,
10708                // attach a className that condenses the title into the time area.
10709                if (seg.eventRange.def.title && seg.bottom - seg.top < 30) {
10710                    seg.el.classList.add('fc-short'); // TODO: "condensed" is a better name
10711                }
10712            }
10713        };
10714        // Generates an object with CSS properties/values that should be applied to an event segment element.
10715        // Contains important positioning-related properties that should be applied to any event element, customized or not.
10716        TimeGridEventRenderer.prototype.generateSegCss = function (seg) {
10717            var shouldOverlap = this.context.options.slotEventOverlap;
10718            var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
10719            var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
10720            var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first
10721            var isRtl = this.timeGrid.isRtl;
10722            var left; // amount of space from left edge, a fraction of the total width
10723            var right; // amount of space from right edge, a fraction of the total width
10724            if (shouldOverlap) {
10725                // double the width, but don't go beyond the maximum forward coordinate (1.0)
10726                forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
10727            }
10728            if (isRtl) {
10729                left = 1 - forwardCoord;
10730                right = backwardCoord;
10731            }
10732            else {
10733                left = backwardCoord;
10734                right = 1 - forwardCoord;
10735            }
10736            props.zIndex = seg.level + 1; // convert from 0-base to 1-based
10737            props.left = left * 100 + '%';
10738            props.right = right * 100 + '%';
10739            if (shouldOverlap && seg.forwardPressure) {
10740                // add padding to the edge so that forward stacked events don't cover the resizer's icon
10741                props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
10742            }
10743            return props;
10744        };
10745        return TimeGridEventRenderer;
10746    }(core.FgEventRenderer));
10747    // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
10748    // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
10749    function buildSlotSegLevels(segs) {
10750        var levels = [];
10751        var i;
10752        var seg;
10753        var j;
10754        for (i = 0; i < segs.length; i++) {
10755            seg = segs[i];
10756            // go through all the levels and stop on the first level where there are no collisions
10757            for (j = 0; j < levels.length; j++) {
10758                if (!computeSlotSegCollisions(seg, levels[j]).length) {
10759                    break;
10760                }
10761            }
10762            seg.level = j;
10763            (levels[j] || (levels[j] = [])).push(seg);
10764        }
10765        return levels;
10766    }
10767    // For every segment, figure out the other segments that are in subsequent
10768    // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
10769    function computeForwardSlotSegs(levels) {
10770        var i;
10771        var level;
10772        var j;
10773        var seg;
10774        var k;
10775        for (i = 0; i < levels.length; i++) {
10776            level = levels[i];
10777            for (j = 0; j < level.length; j++) {
10778                seg = level[j];
10779                seg.forwardSegs = [];
10780                for (k = i + 1; k < levels.length; k++) {
10781                    computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
10782                }
10783            }
10784        }
10785    }
10786    // Figure out which path forward (via seg.forwardSegs) results in the longest path until
10787    // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
10788    function computeSlotSegPressures(seg) {
10789        var forwardSegs = seg.forwardSegs;
10790        var forwardPressure = 0;
10791        var i;
10792        var forwardSeg;
10793        if (seg.forwardPressure === undefined) { // not already computed
10794            for (i = 0; i < forwardSegs.length; i++) {
10795                forwardSeg = forwardSegs[i];
10796                // figure out the child's maximum forward path
10797                computeSlotSegPressures(forwardSeg);
10798                // either use the existing maximum, or use the child's forward pressure
10799                // plus one (for the forwardSeg itself)
10800                forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
10801            }
10802            seg.forwardPressure = forwardPressure;
10803        }
10804    }
10805    // Find all the segments in `otherSegs` that vertically collide with `seg`.
10806    // Append into an optionally-supplied `results` array and return.
10807    function computeSlotSegCollisions(seg, otherSegs, results) {
10808        if (results === void 0) { results = []; }
10809        for (var i = 0; i < otherSegs.length; i++) {
10810            if (isSlotSegCollision(seg, otherSegs[i])) {
10811                results.push(otherSegs[i]);
10812            }
10813        }
10814        return results;
10815    }
10816    // Do these segments occupy the same vertical space?
10817    function isSlotSegCollision(seg1, seg2) {
10818        return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
10819    }
10820    function buildTimeGridSegCompareObj(seg) {
10821        var obj = core.buildSegCompareObj(seg);
10822        obj.forwardPressure = seg.forwardPressure;
10823        obj.backwardCoord = seg.backwardCoord;
10824        return obj;
10825    }
10826
10827    var TimeGridMirrorRenderer = /** @class */ (function (_super) {
10828        __extends(TimeGridMirrorRenderer, _super);
10829        function TimeGridMirrorRenderer() {
10830            return _super !== null && _super.apply(this, arguments) || this;
10831        }
10832        TimeGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
10833            this.segsByCol = this.timeGrid.groupSegsByCol(segs);
10834            this.timeGrid.attachSegsByCol(this.segsByCol, this.timeGrid.mirrorContainerEls);
10835            this.sourceSeg = mirrorInfo.sourceSeg;
10836        };
10837        TimeGridMirrorRenderer.prototype.generateSegCss = function (seg) {
10838            var props = _super.prototype.generateSegCss.call(this, seg);
10839            var sourceSeg = this.sourceSeg;
10840            if (sourceSeg && sourceSeg.col === seg.col) {
10841                var sourceSegProps = _super.prototype.generateSegCss.call(this, sourceSeg);
10842                props.left = sourceSegProps.left;
10843                props.right = sourceSegProps.right;
10844                props.marginLeft = sourceSegProps.marginLeft;
10845                props.marginRight = sourceSegProps.marginRight;
10846            }
10847            return props;
10848        };
10849        return TimeGridMirrorRenderer;
10850    }(TimeGridEventRenderer));
10851
10852    var TimeGridFillRenderer = /** @class */ (function (_super) {
10853        __extends(TimeGridFillRenderer, _super);
10854        function TimeGridFillRenderer(timeGrid) {
10855            var _this = _super.call(this, timeGrid.context) || this;
10856            _this.timeGrid = timeGrid;
10857            return _this;
10858        }
10859        TimeGridFillRenderer.prototype.attachSegs = function (type, segs) {
10860            var timeGrid = this.timeGrid;
10861            var containerEls;
10862            // TODO: more efficient lookup
10863            if (type === 'bgEvent') {
10864                containerEls = timeGrid.bgContainerEls;
10865            }
10866            else if (type === 'businessHours') {
10867                containerEls = timeGrid.businessContainerEls;
10868            }
10869            else if (type === 'highlight') {
10870                containerEls = timeGrid.highlightContainerEls;
10871            }
10872            timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls);
10873            return segs.map(function (seg) {
10874                return seg.el;
10875            });
10876        };
10877        TimeGridFillRenderer.prototype.computeSegSizes = function (segs) {
10878            this.timeGrid.computeSegVerticals(segs);
10879        };
10880        TimeGridFillRenderer.prototype.assignSegSizes = function (segs) {
10881            this.timeGrid.assignSegVerticals(segs);
10882        };
10883        return TimeGridFillRenderer;
10884    }(core.FillRenderer));
10885
10886    /* A component that renders one or more columns of vertical time slots
10887    ----------------------------------------------------------------------------------------------------------------------*/
10888    // potential nice values for the slot-duration and interval-duration
10889    // from largest to smallest
10890    var AGENDA_STOCK_SUB_DURATIONS = [
10891        { hours: 1 },
10892        { minutes: 30 },
10893        { minutes: 15 },
10894        { seconds: 30 },
10895        { seconds: 15 }
10896    ];
10897    var TimeGrid = /** @class */ (function (_super) {
10898        __extends(TimeGrid, _super);
10899        function TimeGrid(context, el, renderProps) {
10900            var _this = _super.call(this, context, el) || this;
10901            _this.isSlatSizesDirty = false;
10902            _this.isColSizesDirty = false;
10903            _this.renderSlats = core.memoizeRendering(_this._renderSlats);
10904            var eventRenderer = _this.eventRenderer = new TimeGridEventRenderer(_this);
10905            var fillRenderer = _this.fillRenderer = new TimeGridFillRenderer(_this);
10906            _this.mirrorRenderer = new TimeGridMirrorRenderer(_this);
10907            var renderColumns = _this.renderColumns = core.memoizeRendering(_this._renderColumns, _this._unrenderColumns);
10908            _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderColumns]);
10909            _this.renderDateSelection = core.memoizeRendering(_this._renderDateSelection, _this._unrenderDateSelection, [renderColumns]);
10910            _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderColumns]);
10911            _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderColumns]);
10912            _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
10913            _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderColumns]);
10914            _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderColumns]);
10915            _this.processOptions();
10916            el.innerHTML =
10917                '<div class="fc-bg"></div>' +
10918                    '<div class="fc-slats"></div>' +
10919                    '<hr class="fc-divider ' + _this.theme.getClass('widgetHeader') + '" style="display:none" />';
10920            _this.rootBgContainerEl = el.querySelector('.fc-bg');
10921            _this.slatContainerEl = el.querySelector('.fc-slats');
10922            _this.bottomRuleEl = el.querySelector('.fc-divider');
10923            _this.renderProps = renderProps;
10924            return _this;
10925        }
10926        /* Options
10927        ------------------------------------------------------------------------------------------------------------------*/
10928        // Parses various options into properties of this object
10929        TimeGrid.prototype.processOptions = function () {
10930            var slotDuration = this.opt('slotDuration');
10931            var snapDuration = this.opt('snapDuration');
10932            var snapsPerSlot;
10933            var input;
10934            slotDuration = core.createDuration(slotDuration);
10935            snapDuration = snapDuration ? core.createDuration(snapDuration) : slotDuration;
10936            snapsPerSlot = core.wholeDivideDurations(slotDuration, snapDuration);
10937            if (snapsPerSlot === null) {
10938                snapDuration = slotDuration;
10939                snapsPerSlot = 1;
10940                // TODO: say warning?
10941            }
10942            this.slotDuration = slotDuration;
10943            this.snapDuration = snapDuration;
10944            this.snapsPerSlot = snapsPerSlot;
10945            // might be an array value (for TimelineView).
10946            // if so, getting the most granular entry (the last one probably).
10947            input = this.opt('slotLabelFormat');
10948            if (Array.isArray(input)) {
10949                input = input[input.length - 1];
10950            }
10951            this.labelFormat = core.createFormatter(input || {
10952                hour: 'numeric',
10953                minute: '2-digit',
10954                omitZeroMinute: true,
10955                meridiem: 'short'
10956            });
10957            input = this.opt('slotLabelInterval');
10958            this.labelInterval = input ?
10959                core.createDuration(input) :
10960                this.computeLabelInterval(slotDuration);
10961        };
10962        // Computes an automatic value for slotLabelInterval
10963        TimeGrid.prototype.computeLabelInterval = function (slotDuration) {
10964            var i;
10965            var labelInterval;
10966            var slotsPerLabel;
10967            // find the smallest stock label interval that results in more than one slots-per-label
10968            for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
10969                labelInterval = core.createDuration(AGENDA_STOCK_SUB_DURATIONS[i]);
10970                slotsPerLabel = core.wholeDivideDurations(labelInterval, slotDuration);
10971                if (slotsPerLabel !== null && slotsPerLabel > 1) {
10972                    return labelInterval;
10973                }
10974            }
10975            return slotDuration; // fall back
10976        };
10977        /* Rendering
10978        ------------------------------------------------------------------------------------------------------------------*/
10979        TimeGrid.prototype.render = function (props) {
10980            var cells = props.cells;
10981            this.colCnt = cells.length;
10982            this.renderSlats(props.dateProfile);
10983            this.renderColumns(props.cells, props.dateProfile);
10984            this.renderBusinessHours(props.businessHourSegs);
10985            this.renderDateSelection(props.dateSelectionSegs);
10986            this.renderFgEvents(props.fgEventSegs);
10987            this.renderBgEvents(props.bgEventSegs);
10988            this.renderEventSelection(props.eventSelection);
10989            this.renderEventDrag(props.eventDrag);
10990            this.renderEventResize(props.eventResize);
10991        };
10992        TimeGrid.prototype.destroy = function () {
10993            _super.prototype.destroy.call(this);
10994            // should unrender everything else too
10995            this.renderSlats.unrender();
10996            this.renderColumns.unrender();
10997        };
10998        TimeGrid.prototype.updateSize = function (isResize) {
10999            var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer;
11000            if (isResize || this.isSlatSizesDirty) {
11001                this.buildSlatPositions();
11002                this.isSlatSizesDirty = false;
11003            }
11004            if (isResize || this.isColSizesDirty) {
11005                this.buildColPositions();
11006                this.isColSizesDirty = false;
11007            }
11008            fillRenderer.computeSizes(isResize);
11009            eventRenderer.computeSizes(isResize);
11010            mirrorRenderer.computeSizes(isResize);
11011            fillRenderer.assignSizes(isResize);
11012            eventRenderer.assignSizes(isResize);
11013            mirrorRenderer.assignSizes(isResize);
11014        };
11015        TimeGrid.prototype._renderSlats = function (dateProfile) {
11016            var theme = this.theme;
11017            this.slatContainerEl.innerHTML =
11018                '<table class="' + theme.getClass('tableGrid') + '">' +
11019                    this.renderSlatRowHtml(dateProfile) +
11020                    '</table>';
11021            this.slatEls = core.findElements(this.slatContainerEl, 'tr');
11022            this.slatPositions = new core.PositionCache(this.el, this.slatEls, false, true // vertical
11023            );
11024            this.isSlatSizesDirty = true;
11025        };
11026        // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
11027        TimeGrid.prototype.renderSlatRowHtml = function (dateProfile) {
11028            var _a = this, dateEnv = _a.dateEnv, theme = _a.theme, isRtl = _a.isRtl;
11029            var html = '';
11030            var dayStart = core.startOfDay(dateProfile.renderRange.start);
11031            var slotTime = dateProfile.minTime;
11032            var slotIterator = core.createDuration(0);
11033            var slotDate; // will be on the view's first day, but we only care about its time
11034            var isLabeled;
11035            var axisHtml;
11036            // Calculate the time for each slot
11037            while (core.asRoughMs(slotTime) < core.asRoughMs(dateProfile.maxTime)) {
11038                slotDate = dateEnv.add(dayStart, slotTime);
11039                isLabeled = core.wholeDivideDurations(slotIterator, this.labelInterval) !== null;
11040                axisHtml =
11041                    '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '">' +
11042                        (isLabeled ?
11043                            '<span>' + // for matchCellWidths
11044                                core.htmlEscape(dateEnv.format(slotDate, this.labelFormat)) +
11045                                '</span>' :
11046                            '') +
11047                        '</td>';
11048                html +=
11049                    '<tr data-time="' + core.formatIsoTimeString(slotDate) + '"' +
11050                        (isLabeled ? '' : ' class="fc-minor"') +
11051                        '>' +
11052                        (!isRtl ? axisHtml : '') +
11053                        '<td class="' + theme.getClass('widgetContent') + '"></td>' +
11054                        (isRtl ? axisHtml : '') +
11055                        '</tr>';
11056                slotTime = core.addDurations(slotTime, this.slotDuration);
11057                slotIterator = core.addDurations(slotIterator, this.slotDuration);
11058            }
11059            return html;
11060        };
11061        TimeGrid.prototype._renderColumns = function (cells, dateProfile) {
11062            var _a = this, theme = _a.theme, dateEnv = _a.dateEnv, view = _a.view;
11063            var bgRow = new daygrid.DayBgRow(this.context);
11064            this.rootBgContainerEl.innerHTML =
11065                '<table class="' + theme.getClass('tableGrid') + '">' +
11066                    bgRow.renderHtml({
11067                        cells: cells,
11068                        dateProfile: dateProfile,
11069                        renderIntroHtml: this.renderProps.renderBgIntroHtml
11070                    }) +
11071                    '</table>';
11072            this.colEls = core.findElements(this.el, '.fc-day, .fc-disabled-day');
11073            for (var col = 0; col < this.colCnt; col++) {
11074                this.publiclyTrigger('dayRender', [
11075                    {
11076                        date: dateEnv.toDate(cells[col].date),
11077                        el: this.colEls[col],
11078                        view: view
11079                    }
11080                ]);
11081            }
11082            if (this.isRtl) {
11083                this.colEls.reverse();
11084            }
11085            this.colPositions = new core.PositionCache(this.el, this.colEls, true, // horizontal
11086            false);
11087            this.renderContentSkeleton();
11088            this.isColSizesDirty = true;
11089        };
11090        TimeGrid.prototype._unrenderColumns = function () {
11091            this.unrenderContentSkeleton();
11092        };
11093        /* Content Skeleton
11094        ------------------------------------------------------------------------------------------------------------------*/
11095        // Renders the DOM that the view's content will live in
11096        TimeGrid.prototype.renderContentSkeleton = function () {
11097            var parts = [];
11098            var skeletonEl;
11099            parts.push(this.renderProps.renderIntroHtml());
11100            for (var i = 0; i < this.colCnt; i++) {
11101                parts.push('<td>' +
11102                    '<div class="fc-content-col">' +
11103                    '<div class="fc-event-container fc-mirror-container"></div>' +
11104                    '<div class="fc-event-container"></div>' +
11105                    '<div class="fc-highlight-container"></div>' +
11106                    '<div class="fc-bgevent-container"></div>' +
11107                    '<div class="fc-business-container"></div>' +
11108                    '</div>' +
11109                    '</td>');
11110            }
11111            if (this.isRtl) {
11112                parts.reverse();
11113            }
11114            skeletonEl = this.contentSkeletonEl = core.htmlToElement('<div class="fc-content-skeleton">' +
11115                '<table>' +
11116                '<tr>' + parts.join('') + '</tr>' +
11117                '</table>' +
11118                '</div>');
11119            this.colContainerEls = core.findElements(skeletonEl, '.fc-content-col');
11120            this.mirrorContainerEls = core.findElements(skeletonEl, '.fc-mirror-container');
11121            this.fgContainerEls = core.findElements(skeletonEl, '.fc-event-container:not(.fc-mirror-container)');
11122            this.bgContainerEls = core.findElements(skeletonEl, '.fc-bgevent-container');
11123            this.highlightContainerEls = core.findElements(skeletonEl, '.fc-highlight-container');
11124            this.businessContainerEls = core.findElements(skeletonEl, '.fc-business-container');
11125            if (this.isRtl) {
11126                this.colContainerEls.reverse();
11127                this.mirrorContainerEls.reverse();
11128                this.fgContainerEls.reverse();
11129                this.bgContainerEls.reverse();
11130                this.highlightContainerEls.reverse();
11131                this.businessContainerEls.reverse();
11132            }
11133            this.el.appendChild(skeletonEl);
11134        };
11135        TimeGrid.prototype.unrenderContentSkeleton = function () {
11136            core.removeElement(this.contentSkeletonEl);
11137        };
11138        // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
11139        TimeGrid.prototype.groupSegsByCol = function (segs) {
11140            var segsByCol = [];
11141            var i;
11142            for (i = 0; i < this.colCnt; i++) {
11143                segsByCol.push([]);
11144            }
11145            for (i = 0; i < segs.length; i++) {
11146                segsByCol[segs[i].col].push(segs[i]);
11147            }
11148            return segsByCol;
11149        };
11150        // Given segments grouped by column, insert the segments' elements into a parallel array of container
11151        // elements, each living within a column.
11152        TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) {
11153            var col;
11154            var segs;
11155            var i;
11156            for (col = 0; col < this.colCnt; col++) { // iterate each column grouping
11157                segs = segsByCol[col];
11158                for (i = 0; i < segs.length; i++) {
11159                    containerEls[col].appendChild(segs[i].el);
11160                }
11161            }
11162        };
11163        /* Now Indicator
11164        ------------------------------------------------------------------------------------------------------------------*/
11165        TimeGrid.prototype.getNowIndicatorUnit = function () {
11166            return 'minute'; // will refresh on the minute
11167        };
11168        TimeGrid.prototype.renderNowIndicator = function (segs, date) {
11169            // HACK: if date columns not ready for some reason (scheduler)
11170            if (!this.colContainerEls) {
11171                return;
11172            }
11173            var top = this.computeDateTop(date);
11174            var nodes = [];
11175            var i;
11176            // render lines within the columns
11177            for (i = 0; i < segs.length; i++) {
11178                var lineEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-line' });
11179                lineEl.style.top = top + 'px';
11180                this.colContainerEls[segs[i].col].appendChild(lineEl);
11181                nodes.push(lineEl);
11182            }
11183            // render an arrow over the axis
11184            if (segs.length > 0) { // is the current time in view?
11185                var arrowEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-arrow' });
11186                arrowEl.style.top = top + 'px';
11187                this.contentSkeletonEl.appendChild(arrowEl);
11188                nodes.push(arrowEl);
11189            }
11190            this.nowIndicatorEls = nodes;
11191        };
11192        TimeGrid.prototype.unrenderNowIndicator = function () {
11193            if (this.nowIndicatorEls) {
11194                this.nowIndicatorEls.forEach(core.removeElement);
11195                this.nowIndicatorEls = null;
11196            }
11197        };
11198        /* Coordinates
11199        ------------------------------------------------------------------------------------------------------------------*/
11200        TimeGrid.prototype.getTotalSlatHeight = function () {
11201            return this.slatContainerEl.offsetHeight;
11202        };
11203        // Computes the top coordinate, relative to the bounds of the grid, of the given date.
11204        // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
11205        TimeGrid.prototype.computeDateTop = function (when, startOfDayDate) {
11206            if (!startOfDayDate) {
11207                startOfDayDate = core.startOfDay(when);
11208            }
11209            return this.computeTimeTop(when.valueOf() - startOfDayDate.valueOf());
11210        };
11211        // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
11212        TimeGrid.prototype.computeTimeTop = function (timeMs) {
11213            var len = this.slatEls.length;
11214            var dateProfile = this.props.dateProfile;
11215            var slatCoverage = (timeMs - core.asRoughMs(dateProfile.minTime)) / core.asRoughMs(this.slotDuration); // floating-point value of # of slots covered
11216            var slatIndex;
11217            var slatRemainder;
11218            // compute a floating-point number for how many slats should be progressed through.
11219            // from 0 to number of slats (inclusive)
11220            // constrained because minTime/maxTime might be customized.
11221            slatCoverage = Math.max(0, slatCoverage);
11222            slatCoverage = Math.min(len, slatCoverage);
11223            // an integer index of the furthest whole slat
11224            // from 0 to number slats (*exclusive*, so len-1)
11225            slatIndex = Math.floor(slatCoverage);
11226            slatIndex = Math.min(slatIndex, len - 1);
11227            // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
11228            // could be 1.0 if slatCoverage is covering *all* the slots
11229            slatRemainder = slatCoverage - slatIndex;
11230            return this.slatPositions.tops[slatIndex] +
11231                this.slatPositions.getHeight(slatIndex) * slatRemainder;
11232        };
11233        // For each segment in an array, computes and assigns its top and bottom properties
11234        TimeGrid.prototype.computeSegVerticals = function (segs) {
11235            var eventMinHeight = this.opt('timeGridEventMinHeight');
11236            var i;
11237            var seg;
11238            var dayDate;
11239            for (i = 0; i < segs.length; i++) {
11240                seg = segs[i];
11241                dayDate = this.props.cells[seg.col].date;
11242                seg.top = this.computeDateTop(seg.start, dayDate);
11243                seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.end, dayDate));
11244            }
11245        };
11246        // Given segments that already have their top/bottom properties computed, applies those values to
11247        // the segments' elements.
11248        TimeGrid.prototype.assignSegVerticals = function (segs) {
11249            var i;
11250            var seg;
11251            for (i = 0; i < segs.length; i++) {
11252                seg = segs[i];
11253                core.applyStyle(seg.el, this.generateSegVerticalCss(seg));
11254            }
11255        };
11256        // Generates an object with CSS properties for the top/bottom coordinates of a segment element
11257        TimeGrid.prototype.generateSegVerticalCss = function (seg) {
11258            return {
11259                top: seg.top,
11260                bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container
11261            };
11262        };
11263        /* Sizing
11264        ------------------------------------------------------------------------------------------------------------------*/
11265        TimeGrid.prototype.buildPositionCaches = function () {
11266            this.buildColPositions();
11267            this.buildSlatPositions();
11268        };
11269        TimeGrid.prototype.buildColPositions = function () {
11270            this.colPositions.build();
11271        };
11272        TimeGrid.prototype.buildSlatPositions = function () {
11273            this.slatPositions.build();
11274        };
11275        /* Hit System
11276        ------------------------------------------------------------------------------------------------------------------*/
11277        TimeGrid.prototype.positionToHit = function (positionLeft, positionTop) {
11278            var _a = this, dateEnv = _a.dateEnv, snapsPerSlot = _a.snapsPerSlot, slatPositions = _a.slatPositions, colPositions = _a.colPositions;
11279            var colIndex = colPositions.leftToIndex(positionLeft);
11280            var slatIndex = slatPositions.topToIndex(positionTop);
11281            if (colIndex != null && slatIndex != null) {
11282                var slatTop = slatPositions.tops[slatIndex];
11283                var slatHeight = slatPositions.getHeight(slatIndex);
11284                var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
11285                var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
11286                var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
11287                var dayDate = this.props.cells[colIndex].date;
11288                var time = core.addDurations(this.props.dateProfile.minTime, core.multiplyDuration(this.snapDuration, snapIndex));
11289                var start = dateEnv.add(dayDate, time);
11290                var end = dateEnv.add(start, this.snapDuration);
11291                return {
11292                    col: colIndex,
11293                    dateSpan: {
11294                        range: { start: start, end: end },
11295                        allDay: false
11296                    },
11297                    dayEl: this.colEls[colIndex],
11298                    relativeRect: {
11299                        left: colPositions.lefts[colIndex],
11300                        right: colPositions.rights[colIndex],
11301                        top: slatTop,
11302                        bottom: slatTop + slatHeight
11303                    }
11304                };
11305            }
11306        };
11307        /* Event Drag Visualization
11308        ------------------------------------------------------------------------------------------------------------------*/
11309        TimeGrid.prototype._renderEventDrag = function (state) {
11310            if (state) {
11311                this.eventRenderer.hideByHash(state.affectedInstances);
11312                if (state.isEvent) {
11313                    this.mirrorRenderer.renderSegs(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
11314                }
11315                else {
11316                    this.fillRenderer.renderSegs('highlight', state.segs);
11317                }
11318            }
11319        };
11320        TimeGrid.prototype._unrenderEventDrag = function (state) {
11321            if (state) {
11322                this.eventRenderer.showByHash(state.affectedInstances);
11323                this.mirrorRenderer.unrender(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
11324                this.fillRenderer.unrender('highlight');
11325            }
11326        };
11327        /* Event Resize Visualization
11328        ------------------------------------------------------------------------------------------------------------------*/
11329        TimeGrid.prototype._renderEventResize = function (state) {
11330            if (state) {
11331                this.eventRenderer.hideByHash(state.affectedInstances);
11332                this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
11333            }
11334        };
11335        TimeGrid.prototype._unrenderEventResize = function (state) {
11336            if (state) {
11337                this.eventRenderer.showByHash(state.affectedInstances);
11338                this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
11339            }
11340        };
11341        /* Selection
11342        ------------------------------------------------------------------------------------------------------------------*/
11343        // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
11344        TimeGrid.prototype._renderDateSelection = function (segs) {
11345            if (segs) {
11346                if (this.opt('selectMirror')) {
11347                    this.mirrorRenderer.renderSegs(segs, { isSelecting: true });
11348                }
11349                else {
11350                    this.fillRenderer.renderSegs('highlight', segs);
11351                }
11352            }
11353        };
11354        TimeGrid.prototype._unrenderDateSelection = function (segs) {
11355            this.mirrorRenderer.unrender(segs, { isSelecting: true });
11356            this.fillRenderer.unrender('highlight');
11357        };
11358        return TimeGrid;
11359    }(core.DateComponent));
11360
11361    var AllDaySplitter = /** @class */ (function (_super) {
11362        __extends(AllDaySplitter, _super);
11363        function AllDaySplitter() {
11364            return _super !== null && _super.apply(this, arguments) || this;
11365        }
11366        AllDaySplitter.prototype.getKeyInfo = function () {
11367            return {
11368                allDay: {},
11369                timed: {}
11370            };
11371        };
11372        AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
11373            if (dateSpan.allDay) {
11374                return ['allDay'];
11375            }
11376            else {
11377                return ['timed'];
11378            }
11379        };
11380        AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
11381            if (!eventDef.allDay) {
11382                return ['timed'];
11383            }
11384            else if (core.hasBgRendering(eventDef)) {
11385                return ['timed', 'allDay'];
11386            }
11387            else {
11388                return ['allDay'];
11389            }
11390        };
11391        return AllDaySplitter;
11392    }(core.Splitter));
11393
11394    var TIMEGRID_ALL_DAY_EVENT_LIMIT = 5;
11395    var WEEK_HEADER_FORMAT = core.createFormatter({ week: 'short' });
11396    /* An abstract class for all timegrid-related views. Displays one more columns with time slots running vertically.
11397    ----------------------------------------------------------------------------------------------------------------------*/
11398    // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
11399    // Responsible for managing width/height.
11400    var TimeGridView = /** @class */ (function (_super) {
11401        __extends(TimeGridView, _super);
11402        function TimeGridView(context, viewSpec, dateProfileGenerator, parentEl) {
11403            var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
11404            _this.splitter = new AllDaySplitter();
11405            /* Header Render Methods
11406            ------------------------------------------------------------------------------------------------------------------*/
11407            // Generates the HTML that will go before the day-of week header cells
11408            _this.renderHeadIntroHtml = function () {
11409                var _a = _this, theme = _a.theme, dateEnv = _a.dateEnv;
11410                var range = _this.props.dateProfile.renderRange;
11411                var dayCnt = core.diffDays(range.start, range.end);
11412                var weekText;
11413                if (_this.opt('weekNumbers')) {
11414                    weekText = dateEnv.format(range.start, WEEK_HEADER_FORMAT);
11415                    return '' +
11416                        '<th class="fc-axis fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '>' +
11417                        core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
11418                        _this, { date: range.start, type: 'week', forceOff: dayCnt > 1 }, core.htmlEscape(weekText) // inner HTML
11419                        ) +
11420                        '</th>';
11421                }
11422                else {
11423                    return '<th class="fc-axis ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '></th>';
11424                }
11425            };
11426            /* Time Grid Render Methods
11427            ------------------------------------------------------------------------------------------------------------------*/
11428            // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
11429            _this.renderTimeGridBgIntroHtml = function () {
11430                var theme = _this.theme;
11431                return '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '></td>';
11432            };
11433            // Generates the HTML that goes before all other types of cells.
11434            // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
11435            _this.renderTimeGridIntroHtml = function () {
11436                return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
11437            };
11438            /* Day Grid Render Methods
11439            ------------------------------------------------------------------------------------------------------------------*/
11440            // Generates the HTML that goes before the all-day cells
11441            _this.renderDayGridBgIntroHtml = function () {
11442                var theme = _this.theme;
11443                return '' +
11444                    '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '>' +
11445                    '<span>' + // needed for matchCellWidths
11446                    core.getAllDayHtml(_this) +
11447                    '</span>' +
11448                    '</td>';
11449            };
11450            // Generates the HTML that goes before all other types of cells.
11451            // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
11452            _this.renderDayGridIntroHtml = function () {
11453                return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
11454            };
11455            _this.el.classList.add('fc-timeGrid-view');
11456            _this.el.innerHTML = _this.renderSkeletonHtml();
11457            _this.scroller = new core.ScrollComponent('hidden', // overflow x
11458            'auto' // overflow y
11459            );
11460            var timeGridWrapEl = _this.scroller.el;
11461            _this.el.querySelector('.fc-body > tr > td').appendChild(timeGridWrapEl);
11462            timeGridWrapEl.classList.add('fc-time-grid-container');
11463            var timeGridEl = core.createElement('div', { className: 'fc-time-grid' });
11464            timeGridWrapEl.appendChild(timeGridEl);
11465            _this.timeGrid = new TimeGrid(_this.context, timeGridEl, {
11466                renderBgIntroHtml: _this.renderTimeGridBgIntroHtml,
11467                renderIntroHtml: _this.renderTimeGridIntroHtml
11468            });
11469            if (_this.opt('allDaySlot')) { // should we display the "all-day" area?
11470                _this.dayGrid = new daygrid.DayGrid(// the all-day subcomponent of this view
11471                _this.context, _this.el.querySelector('.fc-day-grid'), {
11472                    renderNumberIntroHtml: _this.renderDayGridIntroHtml,
11473                    renderBgIntroHtml: _this.renderDayGridBgIntroHtml,
11474                    renderIntroHtml: _this.renderDayGridIntroHtml,
11475                    colWeekNumbersVisible: false,
11476                    cellWeekNumbersVisible: false
11477                });
11478                // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
11479                _this.dayGrid.bottomCoordPadding = _this.el.querySelector('.fc-divider').offsetHeight;
11480            }
11481            return _this;
11482        }
11483        TimeGridView.prototype.destroy = function () {
11484            _super.prototype.destroy.call(this);
11485            this.timeGrid.destroy();
11486            if (this.dayGrid) {
11487                this.dayGrid.destroy();
11488            }
11489            this.scroller.destroy();
11490        };
11491        /* Rendering
11492        ------------------------------------------------------------------------------------------------------------------*/
11493        // Builds the HTML skeleton for the view.
11494        // The day-grid and time-grid components will render inside containers defined by this HTML.
11495        TimeGridView.prototype.renderSkeletonHtml = function () {
11496            var theme = this.theme;
11497            return '' +
11498                '<table class="' + theme.getClass('tableGrid') + '">' +
11499                (this.opt('columnHeader') ?
11500                    '<thead class="fc-head">' +
11501                        '<tr>' +
11502                        '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
11503                        '</tr>' +
11504                        '</thead>' :
11505                    '') +
11506                '<tbody class="fc-body">' +
11507                '<tr>' +
11508                '<td class="' + theme.getClass('widgetContent') + '">' +
11509                (this.opt('allDaySlot') ?
11510                    '<div class="fc-day-grid"></div>' +
11511                        '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" />' :
11512                    '') +
11513                '</td>' +
11514                '</tr>' +
11515                '</tbody>' +
11516                '</table>';
11517        };
11518        /* Now Indicator
11519        ------------------------------------------------------------------------------------------------------------------*/
11520        TimeGridView.prototype.getNowIndicatorUnit = function () {
11521            return this.timeGrid.getNowIndicatorUnit();
11522        };
11523        // subclasses should implement
11524        // renderNowIndicator(date: DateMarker) {
11525        // }
11526        TimeGridView.prototype.unrenderNowIndicator = function () {
11527            this.timeGrid.unrenderNowIndicator();
11528        };
11529        /* Dimensions
11530        ------------------------------------------------------------------------------------------------------------------*/
11531        TimeGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
11532            _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first
11533            this.timeGrid.updateSize(isResize);
11534            if (this.dayGrid) {
11535                this.dayGrid.updateSize(isResize);
11536            }
11537        };
11538        // Adjusts the vertical dimensions of the view to the specified values
11539        TimeGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
11540            var _this = this;
11541            var eventLimit;
11542            var scrollerHeight;
11543            var scrollbarWidths;
11544            // make all axis cells line up
11545            this.axisWidth = core.matchCellWidths(core.findElements(this.el, '.fc-axis'));
11546            // hack to give the view some height prior to timeGrid's columns being rendered
11547            // TODO: separate setting height from scroller VS timeGrid.
11548            if (!this.timeGrid.colEls) {
11549                if (!isAuto) {
11550                    scrollerHeight = this.computeScrollerHeight(viewHeight);
11551                    this.scroller.setHeight(scrollerHeight);
11552                }
11553                return;
11554            }
11555            // set of fake row elements that must compensate when scroller has scrollbars
11556            var noScrollRowEls = core.findElements(this.el, '.fc-row').filter(function (node) {
11557                return !_this.scroller.el.contains(node);
11558            });
11559            // reset all dimensions back to the original state
11560            this.timeGrid.bottomRuleEl.style.display = 'none'; // will be shown later if this <hr> is necessary
11561            this.scroller.clear(); // sets height to 'auto' and clears overflow
11562            noScrollRowEls.forEach(core.uncompensateScroll);
11563            // limit number of events in the all-day area
11564            if (this.dayGrid) {
11565                this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
11566                eventLimit = this.opt('eventLimit');
11567                if (eventLimit && typeof eventLimit !== 'number') {
11568                    eventLimit = TIMEGRID_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number
11569                }
11570                if (eventLimit) {
11571                    this.dayGrid.limitRows(eventLimit);
11572                }
11573            }
11574            if (!isAuto) { // should we force dimensions of the scroll container?
11575                scrollerHeight = this.computeScrollerHeight(viewHeight);
11576                this.scroller.setHeight(scrollerHeight);
11577                scrollbarWidths = this.scroller.getScrollbarWidths();
11578                if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
11579                    // make the all-day and header rows lines up
11580                    noScrollRowEls.forEach(function (rowEl) {
11581                        core.compensateScroll(rowEl, scrollbarWidths);
11582                    });
11583                    // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
11584                    // and reapply the desired height to the scroller.
11585                    scrollerHeight = this.computeScrollerHeight(viewHeight);
11586                    this.scroller.setHeight(scrollerHeight);
11587                }
11588                // guarantees the same scrollbar widths
11589                this.scroller.lockOverflow(scrollbarWidths);
11590                // if there's any space below the slats, show the horizontal rule.
11591                // this won't cause any new overflow, because lockOverflow already called.
11592                if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) {
11593                    this.timeGrid.bottomRuleEl.style.display = '';
11594                }
11595            }
11596        };
11597        // given a desired total height of the view, returns what the height of the scroller should be
11598        TimeGridView.prototype.computeScrollerHeight = function (viewHeight) {
11599            return viewHeight -
11600                core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
11601        };
11602        /* Scroll
11603        ------------------------------------------------------------------------------------------------------------------*/
11604        // Computes the initial pre-configured scroll state prior to allowing the user to change it
11605        TimeGridView.prototype.computeDateScroll = function (timeMs) {
11606            var top = this.timeGrid.computeTimeTop(timeMs);
11607            // zoom can give weird floating-point values. rather scroll a little bit further
11608            top = Math.ceil(top);
11609            if (top) {
11610                top++; // to overcome top border that slots beyond the first have. looks better
11611            }
11612            return { top: top };
11613        };
11614        TimeGridView.prototype.queryDateScroll = function () {
11615            return { top: this.scroller.getScrollTop() };
11616        };
11617        TimeGridView.prototype.applyDateScroll = function (scroll) {
11618            if (scroll.top !== undefined) {
11619                this.scroller.setScrollTop(scroll.top);
11620            }
11621        };
11622        // Generates an HTML attribute string for setting the width of the axis, if it is known
11623        TimeGridView.prototype.axisStyleAttr = function () {
11624            if (this.axisWidth != null) {
11625                return 'style="width:' + this.axisWidth + 'px"';
11626            }
11627            return '';
11628        };
11629        return TimeGridView;
11630    }(core.View));
11631    TimeGridView.prototype.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering
11632
11633    var SimpleTimeGrid = /** @class */ (function (_super) {
11634        __extends(SimpleTimeGrid, _super);
11635        function SimpleTimeGrid(context, timeGrid) {
11636            var _this = _super.call(this, context, timeGrid.el) || this;
11637            _this.buildDayRanges = core.memoize(buildDayRanges);
11638            _this.slicer = new TimeGridSlicer();
11639            _this.timeGrid = timeGrid;
11640            context.calendar.registerInteractiveComponent(_this, {
11641                el: _this.timeGrid.el
11642            });
11643            return _this;
11644        }
11645        SimpleTimeGrid.prototype.destroy = function () {
11646            _super.prototype.destroy.call(this);
11647            this.calendar.unregisterInteractiveComponent(this);
11648        };
11649        SimpleTimeGrid.prototype.render = function (props) {
11650            var dateProfile = props.dateProfile, dayTable = props.dayTable;
11651            var dayRanges = this.dayRanges = this.buildDayRanges(dayTable, dateProfile, this.dateEnv);
11652            this.timeGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, null, this.timeGrid, dayRanges), { dateProfile: dateProfile, cells: dayTable.cells[0] }));
11653        };
11654        SimpleTimeGrid.prototype.renderNowIndicator = function (date) {
11655            this.timeGrid.renderNowIndicator(this.slicer.sliceNowDate(date, this.timeGrid, this.dayRanges), date);
11656        };
11657        SimpleTimeGrid.prototype.buildPositionCaches = function () {
11658            this.timeGrid.buildPositionCaches();
11659        };
11660        SimpleTimeGrid.prototype.queryHit = function (positionLeft, positionTop) {
11661            var rawHit = this.timeGrid.positionToHit(positionLeft, positionTop);
11662            if (rawHit) {
11663                return {
11664                    component: this.timeGrid,
11665                    dateSpan: rawHit.dateSpan,
11666                    dayEl: rawHit.dayEl,
11667                    rect: {
11668                        left: rawHit.relativeRect.left,
11669                        right: rawHit.relativeRect.right,
11670                        top: rawHit.relativeRect.top,
11671                        bottom: rawHit.relativeRect.bottom
11672                    },
11673                    layer: 0
11674                };
11675            }
11676        };
11677        return SimpleTimeGrid;
11678    }(core.DateComponent));
11679    function buildDayRanges(dayTable, dateProfile, dateEnv) {
11680        var ranges = [];
11681        for (var _i = 0, _a = dayTable.headerDates; _i < _a.length; _i++) {
11682            var date = _a[_i];
11683            ranges.push({
11684                start: dateEnv.add(date, dateProfile.minTime),
11685                end: dateEnv.add(date, dateProfile.maxTime)
11686            });
11687        }
11688        return ranges;
11689    }
11690    var TimeGridSlicer = /** @class */ (function (_super) {
11691        __extends(TimeGridSlicer, _super);
11692        function TimeGridSlicer() {
11693            return _super !== null && _super.apply(this, arguments) || this;
11694        }
11695        TimeGridSlicer.prototype.sliceRange = function (range, dayRanges) {
11696            var segs = [];
11697            for (var col = 0; col < dayRanges.length; col++) {
11698                var segRange = core.intersectRanges(range, dayRanges[col]);
11699                if (segRange) {
11700                    segs.push({
11701                        start: segRange.start,
11702                        end: segRange.end,
11703                        isStart: segRange.start.valueOf() === range.start.valueOf(),
11704                        isEnd: segRange.end.valueOf() === range.end.valueOf(),
11705                        col: col
11706                    });
11707                }
11708            }
11709            return segs;
11710        };
11711        return TimeGridSlicer;
11712    }(core.Slicer));
11713
11714    var TimeGridView$1 = /** @class */ (function (_super) {
11715        __extends(TimeGridView, _super);
11716        function TimeGridView(_context, viewSpec, dateProfileGenerator, parentEl) {
11717            var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this;
11718            _this.buildDayTable = core.memoize(buildDayTable);
11719            if (_this.opt('columnHeader')) {
11720                _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container'));
11721            }
11722            _this.simpleTimeGrid = new SimpleTimeGrid(_this.context, _this.timeGrid);
11723            if (_this.dayGrid) {
11724                _this.simpleDayGrid = new daygrid.SimpleDayGrid(_this.context, _this.dayGrid);
11725            }
11726            return _this;
11727        }
11728        TimeGridView.prototype.destroy = function () {
11729            _super.prototype.destroy.call(this);
11730            if (this.header) {
11731                this.header.destroy();
11732            }
11733            this.simpleTimeGrid.destroy();
11734            if (this.simpleDayGrid) {
11735                this.simpleDayGrid.destroy();
11736            }
11737        };
11738        TimeGridView.prototype.render = function (props) {
11739            _super.prototype.render.call(this, props); // for flags for updateSize
11740            var dateProfile = this.props.dateProfile;
11741            var dayTable = this.buildDayTable(dateProfile, this.dateProfileGenerator);
11742            var splitProps = this.splitter.splitProps(props);
11743            if (this.header) {
11744                this.header.receiveProps({
11745                    dateProfile: dateProfile,
11746                    dates: dayTable.headerDates,
11747                    datesRepDistinctDays: true,
11748                    renderIntroHtml: this.renderHeadIntroHtml
11749                });
11750            }
11751            this.simpleTimeGrid.receiveProps(__assign({}, splitProps['timed'], { dateProfile: dateProfile,
11752                dayTable: dayTable }));
11753            if (this.simpleDayGrid) {
11754                this.simpleDayGrid.receiveProps(__assign({}, splitProps['allDay'], { dateProfile: dateProfile,
11755                    dayTable: dayTable, nextDayThreshold: this.nextDayThreshold, isRigid: false }));
11756            }
11757        };
11758        TimeGridView.prototype.renderNowIndicator = function (date) {
11759            this.simpleTimeGrid.renderNowIndicator(date);
11760        };
11761        return TimeGridView;
11762    }(TimeGridView));
11763    function buildDayTable(dateProfile, dateProfileGenerator) {
11764        var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator);
11765        return new core.DayTable(daySeries, false);
11766    }
11767
11768    var main = core.createPlugin({
11769        defaultView: 'timeGridWeek',
11770        views: {
11771            timeGrid: {
11772                class: TimeGridView$1,
11773                allDaySlot: true,
11774                slotDuration: '00:30:00',
11775                slotEventOverlap: true // a bad name. confused with overlap/constraint system
11776            },
11777            timeGridDay: {
11778                type: 'timeGrid',
11779                duration: { days: 1 }
11780            },
11781            timeGridWeek: {
11782                type: 'timeGrid',
11783                duration: { weeks: 1 }
11784            }
11785        }
11786    });
11787
11788    exports.AbstractTimeGridView = TimeGridView;
11789    exports.TimeGrid = TimeGrid;
11790    exports.TimeGridSlicer = TimeGridSlicer;
11791    exports.TimeGridView = TimeGridView$1;
11792    exports.buildDayRanges = buildDayRanges;
11793    exports.buildDayTable = buildDayTable;
11794    exports.default = main;
11795
11796    Object.defineProperty(exports, '__esModule', { value: true });
11797
11798}));
11799
11800/*!
11801FullCalendar List View Plugin v4.1.0
11802Docs & License: https://fullcalendar.io/
11803(c) 2019 Adam Shaw
11804*/
11805(function (global, factory) {
11806    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
11807    typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
11808    (global = global || self, factory(global.FullCalendarList = {}, global.FullCalendar));
11809}(this, function (exports, core) { 'use strict';
11810
11811    /*! *****************************************************************************
11812    Copyright (c) Microsoft Corporation. All rights reserved.
11813    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
11814    this file except in compliance with the License. You may obtain a copy of the
11815    License at http://www.apache.org/licenses/LICENSE-2.0
11816
11817    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11818    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
11819    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
11820    MERCHANTABLITY OR NON-INFRINGEMENT.
11821
11822    See the Apache Version 2.0 License for specific language governing permissions
11823    and limitations under the License.
11824    ***************************************************************************** */
11825    /* global Reflect, Promise */
11826
11827    var extendStatics = function(d, b) {
11828        extendStatics = Object.setPrototypeOf ||
11829            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
11830            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
11831        return extendStatics(d, b);
11832    };
11833
11834    function __extends(d, b) {
11835        extendStatics(d, b);
11836        function __() { this.constructor = d; }
11837        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
11838    }
11839
11840    var ListEventRenderer = /** @class */ (function (_super) {
11841        __extends(ListEventRenderer, _super);
11842        function ListEventRenderer(listView) {
11843            var _this = _super.call(this, listView.context) || this;
11844            _this.listView = listView;
11845            return _this;
11846        }
11847        ListEventRenderer.prototype.attachSegs = function (segs) {
11848            if (!segs.length) {
11849                this.listView.renderEmptyMessage();
11850            }
11851            else {
11852                this.listView.renderSegList(segs);
11853            }
11854        };
11855        ListEventRenderer.prototype.detachSegs = function () {
11856        };
11857        // generates the HTML for a single event row
11858        ListEventRenderer.prototype.renderSegHtml = function (seg) {
11859            var _a = this.context, view = _a.view, theme = _a.theme;
11860            var eventRange = seg.eventRange;
11861            var eventDef = eventRange.def;
11862            var eventInstance = eventRange.instance;
11863            var eventUi = eventRange.ui;
11864            var url = eventDef.url;
11865            var classes = ['fc-list-item'].concat(eventUi.classNames);
11866            var bgColor = eventUi.backgroundColor;
11867            var timeHtml;
11868            if (eventDef.allDay) {
11869                timeHtml = core.getAllDayHtml(view);
11870            }
11871            else if (core.isMultiDayRange(eventRange.range)) {
11872                if (seg.isStart) {
11873                    timeHtml = core.htmlEscape(this._getTimeText(eventInstance.range.start, seg.end, false // allDay
11874                    ));
11875                }
11876                else if (seg.isEnd) {
11877                    timeHtml = core.htmlEscape(this._getTimeText(seg.start, eventInstance.range.end, false // allDay
11878                    ));
11879                }
11880                else { // inner segment that lasts the whole day
11881                    timeHtml = core.getAllDayHtml(view);
11882                }
11883            }
11884            else {
11885                // Display the normal time text for the *event's* times
11886                timeHtml = core.htmlEscape(this.getTimeText(eventRange));
11887            }
11888            if (url) {
11889                classes.push('fc-has-url');
11890            }
11891            return '<tr class="' + classes.join(' ') + '">' +
11892                (this.displayEventTime ?
11893                    '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' +
11894                        (timeHtml || '') +
11895                        '</td>' :
11896                    '') +
11897                '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' +
11898                '<span class="fc-event-dot"' +
11899                (bgColor ?
11900                    ' style="background-color:' + bgColor + '"' :
11901                    '') +
11902                '></span>' +
11903                '</td>' +
11904                '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' +
11905                '<a' + (url ? ' href="' + core.htmlEscape(url) + '"' : '') + '>
11905' +
11906                core.htmlEscape(eventDef.title || '') +
11907                '</a>' +
11908                '</td>' +
11909                '</tr>';
11910        };
11911        // like "4:00am"
11912        ListEventRenderer.prototype.computeEventTimeFormat = function () {
11913            return {
11914                hour: 'numeric',
11915                minute: '2-digit',
11916                meridiem: 'short'
11917            };
11918        };
11919        return ListEventRenderer;
11920    }(core.FgEventRenderer));
11921
11922    /*
11923    Responsible for the scroller, and forwarding event-related actions into the "grid".
11924    */
11925    var ListView = /** @class */ (function (_super) {
11926        __extends(ListView, _super);
11927        function ListView(context, viewSpec, dateProfileGenerator, parentEl) {
11928            var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
11929            _this.computeDateVars = core.memoize(computeDateVars);
11930            _this.eventStoreToSegs = core.memoize(_this._eventStoreToSegs);
11931            var eventRenderer = _this.eventRenderer = new ListEventRenderer(_this);
11932            _this.renderContent = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer));
11933            _this.el.classList.add('fc-list-view');
11934            var listViewClassNames = (_this.theme.getClass('listView') || '').split(' '); // wish we didn't have to do this
11935            for (var _i = 0, listViewClassNames_1 = listViewClassNames; _i < listViewClassNames_1.length; _i++) {
11936                var listViewClassName = listViewClassNames_1[_i];
11937                if (listViewClassName) { // in case input was empty string
11938                    _this.el.classList.add(listViewClassName);
11939                }
11940            }
11941            _this.scroller = new core.ScrollComponent('hidden', // overflow x
11942            'auto' // overflow y
11943            );
11944            _this.el.appendChild(_this.scroller.el);
11945            _this.contentEl = _this.scroller.el; // shortcut
11946            context.calendar.registerInteractiveComponent(_this, {
11947                el: _this.el
11948                // TODO: make aware that it doesn't do Hits
11949            });
11950            return _this;
11951        }
11952        ListView.prototype.render = function (props) {
11953            var _a = this.computeDateVars(props.dateProfile), dayDates = _a.dayDates, dayRanges = _a.dayRanges;
11954            this.dayDates = dayDates;
11955            this.renderContent(this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges));
11956        };
11957        ListView.prototype.destroy = function () {
11958            _super.prototype.destroy.call(this);
11959            this.scroller.destroy(); // will remove the Grid too
11960            this.calendar.unregisterInteractiveComponent(this);
11961        };
11962        ListView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
11963            _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto);
11964            this.eventRenderer.computeSizes(isResize);
11965            this.eventRenderer.assignSizes(isResize);
11966            this.scroller.clear(); // sets height to 'auto' and clears overflow
11967            if (!isAuto) {
11968                this.scroller.setHeight(this.computeScrollerHeight(viewHeight));
11969            }
11970        };
11971        ListView.prototype.computeScrollerHeight = function (viewHeight) {
11972            return viewHeight -
11973                core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
11974        };
11975        ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) {
11976            return this.eventRangesToSegs(core.sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.nextDayThreshold).fg, dayRanges);
11977        };
11978        ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) {
11979            var segs = [];
11980            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
11981                var eventRange = eventRanges_1[_i];
11982                segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges));
11983            }
11984            return segs;
11985        };
11986        ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) {
11987            var _a = this, dateEnv = _a.dateEnv, nextDayThreshold = _a.nextDayThreshold;
11988            var range = eventRange.range;
11989            var allDay = eventRange.def.allDay;
11990            var dayIndex;
11991            var segRange;
11992            var seg;
11993            var segs = [];
11994            for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) {
11995                segRange = core.intersectRanges(range, dayRanges[dayIndex]);
11996                if (segRange) {
11997                    seg = {
11998                        component: this,
11999                        eventRange: eventRange,
12000                        start: segRange.start,
12001                        end: segRange.end,
12002                        isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(),
12003                        isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(),
12004                        dayIndex: dayIndex
12005                    };
12006                    segs.push(seg);
12007                    // detect when range won't go fully into the next day,
12008                    // and mutate the latest seg to the be the end.
12009                    if (!seg.isEnd && !allDay &&
12010                        dayIndex + 1 < dayRanges.length &&
12011                        range.end <
12012                            dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) {
12013                        seg.end = range.end;
12014                        seg.isEnd = true;
12015                        break;
12016                    }
12017                }
12018            }
12019            return segs;
12020        };
12021        ListView.prototype.renderEmptyMessage = function () {
12022            this.contentEl.innerHTML =
12023                '<div class="fc-list-empty-wrap2">' + // TODO: try less wraps
12024                    '<div class="fc-list-empty-wrap1">' +
12025                    '<div class="fc-list-empty">' +
12026                    core.htmlEscape(this.opt('noEventsMessage')) +
12027                    '</div>' +
12028                    '</div>' +
12029                    '</div>';
12030        };
12031        // called by ListEventRenderer
12032        ListView.prototype.renderSegList = function (allSegs) {
12033            var segsByDay = this.groupSegsByDay(allSegs); // sparse array
12034            var dayIndex;
12035            var daySegs;
12036            var i;
12037            var tableEl = core.htmlToElement('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody></tbody></table>');
12038            var tbodyEl = tableEl.querySelector('tbody');
12039            for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) {
12040                daySegs = segsByDay[dayIndex];
12041                if (daySegs) { // sparse array, so might be undefined
12042                    // append a day header
12043                    tbodyEl.appendChild(this.buildDayHeaderRow(this.dayDates[dayIndex]));
12044                    daySegs = this.eventRenderer.sortEventSegs(daySegs);
12045                    for (i = 0;
12045 i < daySegs.length; i++) {
12046                        tbodyEl.appendChild(daySegs[i].el); // append event row
12047                    }
12048                }
12049            }
12050            this.contentEl.innerHTML = '';
12051            this.contentEl.appendChild(tableEl);
12052        };
12053        // Returns a sparse array of arrays, segs grouped by their dayIndex
12054        ListView.prototype.groupSegsByDay = function (segs) {
12055            var segsByDay = []; // sparse array
12056            var i;
12057            var seg;
12058            for (i = 0; i < segs.length; i++) {
12059                seg = segs[i];
12060                (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
12061                    .push(seg);
12062            }
12063            return segsByDay;
12064        };
12065        // generates the HTML for the day headers that live amongst the event rows
12066        ListView.prototype.buildDayHeaderRow = function (dayDate) {
12067            var dateEnv = this.dateEnv;
12068            var mainFormat = core.createFormatter(this.opt('listDayFormat')); // TODO: cache
12069            var altFormat = core.createFormatter(this.opt('listDayAltFormat')); // TODO: cache
12070            return core.createElement('tr', {
12071                className: 'fc-list-heading',
12072                'data-date': dateEnv.formatIso(dayDate, { omitTime: true })
12073            }, '<td class="' + (this.calendar.theme.getClass('tableListHeading') ||
12074                this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' +
12075                (mainFormat ?
12076                    core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-main' }, core.htmlEscape(dateEnv.format(dayDate, mainFormat)) // inner HTML
12077                    ) :
12078                    '') +
12079                (altFormat ?
12080                    core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-alt' }, core.htmlEscape(dateEnv.format(dayDate, altFormat)) // inner HTML
12081                    ) :
12082                    '') +
12083                '</td>');
12084        };
12085        return ListView;
12086    }(core.View));
12087    ListView.prototype.fgSegSelector = '.fc-list-item'; // which elements accept event actions
12088    function computeDateVars(dateProfile) {
12089        var dayStart = core.startOfDay(dateProfile.renderRange.start);
12090        var viewEnd = dateProfile.renderRange.end;
12091        var dayDates = [];
12092        var dayRanges = [];
12093        while (dayStart < viewEnd) {
12094            dayDates.push(dayStart);
12095            dayRanges.push({
12096                start: dayStart,
12097                end: core.addDays(dayStart, 1)
12098            });
12099            dayStart = core.addDays(dayStart, 1);
12100        }
12101        return { dayDates: dayDates, dayRanges: dayRanges };
12102    }
12103
12104    var main = core.createPlugin({
12105        views: {
12106            list: {
12107                class: ListView,
12108                buttonTextKey: 'list',
12109                listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' } // like "January 1, 2016"
12110            },
12111            listDay: {
12112                type: 'list',
12113                duration: { days: 1 },
12114                listDayFormat: { weekday: 'long' } // day-of-week is all we need. full date is probably in header
12115            },
12116            listWeek: {
12117                type: 'list',
12118                duration: { weeks: 1 },
12119                listDayFormat: { weekday: 'long' },
12120                listDayAltFormat: { month: 'long', day: 'numeric', year: 'numeric' }
12121            },
12122            listMonth: {
12123                type: 'list',
12124                duration: { month: 1 },
12125                listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have
12126            },
12127            listYear: {
12128                type: 'list',
12129                duration: { year: 1 },
12130                listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have
12131            }
12132        }
12133    });
12134
12135    exports.ListView = ListView;
12136    exports.default = main;
12137
12138    Object.defineProperty(exports, '__esModule', { value: true });
12139
12140}));

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.