PageSourceSearch

https://autogab.com.br/assets/plugins/fullcalendar/main.js

js autogab.com.br collected 2026-09-27 10:53:52 UTC 675,761 bytes, 14,332 lines download raw bytes

vendor: 11,814 bytes, lines 1-57
1/*!
2FullCalendar v5.5.1
3Docs & License: https://fullcalendar.io/
4(c) 2020 Adam Shaw
5*/
6var FullCalendar = (function (exports) {
7    'use strict';
8
9    /*! *****************************************************************************
10    Copyright (c) Microsoft Corporation.
11
12    Permission to use, copy, modify, and/or distribute this software for any
13    purpose with or without fee is hereby granted.
14
15    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
18    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21    PERFORMANCE OF THIS SOFTWARE.
22    ***************************************************************************** */
23    /* global Reflect, Promise */
24
25    var extendStatics = function(d, b) {
26        extendStatics = Object.setPrototypeOf ||
27            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
28            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
29        return extendStatics(d, b);
30    };
31
32    function __extends(d, b) {
33        extendStatics(d, b);
34        function __() { this.constructor = d; }
35        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
36    }
37
38    var __assign = function() {
39        __assign = Object.assign || function __assign(t) {
40            for (var s, i = 1, n = arguments.length; i < n; i++) {
41                s = arguments[i];
42                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
43            }
44            return t;
45        };
46        return __assign.apply(this, arguments);
47    };
48
49    function __spreadArrays() {
50        for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
51        for (var r = Array(s), k = 0, i = 0; i < il; i++)
52            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
53                r[k] = a[j];
54        return r;
55    }
56
57    var n,u,i,t,o,r,f={},e=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(n,l){for(var u in l)n[u]=l[u];return n}function a(n){var l=n.parentNode;l&&l.removeChild(n);}function v(n,l,u){var i,t,o,r=arguments,f={};for(o in l)"key"==o?i=l[o]:"ref"==o?t=l[o]:f[o]=l[o];if(arguments.length>3)for(u=[u],o=3;o<arguments.length;o++)u.push(r[o]);if(null!=u&&(f.children=u),"function"==typeof n&&null!=n.defaultProps)for(o in n.defaultProps)void 0===f[o]&&(f[o]=n.defaultProps[o]);return h(n,f,i,t,null)}function h(l,u,i,t,o){var r={type:l,props:u,key:i,ref:t,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++n.__v:o};return null!=n.vnode&&n.vnode(r),r}function y(){return {current:null}}function p(n){return n.children}function d(n,l){this.props=n,this.context=l;}function _(n,l){if(null==l)return n.__?_(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?_(n):null}function w(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return w(n)}}function k(l){(!l.__d&&(l.__d=!0)&&u.push(l)&&!g.__r++||t!==n.debounceRendering)&&((t=n.debounceRendering)||i)(g);}function g(){for(var n;g.__r=u.length;)n=u.sort(function(n,l){return n.__v.__b-l.__v.__b}),u=[],n.some(function(n){var l,u,i,t,o,r,f;n.__d&&(r=(o=(l=n).__v).__e,(f=l.__P)&&(u=[],(i=s({},o)).__v=o.__v+1,t=$(f,o,i,l.__n,void 0!==f.ownerSVGElement,null!=o.__h?[r]:null,u,null==r?_(o):r,o.__h),j(u,o),t!=r&&w(o)));});}function m(n,l,u,i,t,o,r,c,s,v){var y,d,w,k,g,m,b,A=i&&i.__k||e,P=A.length;for(s==f&&(s=null!=r?r[0]:P?_(i,0):null),u.__k=[],y=0;y<l.length;y++)if(null!=(k=u.__k[y]=null==(k=l[y])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k?h(null,k,null,null,k):Array.isArray(k)?h(p,{children:k},null,null,null):null!=k.__e||null!=k.__c?h(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(w=A[y])||w&&k.key==w.key&&k.type===w.type)A[y]=void 0;else for(d=0;d<P;d++){if((w=A[d])&&k.key==w.key&&k.type===w.type){A[d]=void 0;break}w=null;}g=$(n,k,w=w||f,t,o,r,c,s,v),(d=k.ref)&&w.ref!=d&&(b||(b=[]),w.ref&&b.push(w.ref,null,k),b.push(d,k.__c||g,k)),null!=g?(null==m&&(m=g),s=x(n,k,w,A,r,g,s),v||"option"!=u.type?"function"==typeof u.type&&(u.__d=s):n.value=""):s&&w.__e==s&&s.parentNode!=n&&(s=_(w));}if(u.__e=m,null!=r&&"function"!=typeof u.type)for(y=r.length;y--;)null!=r[y]&&a(r[y]);for(y=P;y--;)null!=A[y]&&L(A[y],A[y]);if(b)for(y=0;y<b.length;y++)I(b[y],b[++y],b[++y]);}function x(n,l,u,i,t,o,r){var f,e,c;if(void 0!==l.__d)f=l.__d,l.__d=void 0;else if(t==u||o!=r||null==o.parentNode)n:if(null==r||r.parentNode!==n)n.appendChild(o),f=null;else {for(e=r,c=0;(e=e.nextSibling)&&c<i.length;c+=2)if(e==o)break n;n.insertBefore(o,r),f=r;}return void 0!==f?f:o.nextSibling}function A(n,l,u,i,t){var o;for(o in u)"children"===o||"key"===o||o in l||C(n,o,null,u[o],i);for(o in l)t&&"function"!=typeof l[o]||"children"===o||"key"===o||"value"===o||"checked"===o||u[o]===l[o]||C(n,o,l[o],u[o],i);}function P(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||c.test(l)?u:u+"px";}function C(n,l,u,i,t){var o,r,f;if(t&&"className"==l&&(l="class"),"style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||P(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||P(n.style,l,u[l]);}else "o"===l[0]&&"n"===l[1]?(o=l!==(l=l.replace(/Capture$/,"")),(r=l.toLowerCase())in n&&(l=r),l=l.slice(2),n.l||(n.l={}),n.l[l+o]=u,f=o?N:z,u?i||n.addEventListener(l,f,o):n.removeEventListener(l,f,o)):"list"!==l&&"tagName"!==l&&"form"!==l&&"type"!==l&&"size"!==l&&"download"!==l&&"href"!==l&&!t&&l in n?n[l]=null==u?"":u:"function"!=typeof u&&"dangerouslySetInnerHTML"!==l&&(l!==(l=l.replace(/xlink:?/,""))?null==u||!1===u?n.removeAttributeNS("http://www.w3.org/1999/xlink",l.toLowerCase()):n.setAttributeNS("http://www.w3.org/1999/xlink",l.toLowerCase(),u):null==u||!1===u&&!/^ar/.test(l)?n.removeAttribute(l):n.setAttribute(l,u));}function z(l){this.l[l.type+!1](n.event?n.event(l):l);}function N(l){this.l[l.type+!0](n.event?n.event(l):l);}function T(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,t.__e&&("function"==typeof t.type&&t.__k.length>1&&T(t,l,u),l=x(u,t,t,n.__k,null,t.__e,l),"function"==typeof n.type&&(n.__d=l)));}function $(l,u,i,t,o,r,f,e,c){var a,v,h,y,_,w,k,g,b,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=n.__b)&&a(u);try{n:if("function"==typeof P){if(g=u.props,b=(a=P.contextType)&&t[a.__c],x=a?b?b.props.value:a.__:t,i.__c?k=(v=u.__c=i.__c).__=v.__E:("prototype"in P&&P.prototype.render?u.__c=v=new P(g,x):(u.__c=v=new d(g,x),v.constructor=P,v.render=M),b&&b.sub(v),v.props=g,v.state||(v.state={}),v.context=x,v.__n=t,h=v.__d=!0,v.__h=[]),null==v.__s&&(v.__s=v.state),null!=P.getDerivedStateFromProps&&(v.__s==v.state&&(v.__s=s({},v.__s)),s(v.__s,P.getDerivedStateFromProps(g,v.__s))),y=v.props,_=v.state,h)null==P.getDerivedStateFromProps&&null!=v.componentWillMount&&v.componentWillMount(),null!=v.componentDidMount&&v.__h.push(v.componentDidMount);else {if(null==P.getDerivedStateFromProps&&g!==y&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(g,x),!v.__e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(g,v.__s,x)||u.__v===i.__v){v.props=g,v.state=v.__s,u.__v!==i.__v&&(v.__d=!1),v.__v=u,u.__e=i.__e,u.__k=i.__k,v.__h.length&&f.push(v),T(u,e,l);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(g,v.__s,x),null!=v.componentDidUpdate&&v.__h.push(function(){v.componentDidUpdate(y,_,w);});}v.context=x,v.props=g,v.state=v.__s,(a=n.__r)&&a(u),v.__d=!1,v.__v=u,v.__P=l,a=v.render(v.props,v.state,v.context),v.state=v.__s,null!=v.getChildContext&&(t=s(s({},t),v.getChildContext())),h||null==v.getSnapshotBeforeUpdate||(w=v.getSnapshotBeforeUpdate(y,_)),A=null!=a&&a.type==p&&null==a.key?a.props.children:a,m(l,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,c),v.base=u.__e,u.__h=null,v.__h.length&&f.push(v),k&&(v.__E=v.__=null),v.__e=!1;}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=H(i.__e,u,i,t,o,r,f,c);(a=n.diffed)&&a(u);}catch(l){u.__v=null,(c||null!=r)&&(u.__e=e,u.__h=!!c,r[r.indexOf(e)]=null),n.__e(l,u,i);}return u.__e}function j(l,u){n.__c&&n.__c(u,l),l.some(function(u){try{l=u.__h,u.__h=[],l.some(function(n){n.call(u);});}catch(l){n.__e(l,u.__v);}});}function H(n,l,u,i,t,o,r,c){var s,a,v,h,y,p=u.props,d=l.props;if(t="svg"===l.type||t,null!=o)for(s=0;s<o.length;s++)if(null!=(a=o[s])&&((null===l.type?3===a.nodeType:a.localName===l.type)||n==a)){n=a,o[s]=null;break}if(null==n){if(null===l.type)return document.createTextNode(d);n=t?document.createElementNS("http://www.w3.org/2000/svg",l.type):document.createElement(l.type,d.is&&{is:d.is}),o=null,c=!1;}if(null===l.type)p===d||c&&n.data===d||(n.data=d);else {if(null!=o&&(o=e.slice.call(n.childNodes)),v=(p=u.props||f).dangerouslySetInnerHTML,h=d.dangerouslySetInnerHTML,!c){if(null!=o)for(p={},y=0;y<n.attributes.length;y++)p[n.attributes[y].name]=n.attributes[y].value;(h||v)&&(h&&(v&&h.__html==v.__html||h.__html===n.innerHTML)||(n.innerHTML=h&&h.__html||""));}A(n,d,p,t,c),h?l.__k=[]:(s=l.props.children,m(n,Array.isArray(s)?s:[s],l,u,i,"foreignObject"!==l.type&&t,o,r,f,c)),c||("value"in d&&void 0!==(s=d.value)&&(s!==n.value||"progress"===l.type&&!s)&&C(n,"value",s,p.value,!1),"checked"in d&&void 0!==(s=d.checked)&&s!==n.checked&&C(n,"checked",s,p.checked,!1));}return n}function I(l,u,i){try{"function"==typeof l?l(u):l.current=u;}catch(l){n.__e(l,i);}}function L(l,u,i){var t,o,r;if(n.unmount&&n.unmount(l),(t=l.ref)&&(t.current&&t.current!==l.__e||I(t,null,u)),i||"function"==typeof l.type||(i=null!=(o=l.__e)),l.__e=l.__d=void 0,null!=(t=l.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(l){n.__e(l,u);}t.base=t.__P=null;}if(t=l.__k)for(r=0;r<t.length;r++)t[r]&&L(t[r],u,i);null!=o&&a(o);}function M(n,l,u){return this.constructor(n,u)}function O(l,u,i){var t,r,c;n.__&&n.__(l,u),r=(t=i===o)?null:i&&i.__k||u.__k,l=v(p,null,[l]),c=[],$(u,(t?u:i||u).__k=l,r||f,f,void 0!==u.ownerSVGElement,i&&!t?[i]:r?null:u.childNodes.length?e.slice.call(u.childNodes):null,c,i||f,t),j(c,l);}function B(n,l){var u={__c:l="__cC"+r++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n,u,i){return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(k);},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n={__e:function(n,l){for(var u,i,t,o=l.__h;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return l.__h=o,u.__E=u}catch(l){n=l;}throw n},__v:0},d.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=s({},this.state),"function"==typeof n&&(n=n(s({},u),this.props)),n&&s(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),k(this));},d.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),k(this));},d.prototype.render=p,u=[],i="function"==typeof Promise?Promise.prototype.then.bind(Prom
57ise.resolve()):setTimeout,g.__r=0,o=f,r=0;
58
59    var globalObj = typeof globalThis !== 'undefined' ? globalThis : window; // // TODO: streamline when killing IE11 support
60    if (globalObj.FullCalendarVDom) {
61        console.warn('FullCalendar VDOM already loaded');
62    }
63    else {
64        globalObj.FullCalendarVDom = {
65            Component: d,
66            createElement: v,
67            render: O,
68            createRef: y,
69            Fragment: p,
70            createContext: createContext,
71            flushToDom: flushToDom,
72            unmountComponentAtNode: unmountComponentAtNode,
73        };
74    }
75    // HACKS...
76    // TODO: lock version
77    // TODO: link gh issues
78    function flushToDom() {
79        var oldDebounceRendering = n.debounceRendering; // orig
80        var callbackQ = [];
81        function execCallbackSync(callback) {
82            callbackQ.push(callback);
83        }
84        n.debounceRendering = execCallbackSync;
85        O(v(FakeComponent, {}), document.createElement('div'));
86        while (callbackQ.length) {
87            callbackQ.shift()();
88        }
89        n.debounceRendering = oldDebounceRendering;
90    }
91    var FakeComponent = /** @class */ (function (_super) {
92        __extends(FakeComponent, _super);
93        function FakeComponent() {
94            return _super !== null && _super.apply(this, arguments) || this;
95        }
96        FakeComponent.prototype.render = function () { return v('div', {}); };
97        FakeComponent.prototype.componentDidMount = function () { this.setState({}); };
98        return FakeComponent;
99    }(d));
100    function createContext(defaultValue) {
101        var ContextType = B(defaultValue);
102        var origProvider = ContextType.Provider;
103        ContextType.Provider = function () {
104            var _this = this;
105            var isNew = !this.getChildContext;
106            var children = origProvider.apply(this, arguments); // eslint-disable-line prefer-rest-params
107            if (isNew) {
108                var subs_1 = [];
109                this.shouldComponentUpdate = function (_props) {
110                    if (_this.props.value !== _props.value) {
111                        subs_1.forEach(function (c) {
112                            c.context = _props.value;
113                            c.forceUpdate();
114                        });
115                    }
116                };
117                this.sub = function (c) {
118                    subs_1.push(c);
119                    var old = c.componentWillUnmount;
120                    c.componentWillUnmount = function () {
121                        subs_1.splice(subs_1.indexOf(c), 1);
122                        old && old.call(c);
123                    };
124                };
125            }
126            return children;
127        };
128        return ContextType;
129    }
130    function unmountComponentAtNode(node) {
131        O(null, node);
132    }
133
134    // no public types yet. when there are, export from:
135    // import {} from './api-type-deps'
136    var EventSourceApi = /** @class */ (function () {
137        function EventSourceApi(context, internalEventSource) {
138            this.context = context;
139            this.internalEventSource = internalEventSource;
140        }
141        EventSourceApi.prototype.remove = function () {
142            this.context.dispatch({
143                type: 'REMOVE_EVENT_SOURCE',
144                sourceId: this.internalEventSource.sourceId,
145            });
146        };
147        EventSourceApi.prototype.refetch = function () {
148            this.context.dispatch({
149                type: 'FETCH_EVENT_SOURCES',
150                sourceIds: [this.internalEventSource.sourceId],
151            });
152        };
153        Object.defineProperty(EventSourceApi.prototype, "id", {
154            get: function () {
155                return this.internalEventSource.publicId;
156            },
157            enumerable: false,
158            configurable: true
159        });
160        Object.defineProperty(EventSourceApi.prototype, "url", {
161            get: function () {
162                return this.internalEventSource.meta.url;
163            },
164            enumerable: false,
165            configurable: true
166        });
167        Object.defineProperty(EventSourceApi.prototype, "format", {
168            get: function () {
169                return this.internalEventSource.meta.format; // TODO: bad. not guaranteed
170            },
171            enumerable: false,
172            configurable: true
173        });
174        return EventSourceApi;
175    }());
176
177    function removeElement(el) {
178        if (el.parentNode) {
179            el.parentNode.removeChild(el);
180        }
181    }
182    // Querying
183    // ----------------------------------------------------------------------------------------------------------------
184    function elementClosest(el, selector) {
185        if (el.closest) {
186            return el.closest(selector);
187            // really bad fallback for IE
188            // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
189        }
190        if (!document.documentElement.contains(el)) {
191            return null;
192        }
193        do {
194            if (elementMatches(el, selector)) {
195                return el;
196            }
197            el = (el.parentElement || el.parentNode);
198        } while (el !== null && el.nodeType === 1);
199        return null;
200    }
201    function elementMatches(el, selector) {
202        var method = el.matches || el.matchesSelector || el.msMatchesSelector;
203        return method.call(el, selector);
204    }
205    // accepts multiple subject els
206    // returns a real array. good for methods like forEach
207    // TODO: accept the document
208    function findElements(container, selector) {
209        var containers = container instanceof HTMLElement ? [container] : container;
210        var allMatches = [];
211        for (var i = 0; i < containers.length; i += 1) {
212            var matches = containers[i].querySelectorAll(selector);
213            for (var j = 0; j < matches.length; j += 1) {
214                allMatches.push(matches[j]);
215            }
216        }
217        return allMatches;
218    }
219    // accepts multiple subject els
220    // only queries direct child elements // TODO: rename to findDirectChildren!
221    function findDirectChildren(parent, selector) {
222        var parents = parent instanceof HTMLElement ? [parent] : parent;
223        var allMatches = [];
224        for (var i = 0; i < parents.length; i += 1) {
225            var childNodes = parents[i].children; // only ever elements
226            for (var j = 0; j < childNodes.length; j += 1) {
227                var childNode = childNodes[j];
228                if (!selector || elementMatches(childNode, selector)) {
229                    allMatches.push(childNode);
230                }
231            }
232        }
233        return allMatches;
234    }
235    // Style
236    // ----------------------------------------------------------------------------------------------------------------
237    var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;
238    function applyStyle(el, props) {
239        for (var propName in props) {
240            applyStyleProp(el, propName, props[propName]);
241        }
242    }
243    function applyStyleProp(el, name, val) {
244        if (val == null) {
245            el.style[name] = '';
246        }
247        else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
248            el.style[name] = val + "px";
249        }
250        else {
251            el.style[name] = val;
252        }
253    }
254
255    // Stops a mouse/touch event from doing it's native browser action
256    function preventDefault(ev) {
257        ev.preventDefault();
258    }
259    // Event Delegation
260    // ----------------------------------------------------------------------------------------------------------------
261    function buildDelegationHandler(selector, handler) {
262        return function (ev) {
vendor: 15,134 bytes, lines 263-694
263            var matchedChild = elementClosest(ev.target, selector);
264            if (matchedChild) {
265                handler.call(matchedChild, ev, matchedChild);
266            }
267        };
268    }
269    function listenBySelector(container, eventType, selector, handler) {
270        var attachedHandler = buildDelegationHandler(selector, handler);
271        container.addEventListener(eventType, attachedHandler);
272        return function () {
273            container.removeEventListener(eventType, attachedHandler);
274        };
275    }
276    function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
277        var currentMatchedChild;
278        return listenBySelector(container, 'mouseover', selector, function (mouseOverEv, matchedChild) {
279            if (matchedChild !== currentMatchedChild) {
280                currentMatchedChild = matchedChild;
281                onMouseEnter(mouseOverEv, matchedChild);
282                var realOnMouseLeave_1 = function (mouseLeaveEv) {
283                    currentMatchedChild = null;
284                    onMouseLeave(mouseLeaveEv, matchedChild);
285                    matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1);
286                };
287                // listen to the next mouseleave, and then unattach
288                matchedChild.addEventListener('mouseleave', realOnMouseLeave_1);
289            }
290        });
291    }
292    // Animation
293    // ----------------------------------------------------------------------------------------------------------------
294    var transitionEventNames = [
295        'webkitTransitionEnd',
296        'otransitionend',
297        'oTransitionEnd',
298        'msTransitionEnd',
299        'transitionend',
300    ];
301    // triggered only when the next single subsequent transition finishes
302    function whenTransitionDone(el, callback) {
303        var realCallback = function (ev) {
304            callback(ev);
305            transitionEventNames.forEach(function (eventName) {
306                el.removeEventListener(eventName, realCallback);
307            });
308        };
309        transitionEventNames.forEach(function (eventName) {
310            el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes
311        });
312    }
313
314    var guidNumber = 0;
315    function guid() {
316        guidNumber += 1;
317        return String(guidNumber);
318    }
319    /* FullCalendar-specific DOM Utilities
320    ----------------------------------------------------------------------------------------------------------------------*/
321    // Make the mouse cursor express that an event is not allowed in the current area
322    function disableCursor() {
323        document.body.classList.add('fc-not-allowed');
324    }
325    // Returns the mouse cursor to its original look
326    function enableCursor() {
327        document.body.classList.remove('fc-not-allowed');
328    }
329    /* Selection
330    ----------------------------------------------------------------------------------------------------------------------*/
331    function preventSelection(el) {
332        el.classList.add('fc-unselectable');
333        el.addEventListener('selectstart', preventDefault);
334    }
335    function allowSelection(el) {
336        el.classList.remove('fc-unselectable');
337        el.removeEventListener('selectstart', preventDefault);
338    }
339    /* Context Menu
340    ----------------------------------------------------------------------------------------------------------------------*/
341    function preventContextMenu(el) {
342        el.addEventListener('contextmenu', preventDefault);
343    }
344    function allowContextMenu(el) {
345        el.removeEventListener('contextmenu', preventDefault);
346    }
347    function parseFieldSpecs(input) {
348        var specs = [];
349        var tokens = [];
350        var i;
351        var token;
352        if (typeof input === 'string') {
353            tokens = input.split(/\s*,\s*/);
354        }
355        else if (typeof input === 'function') {
356            tokens = [input];
357        }
358        else if (Array.isArray(input)) {
359            tokens = input;
360        }
361        for (i = 0; i < tokens.length; i += 1) {
362            token = tokens[i];
363            if (typeof token === 'string') {
364                specs.push(token.charAt(0) === '-' ?
365                    { field: token.substring(1), order: -1 } :
366                    { field: token, order: 1 });
367            }
368            else if (typeof token === 'function') {
369                specs.push({ func: token });
370            }
371        }
372        return specs;
373    }
374    function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
375        var i;
376        var cmp;
377        for (i = 0; i < fieldSpecs.length; i += 1) {
378            cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
379            if (cmp) {
380                return cmp;
381            }
382        }
383        return 0;
384    }
385    function compareByFieldSpec(obj0, obj1, fieldSpec) {
386        if (fieldSpec.func) {
387            return fieldSpec.func(obj0, obj1);
388        }
389        return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])
390            * (fieldSpec.order || 1);
391    }
392    function flexibleCompare(a, b) {
393        if (!a && !b) {
394            return 0;
395        }
396        if (b == null) {
397            return -1;
398        }
399        if (a == null) {
400            return 1;
401        }
402        if (typeof a === 'string' || typeof b === 'string') {
403            return String(a).localeCompare(String(b));
404        }
405        return a - b;
406    }
407    /* String Utilities
408    ----------------------------------------------------------------------------------------------------------------------*/
409    function padStart(val, len) {
410        var s = String(val);
411        return '000'.substr(0, len - s.length) + s;
412    }
413    /* Number Utilities
414    ----------------------------------------------------------------------------------------------------------------------*/
415    function compareNumbers(a, b) {
416        return a - b;
417    }
418    function isInt(n) {
419        return n % 1 === 0;
420    }
421    /* FC-specific DOM dimension stuff
422    ----------------------------------------------------------------------------------------------------------------------*/
423    function computeSmallestCellWidth(cellEl) {
424        var allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame');
425        var contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion');
426        if (!allWidthEl) {
427            throw new Error('needs fc-scrollgrid-shrink-frame className'); // TODO: use const
428        }
429        if (!contentWidthEl) {
430            throw new Error('needs fc-scrollgrid-shrink-cushion className');
431        }
432        return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width + // the cell padding+border
433            contentWidthEl.getBoundingClientRect().width;
434    }
435
436    var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
437    // Adding
438    function addWeeks(m, n) {
439        var a = dateToUtcArray(m);
440        a[2] += n * 7;
441        return arrayToUtcDate(a);
442    }
443    function addDays(m, n) {
444        var a = dateToUtcArray(m);
445        a[2] += n;
446        return arrayToUtcDate(a);
447    }
448    function addMs(m, n) {
449        var a = dateToUtcArray(m);
450        a[6] += n;
451        return arrayToUtcDate(a);
452    }
453    // Diffing (all return floats)
454    // TODO: why not use ranges?
455    function diffWeeks(m0, m1) {
456        return diffDays(m0, m1) / 7;
457    }
458    function diffDays(m0, m1) {
459        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
460    }
461    function diffHours(m0, m1) {
462        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
463    }
464    function diffMinutes(m0, m1) {
465        return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
466    }
467    function diffSeconds(m0, m1) {
468        return (m1.valueOf() - m0.valueOf()) / 1000;
469    }
470    function diffDayAndTime(m0, m1) {
471        var m0day = startOfDay(m0);
472        var m1day = startOfDay(m1);
473        return {
474            years: 0,
475            months: 0,
476            days: Math.round(diffDays(m0day, m1day)),
477            milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()),
478        };
479    }
480    // Diffing Whole Units
481    function diffWholeWeeks(m0, m1) {
482        var d = diffWholeDays(m0, m1);
483        if (d !== null && d % 7 === 0) {
484            return d / 7;
485        }
486        return null;
487    }
488    function diffWholeDays(m0, m1) {
489        if (timeAsMs(m0) === timeAsMs(m1)) {
490            return Math.round(diffDays(m0, m1));
491        }
492        return null;
493    }
494    // Start-Of
495    function startOfDay(m) {
496        return arrayToUtcDate([
497            m.getUTCFullYear(),
498            m.getUTCMonth(),
499            m.getUTCDate(),
500        ]);
501    }
502    function startOfHour(m) {
503        return arrayToUtcDate([
504            m.getUTCFullYear(),
505            m.getUTCMonth(),
506            m.getUTCDate(),
507            m.getUTCHours(),
508        ]);
509    }
510    function startOfMinute(m) {
511        return arrayToUtcDate([
512            m.getUTCFullYear(),
513            m.getUTCMonth(),
514            m.getUTCDate(),
515            m.getUTCHours(),
516            m.getUTCMinutes(),
517        ]);
518    }
519    function startOfSecond(m) {
520        return arrayToUtcDate([
521            m.getUTCFullYear(),
522            m.getUTCMonth(),
523            m.getUTCDate(),
524            m.getUTCHours(),
525            m.getUTCMinutes(),
526            m.getUTCSeconds(),
527        ]);
528    }
529    // Week Computation
530    function weekOfYear(marker, dow, doy) {
531        var y = marker.getUTCFullYear();
532        var w = weekOfGivenYear(marker, y, dow, doy);
533        if (w < 1) {
534            return weekOfGivenYear(marker, y - 1, dow, doy);
535        }
536        var nextW = weekOfGivenYear(marker, y + 1, dow, doy);
537        if (nextW >= 1) {
538            return Math.min(w, nextW);
539        }
540        return w;
541    }
542    function weekOfGivenYear(marker, year, dow, doy) {
543        var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
544        var dayStart = startOfDay(marker);
545        var days = Math.round(diffDays(firstWeekStart, dayStart));
546        return Math.floor(days / 7) + 1; // zero-indexed
547    }
548    // start-of-first-week - start-of-year
549    function firstWeekOffset(year, dow, doy) {
550        // first-week day -- which january is always in the first week (4 for iso, 1 for other)
551        var fwd = 7 + dow - doy;
552        // first-week day local weekday -- which local weekday is fwd
553        var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
554        return -fwdlw + fwd - 1;
555    }
556    // Array Conversion
557    function dateToLocalArray(date) {
558        return [
559            date.getFullYear(),
560            date.getMonth(),
561            date.getDate(),
562            date.getHours(),
563            date.getMinutes(),
564            date.getSeconds(),
565            date.getMilliseconds(),
566        ];
567    }
568    function arrayToLocalDate(a) {
569        return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month
570        a[3] || 0, a[4] || 0, a[5] || 0);
571    }
572    function dateToUtcArray(date) {
573        return [
574            date.getUTCFullYear(),
575            date.getUTCMonth(),
576            date.getUTCDate(),
577            date.getUTCHours(),
578            date.getUTCMinutes(),
579            date.getUTCSeconds(),
580            date.getUTCMilliseconds(),
581        ];
582    }
583    function arrayToUtcDate(a) {
584        // according to web standards (and Safari), a month index is required.
585        // massage if only given a year.
586        if (a.length === 1) {
587            a = a.concat([0]);
588        }
589        return new Date(Date.UTC.apply(Date, a));
590    }
591    // Other Utils
592    function isValidDate(m) {
593        return !isNaN(m.valueOf());
594    }
595    function timeAsMs(m) {
596        return m.getUTCHours() * 1000 * 60 * 60 +
597            m.getUTCMinutes() * 1000 * 60 +
598            m.getUTCSeconds() * 1000 +
599            m.getUTCMilliseconds();
600    }
601
602    function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
603        return {
604            instanceId: guid(),
605            defId: defId,
606            range: range,
607            forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
608            forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo,
609        };
610    }
611
612    var hasOwnProperty = Object.prototype.hasOwnProperty;
613    // Merges an array of objects into a single object.
614    // The second argument allows for an array of property names who's object values will be merged together.
615    function mergeProps(propObjs, complexPropsMap) {
616        var dest = {};
617        if (complexPropsMap) {
618            for (var name_1 in complexPropsMap) {
619                var complexObjs = [];
620                // collect the trailing object values, stopping when a non-object is discovered
621                for (var i = propObjs.length - 1; i >= 0; i -= 1) {
622                    var val = propObjs[i][name_1];
623                    if (typeof val === 'object' && val) { // non-null object
624                        complexObjs.unshift(val);
625                    }
626                    else if (val !== undefined) {
627                        dest[name_1] = val; // if there were no objects, this value will be used
628                        break;
629                    }
630                }
631                // if the trailing values were objects, use the merged value
632                if (complexObjs.length) {
633                    dest[name_1] = mergeProps(complexObjs);
634                }
635            }
636        }
637        // copy values into the destination, going from last to first
638        for (var i = propObjs.length - 1; i >= 0; i -= 1) {
639            var props = propObjs[i];
640            for (var name_2 in props) {
641                if (!(name_2 in dest)) { // if already assigned by previous props or complex props, don't reassign
642                    dest[name_2] = props[name_2];
643                }
644            }
645        }
646        return dest;
647    }
648    function filterHash(hash, func) {
649        var filtered = {};
650        for (var key in hash) {
651            if (func(hash[key], key)) {
652                filtered[key] = hash[key];
653            }
654        }
655        return filtered;
656    }
657    function mapHash(hash, func) {
658        var newHash = {};
659        for (var key in hash) {
660            newHash[key] = func(hash[key], key);
661        }
662        return newHash;
663    }
664    function arrayToHash(a) {
665        var hash = {};
666        for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
667            var item = a_1[_i];
668            hash[item] = true;
669        }
670        return hash;
671    }
672    function buildHashFromArray(a, func) {
673        var hash = {};
674        for (var i = 0; i < a.length; i += 1) {
675            var tuple = func(a[i], i);
676            hash[tuple[0]] = tuple[1];
677        }
678        return hash;
679    }
680    function hashValuesToArray(obj) {
681        var a = [];
682        for (var key in obj) {
683            a.push(obj[key]);
684        }
685        return a;
686    }
687    function isPropsEqual(obj0, obj1) {
688        if (obj0 === obj1) {
689            return true;
690        }
691        for (var key in obj0) {
692            if (hasOwnProperty.call(obj0, key)) {
693                if (!(key in obj1)) {
694                    return false;
695                }
696            }
697        }
698        for (var key in obj1) {
699            if (hasOwnProperty.call(obj1, key)) {
700                if (obj0[key] !== obj1[key]) {
701                    return false;
702                }
703            }
704        }
705        return true;
706    }
707    function getUnequalProps(obj0, obj1) {
708        var keys = [];
709        for (var key in obj0) {
710            if (hasOwnProperty.call(obj0, key)) {
711                if (!(key in obj1)) {
712                    keys.push(key);
713                }
714            }
715        }
716        for (var key in obj1) {
717            if (hasOwnProperty.call(obj1, key)) {
718                if (obj0[key] !== obj1[key]) {
719                    keys.push(key);
720                }
721            }
722        }
723        return keys;
724    }
725    function compareObjs(oldProps, newProps, equalityFuncs) {
726        if (equalityFuncs === void 0) { equalityFuncs = {}; }
727        if (oldProps === newProps) {
728            return true;
729        }
730        for (var key in newProps) {
731            if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ;
732            else {
733                return false;
734            }
735        }
736        // check for props that were omitted in the new
737        for (var key in oldProps) {
738            if (!(key in newProps)) {
739                return false;
740            }
741        }
742        return true;
743    }
744    /*
745    assumed "true" equality for handler names like "onReceiveSomething"
746    */
747    function isObjValsEqual(val0, val1, comparator) {
748        if (val0 === val1 || comparator === true) {
749            return true;
750        }
751        if (comparator) {
752            return comparator(val0, val1);
753        }
754        return false;
755    }
756    function collectFromHash(hash, startIndex, endIndex, step) {
757        if (startIndex === void 0) { startIndex = 0; }
758        if (step === void 0) { step = 1; }
759        var res = [];
760        if (endIndex == null) {
761            endIndex = Object.keys(hash).length;
762        }
763        for (var i = startIndex; i < endIndex; i += step) {
764            var val = hash[i];
765            if (val !== undefined) { // will disregard undefined for sparse arrays
766                res.push(val);
767            }
768        }
769        return res;
770    }
771
772    function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) {
773        for (var i = 0; i < recurringTypes.length; i += 1) {
774            var parsed = recurringTypes[i].parse(refined, dateEnv);
775            if (parsed) {
776                var allDay = refined.allDay;
777                if (allDay == null) {
778                    allDay = defaultAllDay;
779                    if (allDay == null) {
780                        allDay = parsed.allDayGuess;
781                        if (allDay == null) {
782                            allDay = false;
783                        }
784                    }
785                }
786                return {
787                    allDay: allDay,
788                    duration: parsed.duration,
789                    typeData: parsed.typeData,
790                    typeId: i,
791                };
792            }
793        }
794        return null;
795    }
796    function expandRecurring(eventStore, framingRange, context) {
797        var dateEnv = context.dateEnv, pluginHooks = context.pluginHooks, options = context.options;
798        var defs = eventStore.defs, instances = eventStore.instances;
799        // remove existing recurring instances
800        // TODO: bad. always expand events as a second step
801        instances = filterHash(instances, function (instance) { return !defs[instance.defId].recurringDef; });
802        for (var defId in defs) {
803            var def = defs[defId];
804            if (def.recurringDef) {
805                var duration = def.recurringDef.duration;
806                if (!duration) {
807                    duration = def.allDay ?
808                        options.defaultAllDayEventDuration :
809                        options.defaultTimedEventDuration;
810                }
811                var starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes);
812                for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) {
813                    var start = starts_1[_i];
814                    var instance = createEventInstance(defId, {
815                        start: start,
816                        end: dateEnv.add(start, duration),
817                    });
818                    instances[instance.instanceId] = instance;
819                }
820            }
821        }
822        return { defs: defs, instances: instances };
823    }
824    /*
825    Event MUST have a recurringDef
826    */
827    function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) {
828        var typeDef = recurringTypes[eventDef.recurringDef.typeId];
829        var markers = typeDef.expand(eventDef.recurringDef.typeData, {
830            start: dateEnv.subtract(framingRange.start, duration),
831            end: framingRange.end,
832        }, dateEnv);
833        // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to
834        if (eventDef.allDay) {
835            markers = markers.map(startOfDay);
836        }
837        return markers;
838    }
839
840    var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
vendor: 7,700 bytes, lines 841-1066
841    var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
842    // Parsing and Creation
843    function createDuration(input, unit) {
844        var _a;
845        if (typeof input === 'string') {
846            return parseString(input);
847        }
848        if (typeof input === 'object' && input) { // non-null object
849            return parseObject(input);
850        }
851        if (typeof input === 'number') {
852            return parseObject((_a = {}, _a[unit || 'milliseconds'] = input, _a));
853        }
854        return null;
855    }
856    function parseString(s) {
857        var m = PARSE_RE.exec(s);
858        if (m) {
859            var sign = m[1] ? -1 : 1;
860            return {
861                years: 0,
862                months: 0,
863                days: sign * (m[2] ? parseInt(m[2], 10) : 0),
864                milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours
865                    (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes
866                    (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds
867                    (m[6] ? parseInt(m[6], 10) : 0) // ms
868                ),
869            };
870        }
871        return null;
872    }
873    function parseObject(obj) {
874        var duration = {
875            years: obj.years || obj.year || 0,
876            months: obj.months || obj.month || 0,
877            days: obj.days || obj.day || 0,
878            milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours
879                (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes
880                (obj.seconds || obj.second || 0) * 1000 + // seconds
881                (obj.milliseconds || obj.millisecond || obj.ms || 0),
882        };
883        var weeks = obj.weeks || obj.week;
884        if (weeks) {
885            duration.days += weeks * 7;
886            duration.specifiedWeeks = true;
887        }
888        return duration;
889    }
890    // Equality
891    function durationsEqual(d0, d1) {
892        return d0.years === d1.years &&
893            d0.months === d1.months &&
894            d0.days === d1.days &&
895            d0.milliseconds === d1.milliseconds;
896    }
897    function asCleanDays(dur) {
898        if (!dur.years && !dur.months && !dur.milliseconds) {
899            return dur.days;
900        }
901        return 0;
902    }
903    // Simple Math
904    function addDurations(d0, d1) {
905        return {
906            years: d0.years + d1.years,
907            months: d0.months + d1.months,
908            days: d0.days + d1.days,
909            milliseconds: d0.milliseconds + d1.milliseconds,
910        };
911    }
912    function subtractDurations(d1, d0) {
913        return {
914            years: d1.years - d0.years,
915            months: d1.months - d0.months,
916            days: d1.days - d0.days,
917            milliseconds: d1.milliseconds - d0.milliseconds,
918        };
919    }
920    function multiplyDuration(d, n) {
921        return {
922            years: d.years * n,
923            months: d.months * n,
924            days: d.days * n,
925            milliseconds: d.milliseconds * n,
926        };
927    }
928    // Conversions
929    // "Rough" because they are based on average-case Gregorian months/years
930    function asRoughYears(dur) {
931        return asRoughDays(dur) / 365;
932    }
933    function asRoughMonths(dur) {
934        return asRoughDays(dur) / 30;
935    }
936    function asRoughDays(dur) {
937        return asRoughMs(dur) / 864e5;
938    }
939    function asRoughMinutes(dur) {
940        return asRoughMs(dur) / (1000 * 60);
941    }
942    function asRoughSeconds(dur) {
943        return asRoughMs(dur) / 1000;
944    }
945    function asRoughMs(dur) {
946        return dur.years * (365 * 864e5) +
947            dur.months * (30 * 864e5) +
948            dur.days * 864e5 +
949            dur.milliseconds;
950    }
951    // Advanced Math
952    function wholeDivideDurations(numerator, denominator) {
953        var res = null;
954        for (var i = 0; i < INTERNAL_UNITS.length; i += 1) {
955            var unit = INTERNAL_UNITS[i];
956            if (denominator[unit]) {
957                var localRes = numerator[unit] / denominator[unit];
958                if (!isInt(localRes) || (res !== null && res !== localRes)) {
959                    return null;
960                }
961                res = localRes;
962            }
963            else if (numerator[unit]) {
964                // needs to divide by something but can't!
965                return null;
966            }
967        }
968        return res;
969    }
970    function greatestDurationDenominator(dur) {
971        var ms = dur.milliseconds;
972        if (ms) {
973            if (ms % 1000 !== 0) {
974                return { unit: 'millisecond', value: ms };
975            }
976            if (ms % (1000 * 60) !== 0) {
977                return { unit: 'second', value: ms / 1000 };
978            }
979            if (ms % (1000 * 60 * 60) !== 0) {
980                return { unit: 'minute', value: ms / (1000 * 60) };
981            }
982            if (ms) {
983                return { unit: 'hour', value: ms / (1000 * 60 * 60) };
984            }
985        }
986        if (dur.days) {
987            if (dur.specifiedWeeks && dur.days % 7 === 0) {
988                return { unit: 'week', value: dur.days / 7 };
989            }
990            return { unit: 'day', value: dur.days };
991        }
992        if (dur.months) {
993            return { unit: 'month', value: dur.months };
994        }
995        if (dur.years) {
996            return { unit: 'year', value: dur.years };
997        }
998        return { unit: 'millisecond', value: 0 };
999    }
1000
1001    // timeZoneOffset is in minutes
1002    function buildIsoString(marker, timeZoneOffset, stripZeroTime) {
1003        if (stripZeroTime === void 0) { stripZeroTime = false; }
1004        var s = marker.toISOString();
1005        s = s.replace('.000', '');
1006        if (stripZeroTime) {
1007            s = s.replace('T00:00:00Z', '');
1008        }
1009        if (s.length > 10) { // time part wasn't stripped, can add timezone info
1010            if (timeZoneOffset == null) {
1011                s = s.replace('Z', '');
1012            }
1013            else if (timeZoneOffset !== 0) {
1014                s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
1015            }
1016            // otherwise, its UTC-0 and we want to keep the Z
1017        }
1018        return s;
1019    }
1020    // formats the date, but with no time part
1021    // TODO: somehow merge with buildIsoString and stripZeroTime
1022    // TODO: rename. omit "string"
1023    function formatDayString(marker) {
1024        return marker.toISOString().replace(/T.*$/, '');
1025    }
1026    // TODO: use Date::toISOString and use everything after the T?
1027    function formatIsoTimeString(marker) {
1028        return padStart(marker.getUTCHours(), 2) + ':' +
1029            padStart(marker.getUTCMinutes(), 2) + ':' +
1030            padStart(marker.getUTCSeconds(), 2);
1031    }
1032    function formatTimeZoneOffset(minutes, doIso) {
1033        if (doIso === void 0) { doIso = false; }
1034        var sign = minutes < 0 ? '-' : '+';
1035        var abs = Math.abs(minutes);
1036        var hours = Math.floor(abs / 60);
1037        var mins = Math.round(abs % 60);
1038        if (doIso) {
1039            return sign + padStart(hours, 2) + ":" + padStart(mins, 2);
1040        }
1041        return "GMT" + sign + hours + (mins ? ":" + padStart(mins, 2) : '');
1042    }
1043
1044    // TODO: new util arrayify?
1045    function removeExact(array, exactVal) {
1046        var removeCnt = 0;
1047        var i = 0;
1048        while (i < array.length) {
1049            if (array[i] === exactVal) {
1050                array.splice(i, 1);
1051                removeCnt += 1;
1052            }
1053            else {
1054                i += 1;
1055            }
1056        }
1057        return removeCnt;
1058    }
1059    function isArraysEqual(a0, a1, equalityFunc) {
1060        if (a0 === a1) {
1061            return true;
1062        }
1063        var len = a0.length;
1064        var i;
1065        if (len !== a1.length) { // not array? or not same length?
1066            return false;
1067        }
1068        for (i = 0; i < len; i += 1) {
1069            if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) {
1070                return false;
1071            }
1072        }
1073        return true;
1074    }
1075
1076    function memoize(workerFunc, resEquality, teardownFunc) {
1077        var currentArgs;
1078        var currentRes;
1079        return function () {
1080            var newArgs = [];
1081            for (var _i = 0; _i < arguments.length; _i++) {
1082                newArgs[_i] = arguments[_i];
1083            }
1084            if (!currentArgs) {
1085                currentRes = workerFunc.apply(this, newArgs);
1086            }
1087            else if (!isArraysEqual(currentArgs, newArgs)) {
1088                if (teardownFunc) {
1089                    teardownFunc(currentRes);
1090                }
1091                var res = workerFunc.apply(this, newArgs);
1092                if (!resEquality || !resEquality(res, currentRes)) {
1093                    currentRes = res;
1094                }
1095            }
1096            currentArgs = newArgs;
1097            return currentRes;
1098        };
1099    }
1100    function memoizeObjArg(workerFunc, resEquality, teardownFunc) {
1101        var _this = this;
1102        var currentArg;
1103        var currentRes;
1104        return function (newArg) {
1105            if (!currentArg) {
1106                currentRes = workerFunc.call(_this, newArg);
1107            }
1108            else if (!isPropsEqual(currentArg, newArg)) {
1109                if (teardownFunc) {
1110                    teardownFunc(currentRes);
1111                }
1112                var res = workerFunc.call(_this, newArg);
1113                if (!resEquality || !resEquality(res, currentRes)) {
1114                    currentRes = res;
1115                }
1116            }
1117            currentArg = newArg;
1118            return currentRes;
1119        };
1120    }
1121    function memoizeArraylike(// used at all?
1122    workerFunc, resEquality, teardownFunc) {
1123        var _this = this;
1124        var currentArgSets = [];
1125        var currentResults = [];
1126        return function (newArgSets) {
1127            var currentLen = currentArgSets.length;
1128            var newLen = newArgSets.length;
1129            var i = 0;
1130            for (; i < currentLen; i += 1) {
1131                if (!newArgSets[i]) { // one of the old sets no longer exists
1132                    if (teardownFunc) {
1133                        teardownFunc(currentResults[i]);
1134                    }
1135                }
1136                else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) {
1137                    if (teardownFunc) {
1138                        teardownFunc(currentResults[i]);
1139                    }
1140                    var res = workerFunc.apply(_this, newArgSets[i]);
1141                    if (!resEquality || !resEquality(res, currentResults[i])) {
1142                        currentResults[i] = res;
1143                    }
1144                }
1145            }
1146            for (; i < newLen; i += 1) {
1147                currentResults[i] = workerFunc.apply(_this, newArgSets[i]);
1148            }
1149            currentArgSets = newArgSets;
1150            currentResults.splice(newLen); // remove excess
1151            return currentResults;
1152        };
1153    }
1154    function memoizeHashlike(// used?
1155    workerFunc, resEquality, teardownFunc) {
1156        var _this = this;
1157        var currentArgHash = {};
1158        var currentResHash = {};
1159        return function (newArgHash) {
1160            var newResHash = {};
1161            for (var key in newArgHash) {
1162                if (!currentResHash[key]) {
1163                    newResHash[key] = workerFunc.apply(_this, newArgHash[key]);
1164                }
1165                else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) {
1166                    if (teardownFunc) {
1167                        teardownFunc(currentResHash[key]);
1168                    }
1169                    var res = workerFunc.apply(_this, newArgHash[key]);
1170                    newResHash[key] = (resEquality && resEquality(res, currentResHash[key]))
1171                        ? currentResHash[key]
1172                        : res;
1173                }
1174                else {
1175                    newResHash[key] = currentResHash[key];
1176                }
1177            }
1178            currentArgHash = newArgHash;
1179            currentResHash = newResHash;
1180            return newResHash;
1181        };
1182    }
1183
1184    var EXTENDED_SETTINGS_AND_SEVERITIES = {
1185        week: 3,
1186        separator: 0,
1187        omitZeroMinute: 0,
1188        meridiem: 0,
1189        omitCommas: 0,
1190    };
1191    var STANDARD_DATE_PROP_SEVERITIES = {
1192        timeZoneName: 7,
1193        era: 6,
1194        year: 5,
1195        month: 4,
1196        day: 2,
1197        weekday: 2,
1198        hour: 1,
1199        minute: 1,
1200        second: 1,
1201    };
1202    var MERIDIEM_RE = /\s*([ap])\.?m\.?/i;
1202 // eats up leading spaces too
1203    var COMMA_RE = /,/g; // we need re for globalness
1204    var MULTI_SPACE_RE = /\s+/g;
1205    var LTR_RE = /\u200e/g; // control character
1206    var UTC_RE = /UTC|GMT/;
1207    var NativeFormatter = /** @class */ (function () {
1208        function NativeFormatter(formatSettings) {
1209            var standardDateProps = {};
1210            var extendedSettings = {};
1211            var severity = 0;
1212            for (var name_1 in formatSettings) {
1213                if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) {
1214                    extendedSettings[name_1] = formatSettings[name_1];
1215                    severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity);
1216                }
1217                else {
1218                    standardDateProps[name_1] = formatSettings[name_1];
1219                    if (name_1 in STANDARD_DATE_PROP_SEVERITIES) { // TODO: what about hour12? no severity
1220                        severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity);
1221                    }
1222                }
1223            }
1224            this.standardDateProps = standardDateProps;
1225            this.extendedSettings = extendedSettings;
1226            this.severity = severity;
1227            this.buildFormattingFunc = memoize(buildFormattingFunc);
1228        }
1229        NativeFormatter.prototype.format = function (date, context) {
1230            return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
1231        };
1232        NativeFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
1233            var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings;
1234            var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
1235            if (!diffSeverity) {
1236                return this.format(start, context);
1237            }
1238            var biggestUnitForPartial = diffSeverity;
1239            if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time
1240                (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&
1241                (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&
1242                (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
1243                biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time
1244            }
1245            var full0 = this.format(start, context);
1246            var full1 = this.format(end, context);
1247            if (full0 === full1) {
1248                return full0;
1249            }
1250            var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial);
1251            var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
1252            var partial0 = partialFormattingFunc(start);
1253            var partial1 = partialFormattingFunc(end);
1254            var insertion = findCommonInsertion(full0, partial0, full1, partial1);
1255            var separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || '';
1256            if (insertion) {
1257                return insertion.before + partial0 + separator + partial1 + insertion.after;
1258            }
1259            return full0 + separator + full1;
1260        };
1261        NativeFormatter.prototype.getLargestUnit = function () {
1262            switch (this.severity) {
1263                case 7:
1264                case 6:
1265                case 5:
1266                    return 'year';
1267                case 4:
1268                    return 'month';
1269                case 3:
1270                    return 'week';
1271                case 2:
1272                    return 'day';
1273                default:
1274                    return 'time'; // really?
1275            }
1276        };
1277        return NativeFormatter;
1278    }());
1279    function buildFormattingFunc(standardDateProps, extendedSettings, context) {
1280        var standardDatePropCnt = Object.keys(standardDateProps).length;
1281        if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
1282            return function (date) { return (formatTimeZoneOffset(date.timeZoneOffset)); };
1283        }
1284        if (standardDatePropCnt === 0 && extendedSettings.week) {
1285            return function (date) { return (formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.locale, extendedSettings.week)); };
1286        }
1287        return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
1288    }
1289    function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
1290        standardDateProps = __assign({}, standardDateProps); // copy
1291        extendedSettings = __assign({}, extendedSettings); // copy
1292        sanitizeSettings(standardDateProps, extendedSettings);
1293        standardDateProps.timeZone = 'UTC';
1293 // we leverage the only guaranteed timeZone for our UTC markers
1294        var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
1295        var zeroFormat; // needed?
1296        if (extendedSettings.omitZeroMinute) {
1297            var zeroProps = __assign({}, standardDateProps);
1298            delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings
1299            zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
1300        }
1301        return function (date) {
1302            var marker = date.marker;
1303            var format;
1304            if (zeroFormat && !marker.getUTCMinutes()) {
1305                format = zeroFormat;
1306            }
1307            else {
1308                format = normalFormat;
1309            }
1310            var s = format.format(marker);
1311            return postProcess(s, date, standardDateProps, extendedSettings, context);
1312        };
1313    }
1314    function sanitizeSettings(standardDateProps, extendedSettings) {
1315        // deal with a browser inconsistency where formatting the timezone
1316        // requires that the hour/minute be present.
1317        if (standardDateProps.timeZoneName) {
1318            if (!standardDateProps.hour) {
1319                standardDateProps.hour = '2-digit';
1320            }
1321            if (!standardDateProps.minute) {
1322                standardDateProps.minute = '2-digit';
1323            }
1324        }
1325        // only support short timezone names
1326        if (standardDateProps.timeZoneName === 'long') {
1327            standardDateProps.timeZoneName = 'short';
1328        }
1329        // if requesting to display seconds, MUST display minutes
1330        if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
1331            delete extendedSettings.omitZeroMinute;
1332        }
1333    }
1334    function postProcess(s, date, standardDateProps, extendedSettings, context) {
1335        s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes
1336        if (standardDateProps.timeZoneName === 'short') {
1337            s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?
1338                'UTC' : // important to normalize for IE, which does "GMT"
1339                formatTimeZoneOffset(date.timeZoneOffset));
1340        }
1341        if (extendedSettings.omitCommas) {
1342            s = s.replace(COMMA_RE, '').trim();
1343        }
1344        if (extendedSettings.omitZeroMinute) {
1345            s = s.replace(':00', ''); // zeroFormat doesn't always achieve this
1346        }
1347        // ^ do anything that might create adjacent spaces before this point,
1348        // because MERIDIEM_RE likes to eat up loading spaces
1349        if (extendedSettings.meridiem === false) {
1350            s = s.replace(MERIDIEM_RE, '').trim();
1351        }
1352        else if (extendedSettings.meridiem === 'narrow') { // a/p
1353            s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase(); });
1354        }
1355        else if (extendedSettings.meridiem === 'short') { // am/pm
1356            s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase() + "m"; });
1357        }
1358        else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase
1359            s = s.replace(MERIDIEM_RE, function (m0) { return m0.toLocaleLowerCase(); });
1360        }
1361        s = s.replace(MULTI_SPACE_RE, ' ');
1362        s = s.trim();
1363        return s;
1364    }
1365    function injectTzoStr(s, tzoStr) {
1366        var replaced = false;
1367        s = s.replace(UTC_RE, function () {
1368            replaced = true;
1369            return tzoStr;
1370        });
1371        // IE11 doesn't include UTC/GMT in the original string, so append to end
1372        if (!replaced) {
1373            s += " " + tzoStr;
1374        }
1375        return s;
1376    }
1377    function formatWeekNumber(num, weekText, locale, display) {
1378        var parts = [];
1379        if (display === 'narrow') {
1380            parts.push(weekText);
1381        }
1382        else if (display === 'short') {
1383            parts.push(weekText, ' ');
1384        }
1385        // otherwise, considered 'numeric'
1386        parts.push(locale.simpleNumberFormat.format(num));
1387        if (locale.options.direction === 'rtl') { // TODO: use control characters instead?
1388            parts.reverse();
1389        }
1390        return parts.join('');
1391    }
1392    // Range Formatting Utils
1393    // 0 = exactly the same
1394    // 1 = different by time
1395    // and bigger
1396    function computeMarkerDiffSeverity(d0, d1, ca) {
1397        if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
1398            return 5;
1399        }
1400        if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
1401            return 4;
1402        }
1403        if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
1404            return 2;
1405        }
1406        if (timeAsMs(d0) !== timeAsMs(d1)) {
1407            return 1;
1408        }
1409        return 0;
1410    }
1411    function computePartialFormattingOptions(options, biggestUnit) {
1412        var partialOptions = {};
1413        for (var name_2 in options) {
1414            if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)
1415                STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) {
1416                partialOptions[name_2] = options[name_2];
1417            }
1418        }
1419        return partialOptions;
1420    }
1421    function findCommonInsertion(full0, partial0, full1, partial1) {
1422        var i0 = 0;
1423        while (i0 < full0.length) {
1424            var found0 = full0.indexOf(partial0, i0);
1425            if (found0 === -1) {
1426                break;
1427            }
1428            var before0 = full0.substr(0, found0);
1429            i0 = found0 + partial0.length;
1430            var after0 = full0.substr(i0);
1431            var i1 = 0;
1432            while (i1 < full1.length) {
1433                var found1 = full1.indexOf(partial1, i1);
1434                if (found1 === -1) {
1435                    break;
1436                }
1437                var before1 = full1.substr(0, found1);
1438                i1 = found1 + partial1.length;
1439                var after1 = full1.substr(i1);
1440                if (before0 === before1 && after0 === after1) {
1441                    return {
1442                        before: before0,
1443                        after: after0,
1444                    };
1445                }
1446            }
1447        }
1448        return null;
1449    }
1450
1451    function expandZonedMarker(dateInfo, calendarSystem) {
1452        var a = calendarSystem.markerToArray(dateInfo.marker);
1453        return {
1454            marker: dateInfo.marker,
1455            timeZoneOffset: dateInfo.timeZoneOffset,
1456            array: a,
1457            year: a[0],
1458            month: a[1],
1459            day: a[2],
1460            hour: a[3],
1461            minute: a[4],
1462            second: a[5],
1463            millisecond: a[6],
1464        };
1465    }
1466
1467    function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {
1468        var startInfo = expandZonedMarker(start, context.calendarSystem);
1469        var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
1470        return {
1471            date: startInfo,
1472            start: startInfo,
1473            end: endInfo,
1474            timeZone: context.timeZone,
1475            localeCodes: context.locale.codes,
1476            defaultSeparator: betterDefaultSeparator || context.defaultSeparator,
1477        };
1478    }
1479
1480    /*
1481    TODO: fix the terminology of "formatter" vs "formatting func"
1482    */
1483    /*
1484    At the time of instantiation, this object does not know which cmd-formatting system it will use.
1485    It receives this at the time of formatting, as a setting.
1486    */
1487    var CmdFormatter = /** @class */ (function () {
1488        function CmdFormatter(cmdStr) {
1489            this.cmdStr = cmdStr;
1490        }
1491        CmdFormatter.prototype.format = function (date, context, betterDefaultSeparator) {
1492            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
1493        };
1494        CmdFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
1495            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
1496        };
1497        return CmdFormatter;
1498    }());
1499
1500    var FuncFormatter = /** @class */ (function () {
1501        function FuncFormatter(func) {
1502            this.func = func;
1503        }
1504        FuncFormatter.prototype.format = function (date, context, betterDefaultSeparator) {
1505            return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
1506        };
1507        FuncFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) {
1508            return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
1509        };
1510        return FuncFormatter;
1511    }());
1512
1513    function createFormatter(input) {
1514        if (typeof input === 'object' && input) { // non-null object
1515            return new NativeFormatter(input);
1516        }
1517        if (typeof input === 'string') {
1518            return new CmdFormatter(input);
1519        }
1520        if (typeof input === 'function') {
1521            return new FuncFormatter(input);
1522        }
1523        return null;
1524    }
1525
1526    // base options
1527    // ------------
1528    var BASE_OPTION_REFINERS = {
1529        navLinkDayClick: identity,
1530        navLinkWeekClick: identity,
1531        duration: createDuration,
1532        bootstrapFontAwesome: identity,
1533        buttonIcons: identity,
1534        customButtons: identity,
1535        defaultAllDayEventDuration: createDuration,
1536        defaultTimedEventDuration: createDuration,
1537        nextDayThreshold: createDuration,
1538        scrollTime: createDuration,
1539        slotMinTime: createDuration,
1540        slotMaxTime: createDuration,
1541        dayPopoverFormat: createFormatter,
1542        slotDuration: createDuration,
1543        snapDuration: createDuration,
1544        headerToolbar: identity,
1545        footerToolbar: identity,
1546        defaultRangeSeparator: String,
1547        titleRangeSeparator: String,
1548        forceEventDuration: Boolean,
1549        dayHeaders: Boolean,
1550        dayHeaderFormat: createFormatter,
1551        dayHeaderClassNames: identity,
1552        dayHeaderContent: identity,
1553        dayHeaderDidMount: identity,
1554        dayHeaderWillUnmount: identity,
1555        dayCellClassNames: identity,
1556        dayCellContent: identity,
1557        dayCellDidMount: identity,
1558        dayCellWillUnmount: identity,
1559        initialView: String,
1560        aspectRatio: Number,
1561        weekends: Boolean,
1562        weekNumberCalculation: identity,
1563        weekNumbers: Boolean,
1564        weekNumberClassNames: identity,
1565        weekNumberContent: identity,
1566        weekNumberDidMount: identity,
1567        weekNumberWillUnmount: identity,
1568        editable: Boolean,
1569        viewClassNames: identity,
1570        viewDidMount: identity,
1571        viewWillUnmount: identity,
1572        nowIndicator: Boolean,
1573        nowIndicatorClassNames: identity,
1574        nowIndicatorContent: identity,
1575        nowIndicatorDidMount: identity,
1576        nowIndicatorWillUnmount: identity,
1577        showNonCurrentDates: Boolean,
1578        lazyFetching: Boolean,
1579        startParam: String,
1580        endParam: String,
1581        timeZoneParam: String,
1582        timeZone: String,
1583        locales: identity,
1584        locale: identity,
1585        themeSystem: String,
1586        dragRevertDuration: Number,
1587        dragScroll: Boolean,
1588        allDayMaintainDuration: Boolean,
1589        unselectAuto: Boolean,
1590        dropAccept: identity,
1591        eventOrder: parseFieldSpecs,
1592        handleWindowResize: Boolean,
1593        windowResizeDelay: Number,
1594        longPressDelay: Number,
1595        eventDragMinDistance: Number,
1596        expandRows: Boolean,
1597        height: identity,
1598        contentHeight: identity,
1599        direction: String,
1600        weekNumberFormat: createFormatter,
1601        eventResizableFromStart: Boolean,
1602        displayEventTime: Boolean,
1603        displayEventEnd: Boolean,
1604        weekText: String,
1605        progressiveEventRendering: Boolean,
1606        businessHours: identity,
1607        initialDate: identity,
1608        now: identity,
1609        eventDataTransform: identity,
1610        stickyHeaderDates: identity,
1611        stickyFooterScrollbar: identity,
1612        viewHeight: identity,
1613        defaultAllDay: Boolean,
1614        eventSourceFailure: identity,
1615        eventSourceSuccess: identity,
1616        eventDisplay: String,
1617        eventStartEditable: Boolean,
1618        eventDurationEditable: Boolean,
1619        eventOverlap: identity,
1620        eventConstraint: identity,
1621        eventAllow: identity,
1622        eventBackgroundColor: String,
1623        eventBorderColor: String,
1624        eventTextColor: String,
1625        eventColor: String,
1626        eventClassNames: identity,
1627        eventContent: identity,
1628        eventDidMount: identity,
1629        eventWillUnmount: identity,
1630        selectConstraint: identity,
1631        selectOverlap: identity,
1632        selectAllow: identity,
1633        droppable: Boolean,
1634        unselectCancel: String,
1635        slotLabelFormat: identity,
1636        slotLaneClassNames: identity,
1637        slotLaneContent: identity,
1638        slotLaneDidMount: identity,
1639        slotLaneWillUnmount: identity,
1640        slotLabelClassNames: identity,
1641        slotLabelContent: identity,
1642        slotLabelDidMount: identity,
1643        slotLabelWillUnmount: identity,
1644        dayMaxEvents: identity,
1645        dayMaxEventRows: identity,
1646        dayMinWidth: Number,
1647        slotLabelInterval: createDuration,
1648        allDayText: String,
1649        allDayClassNames: identity,
1650        allDayContent: identity,
1651        allDayDidMount: identity,
1652        allDayWillUnmount: identity,
1653        slotMinWidth: Number,
1654        navLinks: Boolean,
1655        eventTimeFormat: createFormatter,
1656        rerenderDelay: Number,
1657        moreLinkText: identity,
1658        selectMinDistance: Number,
1659        selectable: Boolean,
1660        selectLongPressDelay: Number,
1661        eventLongPressDelay: Number,
1662        selectMirror: Boolean,
1663        eventMinHeight: Number,
1664        slotEventOverlap: Boolean,
1665        plugins: identity,
1666        firstDay: Number,
1667        dayCount: Number,
1668        dateAlignment: String,
1669        dateIncrement: createDuration,
1670        hiddenDays: identity,
1671        monthMode: Boolean,
1672        fixedWeekCount: Boolean,
1673        validRange: identity,
1674        visibleRange: identity,
1675        titleFormat: identity,
1676        // only used by list-view, but languages define the value, so we need it in base options
1677        noEventsText: String,
1678    };
1679    // do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results.
1680    // raw values.
1681    var BASE_OPTION_DEFAULTS = {
1682        eventDisplay: 'auto',
1683        defaultRangeSeparator: ' - ',
1684        titleRangeSeparator: ' \u2013 ',
1685        defaultTimedEventDuration: '01:00:00',
1686        defaultAllDayEventDuration: { day: 1 },
1687        forceEventDuration: false,
1688        nextDayThreshold: '00:00:00',
1689        dayHeaders: true,
1690        initialView: '',
1691        aspectRatio: 1.35,
1692        headerToolbar: {
1693            start: 'title',
1694            center: '',
1695            end: 'today prev,next',
1696        },
1697        weekends: true,
1698        weekNumbers: false,
1699        weekNumberCalculation: 'local',
1700        editable: false,
1701        nowIndicator: false,
1702        scrollTime: '06:00:00',
1703        slotMinTime: '00:00:00',
1704        slotMaxTime: '24:00:00',
1705        showNonCurrentDates: true,
1706        lazyFetching: true,
1707        startParam: 'start',
1708        endParam: 'end',
1709        timeZoneParam: 'timeZone',
1710        timeZone: 'local',
1711        locales: [],
1712        locale: '',
1713        themeSystem: 'standard',
1714        dragRevertDuration: 500,
1715        dragScroll: true,
1716        allDayMaintainDuration: false,
1717        unselectAuto: true,
1718        dropAccept: '*',
1719        eventOrder: 'start,-duration,allDay,title',
1720        dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
1721        handleWindowResize: true,
1722        windowResizeDelay: 100,
1723        longPressDelay: 1000,
1724        eventDragMinDistance: 5,
1725        expandRows: false,
1726        navLinks: false,
1727        selectable: false,
1728    };
1729    // calendar listeners
1730    // ------------------
1731    var CALENDAR_LISTENER_REFINERS = {
1732        datesSet: identity,
1733        eventsSet: identity,
1734        eventAdd: identity,
1735        eventChange: identity,
1736        eventRemove: identity,
1737        windowResize: identity,
1738        eventClick: identity,
1739        eventMouseEnter: identity,
1740        eventMouseLeave: identity,
1741        select: identity,
1742        unselect: identity,
1743        loading: identity,
1744        // internal
1745        _unmount: identity,
1746        _beforeprint: identity,
1747        _afterprint: identity,
1748        _noEventDrop: identity,
1749        _noEventResize: identity,
1750        _resize: identity,
1751        _scrollRequest: identity,
1752    };
1753    // calendar-specific options
1754    // -------------------------
1755    var CALENDAR_OPTION_REFINERS = {
1756        buttonText: identity,
1757        views: identity,
1758        plugins: identity,
1759        initialEvents: identity,
1760        events: identity,
1761        eventSources: identity,
1762    };
1763    var COMPLEX_OPTION_COMPARATORS = {
1764        headerToolbar: isBoolComplexEqual,
1765        footerToolbar: isBoolComplexEqual,
1766        buttonText: isBoolComplexEqual,
1767        buttonIcons: isBoolComplexEqual,
1768    };
1769    function isBoolComplexEqual(a, b) {
1770        if (typeof a === 'object' && typeof b === 'object' && a && b) { // both non-null objects
1771            return isPropsEqual(a, b);
1772        }
1773        return a === b;
1774    }
1775    // view-specific options
1776    // ---------------------
1777    var VIEW_OPTION_REFINERS = {
1778        type: String,
1779        component: identity,
1780        buttonText: String,
1781        buttonTextKey: String,
1782        dateProfileGeneratorClass: identity,
1783        usesMinMaxTime: Boolean,
1784        classNames: identity,
1785        content: identity,
1786        didMount: identity,
1787        willUnmount: identity,
1788    };
1789    // util funcs
1790    // ----------------------------------------------------------------------------------------------------
1791    function mergeRawOptions(optionSets) {
1792        return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS);
1793    }
1794    function refineProps(input, refiners) {
1795        var refined = {};
1796        var extra = {};
1797        for (var propName in refiners) {
1798            if (propName in input) {
1799                refined[propName] = refiners[propName](input[propName]);
1800            }
1801        }
1802        for (var propName in input) {
1803            if (!(propName in refiners)) {
1804                extra[propName] = input[propName];
1805            }
1806        }
1807        return { refined: refined, extra: extra };
1808    }
1809    function identity(raw) {
1810        return raw;
1811    }
1812
1813    function parseEvents(rawEvents, eventSource, context, allowOpenRange) {
1814        var eventStore = createEmptyEventStore();
1815        var eventRefiners = buildEventRefiners(context);
1816        for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
1817            var rawEvent = rawEvents_1[_i];
1818            var tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners);
1819            if (tuple) {
1820                eventTupleToStore(tuple, eventStore);
1821            }
1822        }
1823        return eventStore;
1824    }
1825    function eventTupleToStore(tuple, eventStore) {
1826        if (eventStore === void 0) { eventStore = createEmptyEventStore(); }
1827        eventStore.defs[tuple.def.defId] = tuple.def;
1828        if (tuple.instance) {
1829            eventStore.instances[tuple.instance.instanceId] = tuple.instance;
1830        }
1831        return eventStore;
1832    }
1833    // retrieves events that have the same groupId as the instance specified by `instanceId`
1834    // or they are the same as the instance.
1835    // why might instanceId not be in the store? an event from another calendar?
1836    function getRelevantEvents(eventStore, instanceId) {
1837        var instance = eventStore.instances[instanceId];
1838        if (instance) {
1839            var def_1 = eventStore.defs[instance.defId];
1840            // get events/instances with same group
1841            var newStore = filterEventStoreDefs(eventStore, function (lookDef) { return isEventDefsGrouped(def_1, lookDef); });
1842            // add the original
1843            // TODO: wish we could use eventTupleToStore or something like it
1844            newStore.defs[def_1.defId] = def_1;
1845            newStore.instances[instance.instanceId] = instance;
1846            return newStore;
1847        }
1848        return createEmptyEventStore();
1849    }
1850    function isEventDefsGrouped(def0, def1) {
1851        return Boolean(def0.groupId && def0.groupId === def1.groupId);
1852    }
1853    function createEmptyEventStore() {
1854        return { defs: {}, instances: {} };
1855    }
1856    function mergeEventStores(store0, store1) {
1857        return {
1858            defs: __assign(__assign({}, store0.defs), store1.defs),
1859            instances: __assign(__assign({}, store0.instances), store1.instances),
1860        };
1861    }
1862    function filterEventStoreDefs(eventStore, filterFunc) {
1863        var defs = filterHash(eventStore.defs, filterFunc);
1864        var instances = filterHash(eventStore.instances, function (instance) { return (defs[instance.defId] // still exists?
1865        ); });
1866        return { defs: defs, instances: instances };
1867    }
1868    function excludeSubEventStore(master, sub) {
1869        var defs = master.defs, instances = master.instances;
1870        var filteredDefs = {};
1871        var filteredInstances = {};
1872        for (var defId in defs) {
1873            if (!sub.defs[defId]) { // not explicitly excluded
vendor: 4,594 bytes, lines 1874-1992
1874                filteredDefs[defId] = defs[defId];
1875            }
1876        }
1877        for (var instanceId in instances) {
1878            if (!sub.instances[instanceId] && // not explicitly excluded
1879                filteredDefs[instances[instanceId].defId] // def wasn't filtered away
1880            ) {
1881                filteredInstances[instanceId] = instances[instanceId];
1882            }
1883        }
1884        return {
1885            defs: filteredDefs,
1886            instances: filteredInstances,
1887        };
1888    }
1889
1890    function normalizeConstraint(input, context) {
1891        if (Array.isArray(input)) {
1892            return parseEvents(input, null, context, true); // allowOpenRange=true
1893        }
1894        if (typeof input === 'object' && input) { // non-null object
1895            return parseEvents([input], null, context, true); // allowOpenRange=true
1896        }
1897        if (input != null) {
1898            return String(input);
1899        }
1900        return null;
1901    }
1902
1903    function parseClassNames(raw) {
1904        if (Array.isArray(raw)) {
1905            return raw;
1906        }
1907        if (typeof raw === 'string') {
1908            return raw.split(/\s+/);
1909        }
1910        return [];
1911    }
1912
1913    // TODO: better called "EventSettings" or "EventConfig"
1914    // TODO: move this file into structs
1915    // TODO: separate constraint/overlap/allow, because selection uses only that, not other props
1916    var EVENT_UI_REFINERS = {
1917        display: String,
1918        editable: Boolean,
1919        startEditable: Boolean,
1920        durationEditable: Boolean,
1921        constraint: identity,
1922        overlap: identity,
1923        allow: identity,
1924        className: parseClassNames,
1925        classNames: parseClassNames,
1926        color: String,
1927        backgroundColor: String,
1928        borderColor: String,
1929        textColor: String,
1930    };
1931    var EMPTY_EVENT_UI = {
1932        display: null,
1933        startEditable: null,
1934        durationEditable: null,
1935        constraints: [],
1936        overlap: null,
1937        allows: [],
1938        backgroundColor: '',
1939        borderColor: '',
1940        textColor: '',
1941        classNames: [],
1942    };
1943    function createEventUi(refined, context) {
1944        var constraint = normalizeConstraint(refined.constraint, context);
1945        return {
1946            display: refined.display || null,
1947            startEditable: refined.startEditable != null ? refined.startEditable : refined.editable,
1948            durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable,
1949            constraints: constraint != null ? [constraint] : [],
1950            overlap: refined.overlap != null ? refined.overlap : null,
1951            allows: refined.allow != null ? [refined.allow] : [],
1952            backgroundColor: refined.backgroundColor || refined.color || '',
1953            borderColor: refined.borderColor || refined.color || '',
1954            textColor: refined.textColor || '',
1955            classNames: (refined.className || []).concat(refined.classNames || []),
1956        };
1957    }
1958    // TODO: prevent against problems with <2 args!
1959    function combineEventUis(uis) {
1960        return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
1961    }
1962    function combineTwoEventUis(item0, item1) {
1963        return {
1964            display: item1.display != null ? item1.display : item0.display,
1965            startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
1966            durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
1967            constraints: item0.constraints.concat(item1.constraints),
1968            overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
1969            allows: item0.allows.concat(item1.allows),
1970            backgroundColor: item1.backgroundColor || item0.backgroundColor,
1971            borderColor: item1.borderColor || item0.borderColor,
1972            textColor: item1.textColor || item0.textColor,
1973            classNames: item0.classNames.concat(item1.classNames),
1974        };
1975    }
1976
1977    var EVENT_NON_DATE_REFINERS = {
1978        id: String,
1979        groupId: String,
1980        title: String,
1981        url: String,
1982    };
1983    var EVENT_DATE_REFINERS = {
1984        start: identity,
1985        end: identity,
1986        date: identity,
1987        allDay: Boolean,
1988    };
1989    var EVENT_REFINERS = __assign(__assign(__assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity });
1990    function parseEvent(raw, eventSource, context, allowOpenRange, refiners) {
1991        if (refiners === void 0) { refiners = buildEventRefiners(context); }
1992        var _a = refineEventDef(raw, context, refiners), refined 
1992= _a.refined, extra = _a.extra;
1993        var defaultAllDay = computeIsDefaultAllDay(eventSource, context);
1994        var recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes);
1995        if (recurringRes) {
1996            var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context);
1997            def.recurringDef = {
1998                typeId: recurringRes.typeId,
1999                typeData: recurringRes.typeData,
2000                duration: recurringRes.duration,
2001            };
2002            return { def: def, instance: null };
2003        }
2004        var singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange);
2005        if (singleRes) {
2006            var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context);
2007            var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
2008            return { def: def, instance: instance };
2009        }
2010        return null;
2011    }
2012    function refineEventDef(raw, context, refiners) {
2013        if (refiners === void 0) { refiners = buildEventRefiners(context); }
2014        return refineProps(raw, refiners);
2015    }
2016    function buildEventRefiners(context) {
2017        return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners);
2018    }
2019    /*
2020    Will NOT populate extendedProps with the leftover properties.
2021    Will NOT populate date-related props.
2022    */
2023    function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context) {
2024        var def = {
2025            title: refined.title || '',
2026            groupId: refined.groupId || '',
2027            publicId: refined.id || '',
2028            url: refined.url || '',
2029            recurringDef: null,
2030            defId: guid(),
2031            sourceId: sourceId,
2032            allDay: allDay,
2033            hasEnd: hasEnd,
2034            ui: createEventUi(refined, context),
2035            extendedProps: __assign(__assign({}, (refined.extendedProps || {})), extra),
2036        };
2037        for (var _i = 0, _a = context.pluginHooks.eventDefMemberAdders; _i < _a.length; _i++) {
2038            var memberAdder = _a[_i];
2039            __assign(def, memberAdder(refined));
2040        }
2041        // help out EventApi from having user modify props
2042        Object.freeze(def.ui.classNames);
2043        Object.freeze(def.extendedProps);
2044        return def;
2045    }
2046    function parseSingle(refined, defaultAllDay, context, allowOpenRange) {
2047        var allDay = refined.allDay;
2048        var startMeta;
2049        var startMarker = null;
2050        var hasEnd = false;
2051        var endMeta;
2052        var endMarker = null;
2053        var startInput = refined.start != null ? refined.start : refined.date;
2054        startMeta = context.dateEnv.createMarkerMeta(startInput);
2055        if (startMeta) {
2056            startMarker = startMeta.marker;
2057        }
2058        else if (!allowOpenRange) {
2059            return null;
2060        }
2061        if (refined.end != null) {
2062            endMeta = context.dateEnv.createMarkerMeta(refined.end);
2063        }
2064        if (allDay == null) {
2065            if (defaultAllDay != null) {
2066                allDay = defaultAllDay;
2067            }
2068            else {
2069                // fall back to the date props LAST
2070                allDay = (!startMeta || startMeta.isTimeUnspecified) &&
2071                    (!endMeta || endMeta.isTimeUnspecified);
2072            }
2073        }
2074        if (allDay && startMarker) {
2075            startMarker = startOfDay(startMarker);
2076        }
2077        if (endMeta) {
2078            endMarker = endMeta.marker;
2079            if (allDay) {
2080                endMarker = startOfDay(endMarker);
2081            }
2082            if (startMarker && endMarker <= startMarker) {
2083                endMarker = null;
2084            }
2085        }
2086        if (endMarker) {
2087            hasEnd = true;
2088        }
2089        else if (!allowOpenRange) {
2090            hasEnd = context.options.forceEventDuration || false;
2091            endMarker = context.dateEnv.add(startMarker, allDay ?
2092                context.options.defaultAllDayEventDuration :
2093                context.options.defaultTimedEventDuration);
2094        }
2095        return {
2096            allDay: allDay,
2097            hasEnd: hasEnd,
2098            range: { start: startMarker, end: endMarker },
2099            forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
2100            forcedEndTzo: endMeta ? endMeta.forcedTzo : null,
2101        };
2102    }
2103    function computeIsDefaultAllDay(eventSource, context) {
2104        var res = null;
2105        if (eventSource) {
2106            res = eventSource.defaultAllDay;
2107        }
2108        if (res == null) {
2109            res = context.options.defaultAllDay;
2110        }
2111        return res;
2112    }
2113
2114    /* Date stuff that doesn't belong in datelib core
2115    ----------------------------------------------------------------------------------------------------------------------*/
2116    // given a timed range, computes an all-day range that has the same exact duration,
2117    // but whose start time is aligned with the start of the day.
2118    function computeAlignedDayRange(timedRange) {
2119        var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
2120        var start = startOfDay(timedRange.start);
2121        var end = addDays(start, dayCnt);
2122        return { start: start, end: end };
2123    }
2124    // given a timed range, computes an all-day range based on how for the end date bleeds into the next day
2125    // TODO: give nextDayThreshold a default arg
2126    function computeVisibleDayRange(timedRange, nextDayThreshold) {
2127        if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); }
2128        var startDay = null;
2129        var endDay = null;
2130        if (timedRange.end) {
2131            endDay = startOfDay(timedRange.end);
2132            var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`
2133            // If the end time is actually inclusively part of the next day and is equal to or
vendor: 15,639 bytes, lines 2134-2509
2134            // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
2135            // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
2136            if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
2137                endDay = addDays(endDay, 1);
2138            }
2139        }
2140        if (timedRange.start) {
2141            startDay = startOfDay(timedRange.start); // the beginning of the day the range starts
2142            // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
2143            if (endDay && endDay <= startDay) {
2144                endDay = addDays(startDay, 1);
2145            }
2146        }
2147        return { start: startDay, end: endDay };
2148    }
2149    // spans from one day into another?
2150    function isMultiDayRange(range) {
2151        var visibleRange = computeVisibleDayRange(range);
2152        return diffDays(visibleRange.start, visibleRange.end) > 1;
2153    }
2154    function diffDates(date0, date1, dateEnv, largeUnit) {
2155        if (largeUnit === 'year') {
2156            return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
2157        }
2158        if (largeUnit === 'month') {
2159            return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
2160        }
2161        return diffDayAndTime(date0, date1); // returns a duration
2162    }
2163
2164    function parseRange(input, dateEnv) {
2165        var start = null;
2166        var end = null;
2167        if (input.start) {
2168            start = dateEnv.createMarker(input.start);
2169        }
2170        if (input.end) {
2171            end = dateEnv.createMarker(input.end);
2172        }
2173        if (!start && !end) {
2174            return null;
2175        }
2176        if (start && end && end < start) {
2177            return null;
2178        }
2179        return { start: start, end: end };
2180    }
2181    // SIDE-EFFECT: will mutate ranges.
2182    // Will return a new array result.
2183    function invertRanges(ranges, constraintRange) {
2184        var invertedRanges = [];
2185        var start = constraintRange.start; // the end of the previous range. the start of the new range
2186        var i;
2187        var dateRange;
2188        // ranges need to be in order. required for our date-walking algorithm
2189        ranges.sort(compareRanges);
2190        for (i = 0; i < ranges.length; i += 1) {
2191            dateRange = ranges[i];
2192            // add the span of time before the event (if there is any)
2193            if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)
2194                invertedRanges.push({ start: start, end: dateRange.start });
2195            }
2196            if (dateRange.end > start) {
2197                start = dateRange.end;
2198            }
2199        }
2200        // add the span of time after the last event (if there is any)
2201        if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)
2202            invertedRanges.push({ start: start, end: constraintRange.end });
2203        }
2204        return invertedRanges;
2205    }
2206    function compareRanges(range0, range1) {
2207        return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
2208    }
2209    function intersectRanges(range0, range1) {
2210        var start = range0.start, end = range0.end;
2211        var newRange = null;
2212        if (range1.start !== null) {
2213            if (start === null) {
2214                start = range1.start;
2215            }
2216            else {
2217                start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
2218            }
2219        }
2220        if (range1.end != null) {
2221            if (end === null) {
2222                end = range1.end;
2223            }
2224            else {
2225                end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
2226            }
2227        }
2228        if (start === null || end === null || start < end) {
2229            newRange = { start: start, end: end };
2230        }
2231        return newRange;
2232    }
2233    function rangesEqual(range0, range1) {
2234        return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
2235            (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
2236    }
2237    function rangesIntersect(range0, range1) {
2238        return (range0.end === null || range1.start === null || range0.end > range1.start) &&
2239            (range0.start === null || range1.end === null || range0.start < range1.end);
2240    }
2241    function rangeContainsRange(outerRange, innerRange) {
2242        return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
2243            (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
2244    }
2245    function rangeContainsMarker(range, date) {
2246        return (range.start === null || date >= range.start) &&
2247            (range.end === null || date < range.end);
2248    }
2249    // If the given date is not within the given range, move it inside.
2250    // (If it's past the end, make it one millisecond before the end).
2251    function constrainMarkerToRange(date, range) {
2252        if (range.start != null && date < range.start) {
2253            return range.start;
2254        }
2255        if (range.end != null && date >= range.end) {
2256            return new Date(range.end.valueOf() - 1);
2257        }
2258        return date;
2259    }
2260
2261    /*
2262    Specifying nextDayThreshold signals that all-day ranges should be sliced.
2263    */
2264    function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
2265        var inverseBgByGroupId = {};
2266        var inverseBgByDefId = {};
2267        var defByGroupId = {};
2268        var bgRanges = [];
2269        var fgRanges = [];
2270        var eventUis = compileEventUis(eventStore.defs, eventUiBases);
2271        for (var defId in eventStore.defs) {
2272            var def = eventStore.defs[defId];
2273            var ui = eventUis[def.defId];
2274            if (ui.display === 'inverse-background') {
2275                if (def.groupId) {
2276                    inverseBgByGroupId[def.groupId] = [];
2277                    if (!defByGroupId[def.groupId]) {
2278                        defByGroupId[def.groupId] = def;
2279                    }
2280                }
2281                else {
2282                    inverseBgByDefId[defId] = [];
2283                }
2284            }
2285        }
2286        for (var instanceId in eventStore.instances) {
2287            var instance = eventStore.instances[instanceId];
2288            var def = eventStore.defs[instance.defId];
2289            var ui = eventUis[def.defId];
2290            var origRange = instance.range;
2291            var normalRange = (!def.allDay && nextDayThreshold) ?
2292                computeVisibleDayRange(origRange, nextDayThreshold) :
2293                origRange;
2294            var slicedRange = intersectRanges(normalRange, framingRange);
2295            if (slicedRange) {
2296                if (ui.display === 'inverse-background') {
2297                    if (def.groupId) {
2298                        inverseBgByGroupId[def.groupId].push(slicedRange);
2299                    }
2300                    else {
2301                        inverseBgByDefId[instance.defId].push(slicedRange);
2302                    }
2303                }
2304                else if (ui.display !== 'none') {
2305                    (ui.display === 'background' ? bgRanges : fgRanges).push({
2306                        def: def,
2307                        ui: ui,
2308                        instance: instance,
2309                        range: slicedRange,
2310                        isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
2311                        isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf(),
2312                    });
2313                }
2314            }
2315        }
2316        for (var groupId in inverseBgByGroupId) { // BY GROUP
2317            var ranges = inverseBgByGroupId[groupId];
2318            var invertedRanges = invertRanges(ranges, framingRange);
2319            for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) {
2320                var invertedRange = invertedRanges_1[_i];
2321                var def = defByGroupId[groupId];
2322                var ui = eventUis[def.defId];
2323                bgRanges.push({
2324                    def: def,
2325                    ui: ui,
2326                    instance: null,
2327                    range: invertedRange,
2328                    isStart: false,
2329                    isEnd: false,
2330                });
2331            }
2332        }
2333        for (var defId in inverseBgByDefId) {
2334            var ranges = inverseBgByDefId[defId];
2335            var invertedRanges = invertRanges(ranges, framingRange);
2336            for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) {
2337                var invertedRange = invertedRanges_2[_a];
2338                bgRanges.push({
2339                    def: eventStore.defs[defId],
2340                    ui: eventUis[defId],
2341                    instance: null,
2342                    range: invertedRange,
2343                    isStart: false,
2344                    isEnd: false,
2345                });
2346            }
2347        }
2348        return { bg: bgRanges, fg: fgRanges };
2349    }
2350    function hasBgRendering(def) {
2351        return def.ui.display === 'background' || def.ui.display === 'inverse-background';
2352    }
2353    function setElSeg(el, seg) {
2354        el.fcSeg = seg;
2355    }
2356    function getElSeg(el) {
2357        return el.fcSeg ||
2358            el.parentNode.fcSeg || // for the harness
2359            null;
2360    }
2361    // event ui computation
2362    function compileEventUis(eventDefs, eventUiBases) {
2363        return mapHash(eventDefs, function (eventDef) { return compileEventUi(eventDef, eventUiBases); });
2364    }
2365    function compileEventUi(eventDef, eventUiBases) {
2366        var uis = [];
2367        if (eventUiBases['']) {
2368            uis.push(eventUiBases['']);
2369        }
2370        if (eventUiBases[eventDef.defId]) {
2371            uis.push(eventUiBases[eventDef.defId]);
2372        }
2373        uis.push(eventDef.ui);
2374        return combineEventUis(uis);
2375    }
2376    function sortEventSegs(segs, eventOrderSpecs) {
2377        var objs = segs.map(buildSegCompareObj);
2378        objs.sort(function (obj0, obj1) { return compareByFieldSpecs(obj0, obj1, eventOrderSpecs); });
2379        return objs.map(function (c) { return c._seg; });
2380    }
2381    // returns a object with all primitive props that can be compared
2382    function buildSegCompareObj(seg) {
2383        var eventRange = seg.eventRange;
2384        var eventDef = eventRange.def;
2385        var range = eventRange.instance ? eventRange.instance.range : eventRange.range;
2386        var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
2387        var end = range.end ? range.end.valueOf() : 0; // "
2388        return __assign(__assign(__assign({}, eventDef.extendedProps), eventDef), { id: eventDef.publicId, start: start,
2389            end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg });
2390    }
2391    function computeSegDraggable(seg, context) {
2392        var pluginHooks = context.pluginHooks;
2393        var transformers = pluginHooks.isDraggableTransformers;
2394        var _a = seg.eventRange, def = _a.def, ui = _a.ui;
2395        var val = ui.startEditable;
2396        for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
2397            var transformer = transformers_1[_i];
2398            val = transformer(val, def, ui, context);
2399        }
2400        return val;
2401    }
2402    function computeSegStartResizable(seg, context) {
2403        return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart;
2404    }
2405    function computeSegEndResizable(seg, context) {
2406        return seg.isEnd && seg.eventRange.ui.durationEditable;
2407    }
2408    function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, // defaults to true
2409    defaultDisplayEventEnd, // defaults to true
2410    startOverride, endOverride) {
2411        var dateEnv = context.dateEnv, options = context.options;
2412        var displayEventTime = options.displayEventTime, displayEventEnd = options.displayEventEnd;
2413        var eventDef = seg.eventRange.def;
2414        var eventInstance = seg.eventRange.instance;
2415        if (displayEventTime == null) {
2416            displayEventTime = defaultDisplayEventTime !== false;
2417        }
2418        if (displayEventEnd == null) {
2419            displayEventEnd = defaultDisplayEventEnd !== false;
2420        }
2421        if (displayEventTime && !eventDef.allDay && (seg.isStart || seg.isEnd)) {
2422            var segStart = startOverride || (seg.isStart ? eventInstance.range.start : (seg.start || seg.eventRange.range.start));
2423            var segEnd = endOverride || (seg.isEnd ? eventInstance.range.end : (seg.end || seg.eventRange.range.end));
2424            if (displayEventEnd && eventDef.hasEnd) {
2425                return dateEnv.formatRange(segStart, segEnd, timeFormat, {
2426                    forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo,
2427                    forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo,
2428                });
2429            }
2430            return dateEnv.format(segStart, timeFormat, {
2431                forcedTzo: startOverride ? null : eventInstance.forcedStartTzo,
2432            });
2433        }
2434        return '';
2435    }
2436    function getSegMeta(seg, todayRange, nowDate) {
2437        var segRange = seg.eventRange.range;
2438        return {
2439            isPast: segRange.end < (nowDate || todayRange.start),
2440            isFuture: segRange.start >= (nowDate || todayRange.end),
2441            isToday: todayRange && rangeContainsMarker(todayRange, segRange.start),
2442        };
2443    }
2444    function getEventClassNames(props) {
2445        var classNames = ['fc-event'];
2446        if (props.isMirror) {
2447            classNames.push('fc-event-mirror');
2448        }
2449        if (props.isDraggable) {
2450            classNames.push('fc-event-draggable');
2451        }
2452        if (props.isStartResizable || props.isEndResizable) {
2453            classNames.push('fc-event-resizable');
2454        }
2455        if (props.isDragging) {
2456            classNames.push('fc-event-dragging');
2457        }
2458        if (props.isResizing) {
2459            classNames.push('fc-event-resizing');
2460        }
2461        if (props.isSelected) {
2462            classNames.push('fc-event-selected');
2463        }
2464        if (props.isStart) {
2465            classNames.push('fc-event-start');
2466        }
2467        if (props.isEnd) {
2468            classNames.push('fc-event-end');
2469        }
2470        if (props.isPast) {
2471            classNames.push('fc-event-past');
2472        }
2473        if (props.isToday) {
2474            classNames.push('fc-event-today');
2475        }
2476        if (props.isFuture) {
2477            classNames.push('fc-event-future');
2478        }
2479        return classNames;
2480    }
2481    function buildEventRangeKey(eventRange) {
2482        return eventRange.instance
2483            ? eventRange.instance.instanceId
2484            : eventRange.def.defId + ":" + eventRange.range.start.toISOString();
2485        // inverse-background events don't have specific instances. TODO: better solution
2486    }
2487
2488    var STANDARD_PROPS = {
2489        start: identity,
2490        end: identity,
2491        allDay: Boolean,
2492    };
2493    function parseDateSpan(raw, dateEnv, defaultDuration) {
2494        var span = parseOpenDateSpan(raw, dateEnv);
2495        var range = span.range;
2496        if (!range.start) {
2497            return null;
2498        }
2499        if (!range.end) {
2500            if (defaultDuration == null) {
2501                return null;
2502            }
2503            range.end = dateEnv.add(range.start, defaultDuration);
2504        }
2505        return span;
2506    }
2507    /*
2508    TODO: somehow combine with parseRange?
2509    Will return null if the start/end props were present but parsed invali
2509dly.
2510    */
2511    function parseOpenDateSpan(raw, dateEnv) {
2512        var _a = refineProps(raw, STANDARD_PROPS), standardProps = _a.refined, extra = _a.extra;
2513        var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
2514        var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
2515        var allDay = standardProps.allDay;
2516        if (allDay == null) {
2517            allDay = (startMeta && startMeta.isTimeUnspecified) &&
2518                (!endMeta || endMeta.isTimeUnspecified);
2519        }
2520        return __assign({ range: {
2521                start: startMeta ? startMeta.marker : null,
2522                end: endMeta ? endMeta.marker : null,
2523            }, allDay: allDay }, extra);
2524    }
2525    function isDateSpansEqual(span0, span1) {
2526        return rangesEqual(span0.range, span1.range) &&
2527            span0.allDay === span1.allDay &&
2528            isSpanPropsEqual(span0, span1);
2529    }
2530    // the NON-DATE-RELATED props
2531    function isSpanPropsEqual(span0, span1) {
2532        for (var propName in span1) {
2533            if (propName !== 'range' && propName !== 'allDay') {
2534                if (span0[propName] !== span1[propName]) {
2535                    return false;
2536                }
2537            }
2538        }
2539        // are there any props that span0 has that span1 DOESN'T have?
2540        // both have range/allDay, so no need to special-case.
2541        for (var propName in span0) {
2542            if (!(propName in span1)) {
2543                return false;
2544            }
2545        }
2546        return true;
2547    }
2548    function buildDateSpanApi(span, dateEnv) {
2549        return __assign(__assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay });
2550    }
2551    function buildRangeApiWithTimeZone(range, dateEnv, omitTime) {
2552        return __assign(__assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone });
2553    }
2554    function buildRangeApi(range, dateEnv, omitTime) {
2555        return {
2556            start: dateEnv.toDate(range.start),
2557            end: dateEnv.toDate(range.end),
2558            startStr: dateEnv.formatIso(range.start, { omitTime: omitTime }),
2559            endStr: dateEnv.formatIso(range.end, { omitTime: omitTime }),
2560        };
2561    }
2562    function fabricateEventRange(dateSpan, eventUiBases, context) {
2563        var res = refineEventDef({ editable: false }, context);
2564        var def = parseEventDef(res.refined, res.extra, '', // sourceId
2565        dateSpan.allDay, true, // hasEnd
2566        context);
2567        return {
2568            def: def,
2569            ui: compileEventUi(def, eventUiBases),
2570            instance: createEventInstance(def.defId, dateSpan.range),
2571            range: dateSpan.range,
2572            isStart: true,
2573            isEnd: true,
2574        };
2575    }
2576
2577    function triggerDateSelect(selection, pev, context) {
2578        context.emitter.trigger('select', __assign(__assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view }));
2579    }
2580    function triggerDateUnselect(pev, context) {
2581        context.emitter.trigger('unselect', {
2582            jsEvent: pev ? pev.origEvent : null,
2583            view: context.viewApi || context.calendarApi.view,
2584        });
2585    }
2586    function buildDateSpanApiWithContext(dateSpan, context) {
2587        var props = {};
2588        for (var _i = 0, _a = context.pluginHooks.dateSpanTransforms; _i < _a.length; _i++) {
2589            var transform = _a[_i];
2590            __assign(props, transform(dateSpan, context));
2591        }
2592        __assign(props, buildDateSpanApi(dateSpan, context.dateEnv));
2593        return props;
2594    }
2595    // Given an event's allDay status and start date, return what its fallback end date should be.
2596    // TODO: rename to computeDefaultEventEnd
2597    function getDefaultEventEnd(allDay, marker, context) {
2598        var dateEnv = context.dateEnv, options = context.options;
2599        var end = marker;
2600        if (allDay) {
2601            end = startOfDay(end);
2602            end = dateEnv.add(end, options.defaultAllDayEventDuration);
2603        }
2604        else {
2605            end = dateEnv.add(end, options.defaultTimedEventDuration);
2606        }
2607        return end;
2608    }
2609
2610    // applies the mutation to ALL defs/instances within the event store
2611    function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) {
2612        var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
2613        var dest = createEmptyEventStore();
2614        for (var defId in eventStore.defs) {
2615            var def = eventStore.defs[defId];
2616            dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context);
2617        }
2618        for (var instanceId in eventStore.instances) {
2619            var instance = eventStore.instances[instanceId];
2620            var def = dest.defs[instance.defId]; // important to grab the newly modified def
2621            dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context);
2622        }
2623        return dest;
2624    }
2625    function applyMutationToEventDef(eventDef, eventConfig, mutation, context) {
2626        var standardProps = mutation.standardProps || {};
2627        // if hasEnd has not been specified, guess a good value based on deltas.
2628        // if duration will change, there's no way the default duration will persist,
2629        // and thus, we need to mark the event as having a real end
2630        if (standardProps.hasEnd == null &&
2631            eventConfig.durationEditable &&
2632            (mutation.startDelta || mutation.endDelta)) {
2633            standardProps.hasEnd = true; // TODO: is this mutation okay?
2634        }
2635        var copy = __assign(__assign(__assign({}, eventDef), standardProps), { ui: __assign(__assign({}, eventDef.ui), standardProps.ui) });
2636        if (mutation.extendedProps) {
2637            copy.extendedProps = __assign(__assign({}, copy.extendedProps), mutation.extendedProps);
2638        }
2639        for (var _i = 0, _a = context.pluginHooks.eventDefMutationAppliers; _i < _a.length; _i++) {
2640            var applier = _a[_i];
2641            applier(copy, mutation, context);
2642        }
2643        if (!copy.hasEnd && context.options.forceEventDuration) {
2644            copy.hasEnd = true;
2645        }
2646        return copy;
2647    }
2648    function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
2649    eventConfig, mutation, context) {
2650        var dateEnv = context.dateEnv;
2651        var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
2652        var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
2653        var copy = __assign({}, eventInstance);
2654        if (forceAllDay) {
2655            copy.range = computeAlignedDayRange(copy.range);
2656        }
2657        if (mutation.datesDelta && eventConfig.startEditable) {
2658            copy.range = {
2659                start: dateEnv.add(copy.range.start, mutation.datesDelta),
2660                end: dateEnv.add(copy.range.end, mutation.datesDelta),
2661            };
2662        }
2663        if (mutation.startDelta && eventConfig.durationEditable) {
2664            copy.range = {
2665                start: dateEnv.add(copy.range.start, mutation.startDelta),
2666                end: copy.range.end,
2667            };
2668        }
2669        if (mutation.endDelta && eventConfig.durationEditable) {
2670            copy.range = {
2671                start: copy.range.start,
2672                end: dateEnv.add(copy.range.end, mutation.endDelta),
2673            };
2674        }
2675        if (clearEnd) {
2676            copy.range = {
2677                start: copy.range.start,
2678                end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context),
2679            };
2680        }
2681        // in case event was all-day but the supplied deltas were not
2682        // better util for this?
2683        if (eventDef.allDay) {
2684            copy.range = {
2685                start: startOfDay(copy.range.start),
2686                end: startOfDay(copy.range.end),
2687            };
2688        }
2689        // handle invalid durations
2690        if (copy.range.end < copy.range.start) {
2691            copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context);
2692        }
2693        return copy;
2694    }
2695
2696    // no public types yet. when there are, export from:
2697    // import {} from './api-type-deps'
2698    var ViewApi = /** @class */ (function () {
2699        function ViewApi(type, getCurrentData, dateEnv) {
2700            this.type = type;
2701            this.getCurrentData = getCurrentData;
2702            this.dateEnv = dateEnv;
2703        }
2704        Object.defineProperty(ViewApi.prototype, "calendar", {
2705            get: function () {
2706                return this.getCurrentData().calendarApi;
2707            },
2708            enumerable: false,
2709            configurable: true
2710        });
2711        Object.defineProperty(ViewApi.prototype, "title", {
2712            get: function () {
2713                return this.getCurrentData().viewTitle;
2714            },
2715            enumerable: false,
2716            configurable: true
2717        });
2718        Object.defineProperty(ViewApi.prototype, "activeStart", {
2719            get: function () {
2720                return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start);
2721            },
2722            enumerable: false,
2723            configurable: true
2724        });
2725        Object.defineProperty(ViewApi.prototype, "activeEnd", {
2726            get: function () {
2727                return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end);
2728            },
2729            enumerable: false,
2730            configurable: true
2731        });
2732        Object.defineProperty(ViewApi.prototype, "currentStart", {
2733            get: function () {
2734                return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start);
2735            },
2736            enumerable: false,
2737            configurable: true
2738        });
2739        Object.defineProperty(ViewApi.prototype, "currentEnd", {
2740            get: function () {
2741                return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end);
2742            },
2743            enumerable: false,
2744            configurable: true
2745        });
2746        ViewApi.prototype.getOption = function (name) {
2747            return this.getCurrentData().options[name]; // are the view-specific options
2748        };
2749        return ViewApi;
2750    }());
2751
2752    var EVENT_SOURCE_REFINERS = {
2753        id: String,
2754        defaultAllDay: Boolean,
2755        url: String,
2756        format: String,
2757        events: identity,
2758        eventDataTransform: identity,
2759        // for any network-related sources
2760        success: identity,
2761        failure: identity,
2762    };
2763    function parseEventSource(raw, context, refiners) {
2764        if (refiners === void 0) { refiners = buildEventSourceRefiners(context); }
2765        var rawObj;
2766        if (typeof raw === 'string') {
2767            rawObj = { url: raw };
2768        }
2769        else if (typeof raw === 'function' || Array.isArray(raw)) {
2770            rawObj = { events: raw };
2771        }
2772        else if (typeof raw === 'object' && raw) { // not null
2773            rawObj = raw;
2774        }
2775        if (rawObj) {
2776            var _a = refineProps(rawObj, refiners), refined = _a.refined, extra = _a.extra;
2777            var metaRes = buildEventSourceMeta(refined, context);
2778            if (metaRes) {
2779                return {
2780                    _raw: raw,
2781                    isFetching: false,
2782                    latestFetchId: '',
2783                    fetchRange: null,
2784                    defaultAllDay: refined.defaultAllDay,
2785                    eventDataTransform: refined.eventDataTransform,
2786                    success: refined.success,
2787                    failure: refined.failure,
2788                    publicId: refined.id || '',
2789                    sourceId: guid(),
2790                    sourceDefId: metaRes.sourceDefId,
2791                    meta: metaRes.meta,
2792                    ui: createEventUi(refined, context),
2793                    extendedProps: extra,
2794                };
2795            }
2796        }
2797        return null;
2798    }
2799    function buildEventSourceRefiners(context) {
2800        return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS), context.pluginHooks.eventSourceRefiners);
2801    }
2802    function buildEventSourceMeta(raw, context) {
2803        var defs = context.pluginHooks.eventSourceDefs;
2804        for (var i = defs.length - 1; i >= 0; i -= 1) { // later-added plugins take precedence
2805            var def = defs[i];
2806            var meta = def.parseMeta(raw);
2807            if (meta) {
2808                return { sourceDefId: i, meta: meta };
2809            }
2810        }
2811        return null;
2812    }
2813
2814    function reduceCurrentDate(currentDate, action) {
2815        switch (action.type) {
2816            case 'CHANGE_DATE':
2817                return action.dateMarker;
2818            default:
2819                return currentDate;
2820        }
2821    }
2822    function getInitialDate(options, dateEnv) {
2823        var initialDateInput = options.initialDate;
2824        // compute the initial ambig-timezone date
2825        if (initialDateInput != null) {
2826            return dateEnv.createMarker(initialDateInput);
2827        }
2828        return getNow(options.now, dateEnv); // getNow already returns unzoned
2829    }
2830    function getNow(nowInput, dateEnv) {
2831        if (typeof nowInput === 'function') {
2832            nowInput = nowInput();
2833        }
2834        if (nowInput == null) {
2835            return dateEnv.createNowMarker();
2836        }
2837        return dateEnv.createMarker(nowInput);
2838    }
2839
2840    var CalendarApi = /** @class */ (function () {
2841        function CalendarApi() {
2842        }
2843        CalendarApi.prototype.getCurrentData = function () {
2844            return this.currentDataManager.getCurrentData();
2845        };
2846        CalendarApi.prototype.dispatch = function (action) {
2847            return this.currentDataManager.dispatch(action);
2848        };
2849        Object.defineProperty(CalendarApi.prototype, "view", {
2850            get: function () { return this.getCurrentData().viewApi; } // for public API
2851            ,
2852            enumerable: false,
2853            configurable: true
2854        });
2855        CalendarApi.prototype.batchRendering = function (callback) {
2856            callback();
2857        };
2858        CalendarApi.prototype.updateSize = function () {
2859            this.trigger('_resize', true);
2860        };
2861        // Options
2862        // -----------------------------------------------------------------------------------------------------------------
2863        CalendarApi.prototype.setOption = function (name, val) {
2864            this.dispatch({
2865                type: 'SET_OPTION',
2866                optionName: name,
2867                rawOptionValue: val,
2868            });
2869        };
2870        CalendarApi.prototype.getOption = function (name) {
2871            return this.currentDataManager.currentCalendarOptionsInput[name];
2872        };
2873        CalendarApi.prototype.getAvailableLocaleCodes = function () {
2874            return Object.keys(this.getCurrentData().availableRawLocales);
2875        };
2876        // Trigger
2877        // -----------------------------------------------------------------------------------------------------------------
2878        CalendarApi.prototype.on = function (handlerName, handler) {
2879            var currentDataManager = this.currentDataManager;
2880            if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) {
2881                currentDataManager.emitter.on(handlerName, handler);
2882            }
2883            else {
2884                console.warn("Unknown listener name '" + handlerName + "'");
2885            }
2886        };
2887        CalendarApi.prototype.off = function (handlerName, handler) {
2888            this.currentDataManager.emitter.off(handlerName, handler);
2889        };
2890        // not meant for public use
2891        CalendarApi.prototype.trigger = function (handlerName) {
2892            var _a;
2893            var args = [];
2894            for (var _i = 1; _i < arguments.length; _i++) {
2895                args[_i - 1] = arguments[_i];
2896            }
2897            (_a = this.currentDataManager.emitter).trigger.apply(_a, __spreadArrays([handlerName], args));
2898        };
2899        // View
2900        // -----------------------------------------------------------------------------------------------------------------
2901        CalendarApi.prototype.changeView = function (viewType, dateOrRange) {
2902            var _this = this;
2903            this.batchRendering(function () {
2904                _this.unselect();
2905                if (dateOrRange) {
2906                    if (dateOrRange.start && dateOrRange.end) { // a range
2907                        _this.dispatch({
2908                            type: 'CHANGE_VIEW_TYPE',
2909                            viewType: viewType,
2910                        });
2911                        _this.dispatch({
2912                            type: 'SET_OPTION',
2913                            optionName: 'visibleRange',
2914                            rawOptionValue: dateOrRange,
2915                        });
2916                    }
2917                    else {
2918                        var dateEnv = _this.getCurrentData().dateEnv;
2919                        _this.dispatch({
2920                            type: 'CHANGE_VIEW_TYPE',
2921                            viewType: viewType,
2922                            dateMarker: dateEnv.createMarker(dateOrRange),
2923                        });
2924                    }
2925                }
2926                else {
2927                    _this.dispatch({
2928                        type: 'CHANGE_VIEW_TYPE',
2929                        viewType: viewType,
2930                    });
2931                }
2932            });
2933        };
2934        // Forces navigation to a view for the given date.
2935        // `viewType` can be a specific view name or a generic one like "week" or "day".
2936        // needs to change
2937        CalendarApi.prototype.zoomTo = function (dateMarker, viewType) {
2938            var state = this.getCurrentData();
2939            var spec;
2940            viewType = viewType || 'day'; // day is default zoom
2941            spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType);
2942            this.unselect();
2943            if (spec) {
2944                this.dispatch({
2945                    type: 'CHANGE_VIEW_TYPE',
2946                    viewType: spec.type,
2947                    dateMarker: dateMarker,
2948                });
2949            }
2950            else {
2951                this.dispatch({
2952                    type: 'CHANGE_DATE',
2953                    dateMarker: dateMarker,
2954                });
2955            }
2956        };
2957        // Given a duration singular unit, like "week" or "day", finds a matching view spec.
2958        // Preference is given to views that have corresponding buttons.
2959        CalendarApi.prototype.getUnitViewSpec = function (unit) {
2960            var _a = this.getCurrentData(), viewSpecs = _a.viewSpecs, toolbarConfig = _a.toolbarConfig;
2961            var viewTypes = [].concat(toolbarConfig.viewsWithButtons);
2962            var i;
2963            var spec;
2964            for (var viewType in viewSpecs) {
2965                viewTypes.push(viewType);
2966            }
2967            for (i = 0; i < viewTypes.length; i += 1) {
2968                spec = viewSpecs[viewTypes[i]];
2969                if (spec) {
2970                    if (spec.singleUnit === unit) {
2971                        return spec;
2972                    }
2973                }
2974            }
2975            return null;
2976        };
2977        // Current Date
2978        // -----------------------------------------------------------------------------------------------------------------
2979        CalendarApi.prototype.prev = function () {
2980            this.unselect();
2981            this.dispatch({ type: 'PREV' });
2982        };
2983        CalendarApi.prototype.next = function () {
2984            this.unselect();
2985            this.dispatch({ type: 'NEXT' });
2986        };
2987        CalendarApi.prototype.prevYear = function () {
2988            var state = this.getCurrentData();
2989            this.unselect();
2990            this.dispatch({
2991                type: 'CHANGE_DATE',
2992                dateMarker: state.dateEnv.addYears(state.currentDate, -1),
2993            });
2994        };
2995        CalendarApi.prototype.nextYear = function () {
2996            var state = this.getCurrentData();
2997            this.unselect();
2998            this.dispatch({
2999                type: 'CHANGE_DATE',
3000                dateMarker: state.dateEnv.addYears(state.currentDate, 1),
3001            });
3002        };
3003        CalendarApi.prototype.today = function () {
3004            var state = this.getCurrentData();
3005            this.unselect();
3006            this.dispatch({
3007                type: 'CHANGE_DATE',
3008                dateMarker: getNow(state.calendarOptions.now, state.dateEnv),
3009            });
3010        };
3011        CalendarApi.prototype.gotoDate = function (zonedDateInput) {
3012            var state = this.getCurrentData();
3013            this.unselect();
3014            this.dispatch({
3015                type: 'CHANGE_DATE',
3016                dateMarker: state.dateEnv.createMarker(zonedDateInput),
3017            });
3018        };
3019        CalendarApi.prototype.incrementDate = function (deltaInput) {
3020            var state = this.getCurrentData();
3021            var delta = createDuration(deltaInput);
3022            if (delta) { // else, warn about invalid input?
3023                this.unselect();
3024                this.dispatch({
3025                    type: 'CHANGE_DATE',
3026                    dateMarker: state.dateEnv.add(state.currentDate, delta),
3027                });
3028            }
3029        };
3030        // for external API
3031        CalendarApi.prototype.getDate = function () {
3032            var state = this.getCurrentData();
3033            return state.dateEnv.toDate(state.currentDate);
3034        };
3035        // Date Formatting Utils
3036        // -----------------------------------------------------------------------------------------------------------------
3037        CalendarApi.prototype.formatDate = function (d, formatter) {
3038            var dateEnv = this.getCurrentData().dateEnv;
3039            return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
3040        };
3041        // `settings` is for formatter AND isEndExclusive
3042        CalendarApi.prototype.formatRange = function (d0, d1, settings) {
3043            var dateEnv = this.getCurrentData().dateEnv;
3044            return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings);
3045        };
3046        CalendarApi.prototype.formatIso = function (d, omitTime) {
3047            var dateEnv = this.getCurrentData().dateEnv;
3048            return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime });
3049        };
3050        // Date Selection / Event Selection / DayClick
3051        // -----------------------------------------------------------------------------------------------------------------
3052        // this public method receives start/end dates in any format, with any timezone
3053        // NOTE: args were changed from v3
3054        CalendarApi.prototype.select = function (dateOrObj, endDate) {
3055            var selectionInput;
3056            if (endDate == null) {
3057                if (dateOrObj.start != null) {
3058                    selectionInput = dateOrObj;
3059                }
3060                else {
3061                    selectionInput = {
3062                        start: dateOrObj,
3063                        end: null,
3064                    };
3065                }
3066            }
3067            else {
3068                selectionInput = {
3069                    start: dateOrObj,
3070                    end: endDate,
3071                };
3072            }
3073            var state = this.getCurrentData();
3074            var selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 }));
3075            if (selection) { // throw parse error otherwise?
3076                this.dispatch({ type: 'SELECT_DATES', selection: selection });
3077                triggerDateSelect(selection, null, state);
3078            }
3079        };
3080        // public method
3081        CalendarApi.prototype.unselect = function (pev) {
3082            var state = this.getCurrentData();
3083            if (state.dateSelection) {
3084                this.dispatch({ type: 'UNSELECT_DATES' });
3085                triggerDateUnselect(pev, state);
3086            }
3087        };
3088        // Public Events API
3089        // -----------------------------------------------------------------------------------------------------------------
3090        CalendarApi.prototype.addEvent = function (eventInput, sourceIn
3090put) {
3091            if (eventInput instanceof EventApi) {
3092                var def = eventInput._def;
3093                var instance = eventInput._instance;
3094                var currentData = this.getCurrentData();
3095                // not already present? don't want to add an old snapshot
3096                if (!currentData.eventStore.defs[def.defId]) {
3097                    this.dispatch({
3098                        type: 'ADD_EVENTS',
3099                        eventStore: eventTupleToStore({ def: def, instance: instance }),
3100                    });
3101                    this.triggerEventAdd(eventInput);
3102                }
3103                return eventInput;
3104            }
3105            var state = this.getCurrentData();
3106            var eventSource;
3107            if (sourceInput instanceof EventSourceApi) {
3108                eventSource = sourceInput.internalEventSource;
3109            }
3110            else if (typeof sourceInput === 'boolean') {
3111                if (sourceInput) { // true. part of the first event source
3112                    eventSource = hashValuesToArray(state.eventSources)[0];
3113                }
3114            }
3115            else if (sourceInput != null) { // an ID. accepts a number too
3116                var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
3117                if (!sourceApi) {
3118                    console.warn("Could not find an event source with ID \"" + sourceInput + "\""); // TODO: test
3119                    return null;
3120                }
3121                eventSource = sourceApi.internalEventSource;
3122            }
3123            var tuple = parseEvent(eventInput, eventSource, state, false);
3124            if (tuple) {
3125                var newEventApi = new EventApi(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
3126                this.dispatch({
3127                    type: 'ADD_EVENTS',
3128                    eventStore: eventTupleToStore(tuple),
3129                });
3130                this.triggerEventAdd(newEventApi);
3131                return newEventApi;
3132            }
3133            return null;
3134        };
3135        CalendarApi.prototype.triggerEventAdd = function (eventApi) {
3136            var _this = this;
3137            var emitter = this.getCurrentData().emitter;
3138            emitter.trigger('eventAdd', {
3139                event: eventApi,
3140                relatedEvents: [],
3141                revert: function () {
3142                    _this.dispatch({
3143                        type: 'REMOVE_EVENTS',
3144                        eventStore: eventApiToStore(eventApi),
3145                    });
3146                },
3147            });
3148        };
3149        // TODO: optimize
3150        CalendarApi.prototype.getEventById = function (id) {
3151            var state = this.getCurrentData();
3152            var _a = state.eventStore, defs = _a.defs, instances = _a.instances;
3153            id = String(id);
3154            for (var defId in defs) {
3155                var def = defs[defId];
3156                if (def.publicId === id) {
3157                    if (def.recurringDef) {
3158                        return new EventApi(state, def, null);
3159                    }
3160                    for (var instanceId in instances) {
3161                        var instance = instances[instanceId];
3162                        if (instance.defId === def.defId) {
3163                            return new EventApi(state, def, instance);
3164                        }
3165                    }
3166                }
3167            }
3168            return null;
3169        };
3170        CalendarApi.prototype.getEvents = function () {
3171            var currentData = this.getCurrentData();
3172            return buildEventApis(currentData.eventStore, currentData);
3173        };
3174        CalendarApi.prototype.removeAllEvents = function () {
3175            this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
3176        };
3177        // Public Event Sources API
3178        // -----------------------------------------------------------------------------------------------------------------
3179        CalendarApi.prototype.getEventSources = function () {
3180            var state = this.getCurrentData();
3181            var sourceHash = state.eventSources;
3182            var sourceApis = [];
3183            for (var internalId in sourceHash) {
3184                sourceApis.push(new EventSourceApi(state, sourceHash[internalId]));
3185            }
3186            return sourceApis;
3187        };
3188        CalendarApi.prototype.getEventSourceById = function (id) {
3189            var state = this.getCurrentData();
3190            var sourceHash = state.eventSources;
3191            id = String(id);
3192            for (var sourceId in sourceHash) {
3193                if (sourceHash[sourceId].publicId === id) {
3194                    return new EventSourceApi(state, sourceHash[sourceId]);
3195                }
3196            }
3197            return null;
3198        };
3199        CalendarApi.prototype.addEventSource = function (sourceInput) {
3200            var state = this.getCurrentData();
3201            if (sourceInput instanceof EventSourceApi) {
3202                // not already present? don't want to add an old snapshot
3203                if (!state.eventSources[sourceInput.internalEventSource.sourceId]) {
3204                    this.dispatch({
3205                        type: 'ADD_EVENT_SOURCES',
3206                        sources: [sourceInput.internalEventSource],
3207                    });
3208                }
3209                return sourceInput;
3210            }
3211            var eventSource = parseEventSource(sourceInput, state);
3212            if (eventSource) { // TODO: error otherwise?
3213                this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
3214                return new EventSourceApi(state, eventSource);
3215            }
3216            return null;
3217        };
3218        CalendarApi.prototype.removeAllEventSources = function () {
3219            this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
3220        };
3221        CalendarApi.prototype.refetchEvents = function () {
3222            this.dispatch({ type: 'FETCH_EVENT_SOURCES' });
3223        };
3224        // Scroll
3225        // -----------------------------------------------------------------------------------------------------------------
3226        CalendarApi.prototype.scrollToTime = function (timeInput) {
3227            var time = createDuration(timeInput);
3228            if (time) {
3229                this.trigger('_scrollRequest', { time: time });
3230            }
3231        };
3232        return CalendarApi;
3233    }());
3234
3235    var EventApi = /** @class */ (function () {
3236        // instance will be null if expressing a recurring event that has no current instances,
3237        // OR if trying to validate an incoming external event that has no dates assigned
3238        function EventApi(context, def, instance) {
3239            this._context = context;
3240            this._def = def;
3241            this._instance = instance || null;
3242        }
3243        /*
3244        TODO: make event struct more responsible for this
3245        */
3246        EventApi.prototype.setProp = function (name, val) {
3247            var _a, _b;
3248            if (name in EVENT_DATE_REFINERS) {
3249                console.warn('Could not set date-related prop \'name\'. Use one of the date-related methods instead.');
3250            }
3251            else if (name in EVENT_NON_DATE_REFINERS) {
3252                val = EVENT_NON_DATE_REFINERS[name](val);
3253                this.mutate({
3254                    standardProps: (_a = {}, _a[name] = val, _a),
3255                });
3256            }
3257            else if (name in EVENT_UI_REFINERS) {
3258                var ui = EVENT_UI_REFINERS[name](val);
3259                if (name === 'color') {
3260                    ui = { backgroundColor: val, borderColor: val };
3261                }
3262                else if (name === 'editable') {
3263                    ui = { startEditable: val, durationEditable: val };
3264                }
3265                else {
3266                    ui = (_b = {}, _b[name] = val, _b);
3267                }
3268                this.mutate({
3269                    standardProps: { ui: ui },
3270                });
3271            }
3272            else {
3273                console.warn("Could not set prop '" + name + "'. Use setExtendedProp instead.");
3274            }
3275        };
3276        EventApi.prototype.setExtendedProp = function (name, val) {
3277            var _a;
3278            this.mutate({
3279                extendedProps: (_a = {}, _a[name] = val, _a),
3280            });
3281        };
3282        EventApi.prototype.setStart = function (startInput, options) {
3283            if (options === void 0) { options = {}; }
3284            var dateEnv = this._context.dateEnv;
3285            var start = dateEnv.createMarker(startInput);
3286            if (start && this._instance) { // TODO: warning if parsed bad
3287                var instanceRange = this._instance.range;
3288                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?
3289                if (options.maintainDuration) {
3290                    this.mutate({ datesDelta: startDelta });
3291                }
3292                else {
3293                    this.mutate({ startDelta: startDelta });
3294                }
3295            }
3296        };
3297        EventApi.prototype.setEnd = function (endInput, options) {
3298            if (options === void 0) { options = {}; }
3299            var dateEnv = this._context.dateEnv;
3300            var end;
3301            if (endInput != null) {
3302                end = dateEnv.createMarker(endInput);
3303                if (!end) {
3304                    return; // TODO: warning if parsed bad
3305                }
3306            }
3307            if (this._instance) {
3308                if (end) {
3309                    var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
3310                    this.mutate({ endDelta: endDelta });
3311                }
3312                else {
3313                    this.mutate({ standardProps: { hasEnd: false } });
3314                }
3315            }
3316        };
3317        EventApi.prototype.setDates = function (startInput, endInput, options) {
3318            if (options === void 0) { options = {}; }
3319            var dateEnv = this._context.dateEnv;
3320            var standardProps = { allDay: options.allDay };
3321            var start = dateEnv.createMarker(startInput);
3322            var end;
3323            if (!start) {
3324                return; // TODO: warning if parsed bad
3325            }
3326            if (endInput != null) {
3327                end = dateEnv.createMarker(endInput);
3328                if (!end) { // TODO: warning if parsed bad
3329                    return;
3330                }
3331            }
3332            if (this._instance) {
3333                var instanceRange = this._instance.range;
3334                // when computing the diff for an event being converted to all-day,
3335                // compute diff off of the all-day values the way event-mutation does.
3336                if (options.allDay === true) {
3337                    instanceRange = computeAlignedDayRange(instanceRange);
3338                }
3339                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
3340                if (end) {
3341                    var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
3342                    if (durationsEqual(startDelta, endDelta)) {
3343                        this.mutate({ datesDelta: startDelta, standardProps: standardProps });
3344                    }
3345                    else {
3346                        this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps });
3347                    }
3348                }
3349                else { // means "clear the end"
3350                    standardProps.hasEnd = false;
3351                    this.mutate({ datesDelta: startDelta, standardProps: standardProps });
3352                }
3353            }
3354        };
3355        EventApi.prototype.moveStart = function (deltaInput) {
3356            var delta = createDuration(deltaInput);
3357            if (delta) { // TODO: warning if parsed bad
3358                this.mutate({ startDelta: delta });
3359            }
3360        };
3361        EventApi.prototype.moveEnd = function (deltaInput) {
3362            var delta = createDuration(deltaInput);
3363            if (delta) { // TODO: warning if parsed bad
3364                this.mutate({ endDelta: delta });
3365            }
3366        };
3367        EventApi.prototype.moveDates = function (deltaInput) {
3368            var delta = createDuration(deltaInput);
3369            if (delta) { // TODO: warning if parsed bad
3370                this.mutate({ datesDelta: delta });
3371            }
3372        };
3373        EventApi.prototype.setAllDay = function (allDay, options) {
3374            if (options === void 0) { options = {}; }
3375            var standardProps = { allDay: allDay };
3376            var maintainDuration = options.maintainDuration;
3377            if (maintainDuration == null) {
3378                maintainDuration = this._context.options.allDayMaintainDuration;
3379            }
3380            if (this._def.allDay !== allDay) {
3381                standardProps.hasEnd = maintainDuration;
3382            }
3383            this.mutate({ standardProps: standardProps });
3384        };
3385        EventApi.prototype.formatRange = function (formatInput) {
3386            var dateEnv = this._context.dateEnv;
3387            var instance = this._instance;
3388            var formatter = createFormatter(formatInput);
3389            if (this._def.hasEnd) {
3390                return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
3391                    forcedStartTzo: instance.forcedStartTzo,
3392                    forcedEndTzo: instance.forcedEndTzo,
3393                });
3394            }
3395            return dateEnv.format(instance.range.start, formatter, {
3396                forcedTzo: instance.forcedStartTzo,
3397            });
3398        };
3399        EventApi.prototype.mutate = function (mutation) {
3400            var instance = this._instance;
3401            if (instance) {
3402                var def = this._def;
3403                var context_1 = this._context;
3404                var eventStore_1 = context_1.getCurrentData().eventStore;
3405                var relevantEvents = getRelevantEvents(eventStore_1, instance.instanceId);
3406                var eventConfigBase = {
3407                    '': {
3408                        display: '',
3409                        startEditable: true,
3410                        durationEditable: true,
3411                        constraints: [],
3412                        overlap: null,
3413                        allows: [],
3414                        backgroundColor: '',
3415                        borderColor: '',
3416                        textColor: '',
3417                        classNames: [],
3418                    },
3419                };
3420                relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context_1);
3421                var oldEvent = new EventApi(context_1, def, instance); // snapshot
3422                this._def = relevantEvents.defs[def.defId];
3423                this._instance = relevantEvents.instances[instance.instanceId];
3424                context_1.dispatch({
3425                    type: 'MERGE_EVENTS',
3426                    eventStore: relevantEvents,
3427                });
3428                context_1.emitter.trigger('eventChange', {
3429                    oldEvent: oldEvent,
3430                    event: this,
3431                    relatedEvents: buildEventApis(relevantEvents, context_1, instance),
3432                    revert: function () {
3433                        context_1.dispatch({
3434                            type: 'RESET_EVENTS',
3435                            eventStore: eventStore_1,
3436                        });
3437                    },
3438                });
3439            }
3440        };
3441        EventApi.prototype.remove = function () {
3442            var context = this._context;
3443            var asStore = eventApiToStore(this);
3444            context.dispatch({
3445                type: 'REMOVE_EVENTS',
3446                eventStore: asStore,
3447            });
3448            context.emitter.trigger('eventRemove', {
3449                event: this,
3450                relatedEvents: [],
3451                revert: function () {
3452                    context.dispatch({
3453                        type: 'MERGE_EVENTS',
3454                        eventStore: asStore,
3455                    });
3456                },
3457            });
3458        };
3459        Object.defineProperty(EventApi.prototype, "source", {
3460            get: function () {
3461                var sourceId = this._def.sourceId;
3462                if (sourceId) {
3463                    return new EventSourceApi(this._context, this._context.getCurrentData().eventSources[sourceId]);
3464                }
3465                return null;
3466            },
3467            enumerable: false,
3468            configurable: true
3469        });
3470        Object.defineProperty(EventApi.prototype, "start", {
3471            get: function () {
3472                return this._instance ?
3473                    this._context.dateEnv.toDate(this._instance.range.start) :
3474                    null;
3475            },
3476            enumerable: false,
3477            configurable: true
3478        });
3479        Object.defineProperty(EventApi.prototype, "end", {
3480            get: function () {
3481                return (this._instance && this._def.hasEnd) ?
3482                    this._context.dateEnv.toDate(this._instance.range.end) :
3483                    null;
3484            },
3485            enumerable: false,
3486            configurable: true
3487        });
3488        Object.defineProperty(EventApi.prototype, "startStr", {
3489            get: function () {
3490                var instance = this._instance;
3491                if (instance) {
3492                    return this._context.dateEnv.formatIso(instance.range.start, {
3493                        omitTime: this._def.allDay,
3494                        forcedTzo: instance.forcedStartTzo,
3495                    });
3496                }
3497                return '';
3498            },
3499            enumerable: false,
3500            configurable: true
3501        });
3502        Object.defineProperty(EventApi.prototype, "endStr", {
3503            get: function () {
3504                var instance = this._instance;
3505                if (instance && this._def.hasEnd) {
3506                    return this._context.dateEnv.formatIso(instance.range.end, {
3507                        omitTime: this._def.allDay,
3508                        forcedTzo: instance.forcedEndTzo,
3509                    });
3510                }
3511                return '';
3512            },
3513            enumerable: false,
3514            configurable: true
3515        });
3516        Object.defineProperty(EventApi.prototype, "id", {
3517            // computable props that all access the def
3518            // TODO: find a TypeScript-compatible way to do this at scale
3519            get: function () { return this._def.publicId; },
3520            enumerable: false,
3521            configurable: true
3522        });
3523        Object.defineProperty(EventApi.prototype, "groupId", {
3524            get: function () { return this._def.groupId; },
3525            enumerable: false,
3526            configurable: true
3527        });
3528        Object.defineProperty(EventApi.prototype, "allDay", {
3529            get: function () { return this._def.allDay; },
3530            enumerable: false,
3531            configurable: true
3532        });
3533        Object.defineProperty(EventApi.prototype, "title", {
3534            get: function () { return this._def.title; },
3535            enumerable: false,
3536            configurable: true
3537        });
3538        Object.defineProperty(EventApi.prototype, "url", {
3539            get: function () { return this._def.url; },
3540            enumerable: false,
3541            configurable: true
3542        });
3543        Object.defineProperty(EventApi.prototype, "display", {
3544            get: function () { return this._def.ui.display || 'auto'; } // bad. just normalize the type earlier
3545            ,
3546            enumerable: false,
3547            configurable: true
3548        });
3549        Object.defineProperty(EventApi.prototype, "startEditable", {
3550            get: function () { return this._def.ui.startEditable; },
3551            enumerable: false,
3552            configurable: true
3553        });
3554        Object.defineProperty(EventApi.prototype, "durationEditable", {
3555            get: function () { return this._def.ui.durationEditable; },
3556            enumerable: false,
3557            configurable: true
3558        });
3559        Object.defineProperty(EventApi.prototype, "constraint", {
3560            get: function () { return this._def.ui.constraints[0] || null; },
3561            enumerable: false,
3562            configurable: true
3563        });
3564        Object.defineProperty(EventApi.prototype, "overlap", {
3565            get: function () { return this._def.ui.overlap; },
3566            enumerable: false,
3567            configurable: true
3568        });
3569        Object.defineProperty(EventApi.prototype, "allow", {
3570            get: function () { return this._def.ui.allows[0] || null; },
3571            enumerable: false,
3572            configurable: true
3573        });
3574        Object.defineProperty(EventApi.prototype, "backgroundColor", {
3575            get: function () { return this._def.ui.backgroundColor; },
3576            enumerable: false,
3577            configurable: true
3578        });
3579        Object.defineProperty(EventApi.prototype, "borderColor", {
3580            get: function () { return this._def.ui.borderColor; },
3581            enumerable: false,
3582            configurable: true
3583        });
3584        Object.defineProperty(EventApi.prototype, "textColor", {
3585            get: function () { return this._def.ui.textColor; },
3586            enumerable: false,
3587            configurable: true
3588        });
3589        Object.defineProperty(EventApi.prototype, "classNames", {
3590            // NOTE: user can't modify these because Object.freeze was called in event-def parsing
3591            get: function () { return this._def.ui.classNames; },
3592            enumerable: false,
3593            configurable: true
3594        });
3595        Object.defineProperty(EventApi.prototype, "extendedProps", {
3596            get: function () { return this._def.extendedProps; },
3597            enumerable: false,
3598            configurable: true
3599        });
3600        EventApi.prototype.toPlainObject = function (settings) {
3601            if (settings === void 0) { settings = {}; }
3602            var def = this._def;
3603            var ui = def.ui;
3604            var _a = this, startStr = _a.startStr, endStr = _a.endStr;
3605            var res = {};
3606            if (def.title) {
3607                res.title = def.title;
3608            }
3609            if (startStr) {
3610                res.start = startStr;
3611            }
3612            if (endStr) {
3613                res.end = endStr;
3614            }
3615            if (def.publicId) {
3616                res.id = def.publicId;
3617            }
3618            if (def.groupId) {
3619                res.groupId = def.groupId;
3620            }
3621            if (def.url) {
3622                res.url = def.url;
3623            }
3624            if (ui.display && ui.display !== 'auto') {
3625                res.display = ui.display;
3626            }
3627            // TODO: what about recurring-event properties???
3628            // TODO: include startEditable/durationEditable/constraint/overlap/allow
3629            if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) {
3630                res.color = ui.backgroundColor;
3631            }
3632            else {
3633                if (ui.backgroundColor) {
3634                    res.backgroundColor = ui.backgroundColor;
3635                }
3636                if (ui.borderColor) {
3637                    res.borderColor = ui.borderColor;
3638                }
3639            }
3640            if (ui.textColor) {
3641                res.textColor = ui.textColor;
3642            }
3643            if (ui.classNames.length) {
3644                res.classNames = ui.classNames;
3645            }
3646            if (Object.keys(def.extendedProps).length) {
3647                if (settings.collapseExtendedProps) {
3648                    __assign(res, def.extendedProps);
3649                }
3650                else {
3651                    res.extendedProps = def.extendedProps;
3652                }
3653            }
3654            return res;
3655        };
3656        EventApi.prototype.toJSON = function () {
3657            return this.toPlainObject();
3658        };
3659        return EventApi;
3660    }());
3661    function eventApiToStore(eventApi) {
3662        var _a, _b;
3663        var def = eventApi._def;
3664        var instance = eventApi._instance;
3665        return {
3666            defs: (_a = {}, _a[def.defId] = def, _a),
3667            instances: instance
3668                ? (_b = {}, _b[instance.instanceId] = instance, _b) : {},
3669        };
3670    }
3671    function buildEventApis(eventStore, context, excludeInstance) {
3672        var defs = eventStore.defs, instances = eventStore.instances;
3673        var eventApis = [];
3674        var excludeInstanceId = excludeInstance ? excludeInstance.instanceId : '';
3675        for (var id in instances) {
3676            var instance = instances[id];
3677            var def = defs[instance.defId];
3678            if (instance.instanceId !== excludeInstanceId) {
3679                eventApis.push(new EventApi(context, def, instance));
3680            }
3681        }
3682        return eventApis;
3683    }
3684
3685    var calendarSystemClassMap = {};
3686    function registerCalendarSystem(name, theClass) {
3687        calendarSystemClassMap[name] = theClass;
3688    }
3689    function createCalendarSystem(name) {
3690        return new calendarSystemClassMap[name]();
3691    }
3692    var GregorianCalendarSystem = /** @class */ (function () {
3693        function GregorianCalendarSystem() {
3694        }
3695        GregorianCalendarSystem.prototype.getMarkerYear = function (d) {
3696            return d.getUTCFullYear();
3697        };
3698        GregorianCalendarSystem.prototype.getMarkerMonth = function (d) {
3699            return d.getUTCMonth();
3700        };
3701        GregorianCalendarSystem.prototype.getMarkerDay = function (d) {
3702            return d.getUTCDate();
3703        };
3704        GregorianCalendarSystem.prototype.arrayToMarker = function (arr) {
3705            return arrayToUtcDate(arr);
3706        };
3707        GregorianCalendarSystem.prototype.markerToArray = function (marker) {
3708            return dateToUtcArray(marker);
3709        };
3710        return GregorianCalendarSystem;
3711    }());
3712    registerCalendarSystem('gregory', GregorianCalendarSystem);
3713
3714    var ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
3715    function parse(str) {
3716        var m = ISO_RE.exec(str);
3717        if (m) {
3718            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));
3719            if (isValidDate(marker)) {
3720                var timeZoneOffset = null;
3721                if (m[13]) {
3722                    timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
3723                        Number(m[18] || 0));
3724                }
3725                return {
3726                    marker: marker,
3727                    isTimeUnspecified: !m[6],
3728                    timeZoneOffset: timeZoneOffset,
3729                };
3730            }
3731        }
3732        return null;
3733    }
3734
3735    var DateEnv = /** @class */ (function () {
3736        function DateEnv(settings) {
3737            var timeZone = this.timeZone = settings.timeZone;
3738            var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
3739            if (settings.namedTimeZoneImpl && isNamedTimeZone) {
3740                this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
3741            }
3742            this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
3743            this.calendarSystem = createCalendarSystem(settings.calendarSystem);
3744            this.locale = settings.locale;
3745            this.weekDow = settings.locale.week.dow;
3746            this.weekDoy = settings.locale.week.doy;
3747            if (settings.weekNumberCalculation === 'ISO') {
3748                this.weekDow = 1;
3749                this.weekDoy = 4;
3750            }
3751            if (typeof settings.firstDay === 'number') {
3752                this.weekDow = settings.firstDay;
3753            }
3754            if (typeof settings.weekNumberCalculation === 'function') {
vendor: 16,384 bytes, lines 3755-4166
3755                this.weekNumberFunc = settings.weekNumberCalculation;
3756            }
3757            this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText;
3758            this.cmdFormatter = settings.cmdFormatter;
3759            this.defaultSeparator = settings.defaultSeparator;
3760        }
3761        // Creating / Parsing
3762        DateEnv.prototype.createMarker = function (input) {
3763            var meta = this.createMarkerMeta(input);
3764            if (meta === null) {
3765                return null;
3766            }
3767            return meta.marker;
3768        };
3769        DateEnv.prototype.createNowMarker = function () {
3770            if (this.canComputeOffset) {
3771                return this.timestampToMarker(new Date().valueOf());
3772            }
3773            // if we can't compute the current date val for a timezone,
3774            // better to give the current local date vals than UTC
3775            return arrayToUtcDate(dateToLocalArray(new Date()));
3776        };
3777        DateEnv.prototype.createMarkerMeta = function (input) {
3778            if (typeof input === 'string') {
3779                return this.parse(input);
3780            }
3781            var marker = null;
3782            if (typeof input === 'number') {
3783                marker = this.timestampToMarker(input);
3784            }
3785            else if (input instanceof Date) {
3786                input = input.valueOf();
3787                if (!isNaN(input)) {
3788                    marker = this.timestampToMarker(input);
3789                }
3790            }
3791            else if (Array.isArray(input)) {
3792                marker = arrayToUtcDate(input);
3793            }
3794            if (marker === null || !isValidDate(marker)) {
3795                return null;
3796            }
3797            return { marker: marker, isTimeUnspecified: false, forcedTzo: null };
3798        };
3799        DateEnv.prototype.parse = function (s) {
3800            var parts = parse(s);
3801            if (parts === null) {
3802                return null;
3803            }
3804            var marker = parts.marker;
3805            var forcedTzo = null;
3806            if (parts.timeZoneOffset !== null) {
3807                if (this.canComputeOffset) {
3808                    marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
3809                }
3810                else {
3811                    forcedTzo = parts.timeZoneOffset;
3812                }
3813            }
3814            return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo };
3815        };
3816        // Accessors
3817        DateEnv.prototype.getYear = function (marker) {
3818            return this.calendarSystem.getMarkerYear(marker);
3819        };
3820        DateEnv.prototype.getMonth = function (marker) {
3821            return this.calendarSystem.getMarkerMonth(marker);
3822        };
3823        // Adding / Subtracting
3824        DateEnv.prototype.add = function (marker, dur) {
3825            var a = this.calendarSystem.markerToArray(marker);
3826            a[0] += dur.years;
3827            a[1] += dur.months;
3828            a[2] += dur.days;
3829            a[6] += dur.milliseconds;
3830            return this.calendarSystem.arrayToMarker(a);
3831        };
3832        DateEnv.prototype.subtract = function (marker, dur) {
3833            var a = this.calendarSystem.markerToArray(marker);
3834            a[0] -= dur.years;
3835            a[1] -= dur.months;
3836            a[2] -= dur.days;
3837            a[6] -= dur.milliseconds;
3838            return this.calendarSystem.arrayToMarker(a);
3839        };
3840        DateEnv.prototype.addYears = function (marker, n) {
3841            var a = this.calendarSystem.markerToArray(marker);
3842            a[0] += n;
3843            return this.calendarSystem.arrayToMarker(a);
3844        };
3845        DateEnv.prototype.addMonths = function (marker, n) {
3846            var a = this.calendarSystem.markerToArray(marker);
3847            a[1] += n;
3848            return this.calendarSystem.arrayToMarker(a);
3849        };
3850        // Diffing Whole Units
3851        DateEnv.prototype.diffWholeYears = function (m0, m1) {
3852            var calendarSystem = this.calendarSystem;
3853            if (timeAsMs(m0) === timeAsMs(m1) &&
3854                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
3855                calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
3856                return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
3857            }
3858            return null;
3859        };
3860        DateEnv.prototype.diffWholeMonths = function (m0, m1) {
3861            var calendarSystem = this.calendarSystem;
3862            if (timeAsMs(m0) === timeAsMs(m1) &&
3863                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
3864                return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
3865                    (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
3866            }
3867            return null;
3868        };
3869        // Range / Duration
3870        DateEnv.prototype.greatestWholeUnit = function (m0, m1) {
3871            var n = this.diffWholeYears(m0, m1);
3872            if (n !== null) {
3873                return { unit: 'year', value: n };
3874            }
3875            n = this.diffWholeMonths(m0, m1);
3876            if (n !== null) {
3877                return { unit: 'month', value: n };
3878            }
3879            n = diffWholeWeeks(m0, m1);
3880            if (n !== null) {
3881                return { unit: 'week', value: n };
3882            }
3883            n = diffWholeDays(m0, m1);
3884            if (n !== null) {
3885                return { unit: 'day', value: n };
3886            }
3887            n = diffHours(m0, m1);
3888            if (isInt(n)) {
3889                return { unit: 'hour', value: n };
3890            }
3891            n = diffMinutes(m0, m1);
3892            if (isInt(n)) {
3893                return { unit: 'minute', value: n };
3894            }
3895            n = diffSeconds(m0, m1);
3896            if (isInt(n)) {
3897                return { unit: 'second', value: n };
3898            }
3899            return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
3900        };
3901        DateEnv.prototype.countDurationsBetween = function (m0, m1, d) {
3902            // TODO: can use greatestWholeUnit
3903            var diff;
3904            if (d.years) {
3905                diff = this.diffWholeYears(m0, m1);
3906                if (diff !== null) {
3907                    return diff / asRoughYears(d);
3908                }
3909            }
3910            if (d.months) {
3911                diff = this.diffWholeMonths(m0, m1);
3912                if (diff !== null) {
3913                    return diff / asRoughMonths(d);
3914                }
3915            }
3916            if (d.days) {
3917                diff = diffWholeDays(m0, m1);
3918                if (diff !== null) {
3919                    return diff / asRoughDays(d);
3920                }
3921            }
3922            return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
3923        };
3924        // Start-Of
3925        // these DON'T return zoned-dates. only UTC start-of dates
3926        DateEnv.prototype.startOf = function (m, unit) {
3927            if (unit === 'year') {
3928                return this.startOfYear(m);
3929            }
3930            if (unit === 'month') {
3931                return this.startOfMonth(m);
3932            }
3933            if (unit === 'week') {
3934                return this.startOfWeek(m);
3935            }
3936            if (unit === 'day') {
3937                return startOfDay(m);
3938            }
3939            if (unit === 'hour') {
3940                return startOfHour(m);
3941            }
3942            if (unit === 'minute') {
3943                return startOfMinute(m);
3944            }
3945            if (unit === 'second') {
3946                return startOfSecond(m);
3947            }
3948            return null;
3949        };
3950        DateEnv.prototype.startOfYear = function (m) {
3951            return this.calendarSystem.arrayToMarker([
3952                this.calendarSystem.getMarkerYear(m),
3953            ]);
3954        };
3955        DateEnv.prototype.startOfMonth = function (m) {
3956            return this.calendarSystem.arrayToMarker([
3957                this.calendarSystem.getMarkerYear(m),
3958                this.calendarSystem.getMarkerMonth(m),
3959            ]);
3960        };
3961        DateEnv.prototype.startOfWeek = function (m) {
3962            return this.calendarSystem.arrayToMarker([
3963                this.calendarSystem.getMarkerYear(m),
3964                this.calendarSystem.getMarkerMonth(m),
3965                m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7),
3966            ]);
3967        };
3968        // Week Number
3969        DateEnv.prototype.computeWeekNumber = function (marker) {
3970            if (this.weekNumberFunc) {
3971                return this.weekNumberFunc(this.toDate(marker));
3972            }
3973            return weekOfYear(marker, this.weekDow, this.weekDoy);
3974        };
3975        // TODO: choke on timeZoneName: long
3976        DateEnv.prototype.format = function (marker, formatter, dateOptions) {
3977            if (dateOptions === void 0) { dateOptions = {}; }
3978            return formatter.format({
3979                marker: marker,
3980                timeZoneOffset: dateOptions.forcedTzo != null ?
3981                    dateOptions.forcedTzo :
3982                    this.offsetForMarker(marker),
3983            }, this);
3984        };
3985        DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) {
3986            if (dateOptions === void 0) { dateOptions = {}; }
3987            if (dateOptions.isEndExclusive) {
3988                end = addMs(end, -1);
3989            }
3990            return formatter.formatRange({
3991                marker: start,
3992                timeZoneOffset: dateOptions.forcedStartTzo != null ?
3993                    dateOptions.forcedStartTzo :
3994                    this.offsetForMarker(start),
3995            }, {
3996                marker: end,
3997                timeZoneOffset: dateOptions.forcedEndTzo != null ?
3998                    dateOptions.forcedEndTzo :
3999                    this.offsetForMarker(end),
4000            }, this, dateOptions.defaultSeparator);
4001        };
4002        /*
4003        DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that,
4004        might as well use buildIsoString or some other util directly
4005        */
4006        DateEnv.prototype.formatIso = function (marker, extraOptions) {
4007            if (extraOptions === void 0) { extraOptions = {}; }
4008            var timeZoneOffset = null;
4009            if (!extraOptions.omitTimeZoneOffset) {
4010                if (extraOptions.forcedTzo != null) {
4011                    timeZoneOffset = extraOptions.forcedTzo;
4012                }
4013                else {
4014                    timeZoneOffset = this.offsetForMarker(marker);
4015                }
4016            }
4017            return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
4018        };
4019        // TimeZone
4020        DateEnv.prototype.timestampToMarker = function (ms) {
4021            if (this.timeZone === 'local') {
4022                return arrayToUtcDate(dateToLocalArray(new Date(ms)));
4023            }
4024            if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
4025                return new Date(ms);
4026            }
4027            return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
4028        };
4029        DateEnv.prototype.offsetForMarker = function (m) {
4030            if (this.timeZone === 'local') {
4031                return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
4032            }
4033            if (this.timeZone === 'UTC') {
4034                return 0;
4035            }
4036            if (this.namedTimeZoneImpl) {
4037                return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
4038            }
4039            return null;
4040        };
4041        // Conversion
4042        DateEnv.prototype.toDate = function (m, forcedTzo) {
4043            if (this.timeZone === 'local') {
4044                return arrayToLocalDate(dateToUtcArray(m));
4045            }
4046            if (this.timeZone === 'UTC') {
4047                return new Date(m.valueOf()); // make sure it's a copy
4048            }
4049            if (!this.namedTimeZoneImpl) {
4050                return new Date(m.valueOf() - (forcedTzo || 0));
4051            }
4052            return new Date(m.valueOf() -
4053                this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60);
4054        };
4055        return DateEnv;
4056    }());
4057
4058    var globalLocales = [];
4059
4060    var RAW_EN_LOCALE = {
4061        code: 'en',
4062        week: {
4063            dow: 0,
4064            doy: 4,
4065        },
4066        direction: 'ltr',
4067        buttonText: {
4068            prev: 'prev',
4069            next: 'next',
4070            prevYear: 'prev year',
4071            nextYear: 'next year',
4072            year: 'year',
4073            today: 'today',
4074            month: 'month',
4075            week: 'week',
4076            day: 'day',
4077            list: 'list',
4078        },
4079        weekText: 'W',
4080        allDayText: 'all-day',
4081        moreLinkText: 'more',
4082        noEventsText: 'No events to display',
4083    };
4084    function organizeRawLocales(explicitRawLocales) {
4085        var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
4086        var allRawLocales = globalLocales.concat(explicitRawLocales);
4087        var rawLocaleMap = {
4088            en: RAW_EN_LOCALE,
4089        };
4090        for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) {
4091            var rawLocale = allRawLocales_1[_i];
4092            rawLocaleMap[rawLocale.code] = rawLocale;
4093        }
4094        return {
4095            map: rawLocaleMap,
4096            defaultCode: defaultCode,
4097        };
4098    }
4099    function buildLocale(inputSingular, available) {
4100        if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
4101            return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
4102        }
4103        return queryLocale(inputSingular, available);
4104    }
4105    function queryLocale(codeArg, available) {
4106        var codes = [].concat(codeArg || []); // will convert to array
4107        var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
4108        return parseLocale(codeArg, codes, raw);
4109    }
4110    function queryRawLocale(codes, available) {
4111        for (var i = 0; i < codes.length; i += 1) {
4112            var parts = codes[i].toLocaleLowerCase().split('-');
4113            for (var j = parts.length; j > 0; j -= 1) {
4114                var simpleId = parts.slice(0, j).join('-');
4115                if (available[simpleId]) {
4116                    return available[simpleId];
4117                }
4118            }
4119        }
4120        return null;
4121    }
4122    function parseLocale(codeArg, codes, raw) {
4123        var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']);
4124        delete merged.code; // don't want this part of the options
4125        var week = merged.week;
4126        delete merged.week;
4127        return {
4128            codeArg: codeArg,
4129            codes: codes,
4130            week: week,
4131            simpleNumberFormat: new Intl.NumberFormat(codeArg),
4132            options: merged,
4133        };
4134    }
4135
4136    function formatDate(dateInput, options) {
4137        if (options === void 0) { options = {}; }
4138        var dateEnv = buildDateEnv(options);
4139        var formatter = createFormatter(options);
4140        var dateMeta = dateEnv.createMarkerMeta(dateInput);
4141        if (!dateMeta) { // TODO: warning?
4142            return '';
4143        }
4144        return dateEnv.format(dateMeta.marker, formatter, {
4145            forcedTzo: dateMeta.forcedTzo,
4146        });
4147    }
4148    function formatRange(startInput, endInput, options) {
4149        var dateEnv = buildDateEnv(typeof options === 'object' && options ? options : {}); // pass in if non-null object
4150        var formatter = createFormatter(options);
4151        var startMeta = dateEnv.createMarkerMeta(startInput);
4152        var endMeta = dateEnv.createMarkerMeta(endInput);
4153        if (!startMeta || !endMeta) { // TODO: warning?
4154            return '';
4155        }
4156        return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
4157            forcedStartTzo: startMeta.forcedTzo,
4158            forcedEndTzo: endMeta.forcedTzo,
4159            isEndExclusive: options.isEndExclusive,
4160            defaultSeparator: BASE_OPTION_DEFAULTS.defaultRangeSeparator,
4161        });
4162    }
4163    // TODO: more DRY and optimized
4164    function buildDateEnv(settings) {
4165        var locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
4166        return new DateEnv(__assign(__assign({ timeZone: BASE_OPTION_DEFAULTS.timeZone, calendarSy
4166stem: 'gregory' }, settings), { locale: locale }));
4167    }
4168
4169    var DEF_DEFAULTS = {
4170        startTime: '09:00',
4171        endTime: '17:00',
4172        daysOfWeek: [1, 2, 3, 4, 5],
4173        display: 'inverse-background',
4174        classNames: 'fc-non-business',
4175        groupId: '_businessHours',
4176    };
4177    /*
4178    TODO: pass around as EventDefHash!!!
4179    */
4180    function parseBusinessHours(input, context) {
4181        return parseEvents(refineInputs(input), null, context);
4182    }
4183    function refineInputs(input) {
4184        var rawDefs;
4185        if (input === true) {
4186            rawDefs = [{}]; // will get DEF_DEFAULTS verbatim
4187        }
4188        else if (Array.isArray(input)) {
4189            // if specifying an array, every sub-definition NEEDS a day-of-week
4190            rawDefs = input.filter(function (rawDef) { return rawDef.daysOfWeek; });
4191        }
4192        else if (typeof input === 'object' && input) { // non-null object
4193            rawDefs = [input];
4194        }
4195        else { // is probably false
4196            rawDefs = [];
4197        }
4198        rawDefs = rawDefs.map(function (rawDef) { return (__assign(__assign({}, DEF_DEFAULTS), rawDef)); });
4199        return rawDefs;
4200    }
4201
4202    function pointInsideRect(point, rect) {
4203        return point.left >= rect.left &&
4204            point.left < rect.right &&
4205            point.top >= rect.top &&
4206            point.top < rect.bottom;
4207    }
4208    // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
4209    function intersectRects(rect1, rect2) {
4210        var res = {
4211            left: Math.max(rect1.left, rect2.left),
4212            right: Math.min(rect1.right, rect2.right),
4213            top: Math.max(rect1.top, rect2.top),
4214            bottom: Math.min(rect1.bottom, rect2.bottom),
4215        };
4216        if (res.left < res.right && res.top < res.bottom) {
4217            return res;
4218        }
4219        return false;
4220    }
4221    function translateRect(rect, deltaX, deltaY) {
4222        return {
4223            left: rect.left + deltaX,
4224            right: rect.right + deltaX,
4225            top: rect.top + deltaY,
4226            bottom: rect.bottom + deltaY,
4227        };
4228    }
4229    // Returns a new point that will have been moved to reside within the given rectangle
4230    function constrainPoint(point, rect) {
4231        return {
4232            left: Math.min(Math.max(point.left, rect.left), rect.right),
4233            top: Math.min(Math.max(point.top, rect.top), rect.bottom),
4234        };
4235    }
4236    // Returns a point that is the center of the given rectangle
4237    function getRectCenter(rect) {
4238        return {
4239            left: (rect.left + rect.right) / 2,
4240            top: (rect.top + rect.bottom) / 2,
4241        };
4242    }
4243    // Subtracts point2's coordinates from point1's coordinates, returning a delta
4244    function diffPoints(point1, point2) {
4245        return {
4246            left: point1.left - point2.left,
4247            top: point1.top - point2.top,
4248        };
4249    }
4250
4251    var canVGrowWithinCell;
4252    function getCanVGrowWithinCell() {
4253        if (canVGrowWithinCell == null) {
4254            canVGrowWithinCell = computeCanVGrowWithinCell();
4255        }
4256        return canVGrowWithinCell;
4257    }
4258    function computeCanVGrowWithinCell() {
4259        // for SSR, because this function is call immediately at top-level
4260        // TODO: just make this logic execute top-level, immediately, instead of doing lazily
4261        if (typeof document === 'undefined') {
4262            return true;
4263        }
4264        var el = document.createElement('div');
4265        el.style.position = 'absolute';
4266        el.style.top = '0px';
4267        el.style.left = '0px';
4268        el.innerHTML = '<table><tr><td><div></div></td></tr></table>';
4269        el.querySelector('table').style.height = '100px';
4270        el.querySelector('div').style.height = '100%';
4271        document.body.appendChild(el);
4272        var div = el.querySelector('div');
4273        var possible = div.offsetHeight > 0;
4274        document.body.removeChild(el);
4275        return possible;
4276    }
4277
4278    var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
4279    var Splitter = /** @class */ (function () {
4280        function Splitter() {
4281            this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
4282            this.splitDateSelection = memoize(this._splitDateSpan);
4283            this.splitEventStore = memoize(this._splitEventStore);
4284            this.splitIndividualUi = memoize(this._splitIndividualUi);
4285            this.splitEventDrag = memoize(this._splitInteraction);
4286            this.splitEventResize = memoize(this._splitInteraction);
4287            this.eventUiBuilders = {}; // TODO: typescript protection
4288        }
4289        Splitter.prototype.splitProps = function (props) {
4290            var _this = this;
4291            var keyInfos = this.getKeyInfo(props);
4292            var defKeys = this.getKeysForEventDefs(props.eventStore);
4293            var dateSelections = this.splitDateSelection(props.dateSelection);
4294            var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
4295            var eventStores = this.splitEventStore(props.eventStore, defKeys);
4296            var eventDrags = this.splitEventDrag(props.eventDrag);
4297            var eventResizes = this.splitEventResize(props.eventResize);
4298            var splitProps = {};
4299            this.eventUiBuilders = mapHash(keyInfos, function (info, key) { return _this.eventUiBuilders[key] || memoize(buildEventUiForKey); });
4300            for (var key in keyInfos) {
4301                var keyInfo = keyInfos[key];
4302                var eventStore = eventStores[key] || EMPTY_EVENT_STORE;
4303                var buildEventUi = this.eventUiBuilders[key];
4304                splitProps[key] = {
4305                    businessHours: keyInfo.businessHours || props.businessHours,
4306                    dateSelection: dateSelections[key] || null,
4307                    eventStore: eventStore,
4308                    eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
4309                    eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
4310                    eventDrag: eventDrags[key] || null,
4311                    eventResize: eventResizes[key] || null,
4312                };
4313            }
4314            return splitProps;
4315        };
4316        Splitter.prototype._splitDateSpan = function (dateSpan) {
4317            var dateSpans = {};
4318            if (dateSpan) {
4319                var keys = this.getKeysForDateSpan(dateSpan);
4320                for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
4321                    var key = keys_1[_i];
4322                    dateSpans[key] = dateSpan;
4323                }
4324            }
4325            return dateSpans;
4326        };
4327        Splitter.prototype._getKeysForEventDefs = function (eventStore) {
4328            var _this = this;
4329            return mapHash(eventStore.defs, function (eventDef) { return _this.getKeysForEventDef(eventDef); });
4330        };
4331        Splitter.prototype._splitEventStore = function (eventStore, defKeys) {
4332            var defs = eventStore.defs, instances = eventStore.instances;
4333            var splitStores = {};
4334            for (var defId in defs) {
4335                for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
4336                    var key = _a[_i];
4337                    if (!splitStores[key]) {
4338                        splitStores[key] = createEmptyEventStore();
4339                    }
4340                    splitStores[key].defs[defId] = defs[defId];
4341                }
4342            }
4343            for (var instanceId in instances) {
4344                var instance = instances[instanceId];
4345                for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) {
4346                    var key = _c[_b];
4347                    if (splitStores[key]) { // must have already been created
4348                        splitStores[key].instances[instanceId] = instance;
4349                    }
4350                }
4351            }
4352            return splitStores;
4353        };
4354        Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) {
4355            var splitHashes = {};
4356            for (var defId in eventUiBases) {
4357                if (defId) { // not the '' key
4358                    for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
4359                        var key = _a[_i];
4360                        if (!splitHashes[key]) {
4361                            splitHashes[key] = {};
4362                        }
4363                        splitHashes[key][defId] = eventUiBases[defId];
4364                    }
4365                }
4366            }
4367            return splitHashes;
4368        };
4369        Splitter.prototype._splitInteraction = function (interaction) {
4370            var splitStates = {};
4371            if (interaction) {
4372                var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeys
4372ForEventDefs(interaction.affectedEvents));
4373                // can't rely on defKeys because event data is mutated
4374                var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
4375                var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
4376                var populate = function (key) {
4377                    if (!splitStates[key]) {
4378                        splitStates[key] = {
4379                            affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE,
4380                            mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE,
4381                            isEvent: interaction.isEvent,
4382                        };
4383                    }
4384                };
4385                for (var key in affectedStores_1) {
4386                    populate(key);
4387                }
4388                for (var key in mutatedStores_1) {
4389                    populate(key);
4390                }
4391            }
4392            return splitStates;
4393        };
4394        return Splitter;
4395    }());
4396    function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
4397        var baseParts = [];
4398        if (allUi) {
4399            baseParts.push(allUi);
4400        }
4401        if (eventUiForKey) {
4402            baseParts.push(eventUiForKey);
4403        }
4404        var stuff = {
4405            '': combineEventUis(baseParts),
4406        };
4407        if (individualUi) {
4408            __assign(stuff, individualUi);
4409        }
4410        return stuff;
4411    }
4412
4413    function getDateMeta(date, todayRange, nowDate, dateProfile) {
4414        return {
4415            dow: date.getUTCDay(),
4416            isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)),
4417            isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)),
4418            isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)),
4419            isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false),
4420            isFuture: Boolean(nowDate ? (date > nowDate) : todayRange ? (date >= todayRange.end) : false),
4421        };
4422    }
4423    function getDayClassNames(meta, theme) {
4424        var classNames = [
4425            'fc-day',
4426            "fc-day-" + DAY_IDS[meta.dow],
4427        ];
4428        if (meta.isDisabled) {
4429            classNames.push('fc-day-disabled');
4430        }
4431        else {
4432            if (meta.isToday) {
4433                classNames.push('fc-day-today');
4434                classNames.push(theme.getClass('today'));
4435            }
4436            if (meta.isPast) {
4437                classNames.push('fc-day-past');
4438            }
4439            if (meta.isFuture) {
4440                classNames.push('fc-day-future');
4441            }
4442            if (meta.isOther) {
4443                classNames.push('fc-day-other');
4444            }
4445        }
4446        return classNames;
4447    }
4448    function getSlotClassNames(meta, theme) {
4449        var classNames = [
4450            'fc-slot',
4451            "fc-slot-" + DAY_IDS[meta.dow],
4452        ];
4453        if (meta.isDisabled) {
4454            classNames.push('fc-slot-disabled');
4455        }
4456        else {
4457            if (meta.isToday) {
4458                classNames.push('fc-slot-today');
4459                classNames.push(theme.getClass('today'));
4460            }
4461            if (meta.isPast) {
4462                classNames.push('fc-slot-past');
4463            }
4464            if (meta.isFuture) {
4465                classNames.push('fc-slot-future');
4466            }
4467        }
4468        return classNames;
4469    }
4470
4471    function buildNavLinkData(date, type) {
4472        if (type === void 0) { type = 'day'; }
4473        return JSON.stringify({
4474            date: formatDayString(date),
4475            type: type,
4476        });
4477    }
4478
4479    var _isRtlScrollbarOnLeft = null;
4480    function getIsRtlScrollbarOnLeft() {
4481        if (_isRtlScrollbarOnLeft === null) {
4482            _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();
4483        }
4484        return _isRtlScrollbarOnLeft;
4485    }
4486    function computeIsRtlScrollbarOnLeft() {
4487        var outerEl = document.createElement('div');
4488        applyStyle(outerEl, {
4489            position: 'absolute',
4490            top: -1000,
4491            left: 0,
4492            border: 0,
4493            padding: 0,
4494            overflow: 'scroll',
4495            direction: 'rtl',
4496        });
4497        outerEl.innerHTML = '<div></div>';
4498        document.body.appendChild(outerEl);
4499        var innerEl = outerEl.firstChild;
4500        var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;
4501        removeElement(outerEl);
4502        return res;
4503    }
4504
4505    var _scrollbarWidths;
4506    function getScrollbarWidths() {
4507        if (!_scrollbarWidths) {
4508            _scrollbarWidths = computeScrollbarWidths();
4509        }
4510        return _scrollbarWidths;
4511    }
4512    function computeScrollbarWidths() {
4513        var el = document.createElement('div');
4514        el.style.overflow = 'scroll';
4515        el.style.position = 'absolute';
4516        el.style.top = '-9999px';
4517        el.style.left = '-9999px';
4518        document.body.appendChild(el);
4519        var res = computeScrollbarWidthsForEl(el);
4520        document.body.removeChild(el);
4521        return res;
4522    }
4523    // WARNING: will include border
4524    function computeScrollbarWidthsForEl(el) {
4525        return {
4526            x: el.offsetHeight - el.clientHeight,
4527            y: el.offsetWidth - el.clientWidth,
4528        };
4529    }
4530
4531    function computeEdges(el, getPadding) {
4532        if (getPadding === void 0) { getPadding = false; }
4533        var computedStyle = window.getComputedStyle(el);
4534        var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
4535        var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
4536        var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
4537        var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
4538        var badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border!
4539        var scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight;
4540        var scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom;
4541        var res = {
4542            borderLeft: borderLeft,
4543            borderRight: borderRight,
4544            borderTop: borderTop,
4545            borderBottom: borderBottom,
4546            scrollbarBottom: scrollbarBottom,
4547            scrollbarLeft: 0,
4548            scrollbarRight: 0,
4549        };
4550        if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side?
4551            res.scrollbarLeft = scrollbarLeftRight;
4552        }
4553        else {
4554            res.scrollbarRight = scrollbarLeftRight;
4555        }
4556        if (getPadding) {
4557            res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
4558            res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
4559            res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
4560            res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
4561        }
4562        return res;
4563    }
4564    function computeInnerRect(el, goWithinPadding, doFromWindowViewport) {
4565        if (goWithinPadding === void 0) { goWithinPadding = false; }
4566        var outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el);
4567        var edges = computeEdges(el, goWithinPadding);
4568        var res = {
4569            left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
4570            right: outerRect.right - edges.borderRight - edges.scrollbarRight,
4571            top: outerRect.top + edges.borderTop,
4572            bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom,
4573        };
4574        if (goWithinPadding) {
4575            res.left += edges.paddingLeft;
4576            res.right -= edges.paddingRight;
4577            res.top += edges.paddingTop;
4578            res.bottom -= edges.paddingBottom;
4579        }
4580        return res;
4581    }
4582    function computeRect(el) {
4583        var rect = el.getBoundingClientRect();
4584        return {
4585            left: rect.left + window.pageXOffset,
4586            top: rect.top + window.pageYOffset,
4587            right: rect.right + window.pageXOffset,
4588            bottom: rect.bottom + window.pageYOffset,
4589        };
4590    }
4591    function computeHeightAndMargins(el) {
4592        return el.getBoundingClientRect().height + computeVMargins(el);
4593    }
4594    function computeVMargins(el) {
4595        var computed = window.getComputedStyle(el);
4596        return parseInt(computed.marginTop, 10) +
4597            parseInt(computed.marginBottom, 10);
4598    }
4599    // does not return window
4600    function getClippingParents(el) {
4601        var parents = [];
4602        while (el instanceof HTMLElement) { // will stop when gets to document or null
4603            var computedStyle = window.getComputedStyle(el);
4604            if (computedStyle.position === 'fixed') {
4605                break;
4606            }
4607            if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
4608                parents.push(el);
4609            }
4610            el = el.parentNode;
4611        }
4612        return parents;
4613    }
4614
4615    // given a function that resolves a result asynchronously.
4616    // the function can either call passed-in success and failure callbacks,
4617    // or it can return a promise.
4618    // if you need to pass additional params to func, bind them first.
4619    function unpromisify(func, success, failure) {
4620        // guard against success/failure callbacks being called more than once
4621        // and guard against a promise AND callback being used together.
4622        var isResolved = false;
4623        var wrappedSuccess = function () {
4624            if (!isResolved) {
4625                isResolved = true;
4626                success.apply(this, arguments); // eslint-disable-line prefer-rest-params
4627            }
4628        };
4629        var wrappedFailure = function () {
4630            if (!isResolved) {
4631                isResolved = true;
4632                if (failure) {
4633                    failure.apply(this, arguments); // eslint-disable-line prefer-rest-params
4634                }
4635            }
4636        };
4637        var res = func(wrappedSuccess, wrappedFailure);
4638        if (res && typeof res.then === 'function') {
4639            res.then(wrappedSuccess, wrappedFailure);
4640        }
4641    }
4642
4643    var Emitter = /** @class */ (function () {
4644        function Emitter() {
4645            this.handlers = {};
4646            this.thisContext = null;
4647        }
4648        Emitter.prototype.setThisContext = function (thisContext) {
4649            this.thisContext = thisContext;
4650        };
4651        Emitter.prototype.setOptions = function (options) {
4652            this.options = options;
4653        };
4654        Emitter.prototype.on = function (type, handler) {
4655            addToHash(this.handlers, type, handler);
4656        };
4657        Emitter.prototype.off = function (type, handler) {
4658            removeFromHash(this.handlers, type, handler);
4659        };
4660        Emitter.prototype.trigger = function (type) {
4661            var args = [];
4662            for (var _i = 1; _i < arguments.length; _i++) {
4663                args[_i - 1] = arguments[_i];
4664            }
4665            var attachedHandlers = this.handlers[type] || [];
4666            var optionHandler = this.options && this.options[type];
4667            var handlers = [].concat(optionHandler || [], attachedHandlers);
4668            for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) {
4669                var handler = handlers_1[_a];
4670                handler.apply(this.thisContext, args);
4671            }
4672        };
4673        Emitter.prototype.hasHandlers = function (type) {
4674            return (this.handlers[type] && this.handlers[type].length) ||
4675                (this.options && this.options[type]);
4676        };
4677        return Emitter;
4678    }());
4679    function addToHash(hash, type, handler) {
4680        (hash[type] || (hash[type] = []))
4681            .push(handler);
4682    }
4683    function removeFromHash(hash, type, handler) {
4684        if (handler) {
4685            if (hash[type]) {
4686                hash[type] = hash[type].filter(function (func) { return func !== handler; });
4687            }
4688        }
4689        else {
4690            delete hash[type]; // remove all handler funcs for this type
4691        }
4692    }
4693
4694    /*
4695    Records offset information for a set of elements, relative to an origin element.
4696    Can record the left/right OR the top/bottom OR both.
4697    Provides methods for querying the cache by position.
4698    */
4699    var PositionCache = /** @class */ (function () {
4700        function PositionCache(originEl, els, isHorizontal, isVertical) {
4701            this.els = els;
4702            var originClientRect = this.originClientRect = originEl.getBoundingClientRect(); // relative to viewport top-left
4703            if (isHorizontal) {
4704                this.buildElHorizontals(originClientRect.left);
4705            }
4706            if (isVertical) {
4707                this.buildElVerticals(originClientRect.top);
4708            }
4709        }
4710        // Populates the left/right internal coordinate arrays
4711        PositionCache.prototype.buildElHorizontals = function (originClientLeft) {
4712            var lefts = [];
4713            var rights = [];
4714            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
4715                var el = _a[_i];
4716                var rect = el.getBoundingClientRect();
4717                lefts.push(rect.left - originClientLeft);
4718                rights.push(rect.right - originClientLeft);
4719            }
4720            this.lefts = lefts;
4721            this.rights = rights;
4722        };
4723        // Populates the top/bottom internal coordinate arrays
4724        PositionCache.prototype.buildElVerticals = function (originClientTop) {
4725            var tops = [];
4726            var bottoms = [];
4727            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
4728                var el = _a[_i];
4729                var rect = el.getBoundingClientRect();
4730                tops.push(rect.top - originClientTop);
4731                bottoms.push(rect.bottom - originClientTop);
4732            }
4733            this.tops = tops;
4734            this.bottoms = bottoms;
4735        };
4736        // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
4737        // If no intersection is made, returns undefined.
4738        PositionCache.prototype.leftToIndex = function (leftPosition) {
4739            var _a = this, lefts = _a.lefts, rights = _a.rights;
4740            var len = lefts.length;
4741            var i;
4742            for (i = 0; i < len; i += 1) {
4743                if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
4744                    return i;
4745                }
4746            }
4747            return undefined; // TODO: better
4748        };
4749        // Given a top offset (from document top), returns the index of the el that it vertically intersects.
4750        // If no intersection is made, returns undefined.
4751        PositionCache.prototype.topToIndex = function (topPosition) {
4752            var _a = this, tops = _a.tops, bottoms = _a.bottoms;
4753            var len = tops.length;
4754            var i;
4755            for (i = 0; i < len; i += 1) {
4756                if (topPosition >= tops[i] && topPosition < bottoms[i]) {
4757                    return i;
4758                }
4759            }
4760            return undefined; // TODO: better
4761        };
4762        // Gets the width of the element at the given index
4763        PositionCache.prototype.getWidth = function (leftIndex) {
4764            return this.rights[leftIndex] - this.lefts[leftIndex];
4765        };
4766        // Gets the height of the element at the given index
4767        PositionCache.prototype.getHeight = function (topIndex) {
4768            return this.bottoms[topIndex] - this.tops[topIndex];
4769        };
4770        return PositionCache;
4771    }());
4772
4773    /* eslint max-classes-per-file: "off" */
4774    /*
4775    An object for getting/setting scroll-related information for an element.
4776    Internally, this is done very differently for window versus DOM element,
4777    so this object serves as a common interface.
4778    */
4779    var ScrollController = /** @class */ (function () {
4780        function ScrollController() {
4781        }
4782        ScrollController.prototype.getMaxScrollTop = function () {
4783            return this.getScrollHeight() - this.getClientHeight();
4784        };
4785        ScrollController.prototype.getMaxScrollLeft = function () {
4786            return this.getScrollWidth() - this.getClientWidth();
4787        };
4788        ScrollController.prototype.canScrollVertically = function () {
4789            return this.getMaxScrollTop() > 0;
4790        };
4791        ScrollController.prototype.canScrollHorizontally = function () {
4792            return this.getMaxScrollLeft() > 0;
4793        };
4794        ScrollController.prototype.canScrollUp = function () {
4795            return this.getScrollTop() > 0;
4796        };
4797        ScrollController.prototype.canScrollDown = function () {
4798            return this.getScrollTop() < this.getMaxScrollTop();
4799        };
4800        ScrollController.prototype.canScrollLeft = function () {
4801            return this.getScrollLeft() > 0;
4802        };
4803        ScrollController.prototype.canScrollRight = function () {
4804            return this.getScrollLeft() < this.getMaxScrollLeft();
4805        };
4806        return ScrollController;
4807    }());
4808    var ElementScrollController = /** @class */ (function (_super) {
4809        __extends(ElementScrollController, _super);
4810        function ElementScrollController(el) {
4811            var _this = _super.call(this) || this;
4812            _this.el = el;
4813            return _this;
4814        }
4815        ElementScrollController.prototype.getScrollTop = function () {
4816            return this.el.scrollTop;
4817        };
4818        ElementScrollController.prototype.getScrollLeft = function () {
4819            return this.el.scrollLeft;
4820        };
4821        ElementScrollController.prototype.setScrollTop = function (top) {
4822            this.el.scrollTop = top;
4823        };
4824        ElementScrollController.prototype.setScrollLeft = function (left) {
4825            this.el.scrollLeft = left;
4826        };
4827        ElementScrollController.prototype.getScrollWidth = function () {
4828            return this.el.scrollWidth;
4829        };
4830        ElementScrollController.prototype.getScrollHeight = function () {
4831            return this.el.scrollHeight;
4832        };
4833        ElementScrollController.prototype.getClientHeight = function () {
4834            return this.el.clientHeight;
4835        };
4836        ElementScrollController.prototype.getClientWidth = function () {
4837            return this.el.clientWidth;
4838        };
4839        return ElementScrollController;
4840    }(ScrollController));
4841    var WindowScrollController = /** @class */ (function (_super) {
4842        __extends(WindowScrollController, _super);
4843        function WindowScrollController() {
4844            return _super !== null && _super.apply(this, arguments) || this;
4845        }
4846        WindowScrollController.prototype.getScrollTop = function () {
4847            return window.pageYOffset;
4848        };
4849        WindowScrollController.prototype.getScrollLeft = function () {
4850            return window.pageXOffset;
4851        };
4852        WindowScrollController.prototype.setScrollTop = function (n) {
4853            window.scroll(window.pageXOffset, n);
4854        };
4855        WindowScrollController.prototype.setScrollLeft = function (n) {
4856            window.scroll(n, window.pageYOffset);
4857        };
4858        WindowScrollController.prototype.getScrollWidth = function () {
4859            return document.documentElement.scrollWidth;
4860        };
4861        WindowScrollController.prototype.getScrollHeight = function () {
4862            return document.documentElement.scrollHeight;
4863        };
4864        WindowScrollController.prototype.getClientHeight = function () {
4865            return document.documentElement.clientHeight;
4866        };
4867        WindowScrollController.prototype.getClientWidth = function () {
4868            return document.documentElement.clientWidth;
4869        };
4870        return WindowScrollController;
4871    }(ScrollController));
4872
4873    var Theme = /** @class */ (function () {
4874        function Theme(calendarOptions) {
4875            if (this.iconOverrideOption) {
4876                this.setIconOverride(calendarOptions[this.iconOverrideOption]);
4877            }
4878        }
4879        Theme.prototype.setIconOverride = function (iconOverrideHash) {
4880            var iconClassesCopy;
4881            var buttonName;
4882            if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object
4883                iconClassesCopy = __assign({}, this.iconClasses);
4884                for (buttonName in iconOverrideHash) {
4885                    iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
4886                }
4887                this.iconClasses = iconClassesCopy;
4888            }
4889            else if (iconOverrideHash === false) {
4890                this.iconClasses = {};
4891            }
4892        };
4893        Theme.prototype.applyIconOverridePrefix = function (className) {
4894            var prefix = this.iconOverridePrefix;
4895            if (prefix && className.indexOf(prefix) !== 0) { // if not already present
4896                className = prefix + className;
4897            }
4898            return className;
4899        };
4900        Theme.prototype.getClass = function (key) {
4901            return this.classes[key] || '';
4902        };
4903        Theme.prototype.getIconClass = function (buttonName, isRtl) {
4904            var className;
4905            if (isRtl && this.rtlIconClasses) {
4906                className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName];
4907            }
4908            else {
4909                className = this.iconClasses[buttonName];
4910            }
4911            if (className) {
4912                return this.baseIconClass + " " + className;
4913            }
4914            return '';
4915        };
4916        Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
4917            var className;
4918            if (this.iconOverrideCustomButtonOption) {
4919                className = customButtonProps[this.iconOverrideCustomButtonOption];
4920                if (className) {
4921                    return this.baseIconClass + " " + this.applyIconOverridePrefix(className);
4922                }
4923            }
4924            return '';
4925        };
4926        return Theme;
4927    }());
4928    Theme.prototype.classes = {};
4929    Theme.prototype.iconClasses = {};
4930    Theme.prototype.baseIconClass = '';
4931    Theme.prototype.iconOverridePrefix = '';
4932
4933    /// <reference types="@fullcalendar/core-preact" />
4934    if (typeof FullCalendarVDom === 'undefined') {
4935        throw new Error('Please import the top-level fullcalendar lib before attempting to import a plugin.');
4936    }
4937    var Component = FullCalendarVDom.Component;
4938    var createElement = FullCalendarVDom.createElement;
4939    var render = FullCalendarVDom.render;
4940    var createRef = FullCalendarVDom.createRef;
4941    var Fragment = FullCalendarVDom.Fragment;
4942    var createContext$1 = FullCalendarVDom.createContext;
4943    var flushToDom$1 = FullCalendarVDom.flushToDom;
4944    var unmountComponentAtNode$1 = FullCalendarVDom.unmountComponentAtNode;
4945
4946    var ScrollResponder = /** @class */ (function () {
4947        function ScrollResponder(execFunc, emitter, scrollTime) {
4948            var _this = this;
4949            this.execFunc = execFunc;
4950            this.emitter = emitter;
4951            this.scrollTime = scrollTime;
4952            this.handleScrollRequest = function (request) {
4953                _this.queuedRequest = __assign({}, _this.queuedRequest || {}, request);
4954                _this.drain();
4955            };
4956            emitter.on('_scrollRequest', this.handleScrollRequest);
4957            this.fireInitialScroll();
4958        }
4959        ScrollResponder.prototype.detach = function () {
4960            this.emitter.off('_scrollRequest', this.handleScrollRequest);
4961        };
4962        ScrollResponder.prototype.update = function (isDatesNew) {
4963            if (isDatesNew) {
4964                this.fireInitialScroll(); // will drain
4965            }
4966            else {
4967                this.drain();
4968            }
4969        };
4970        ScrollResponder.prototype.fireInitialScroll = function () {
4971            this.handleScrollRequest({
4972                time: this.scrollTime,
4973            });
4974        };
4975        ScrollResponder.prototype.drain = function () {
4976            if (this.queuedRequest && this.execFunc(this.queuedRequest)) {
4977                this.queuedRequest = null;
4978            }
4979        };
4980        return ScrollResponder;
4981    }());
4982
4983    var ViewContextType = createContext$1({}); // for Components
4984    function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) {
4985        return {
4986            dateEnv: dateEnv,
4987            options: viewOptions,
4988            pluginHooks: pluginHooks,
4989            emitter: emitter,
4990            dispatch: dispatch,
4991            getCurrentData: getCurrentData,
4992            calendarApi: calendarApi,
4993            viewSpec: viewSpec,
4994            viewApi: viewApi,
4995            dateProfileGenerator: dateProfileGenerator,
4996            theme: theme,
4997            isRtl: viewOptions.direction === 'rtl',
4998            addResizeHandler: function (handler) {
4999                emitter.on('_resize', handler);
5000            },
5001            removeResizeHandler: function (handler) {
5002                emitter.off('_resize', handler);
5003            },
5004            createScrollResponder: function (execFunc) {
5005                return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime));
5006            },
5007            registerInteractiveComponent: registerInteractiveComponent,
5008            unregisterInteractiveComponent: unregisterInteractiveComponent,
5009        };
5010    }
5011
5012    /* eslint max-classes-per-file: off */
5013    var PureComponent = /** @class */ (function (_super) {
5014        __extends(PureComponent, _super);
5015        function PureComponent() {
5016            return _super !== null && _super.apply(this, arguments) || this;
5017        }
5018        PureComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) {
5019            if (this.debug) {
5020                // eslint-disable-next-line no-console
5021                console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state));
5022            }
5023            return !compareObjs(this.props, nextProps, this.propEquality) ||
5024                !compareObjs(this.state, nextState, this.stateEquality);
5025        };
5026        PureComponent.addPropsEquality = addPropsEquality;
5027        PureComponent.addStateEquality = addStateEquality;
5028        PureComponent.contextType = ViewContextType;
5029        return PureComponent;
5030    }(Component));
5031    PureComponent.prototype.propEquality = {};
5032    PureComponent.prototype.stateEquality = {};
5033    var BaseComponent = /** @class */ (function (_super) {
5034        __extends(BaseComponent, _super);
5035        function BaseComponent() {
5036            return _super !== null && _super.apply(this, arguments) || this;
5037        }
5038        BaseComponent.contextType = ViewContextType;
5039        return BaseComponent;
5040    }(PureComponent));
5041    function addPropsEquality(propEquality) {
5042        var hash = Object.create(this.prototype.propEquality);
5043        __assign(hash, propEquality);
5044        this.prototype.propEquality = hash;
5045    }
5046    function addStateEquality(stateEquality) {
5047        var hash = Object.create(this.prototype.stateEquality);
5048        __assign(hash, stateEquality);
5049        this.prototype.stateEquality = hash;
5050    }
5051    // use other one
5052    function setRef(ref, current) {
5053        if (typeof ref === 'function') {
5054            ref(current);
5055        }
5056        else if (ref) {
5057            // see https://github.com/facebook/react/issues/13029
5058            ref.current = current;
5059        }
5060    }
5061
5062    function reduceEventStore(eventStore, action, eventSources, dateProfile, context) {
5063        switch (action.type) {
5064            case 'RECEIVE_EVENTS': // raw
5065                return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context);
5066            case 'ADD_EVENTS': // already parsed, but not expanded
5067                return addEvent(eventStore, action.eventStore, // new ones
5068                dateProfile ? dateProfile.activeRange : null, context);
5069            case 'RESET_EVENTS':
5070                return action.eventStore;
5071            case 'MERGE_EVENTS': // already parsed and expanded
5072                return mergeEventStores(eventStore, action.eventStore);
5073            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
5074            case 'NEXT':
5075            case 'CHANGE_DATE':
5076            case 'CHANGE_VIEW_TYPE':
5077                if (dateProfile) {
5078                    return expandRecurring(eventStore, dateProfile.activeRange, context);
5079                }
5080                return eventStore;
5081            case 'REMOVE_EVENTS':
5082                return excludeSubEventStore(eventStore, action.eventStore);
5083            case 'REMOVE_EVENT_SOURCE':
5084                return excludeEventsBySourceId(eventStore, action.sourceId);
5085            case 'REMOVE_ALL_EVENT_SOURCES':
5086                return filterEventStoreDefs(eventStore, function (eventDef) { return (!eventDef.sourceId // only keep events with no source id
5087                ); });
5088            case 'REMOVE_ALL_EVENTS':
5089                return createEmptyEventStore();
5090            default:
5091                return eventStore;
5092        }
5093    }
5094    function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) {
5095        if (eventSource && // not already removed
5096            fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
5097        ) {
5098            var subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context);
5099            if (fetchRange) {
5100                subset = expandRecurring(subset, fetchRange, context);
5101            }
5102            return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
5103        }
5104        return eventStore;
5105    }
5106    function transformRawEvents(rawEvents, eventSource, context) {
5107        var calEachTransform = context.options.eventDataTransform;
5108        var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
5109        if (sourceEachTransform) {
5110            rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
5111        }
5112        if (calEachTransform) {
5113            rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
5114        }
5115        return rawEvents;
5116    }
5117    function transformEachRawEvent(rawEvents, func) {
5118        var refinedEvents;
5119        if (!func) {
5120            refinedEvents = rawEvents;
5121        }
5122        else {
5123            refinedEvents = [];
5124            for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
5125                var rawEvent = rawEvents_1[_i];
5126                var refinedEvent = func(rawEvent);
5127                if (refinedEvent) {
5128                    refinedEvents.push(refinedEvent);
5129                }
5130                else if (refinedEvent == null) {
5131                    refinedEvents.push(rawEvent);
5132                } // if a different falsy value, do nothing
5133            }
5134        }
5135        return refinedEvents;
5136    }
5137    function addEvent(eventStore, subset, expandRange, context) {
5138        if (expandRange) {
5139            subset = expandRecurring(subset, expandRange, context);
5140        }
5141        return mergeEventStores(eventStore, subset);
5142    }
5143    function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) {
5144        var defs = eventStore.defs;
5145        var instances = mapHash(eventStore.instances, function (instance) {
5146            var def = defs[instance.defId];
5147            if (def.allDay || def.recurringDef) {
5148                return instance; // isn't dependent on timezone
5149            }
5150            return __assign(__assign({}, instance), { range: {
5151                    start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
5152                    end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)),
5153                }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
5154        });
5155        return { defs: defs, instances: instances };
5156    }
5157    function excludeEventsBySourceId(eventStore, sourceId) {
5158        return filterEventStoreDefs(eventStore, function (eventDef) { return eventDef.sourceId !== sourceId; });
5159    }
5160    // QUESTION: why not just return instances? do a general object-property-exclusion util
5161    function excludeInstances(eventStore, removals) {
5162        return {
5163            defs: eventStore.defs,
5164            instances: filterHash(eventStore.instances, function (instance) { return !removals[instance.instanceId]; }),
5165        };
5166    }
5167
5168    // high-level segmenting-aware tester functions
5169    // ------------------------------------------------------------------------------------------------------------------------
5170    function isInteractionValid(interaction, context) {
5171        return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions
5172    }
5173    function isDateSelectionValid(dateSelection, context) {
5174        return isNewPropsValid({ dateSelection: dateSelection }, context);
5175    }
5176    function isNewPropsValid(newProps, context) {
5177        var calendarState = context.getCurrentData();
5178        var props = __assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
5179        return (context.pluginHooks.isPropsValid || isPropsValid)(props, context);
5180    }
5181    function isPropsValid(state, context, dateSpanMeta, filterConfig) {
5182        if (dateSpanMeta === void 0) { dateSpanMeta = {}; }
5183        if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) {
5184            return false;
5185        }
5186        if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) {
5187            return false;
5188        }
5189        return true;
5190    }
5191    // Moving Event Validation
5192    // ------------------------------------------------------------------------------------------------------------------------
5193    function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) {
5194        var currentState = context.getCurrentData();
5195        var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
5196        var subjectEventStore = interaction.mutatedEvents;
5197        var subjectDefs = subjectEventStore.defs;
5198        var subjectInstances = subjectEventStore.instances;
5199        var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
5200            state.eventUiBases :
5201            { '': currentState.selectionConfig });
5202        if (filterConfig) {
5203            subjectConfigs = mapHash(subjectConfigs, filterConfig);
5204        }
5205        // exclude the subject events. TODO: exclude defs too?
5206        var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances);
5207        var otherDefs = otherEventStore.defs;
5208        var otherInstances = otherEventStore.instances;
5209        var otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
5210        for (var subjectInstanceId in subjectInstances) {
5211            var subjectInstance = subjectInstances[subjectInstanceId];
5212            var subjectRange = subjectInstance.range;
5213            var subjectConfig = subjectConfigs[subjectInstance.defId];
5214            var subjectDef = subjectDefs[subjectInstance.defId];
5215            // constraint
5216            if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) {
5217                return false;
5218            }
5219            // overlap
5220            var eventOverlap = context.options.eventOverlap;
5221            var eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null;
5222            for (var otherInstanceId in otherInstances) {
5223                var otherInstance = otherInstances[otherInstanceId];
5224                // intersect! evaluate
5225                if (rangesIntersect(subjectRange, otherInstance.range)) {
5226                    var otherOverlap = otherConfigs[otherInstance.defId].overlap;
5227                    // consider the other event's overlap. only do this if the subject event is a "real" event
5228                    if (otherOverlap === false && interaction.isEvent) {
5229                        return false;
5230                    }
5231                    if (subjectConfig.overlap === false) {
5232                        return false;
5233                    }
5234                    if (eventOverlapFunc && !eventOverlapFunc(new EventApi(context, otherDefs[otherInstance.defId], otherInstance), // still event
5235                    new EventApi(context, subjectDef, subjectInstance))) {
5236                        return false;
5237                    }
5238                }
5239            }
5240            // allow (a function)
5241            var calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state
5242            for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) {
5243                var subjectAllow = _a[_i];
5244                var subjectDateSpan = __assign(__assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay });
5245                var origDef = calendarEventStore.defs[subjectDef.defId];
5246                var origInstance = calendarEventStore.instances[subjectInstanceId];
5247                var eventApi = void 0;
5248                if (origDef) { // was previously in the calendar
5249                    eventApi = new EventApi(context, origDef, origInstance);
5250                }
5251                else { // was an external event
5252                    eventApi = new EventApi(context, subjectDef); // no instance, because had no dates
5253                }
5254                if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) {
5255                    return false;
5256                }
5257            }
5258        }
5259        return true;
5260    }
5261    // Date Selection Validation
5262    // ------------------------------------------------------------------------------------------------------------------------
5263    function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) {
5264        var relevantEventStore = state.eventStore;
5265        var relevantDefs = relevantEventStore.defs;
5266        var relevantInstances = relevantEventStore.instances;
5267        var selection = state.dateSelection;
5268        var selectionRange = selection.range;
5269        var selectionConfig = context.getCurrentData().selectionConfig;
5270        if (filterConfig) {
5271            selectionConfig = filterConfig(selectionConfig);
5272        }
5273        // constraint
5274        if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) {
5275            return false;
5276        }
5277        // overlap
5278        var selectOverlap = context.options.selectOverlap;
5279        var selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null;
5280        for (var relevantInstanceId in relevantInstances) {
5281            var relevantInstance = relevantInstances[relevantInstanceId];
5282            // intersect! evaluate
5283            if (rangesIntersect(selectionRange, relevantInstance.range)) {
5284                if (selectionConfig.overlap === false) {
5285                    return false;
5286                }
5287                if (selectOverlapFunc && !selectOverlapFunc(new EventApi(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) {
5288                    return false;
5289                }
5290            }
5291        }
5292        // allow (a function)
5293        for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) {
5294            var selectionAllow = _a[_i];
5295            var fullDateSpan = __assign(__assign({}, dateSpanMeta), selection);
5296            if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) {
5297                return false;
5298            }
5299        }
5300        return true;
5301    }
5302    // Constraint Utils
5303    // ------------------------------------------------------------------------------------------------------------------------
5304    function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) {
5305        for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
5306            var constraint = constraints_1[_i];
5307            if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) {
5308                return false;
5309            }
5310        }
5311        return true;
5312    }
5313    function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
5314    otherEventStore, // for if constraint is an even group ID
5315    businessHoursUnexpanded, // for if constraint is 'businessHours'
5316    context) {
5317        if (constraint === 'businessHours') {
5318            return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context));
5319        }
5320        if (typeof constraint === 'string') { // an group ID
5321            return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) { return eventDef.groupId === constraint; }));
5322        }
5323        if (typeof constraint === 'object' && constraint) { // non-null object
5324            return eventStoreToRanges(expandRecurring(constraint, subjectRange, context));
5325        }
5326        return []; // if it's false
5327    }
5328    // TODO: move to event-store file?
5329    function eventStoreToRanges(eventStore) {
5330        var instances = eventStore.instances;
5331        var ranges = [];
5332        for (var instanceId in instances) {
5333            ranges.push(instances[instanceId].range);
5334        }
5335        return ranges;
5336    }
5337    // TODO: move to geom file?
5338    function anyRangesContainRange(outerRanges, innerRange) {
5339        for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) {
5340            var outerRange = outerRanges_1[_i];
5341            if (rangeContainsRange(outerRange, innerRange)) {
5342                return true;
5343            }
5344        }
5345        return false;
5346    }
5347
5348    /*
5349    an INTERACTABLE date component
5350
5351    PURPOSES:
5352    - hook up to fg, fill, and mirror renderers
5353    - interface for dragging and hits
5354    */
5355    var DateComponent = /** @class */ (function (_super) {
5356        __extends(DateComponent, _super);
5357        function DateComponent() {
5358            var _this = _super !== null && _super.apply(this, arguments) || this;
5359            _this.uid = guid();
5360            return _this;
5361        }
5362        // Hit System
5363        // -----------------------------------------------------------------------------------------------------------------
5364        DateComponent.prototype.prepareHits = function () {
5365        };
5366        DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
5367            return null; // this should be abstract
5368        };
5369        // Validation
5370        // -----------------------------------------------------------------------------------------------------------------
5371        DateComponent.prototype.isInteractionValid = function (interaction) {
5372            var dateProfile = this.props.dateProfile; // HACK
5373            var instances = interaction.mutatedEvents.instances;
5374            if (dateProfile) { // HACK for MorePopover
5375                for (var instanceId in instances) {
5376                    if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
5377                        return false;
5378                    }
5379                }
5380            }
5381            return isInteractionValid(interaction, this.context);
5382        };
5383        DateComponent.prototype.isDateSelectionValid = function (selection) {
5384            var dateProfile = this.props.dateProfile; // HACK
5385            if (dateProfile && // HACK for MorePopover
5386                !rangeContainsRange(dateProfile.validRange, selection.range)) {
5387                return false;
5388            }
5389            return isDateSelectionValid(selection, this.context);
5390        };
5391        // Pointer Interaction Utils
5392        // -----------------------------------------------------------------------------------------------------------------
5393        DateComponent.prototype.isValidSegDownEl = function (el) {
5394            return !this.props.eventDrag && // HACK
5395                !this.props.eventResize && // HACK
5396                !elementClosest(el, '.fc-event-mirror');
5397        };
5398        DateComponent.prototype.isValidDateDownEl = function (el) {
5399            return !elementClosest(el, '.fc-event:not(.fc-bg-event)') &&
5400                !elementClosest(el, '.fc-daygrid-more-link') && // a "more.." link
5401                !elementClosest(el, 'a[data-navlink]') && // a clickable nav link
5402                !elementClosest(el, '.fc-popover'); // hack
5403        };
5404        return DateComponent;
5405    }(BaseComponent));
5406
5407    // TODO: easier way to add new hooks? need to update a million things
5408    function createPlugin(input) {
5409        return {
5410            id: guid(),
5411            deps: input.deps || [],
5412            reducers: input.reducers || [],
5413            isLoadingFuncs: input.isLoadingFuncs || [],
5414            contextInit: [].concat(input.contextInit || []),
5415            eventRefiners: input.eventRefiners || {},
5416            eventDefMemberAdders: input.eventDefMemberAdders || [],
5417            eventSourceRefiners: input.eventSourceRefiners || {},
5418            isDraggableTransformers: input.isDraggableTransformers || [],
5419            eventDragMutationMassagers: input.eventDragMutationMassagers || [],
5420            eventDefMutationAppliers: input.eventDefMutationAppliers || [],
5421            dateSelectionTransformers: input.dateSelectionTransformers || [],
5422            datePointTransforms: input.datePointTransforms || [],
5423            dateSpanTransforms: input.dateSpanTransforms || [],
5424            views: input.views || {},
5425            viewPropsTransformers: input.viewPropsTransformers || [],
5426            isPropsValid: input.isPropsValid || null,
5427            externalDefTransforms: input.externalDefTransforms || [],
5428            eventResizeJoinTransforms: input.eventResizeJoinTransforms || [],
5429            viewContainerAppends: input.viewContainerAppends || [],
5430            eventDropTransformers: input.eventDropTransformers || [],
5431            componentInteractions: input.componentInteractions || [],
5432            calendarInteractions: input.calendarInteractions || [],
5433            themeClasses: input.themeClasses || {},
5434            eventSourceDefs: input.eventSourceDefs || [],
5435            cmdFormatter: input.cmdFormatter,
5436            recurringTypes: input.recurringTypes || [],
5437            namedTimeZonedImpl: input.namedTimeZonedImpl,
5438            initialView: input.initialView || '',
5439            elementDraggingImpl: input.elementDraggingImpl,
5440            optionChangeHandlers: input.optionChangeHandlers || {},
5441            scrollGridImpl: input.scrollGridImpl || null,
5442            contentTypeHandlers: input.contentTypeHandlers || {},
5443            listenerRefiners: input.listenerRefiners || {},
5444            optionRefiners: input.optionRefiners || {},
5445            propSetHandlers: input.propSetHandlers || {},
5446        };
5447    }
5448    function buildPluginHooks(pluginDefs, globalDefs) {
5449        var isAdded = {};
5450        var hooks = {
5451            reducers: [],
5452            isLoadingFuncs: [],
5453            contextInit: [],
5454            eventRefiners: {},
5455            eventDefMemberAdders: [],
5456            eventSourceRefiners: {},
5457            isDraggableTransformers: [],
5458            eventDragMutationMassagers: [],
5459            eventDefMutationAppliers: [],
5460            dateSelectionTransformers: [],
5461            datePointTransforms: [],
5462            dateSpanTransforms: [],
5463            views: {},
5464            viewPropsTransformers: [],
5465            isPropsValid: null,
5466            externalDefTransforms: [],
5467            eventResizeJoinTransforms: [],
5468            viewContainerAppends: [],
5469            eventDropTransformers: [],
5470            componentInteractions: [],
5471            calendarInteractions: [],
5472            themeClasses: {},
5473            eventSourceDefs: [],
5474            cmdFormatter: null,
5475            recurringTypes: [],
5476            namedTimeZonedImpl: null,
5477            initialView: '',
5478            elementDraggingImpl: null,
5479            optionChangeHandlers: {},
5480            scrollGridImpl: null,
5481            contentTypeHandlers: {},
5482            listenerRefiners: {},
5483            optionRefiners: {},
5484            propSetHandlers: {},
5485        };
5486        function addDefs(defs) {
5487            for (var _i = 0, defs_1 = defs; _i < defs_1.length; _i++) {
5488                var def = defs_1[_i];
5489                if (!isAdded[def.id]) {
5490                    isAdded[def.id] = true;
5491                    addDefs(def.deps);
5492                    hooks = combineHooks(hooks, def);
5493                }
5494            }
5495        }
5496        if (pluginDefs) {
5497            addDefs(pluginDefs);
5498        }
5499        addDefs(globalDefs);
5500        return hooks;
5501    }
5502    function buildBuildPluginHooks() {
5503        var currentOverrideDefs = [];
5504        var currentGlobalDefs = [];
5505        var currentHooks;
5506        return function (overrideDefs, globalDefs) {
5507            if (!currentHooks || !isArraysEqual(overrideDefs, currentOverrideDefs) || !isArraysEqual(globalDefs, currentGlobalDefs)) {
5508                currentHooks = buildPluginHooks(overrideDefs, globalDefs);
5509            }
5510            currentOverrideDefs = overrideDefs;
5511            currentGlobalDefs = globalDefs;
5512            return currentHooks;
5513        };
5514    }
5515    function combineHooks(hooks0, hooks1) {
5516        return {
5517            reducers: hooks0.reducers.concat(hooks1.reducers),
5518            isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs),
5519            contextInit: hooks0.contextInit.concat(hooks1.contextInit),
5520            eventRefiners: __assign(__assign({}, hooks0.eventRefiners), hooks1.eventRefiners),
5521            eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),
5522            eventSourceRefiners: __assign(__assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners),
5523            isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),
5524            eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
5525            eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
5526            dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
5527            datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
5528            dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
5529            views: __assign(__assign({}, hooks0.views), hooks1.views),
5530            viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
5531            isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
5532            externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
5533            eventResizeJoinTransforms: hooks0.eventResizeJoinTransforms.concat(hooks1.eventResizeJoinTransforms),
5534            viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends),
5535            eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
5536            calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
5537            componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
5538            themeClasses: __assign(__assign({}, hooks0.themeClasses), hooks1.themeClasses),
5539            eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
5540            cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
5541            recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
5542            namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
5543            initialView: hooks0.initialView || hooks1.initialView,
5544            elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
5545            optionChangeHandlers: __assign(__assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers),
5546            scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl,
5547            contentTypeHandlers: __assign(__assign({}, hooks0.contentTypeHandlers), hooks1.contentTypeHandlers),
5548            listenerRefiners: __assign(__assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners),
5549            optionRefiners: __assign(__assign({}, hooks0.optionRefiners), hooks1.optionRefiners),
5550            propSetHandlers: __assign(__assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers),
5551        };
5552    }
5553
5554    var StandardTheme = /** @class */ (function (_super) {
5555        __extends(StandardTheme, _super);
5556        function StandardTheme() {
5557            return _super !== null && _super.apply(this, arguments) || this;
5558        }
5559        return StandardTheme;
5560    }(Theme));
5561    StandardTheme.prototype.classes = {
5562        root: 'fc-theme-standard',
5563        tableCellShaded: 'fc-cell-shaded',
5564        buttonGroup: 'fc-button-group',
5565        button: 'fc-button fc-button-primary',
5566        buttonActive: 'fc-button-active',
5567    };
5568    StandardTheme.prototype.baseIconClass = 'fc-icon';
5569    StandardTheme.prototype.iconClasses = {
5570        close: 'fc-icon-x',
5571        prev: 'fc-icon-chevron-left',
5572        next: 'fc-icon-chevron-right',
5573        prevYear: 'fc-icon-chevrons-left',
5574        nextYear: 'fc-icon-chevrons-right',
5575    };
5576    StandardTheme.prototype.rtlIconClasses = {
5577        prev: 'fc-icon-chevron-right',
5578        next: 'fc-icon-chevron-left',
5579        prevYear: 'fc-icon-chevrons-right',
5580        nextYear: 'fc-icon-chevrons-left',
5581    };
5582    StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly
5583    StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
5584    StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
5585
5586    function compileViewDefs(defaultConfigs, overrideConfigs) {
5587        var hash = {};
5588        var viewType;
5589        for (viewType in defaultConfigs) {
5590            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5591        }
5592        for (viewType in overrideConfigs) {
5593            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5594        }
5595        return hash;
5596    }
5597    function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5598        if (hash[viewType]) {
5599            return hash[viewType];
5600        }
5601        var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5602        if (viewDef) {
5603            hash[viewType] = viewDef;
5604        }
5605        return viewDef;
5606    }
5607    function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5608        var defaultConfig = defaultConfigs[viewType];
5609        var overrideConfig = overrideConfigs[viewType];
5610        var queryProp = function (name) { return ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
5611            ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null)); };
5612        var theComponent = queryProp('component');
5613        var superType = queryProp('superType');
5614        var superDef = null;
5615        if (superType) {
5616            if (superType === viewType) {
5617                throw new Error('Can\'t have a custom view type that references itself');
5618            }
5619            superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);
5620        }
5621        if (!theComponent && superDef) {
5622            theComponent = superDef.component;
5623        }
5624        if (!theComponent) {
5625            return null; // don't throw a warning, might be settings for a single-unit view
5626        }
5627        return {
5628            type: viewType,
5629            component: theComponent,
5630            defaults: __assign(__assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})),
5631            overrides: __assign(__assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})),
5632        };
5633    }
5634
5635    /* eslint max-classes-per-file: off */
5636    // NOTE: in JSX, you should always use this class with <HookProps> arg. otherwise, will default to any???
5637    var RenderHook = /** @class */ (function (_super) {
5638        __extends(RenderHook, _super);
5639        function RenderHook() {
5640            var _this = _super !== null && _super.apply(this, arguments) || this;
5641            _this.rootElRef = createRef();
5642            _this.handleRootEl = function (el) {
5643                setRef(_this.rootElRef, el);
5644                if (_this.props.elRef) {
5645                    setRef(_this.props.elRef, el);
5646                }
5647            };
5648            return _this;
5649        }
5650        RenderHook.prototype.render = function () {
5651            var _this = this;
5652            var props = this.props;
5653            var hookProps = props.hookProps;
5654            return (createElement(MountHook, { hookProps: hookProps, didMount: props.didMount, willUnmount: props.willUnmount, elRef: this.handleRootEl }, function (rootElRef) { return (createElement(ContentHook, { hookProps: hookProps, content: props.content, defaultContent: props.defaultContent, backupElRef: _this.rootElRef }, function (innerElRef, innerContent) { return props.children(rootElRef, normalizeClassNames(props.classNames, hookProps), innerElRef, innerContent); })); }));
5655        };
5656        return RenderHook;
5657    }(BaseComponent));
5658    // TODO: rename to be about function, not default. use in above type
5659    // for forcing rerender of components that use the ContentHook
5660    var CustomContentRenderContext = createContext$1(0);
5661    function ContentHook(props) {
5662        return (createElement(CustomContentRenderContext.Consumer, null, function (renderId) { return (createElement(ContentHookInner, __assign({ renderId: renderId }, props))); }));
5663    }
5664    var ContentHookInner = /** @class */ (function (_super) {
5665        __extends(ContentHookInner, _super);
5666        function ContentHookInner() {
5667            var _this = _super !== null && _super.apply(this, arguments) || this;
5668            _this.innerElRef = createRef();
5669            return _this;
5670        }
5671        ContentHookInner.prototype.render = function () {
5672            return this.props.children(this.innerElRef, this.renderInnerContent());
5673        };
5674        ContentHookInner.prototype.componentDidMount = function () {
5675            this.updateCustomContent();
5676        };
5677        ContentHookInner.prototype.componentDidUpdate = function () {
5678            this.updateCustomContent();
5679        };
5680        ContentHookInner.prototype.componentWillUnmount = function () {
5681            if (this.customContentInfo && this.customContentInfo.destroy) {
5682                this.customContentInfo.destroy();
5683            }
5684        };
5685        ContentHookInner.prototype.renderInnerContent = function () {
5686            var contentTypeHandlers = this.context.pluginHooks.contentTypeHandlers;
5687            var _a = this, props = _a.props, customContentInfo = _a.customContentInfo;
5688            var rawVal = props.content;
5689            var innerContent = normalizeContent(rawVal, props.hookProps);
5690            var innerContentVDom = null;
5691            if (innerContent === undefined) { // use the default
5692                innerContent = normalizeContent(props.defaultContent, props.hookProps);
5693            }
5694            if (innerContent !== undefined) { // we allow custom content handlers to return nothing
5695                if (customContentInfo) {
5696                    customContentInfo.contentVal = innerContent[customContentInfo.contentKey];
5697                }
5698                else if (typeof innerContent === 'object') {
5699                    // look for a prop that would indicate a custom content handler is needed
5700                    for (var contentKey in contentTypeHandlers) {
5701                        if (innerContent[contentKey] !== undefined) {
5702                            var stuff = contentTypeHandlers[contentKey]();
5703                            customContentInfo = this.customContentInfo = __assign({ contentKey: contentKey, contentVal: innerContent[contentKey] }, stuff);
5704                            break;
5705                        }
5706                    }
5707                }
5708                if (customContentInfo) {
5709                    innerContentVDom = []; // signal that something was specified
5710                }
5711                else {
5712                    innerContentVDom = innerContent; // assume a [p]react vdom node. use it
5713                }
5714            }
5715            return innerContentVDom;
5716        };
5717        ContentHookInner.prototype.updateCustomContent = function () {
5718            if (this.customContentInfo) {
5719                this.customContentInfo.render(this.innerElRef.current || this.props.backupElRef.current, // the element to render into
5720                this.customContentInfo.contentVal);
5721            }
5722        };
5723        return ContentHookInner;
5724    }(BaseComponent));
5725    var MountHook = /** @class */ (function (_super) {
5726        __extends(MountHook, _super);
5727        function MountHook() {
5728            var _this = _super !== null && _super.apply(this, arguments) || this;
5729            _this.handleRootEl = function (rootEl) {
5730                _this.rootEl = rootEl;
5731                if (_this.props.elRef) {
5732                    setRef(_this.props.elRef, rootEl);
5733                }
5734            };
5735            return _this;
5736        }
5737        MountHook.prototype.render = function () {
5738            return this.props.children(this.handleRootEl);
5739        };
5740        MountHook.prototype.componentDidMount = function () {
5741            var callback = this.props.didMount;
5742            if (callback) {
5743                callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl }));
5744            }
5745        };
5746        MountHook.prototype.componentWillUnmount = function () {
5747            var callback = this.props.willUnmount;
5748            if (callback) {
5749                callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl }));
5750            }
5751        };
5752        return MountHook;
5753    }(BaseComponent));
5754    function buildClassNameNormalizer() {
5755        var currentGenerator;
5756        var currentHookProps;
5757        var currentClassNames = [];
5758        return function (generator, hookProps) {
5759            if (!currentHookProps || !isPropsEqual(currentHookProps, hookProps) || generator !== currentGenerator) {
5760                currentGenerator = generator;
5761                currentHookProps = hookProps;
5762                currentClassNames = normalizeClassNames(generator, hookProps);
5763            }
5764            return currentClassNames;
5765        };
5766    }
5767    function normalizeClassNames(classNames, hookProps) {
5768        if (typeof classNames === 'function') {
5769            classNames = classNames(hookProps);
5770        }
5771        return parseClassNames(classNames);
5772    }
5773    function normalizeContent(input, hookProps) {
5774        if (typeof input === 'function') {
5775            return input(hookProps, createElement); // give the function the vdom-creation func
5776        }
5777        return input;
5778    }
5779
5780    var ViewRoot = /** @class */ (function (_super) {
5781        __extends(ViewRoot, _super);
5782        function ViewRoot() {
5783            var _this = _super !== null && _super.apply(this, arguments) || this;
5784            _this.normalizeClassNames = buildClassNameNormalizer();
5785            return _this;
5786        }
5787        ViewRoot.prototype.render = function () {
5788            var _a = this, props = _a.props, context = _a.context;
5789            var options = context.options;
5790            var hookProps = { view: context.viewApi };
5791            var customClassNames = this.normalizeClassNames(options.viewClassNames, hookProps);
5792            return (createElement(MountHook, { hookProps: hookProps, didMount: options.viewDidMount, willUnmount: options.viewWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, ["fc-" + props.viewSpec.type + "-view", 'fc-view'].concat(customClassNames)); }));
5793        };
5794        return ViewRoot;
5795    }(BaseComponent));
5796
5797    function parseViewConfigs(inputs) {
5798        return mapHash(inputs, parseViewConfig);
5799    }
5800    function parseViewConfig(input) {
5801        var rawOptions = typeof input === 'function' ?
5802            { component: input } :
5803            input;
5804        var component = rawOptions.component;
5805        if (rawOptions.content) {
5806            component = createViewHookComponent(rawOptions);
5807            // TODO: remove content/classNames/didMount/etc from options?
5808        }
5809        return {
5810            superType: rawOptions.type,
5811            component: component,
5812            rawOptions: rawOptions,
5813        };
5814    }
5815    function createViewHookComponent(options) {
5816        return function (viewProps) { return (createElement(ViewContextType.Consumer, null, function (context) { return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (viewElRef, viewClassNames) {
5817            var hookProps = __assign(__assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold });
5818            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.classNames, content: options.content, didMount: options.didMount, willUnmount: options.willUnmount, elRef: viewElRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("div", { className: viewClassNames.c
5818oncat(customClassNames).join(' '), ref: rootElRef }, innerContent)); }));
5819        })); })); };
5820    }
5821
5822    function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
5823        var defaultConfigs = parseViewConfigs(defaultInputs);
5824        var overrideConfigs = parseViewConfigs(optionOverrides.views);
5825        var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
5826        return mapHash(viewDefs, function (viewDef) { return buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults); });
5827    }
5828    function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
5829        var durationInput = viewDef.overrides.duration ||
5830            viewDef.defaults.duration ||
5831            dynamicOptionOverrides.duration ||
5832            optionOverrides.duration;
5833        var duration = null;
5834        var durationUnit = '';
5835        var singleUnit = '';
5836        var singleUnitOverrides = {};
5837        if (durationInput) {
5838            duration = createDurationCached(durationInput);
5839            if (duration) { // valid?
5840                var denom = greatestDurationDenominator(duration);
5841                durationUnit = denom.unit;
5842                if (denom.value === 1) {
5843                    singleUnit = durationUnit;
5844                    singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {};
5845                }
5846            }
5847        }
5848        var queryButtonText = function (optionsSubset) {
5849            var buttonTextMap = optionsSubset.buttonText || {};
5850            var buttonTextKey = viewDef.defaults.buttonTextKey;
5851            if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
5852                return buttonTextMap[buttonTextKey];
5853            }
5854            if (buttonTextMap[viewDef.type] != null) {
5855                return buttonTextMap[viewDef.type];
5856            }
5857            if (buttonTextMap[singleUnit] != null) {
5858                return buttonTextMap[singleUnit];
5859            }
5860            return null;
5861        };
5862        return {
5863            type: viewDef.type,
5864            component: viewDef.component,
5865            duration: duration,
5866            durationUnit: durationUnit,
5867            singleUnit: singleUnit,
5868            optionDefaults: viewDef.defaults,
5869            optionOverrides: __assign(__assign({}, singleUnitOverrides), viewDef.overrides),
5870            buttonTextOverride: queryButtonText(dynamicOptionOverrides) ||
5871                queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence
5872                viewDef.overrides.buttonText,
5873            buttonTextDefault: queryButtonText(localeDefaults) ||
5874                viewDef.defaults.buttonText ||
5875                queryButtonText(BASE_OPTION_DEFAULTS) ||
5876                viewDef.type,
5877        };
5878    }
5879    // hack to get memoization working
5880    var durationInputMap = {};
5881    function createDurationCached(durationInput) {
5882        var json = JSON.stringify(durationInput);
5883        var res = durationInputMap[json];
5884        if (res === undefined) {
5885            res = createDuration(durationInput);
5886            durationInputMap[json] = res;
5887        }
5888        return res;
5889    }
5890
5891    var DateProfileGenerator = /** @class */ (function () {
5892        function DateProfileGenerator(props) {
5893            this.props = props;
5894            this.nowDate = getNow(props.nowInput, props.dateEnv);
5895            this.initHiddenDays();
5896        }
5897        /* Date Range Computation
5898        ------------------------------------------------------------------------------------------------------------------*/
5899        // Builds a structure with info about what the dates/ranges will be for the "prev" view.
5900        DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate, forceToValid) {
5901            var dateEnv = this.props.dateEnv;
5902            var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5903            currentDateProfile.dateIncrement);
5904            return this.build(prevDate, -1, forceToValid);
5905        };
5906        // Builds a structure with info about what the dates/ranges will be for the "next" view.
5907        DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate, forceToValid) {
5908            var dateEnv = this.props.dateEnv;
5909            var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5910            currentDateProfile.dateIncrement);
5911            return this.build(nextDate, 1, forceToValid);
5912        };
5913        // Builds a structure holding dates/ranges for rendering around the given date.
5914        // Optional direction param indicates whether the date is being incremented/decremented
5915        // from its previous value. decremented = -1, incremented = 1 (default).
5916        DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) {
5917            if (forceToValid === void 0) { forceToValid = true; }
5918            var props = this.props;
5919            var validRange;
5920            var currentInfo;
5921            var isRangeAllDay;
5922            var renderRange;
5923            var activeRange;
5924            var isValid;
5925            validRange = this.buildValidRange();
5926            validRange = this.trimHiddenDays(validRange);
5927            if (forceToValid) {
5928                currentDate = constrainMarkerToRange(currentDate, validRange);
5929            }
5930            currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
5931            isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
5932            renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
5933            renderRange = this.trimHiddenDays(renderRange);
5934            activeRange = renderRange;
5935            if (!props.showNonCurrentDates) {
5936                activeRange = intersectRanges(activeRange, currentInfo.range);
5937            }
5938            activeRange = this.adjustActiveRange(activeRange);
5939            activeRange = intersectRanges(activeRange, validRange); // might return null
5940            // it's invalid if the originally requested date is not contained,
5941            // or if the range is completely outside of the valid range.
5942            isValid = rangesIntersect(currentInfo.range, validRange);
5943            return {
5944                // constraint for where prev/next operations can go and where events can be dragged/resized to.
5945                // an object with optional start and end properties.
5946                validRange: validRange,
5947                // range the view is formally responsible for.
5948                // for example, a month view might have 1st-31st, excluding padded dates
5949                currentRange: currentInfo.range,
5950                // name of largest unit being displayed, like "month" or "week"
5951                currentRangeUnit: currentInfo.unit,
5952                isRangeAllDay: isRangeAllDay,
5953                // dates that display events and accept drag-n-drop
5954                // will be `null` if no dates accept events
5955                activeRange: activeRange,
5956                // date range with a rendered skeleton
5957                // includes not-active days that need some sort of DOM
5958                renderRange: renderRange,
5959                // Duration object that denotes the first visible time of any given day
5960                slotMinTime: props.slotMinTime,
5961                // Duration object that denotes the exclusive visible end time of any given day
5962                slotMaxTime: props.slotMaxTime,
5963                isValid: isValid,
5964                // how far the current date will move for a prev/next operation
5965                dateIncrement: this.buildDateIncrement(currentInfo.duration),
5966            };
5967        };
5968        // Builds an object with optional start/end properties.
5969        // Indicates the minimum/maximum dates to display.
5970        // not responsible for trimming hidden days.
5971        DateProfileGenerator.prototype.buildValidRange = function () {
5972            var input = this.props.validRangeInput;
5973            var simpleInput = typeof input === 'function'
5974                ? input.call(this.props.calendarApi, this.nowDate)
5975                : input;
5976            return this.refineRange(simpleInput) ||
5977                { start: null, end: null }; // completely open-ended
5978        };
5979        // Builds a structure with info about the "current" range, the range that is
5980        // highlighted as being the current month for example.
5981        // See build() for a description of `direction`.
5982        // Guaranteed to have `range` and `unit` properties. `duration` is optional.
5983        DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
5984            var props = this.props;
5985            var duration = null;
5986            var unit = null;
5987            var range = null;
5988            var dayCount;
5989            if (props.duration) {
5990                duration = props.duration;
5991                unit = props.durationUnit;
5992                range = this.buildRangeFromDuration(date, direction, duration, unit);
5993            }
5994            else if ((dayCount = this.props.dayCount)) {
5995                unit = 'day';
5996                range = this.buildRangeFromDayCount(date, direction, dayCount);
5997            }
5998            else if ((range = this.buildCustomVisibleRange(date))) {
5999                unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit;
6000            }
6001            else {
6002                duration = this.getFallbackDuration();
6003                unit = greatestDurationDenominator(duration).unit;
6004                range = this.buildRangeFromDuration(date, direction, duration, unit);
6005            }
6006            return { duration: duration, unit: unit, range: range };
6007        };
6008        DateProfileGenerator.prototype.getFallbackDuration = function () {
6009            return createDuration({ day: 1 });
6010        };
6011        // Returns a new activeRange to have time values (un-ambiguate)
6012        // slotMinTime or slotMaxTime causes the range to expand.
6013        DateProfileGenerator.prototype.adjustActiveRange = function (range) {
6014            var _a = this.props, dateEnv = _a.dateEnv, usesMinMaxTime = _a.usesMinMaxTime, slotMinTime = _a.slotMinTime, slotMaxTime = _a.slotMaxTime;
6015            var start = range.start, end = range.end;
6016            if (usesMinMaxTime) {
6017                // expand active range if slotMinTime is negative (why not when positive?)
6018                if (asRoughDays(slotMinTime) < 0) {
6019                    start = startOfDay(start); // necessary?
6020                    start = dateEnv.add(start, slotMinTime);
6021                }
6022                // expand active range if slotMaxTime is beyond one day (why not when negative?)
6023                if (asRoughDays(slotMaxTime) > 1) {
6024                    end = startOfDay(end); // necessary?
6025                    end = addDays(end, -1);
6026                    end = dateEnv.add(end, slotMaxTime);
6027                }
6028            }
6029            return { start: start, end: end };
6030        };
6031        // Builds the "current" range when it is specified as an explicit duration.
6032        // `unit` is the already-computed greatestDurationDenominator unit of duration.
6033        DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
6034            var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment;
6035            var start;
6036            var end;
6037            var res;
6038            // compute what the alignment should be
6039            if (!dateAlignment) {
6040                var dateIncrement = this.props.dateIncrement;
6041                if (dateIncrement) {
6042                    // use the smaller of the two units
6043                    if (asRoughMs(dateIncrement) < asRoughMs(duration)) {
6044                        dateAlignment = greatestDurationDenominator(dateIncrement).unit;
6045                    }
6046                    else {
6047                        dateAlignment = unit;
6048                    }
6049                }
6050                else {
6051                    dateAlignment = unit;
6052                }
6053            }
6054            // if the view displays a single day or smaller
6055            if (asRoughDays(duration) <= 1) {
6056                if (this.isHiddenDay(start)) {
6057                    start = this.skipHiddenDays(start, direction);
6058                    start = startOfDay(start);
6059                }
6060            }
6061            function computeRes() {
6062                start = dateEnv.startOf(date, dateAlignment);
6063                end = dateEnv.add(start, duration);
6064                res = { start: start, end: end };
6065            }
6066            computeRes();
6067            // if range is completely enveloped by hidden days, go past the hidden days
6068            if (!this.trimHiddenDays(res)) {
6069                date = this.skipHiddenDays(date, direction);
6070                computeRes();
6071            }
6072            return res;
6073        };
6074        // Builds the "current" range when a dayCount is specified.
6075        DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
6076            var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment;
6077            var runningCount = 0;
6078            var start = date;
6079            var end;
6080            if (dateAlignment) {
6081                start = dateEnv.startOf(start, dateAlignment);
6082            }
6083            start = startOfDay(start);
6084            start = this.skipHiddenDays(start, direction);
6085            end = start;
6086            do {
6087                end = addDays(end, 1);
6088                if (!this.isHiddenDay(end)) {
6089                    runningCount += 1;
6090                }
6091            } while (runningCount < dayCount);
6092            return { start: start, end: end };
6093        };
6094        // Builds a normalized range object for the "visible" range,
6095        // which is a way to define the currentRange and activeRange at the same time.
6096        DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
6097            var props = this.props;
6098            var input = props.visibleRangeInput;
6099            var simpleInput = typeof input === 'function'
6100                ? input.call(props.calendarApi, props.dateEnv.toDate(date))
6101                : input;
6102            var range = this.refineRange(simpleInput);
6103            if (range && (range.start == null || range.end == null)) {
6104                return null;
6105            }
6106            return range;
6107        };
6108        // Computes the range that will represent the element/cells for *rendering*,
6109        // but which may have voided days/times.
6110        // not responsible for trimming hidden days.
6111        DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
6112            return currentRange;
6113        };
6114        // Compute the duration value that should be added/substracted to the current date
6115        // when a prev/next operation happens.
6116        DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
6117            var dateIncrement = this.props.dateIncrement;
6118            var customAlignment;
6119            if (dateIncrement) {
6120                return dateIncrement;
6121            }
6122            if ((customAlignment = this.props.dateAlignment)) {
6123                return createDuration(1, customAlignment);
6124            }
6125            if (fallback) {
6126                return fallback;
6127            }
6128            return createDuration({ days: 1 });
6129        };
6130        DateProfileGenerator.prototype.refineRange = function (rangeInput) {
6131            if (rangeInput) {
6132                var range = parseRange(rangeInput, this.props.dateEnv);
6133                if (range) {
6134                    range = computeVisibleDayRange(range);
6135                }
6136                return range;
6137            }
6138            return null;
6139        };
6140        /* Hidden Days
6141        ------------------------------------------------------------------------------------------------------------------*/
6142        // Initializes internal variables related to calculating hidden days-of-week
6143        DateProfileGenerator.prototype.initHiddenDays = function () {
6144            var hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden
6145            var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
6146            var dayCnt = 0;
6147            var i;
6148            if (this.props.weekends === false) {
6149                hiddenDays.push(0, 6); // 0=sunday, 6=saturday
6150            }
6151            for (i = 0; i < 7; i += 1) {
6152                if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
6153                    dayCnt += 1;
6154                }
6155            }
6156            if (!dayCnt) {
6157                throw new Error('invalid hiddenDays'); // all days were hidden? bad.
6158            }
6159            this.isHiddenDayHash = isHiddenDayHash;
6160        };
6161        // Remove days from the beginning and end of the range that are computed as hidden.
6162        // If the whole range is trimmed off, returns null
6163        DateProfileGenerator.prototype.trimHiddenDays = function (range) {
6164            var start = range.start, end = range.end;
6165            if (start) {
6166                start = this.skipHiddenDays(start);
6167            }
6168            if (end) {
6169                end = this.skipHiddenDays(end, -1, true);
6170            }
6171            if (start == null || end == null || start < end) {
6172                return { start: start, end: end };
6173            }
6174            return null;
6175        };
6176        // Is the current day hidden?
6177        // `day` is a day-of-week index (0-6), or a Date (used for UTC)
6178        DateProfileGenerator.prototype.isHiddenDay = function (day) {
6179            if (day instanceof Date) {
6180                day = day.getUTCDay();
6181            }
6182            return this.isHiddenDayHash[day];
6183        };
6184        // Incrementing the current day until it is no longer a hidden day, returning a copy.
6185        // DOES NOT CONSIDER validRange!
6186        // If the initial value of `date` is not a hidden day, don't do anything.
6187        // Pass `isExclusive` as `true` if you are dealing with an end date.
6188        // `inc` defaults to `1` (increment one day forward each time)
6189        DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) {
6190            if (inc === void 0) { inc = 1; }
6191            if (isExclusive === void 0) { isExclusive = false; }
6192            while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
6193                date = addDays(date, inc);
6194            }
6195            return date;
6196        };
6197        return DateProfileGenerator;
6198    }());
6199
6200    function reduceViewType(viewType, action) {
6201        switch (action.type) {
6202            case 'CHANGE_VIEW_TYPE':
6203                viewType = action.viewType;
6204        }
6205        return viewType;
6206    }
6207
6208    function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {
6209        var _a;
6210        switch (action.type) {
6211            case 'SET_OPTION':
6212                return __assign(__assign({}, dynamicOptionOverrides), (_a = {}, _a[action.optionName] = action.rawOptionValue, _a));
6213            default:
6214                return dynamicOptionOverrides;
6215        }
6216    }
6217
6218    function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) {
6219        var dp;
6220        switch (action.type) {
6221            case 'CHANGE_VIEW_TYPE':
6222                return dateProfileGenerator.build(action.dateMarker || currentDate);
6223            case 'CHANGE_DATE':
6224                if (!currentDateProfile.activeRange ||
6225                    !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker) // don't move if date already in view
6226                ) {
6227                    return dateProfileGenerator.build(action.dateMarker);
6228                }
6229                break;
6230            case 'PREV':
6231                dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate);
6232                if (dp.isValid) {
6233                    return dp;
6234                }
6235                break;
6236            case 'NEXT':
6237                dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate);
6238                if (dp.isValid) {
6239                    return dp;
6240                }
6241                break;
6242        }
6243        return currentDateProfile;
6244    }
6245
6246    function initEventSources(calendarOptions, dateProfile, context) {
6247        var activeRange = dateProfile ? dateProfile.activeRange : null;
6248        return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context);
6249    }
6250    function reduceEventSources(eventSources, action, dateProfile, context) {
6251        var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
6252        switch (action.type) {
6253            case 'ADD_EVENT_SOURCES': // already parsed
6254                return addSources(eventSources, action.sources, activeRange, context);
6255            case 'REMOVE_EVENT_SOURCE':
6256                return removeSource(eventSources, action.sourceId);
6257            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
6258            case 'NEXT':
6259            case 'CHANGE_DATE':
6260            case 'CHANGE_VIEW_TYPE':
6261                if (dateProfile) {
6262                    return fetchDirtySources(eventSources, activeRange, context);
6263                }
6264                return eventSources;
6265            case 'FETCH_EVENT_SOURCES':
6266                return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type?
6267                    arrayToHash(action.sourceIds) :
6268                    excludeStaticSources(eventSources, context), activeRange, context);
6269            case 'RECEIVE_EVENTS':
6270            case 'RECEIVE_EVENT_ERROR':
6271                return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
6272            case 'REMOVE_ALL_EVENT_SOURCES':
6273                return {};
6274            default:
6275                return eventSources;
6276        }
6277    }
6278    function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) {
6279        var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
6280        return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, context);
6281    }
6282    function computeEventSourcesLoading(eventSources) {
6283        for (var sourceId in eventSources) {
6284            if (eventSources[sourceId].isFetching) {
6285                return true;
6286            }
6287        }
6288        return false;
6289    }
6290    function addSources(eventSourceHash, sources, fetchRange, context) {
6291        var hash = {};
6292        for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
6293            var source = sources_1[_i];
6294            hash[source.sourceId] = source;
6295        }
6296        if (fetchRange) {
6297            hash = fetchDirtySources(hash, fetchRange, context);
6298        }
6299        return __assign(__assign({}, eventSourceHash), hash);
6300    }
6301    function removeSource(eventSourceHash, sourceId) {
6302        return filterHash(eventSourceHash, function (eventSource) { return eventSource.sourceId !== sourceId; });
6303    }
6304    function fetchDirtySources(sourceHash, fetchRange, context) {
6305        return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) { return isSourceDirty(eventSource, fetchRange, context); }), fetchRange, context);
6306    }
6307    function isSourceDirty(eventSource, fetchRange, context) {
6308        if (!doesSourceNeedRange(eventSource, context)) {
6309            return !eventSource.latestFetchId;
6310        }
6311        return !context.options.lazyFetching ||
6312            !eventSource.fetchRange ||
6313            eventSource.isFetching || // always cancel outdated in-progress fetches
6314            fetchRange.start < eventSource.fetchRange.start ||
6315            fetchRange.end > eventSource.fetchRange.end;
6316    }
6317    function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, context) {
6318        var nextSources = {};
6319        for (var sourceId in prevSources) {
6320            var source = prevSources[sourceId];
6321            if (sourceIdHash[sourceId]) {
6322                nextSources[sourceId] = fetchSource(source, fetchRange, context);
6323            }
6324            else {
6325                nextSources[sourceId] = source;
6326            }
6327        }
6328        return nextSources;
6329    }
6330    function fetchSource(eventSource, fetchRange, context) {
6331        var options = context.options, calendarApi = context.calendarApi;
6332        var sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId];
6333        var fetchId = guid();
6334        sourceDef.fetch({
6335            eventSource: eventSource,
6336            range: fetchRange,
6337            context: context,
6338        }, function (res) {
6339            var rawEvents = res.rawEvents;
6340            if (options.eventSourceSuccess) {
6341                rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.xhr) || rawEvents;
6342            }
6343            if (eventSource.success) {
6344                rawEvents = eventSource.success.call(calendarApi, rawEvents, res.xhr) || rawEvents;
6345            }
6346            context.dispatch({
6347                type: 'RECEIVE_EVENTS',
6348                sourceId: eventSource.sourceId,
6349                fetchId: fetchId,
6350                fetchRange: fetchRange,
6351                rawEvents: rawEvents,
6352            });
6353        }, function (error) {
6354            console.warn(error.message, error);
6355            if (options.eventSourceFailure) {
6356                options.eventSourceFailure.call(calendarApi, error);
6357            }
6358            if (eventSource.failure) {
6359                eventSource.failure(error);
6360            }
6361            context.dispatch({
6362                type: 'RECEIVE_EVENT_ERROR',
6363                sourceId: eventSource.sourceId,
6364                fetchId: fetchId,
6365                fetchRange: fetchRange,
6366                error: error,
6367            });
6368        });
6369        return __assign(__assign({}, eventSource), { isFetching: true, latestFetchId: fetchId });
6370    }
6371    function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
6372        var _a;
6373        var eventSource = sourceHash[sourceId];
6374        if (eventSource && // not already removed
6375            fetchId === eventSource.latestFetchId) {
6376            return __assign(__assign({}, sourceHash), (_a = {}, _a[sourceId] = __assign(__assign({}, eventSource), { isFetching: false, fetchRange: fetchRange }), _a));
6377        }
6378        return sourceHash;
6379    }
6380    function excludeStaticSources(eventSources, context) {
6381        return filterHash(eventSources, function (eventSource) { return doesSourceNeedRange(eventSource, context); });
6382    }
6383    function parseInitialSources(rawOptions, context) {
6384        var refiners = buildEventSourceRefiners(context);
6385        var rawSources = [].concat(rawOptions.eventSources || []);
6386        var sources = []; // parsed
6387        if (rawOptions.initialEvents) {
6388            rawSources.unshift(rawOptions.initialEvents);
6389        }
6390        if (rawOptions.events) {
6391            rawSources.unshift(rawOptions.events);
6392        }
6393        for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) {
6394            var rawSource = rawSources_1[_i];
6395            var source = parseEventSource(rawSource, context, refiners);
6396            if (source) {
6397                sources.push(source);
6398            }
6399        }
6400        return sources;
6401    }
6402    function doesSourceNeedRange(eventSource, context) {
6403        var defs = context.pluginHooks.eventSourceDefs;
6404        return !defs[eventSource.sourceDefId].ignoreRange;
6405    }
6406
6407    function reduceDateSelection(currentSelection, action) {
6408        switch (action.type) {
6409            case 'UNSELECT_DATES':
6410                return null;
6411            case 'SELECT_DATES':
6412                return action.selection;
6413            default:
6414                return currentSelection;
6415        }
6416    }
6417
6418    function reduceSelectedEvent(currentInstanceId, action) {
6419        switch (action.type) {
6420            case 'UNSELECT_EVENT':
6421                return '';
6422            case 'SELECT_EVENT':
6423                return action.eventInstanceId;
6424            default:
6425                return currentInstanceId;
6426        }
6427    }
6428
6429    function reduceEventDrag(currentDrag, action) {
6430        var newDrag;
6431        switch (action.type) {
6432            case 'UNSET_EVENT_DRAG':
6433                return null;
6434            case 'SET_EVENT_DRAG':
6435                newDrag = action.state;
6436                return {
6437                    affectedEvents: newDrag.affectedEvents,
6438                    mutatedEvents: newDrag.mutatedEvents,
6439                    isEvent: newDrag.isEvent,
6440                };
6441            default:
6442                return currentDrag;
6443        }
6444    }
6445
6446    function reduceEventResize(currentResize, action) {
6447        var newResize;
6448        switch (action.type) {
6449            case 'UNSET_EVENT_RESIZE':
6450                return null;
6451            case 'SET_EVENT_RESIZE':
6452                newResize = action.state;
6453                return {
6454                    affectedEvents: newResize.affectedEvents,
6455                    mutatedEvents: newResize.mutatedEvents,
6456                    isEvent: newResize.isEvent,
6457                };
6458            default:
6459                return currentResize;
6460        }
6461    }
6462
6463    function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {
6464        var viewsWithButtons = [];
6465        var headerToolbar = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) : null;
6466        var footerToolbar = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) : null;
6467        return { headerToolbar: headerToolbar, footerToolbar: footerToolbar, viewsWithButtons: viewsWithButtons };
6468    }
6469    function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) {
6470        return mapHash(sectionStrHash, function (sectionStr) { return parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons); });
6471    }
6472    /*
6473    BAD: querying icons and text here. should be done at render time
6474    */
6475    function parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) {
6476        var isRtl = calendarOptions.direction === 'rtl';
6477        var calendarCustomButtons = calendarOptions.customButtons || {};
6478        var calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {};
6479        var calendarButtonText = calendarOptions.buttonText || {};
6480        var sectionSubstrs = sectionStr ? sectionStr.split(' ') : [];
6481        return sectionSubstrs.map(function (buttonGroupStr) { return (buttonGroupStr.split(',').map(function (buttonName) {
6482            if (buttonName === 'title') {
6483                return { buttonName: buttonName };
6484            }
6485            var customButtonProps;
6486            var viewSpec;
6487            var buttonClick;
6488            var buttonIcon; // only one of these will be set
6489            var buttonText; // "
6490            if ((customButtonProps = calendarCustomButtons[buttonName])) {
6491                buttonClick = function (ev) {
6492                    if (customButtonProps.click) {
6493                        customButtonProps.click.call(ev.target, ev, ev.target);
6494                    }
6495                };
6496                (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
6497                    (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
6498                    (buttonText = customButtonProps.text);
6499            }
6500            else if ((viewSpec = viewSpecs[buttonName])) {
6501                viewsWithButtons.push(buttonName);
6502                buttonClick = function () {
6503                    calendarApi.changeView(buttonName);
6504                };
6505                (buttonText = viewSpec.buttonTextOverride) ||
6506                    (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
6507                    (buttonText = viewSpec.buttonTextDefault);
6508            }
6509            else if (calendarApi[buttonName]) { // a calendarApi method
6510                buttonClick = function () {
6511                    calendarApi[buttonName]();
6512                };
6513                (buttonText = calendarButtonTextOverrides[buttonName]) ||
6514                    (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||
6515                    (buttonText = calendarButtonText[buttonName]);
6516                //            ^ everything else is considered default
6517            }
6518            return { buttonName: buttonName, buttonClick: buttonClick, buttonIcon: buttonIcon, buttonText: buttonText };
6519        })); });
6520    }
6521
6522    var eventSourceDef = {
6523        ignoreRange: true,
6524        parseMeta: function (refined) {
6525            if (Array.isArray(refined.events)) {
6526                return refined.events;
6527            }
6528            return null;
6529        },
6530        fetch: function (arg, success) {
6531            success({
6532                rawEvents: arg.eventSource.meta,
6533            });
6534        },
6535    };
6536    var arrayEventSourcePlugin = createPlugin({
6537        eventSourceDefs: [eventSourceDef],
6538    });
6539
6540    var eventSourceDef$1 = {
6541        parseMeta: function (refined) {
6542            if (typeof refined.events === 'function') {
6543                return refined.events;
6544            }
6545            return null;
6546        },
6547        fetch: function (arg, success, failure) {
6548            var dateEnv = arg.context.dateEnv;
6549            var func = arg.eventSource.meta;
6550            unpromisify(func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), function (rawEvents) {
6551                success({ rawEvents: rawEvents }); // needs an object response
6552            }, failure);
6553        },
6554    };
6555    var funcEventSourcePlugin = createPlugin({
6556        eventSourceDefs: [eventSourceDef$1],
6557    });
6558
6559    function requestJson(method, url, params, successCallback, failureCallback) {
6560        method = method.toUpperCase();
6561        var body = null;
6562        if (method === 'GET') {
6563            url = injectQueryStringParams(url, params);
6564        }
6565        else {
6566            body = encodeParams(params);
6567        }
6568        var xhr = new XMLHttpRequest();
6569        xhr.open(method, url, true);
6570        if (method !== 'GET') {
6571            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
6572        }
6573        xhr.onload = function () {
6574            if (xhr.status >= 200 && xhr.status < 400) {
6575                var parsed = false;
6576                var res = void 0;
6577                try {
6578                    res = JSON.parse(xhr.responseText);
6579                    parsed = true;
6580                }
6581                catch (err) {
6582                    // will handle parsed=false
6583                }
6584                if (parsed) {
6585                    successCallback(res, xhr);
6586                }
6587                else {
6588                    failureCallback('Failure parsing JSON', xhr);
6589                }
6590            }
6591            else {
6592                failureCallback('Request failed', xhr);
6593            }
6594        };
6595        xhr.onerror = function () {
6596            failureCallback('Request failed', xhr);
6597        };
6598        xhr.send(body);
6599    }
6600    function injectQueryStringParams(url, params) {
6601        return url +
6602            (url.indexOf('?') === -1 ? '?' : '&') +
6603            encodeParams(params);
6604    }
6605    function encodeParams(params) {
6606        var parts = [];
6607        for (var key in params) {
6608            parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
6609        }
6610        return parts.join('&');
6611    }
6612
6613    var JSON_FEED_EVENT_SOURCE_REFINERS = {
6614        method: String,
6615        extraParams: identity,
6616        startParam: String,
6617        endParam: String,
6618        timeZoneParam: String,
6619    };
6620
6621    var eventSourceDef$2 = {
6622        parseMeta: function (refined) {
6623            if (refined.url && (refined.format === 'json' || !refined.format)) {
6624                return {
6625                    url: refined.url,
6626                    format: 'json',
6627                    method: (refined.method || 'GET').toUpperCase(),
6628                    extraParams: refined.extraParams,
6629                    startParam: refined.startParam,
6630                    endParam: refined.endParam,
6631                    timeZoneParam: refined.timeZoneParam,
6632                };
6633            }
6634            return null;
6635        },
6636        fetch: function (arg, success, failure) {
6637            var meta = arg.eventSource.meta;
6638            var requestParams = buildRequestParams(meta, arg.range, arg.context);
6639            requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) {
6640                success({ rawEvents: rawEvents, xhr: xhr });
6641            }, function (errorMessage, xhr) {
6642                failure({ message: errorMessage, xhr: xhr });
6643            });
6644        },
6645    };
6646    var jsonFeedEventSourcePlugin = createPlugin({
6647        eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS,
6648        eventSourceDefs: [eventSourceDef$2],
6649    });
6650    function buildRequestParams(meta, range, context) {
6651        var dateEnv = context.dateEnv, options = context.options;
6652        var startParam;
6653        var endParam;
6654        var timeZoneParam;
6655        var customRequestParams;
6656        var params = {};
6657        startParam = meta.startParam;
6658        if (startParam == null) {
6659            startParam = options.startParam;
6660        }
6661        endParam = meta.endParam;
6662        if (endParam == null) {
6663            endParam = options.endParam;
6664        }
6665        timeZoneParam = meta.timeZoneParam;
6666        if (timeZoneParam == null) {
6667            timeZoneParam = options.timeZoneParam;
6668        }
6669        // retrieve any outbound GET/POST data from the options
6670        if (typeof meta.extraParams === 'function') {
6671            // supplied as a function that returns a key/value object
6672            customRequestParams = meta.extraParams();
6673        }
6674        else {
6675            // probably supplied as a straight key/value object
6676            customRequestParams = meta.extraParams || {};
6677        }
6678        __assign(params, customRequestParams);
6679        params[startParam] = dateEnv.formatIso(range.start);
6680        params[endParam] = dateEnv.formatIso(range.end);
6681        if (dateEnv.timeZone !== 'local') {
6682            params[timeZoneParam] = dateEnv.timeZone;
6683        }
6684        return params;
6685    }
6686
6687    var SIMPLE_RECURRING_REFINERS = {
6688        daysOfWeek: identity,
6689        startTime: createDuration,
6690        endTime: createDuration,
6691        duration: createDuration,
6692        startRecur: identity,
6693        endRecur: identity,
6694    };
6695
6696    var recurring = {
6697        parse: function (refined, dateEnv) {
6698            if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) {
6699                var recurringData = {
6700                    daysOfWeek: refined.daysOfWeek || null,
6701                    startTime: refined.startTime || null,
6702                    endTime: refined.endTime || null,
6703                    startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,
6704                    endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null,
6705                };
6706                var duration = void 0;
6707                if (refined.duration) {
6708                    duration = refined.duration;
6709                }
6710                if (!duration && refined.startTime && refined.endTime) {
6711                    duration = subtractDurations(refined.endTime, refined.startTime);
6712                }
6713                return {
6714                    allDayGuess: Boolean(!refined.startTime && !refined.endTime),
6715                    duration: duration,
6716                    typeData: recurringData,
6717                };
6718            }
6719            return null;
6720        },
6721        expand: function (typeData, framingRange, dateEnv) {
6722            var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
6723            if (clippedFramingRange) {
6724                return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
6725            }
6726            return [];
6727        },
6728    };
6729    var simpleRecurringEventsPlugin = createPlugin({
6730        recurringTypes: [recurring],
6731        eventRefiners: SIMPLE_RECURRING_REFINERS,
6732    });
6733    function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
6734        var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
6735        var dayMarker = startOfDay(framingRange.start);
6736        var endMarker = framingRange.end;
6737        var instanceStarts = [];
6738        while (dayMarker < endMarker) {
6739            var instanceStart 
6740            // if everyday, or this particular day-of-week
6741            = void 0;
6742            // if everyday, or this particular day-of-week
6743            if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
6744                if (startTime) {
6745                    instanceStart = dateEnv.add(dayMarker, startTime);
6746                }
6747                else {
6748                    instanceStart = dayMarker;
6749                }
6750                instanceStarts.push(instanceStart);
6751            }
6752            dayMarker = addDays(dayMarker, 1);
6753        }
6754        return instanceStarts;
6755    }
6756
6757    var changeHandlerPlugin = createPlugin({
6758        optionChangeHandlers: {
6759            events: function (events, context) {
6760                handleEventSources([events], context);
6761            },
6762            eventSources: handleEventSources,
6763        },
6764    });
6765    /*
6766    BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out
6767    */
6768    function handleEventSources(inputs, context) {
6769        var unfoundSources = hashValuesToArray(context.getCurrentData().eventSources);
6770        var newInputs = [];
6771        for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
6772            var input = inputs_1[_i];
6773            var inputFound = false;
6774            for (var i = 0; i < unfoundSources.length; i += 1) {
6775                if (unfoundSources[i]._raw === input) {
6776                    unfoundSources.splice(i, 1); // delete
6777                    inputFound = true;
6778                    break;
6779                }
6780            }
6781            if (!inputFound) {
6782                newInputs.push(input);
6783            }
6784        }
6785        for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) {
6786            var unfoundSource = unfoundSources_1[_a];
6787            context.dispatch({
6788                type: 'REMOVE_EVENT_SOURCE',
6789                sourceId: unfoundSource.sourceId,
6790            });
6791        }
6792        for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) {
6793            var newInput = newInputs_1[_b];
6794            context.calendarApi.addEventSource(newInput);
6795        }
6796    }
6797
6798    function handleDateProfile(dateProfile, context) {
6799        context.emitter.trigger('datesSet', __assign(__assign({}, buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi }));
6800    }
6801
6802    function handleEventStore(eventStore, context) {
6803        var emitter = context.emitter;
6804        if (emitter.hasHandlers('eventsSet')) {
6805            emitter.trigger('eventsSet', buildEventApis(eventStore, context));
6806        }
6807    }
6808
6809    /*
6810    this array is exposed on the root namespace so that UMD plugins can add to it.
6811    see the rollup-bundles script.
6812    */
6813    var globalPlugins = [
6814        arrayEventSourcePlugin,
6815        funcEventSourcePlugin,
6816        jsonFeedEventSourcePlugin,
6817        simpleRecurringEventsPlugin,
6818        changeHandlerPlugin,
6819        createPlugin({
6820            isLoadingFuncs: [
6821                function (state) { return computeEventSourcesLoading(state.eventSources); },
6822            ],
6823            contentTypeHandlers: {
6824                html: function () { return ({ render: injectHtml }); },
6825                domNodes: function () { return ({ render: injectDomNodes }); },
6826            },
6827            propSetHandlers: {
6828                dateProfile: handleDateProfile,
6829                eventStore: handleEventStore,
6830            },
6831        }),
6832    ];
6833    function injectHtml(el, html) {
6834        el.innerHTML = html;
6835    }
6836    function injectDomNodes(el, domNodes) {
6837        var oldNodes = Array.prototype.slice.call(el.childNodes); // TODO: use array util
6838        var newNodes = Array.prototype.slice.call(domNodes); // TODO: use array util
6839        if (!isArraysEqual(oldNodes, newNodes)) {
6840            for (var _i = 0, newNodes_1 = newNodes; _i < newNodes_1.length; _i++) {
6841                var newNode = newNodes_1[_i];
6842                el.appendChild(newNode);
6843            }
6844            oldNodes.forEach(removeElement);
6845        }
6846    }
6847
6848    var DelayedRunner = /** @class */ (function () {
6849        function DelayedRunner(drainedOption) {
6850            this.drainedOption = drainedOption;
6851            this.isRunning = false;
6852            this.isDirty = false;
6853            this.pauseDepths = {};
6854            this.timeoutId = 0;
6855        }
6856        DelayedRunner.prototype.request = function (delay) {
6857            this.isDirty = true;
6858            if (!this.isPaused()) {
6859                this.clearTimeout();
6860                if (delay == null) {
6861                    this.tryDrain();
6862                }
6863                else {
6864                    this.timeoutId = setTimeout(// NOT OPTIMAL! TODO: look at debounce
6865                    this.tryDrain.bind(this), delay);
6866                }
6867            }
6868        };
6869        DelayedRunner.prototype.pause = function (scope) {
6870            if (scope === void 0) { scope = ''; }
6871            var pauseDepths = this.pauseDepths;
6872            pauseDepths[scope] = (pauseDepths[scope] || 0) + 1;
6873            this.clearTimeout();
6874        };
6875        DelayedRunner.prototype.resume = function (scope, force) {
6876            if (scope === void 0) { scope = ''; }
6877            var pauseDepths = this.pauseDepths;
6878            if (scope in pauseDepths) {
6879                if (force) {
6880                    delete pauseDepths[scope];
6881                }
6882                else {
6883                    pauseDepths[scope] -= 1;
6884                    var depth = pauseDepths[scope];
6885                    if (depth <= 0) {
6886                        delete pauseDepths[scope];
6887                    }
6888                }
6889                this.tryDrain();
6890            }
6891        };
6892        DelayedRunner.prototype.isPaused = function () {
6893            return Object.keys(this.pauseDepths).length;
6894        };
6895        DelayedRunner.prototype.tryDrain = function () {
6896            if (!this.isRunning && !this.isPaused()) {
6897                this.isRunning = true;
6898                while (this.isDirty) {
6899                    this.isDirty = false;
6900                    this.drained(); // might set isDirty to true again
6901                }
6902                this.isRunning = false;
6903            }
6904        };
6905        DelayedRunner.prototype.clear = function () {
6906            this.clearTimeout();
6907            this.isDirty = false;
6908            this.pauseDepths = {};
6909        };
6910        DelayedRunner.prototype.clearTimeout = function () {
6911            if (this.timeoutId) {
6912                clearTimeout(this.timeoutId);
6913                this.timeoutId = 0;
6914            }
6915        };
6916        DelayedRunner.prototype.drained = function () {
6917            if (this.drainedOption) {
6918                this.drainedOption();
6919            }
6920        };
6921        return DelayedRunner;
6922    }());
6923
6924    var TaskRunner = /** @class */ (function () {
6925        function TaskRunner(runTaskOption, drainedOption) {
6926            this.runTaskOption = runTaskOption;
6927            this.drainedOption = drainedOption;
6928            this.queue = [];
6929            this.delayedRunner = new DelayedRunner(this.drain.bind(this));
6930        }
6931        TaskRunner.prototype.request = function (task, delay) {
6932            this.queue.push(task);
6933            this.delayedRunner.request(delay);
6934        };
6935        TaskRunner.prototype.pause = function (scope) {
6936            this.delayedRunner.pause(scope);
6937        };
6938        TaskRunner.prototype.resume = function (scope, force) {
6939            this.delayedRunner.resume(scope, force);
6940        };
6941        TaskRunner.prototype.drain = function () {
6942            var queue = this.queue;
6943            while (queue.length) {
6944                var completedTasks = [];
6945                var task = void 0;
6946                while ((task = queue.shift())) {
6947                    this.runTask(task);
6948                    completedTasks.push(task);
6949                }
6950                this.drained(completedTasks);
6951            } // keep going, in case new tasks were added in the drained handler
6952        };
6953        TaskRunner.prototype.runTask = function (task) {
6954            if (this.runTaskOption) {
6955                this.runTaskOption(task);
6956            }
6957        };
6958        TaskRunner.prototype.drained = function (completedTasks) {
6959            if (this.drainedOption) {
6960                this.drainedOption(completedTasks);
6961            }
6962        };
6963        return TaskRunner;
6964    }());
6965
6966    // Computes what the title at the top of the calendarApi should be for this view
6967    function buildTitle(dateProfile, viewOptions, dateEnv) {
6968        var range;
6969        // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
6970        if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
6971            range = dateProfile.currentRange;
6972        }
6973        else { // for day units or smaller, use the actual day range
6974            range = dateProfile.activeRange;
6975        }
6976        return dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), {
6977            isEndExclusive: dateProfile.isRangeAllDay,
6978            defaultSeparator: viewOptions.titleRangeSeparator,
6979        });
6980    }
6981    // Generates the format string that should be used to generate the title for the current date range.
6982    // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
6983    function buildTitleFormat(dateProfile) {
6984        var currentRangeUnit = dateProfile.currentRangeUnit;
6985        if (currentRangeUnit === 'year') {
6986            return { year: 'numeric' };
6987        }
6988        if (currentRangeUnit === 'month') {
6989            return { year: 'numeric', month: 'long' }; // like "September 2014"
6990        }
6991        var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
6992        if (days !== null && days > 1) {
6993            // multi-day range. shorter, like "Sep 9 - 10 2014"
6994            return { year: 'numeric', month: 'short', day: 'numeric' };
6995        }
6996        // one day. longer, like "September 9 2014"
6997        return { year: 'numeric', month: 'long', day: 'numeric' };
6998    }
6999
7000    // in future refactor, do the redux-style function(state=initial) for initial-state
7001    // also, whatever is happening in constructor, have it happen in action queue too
7002    var CalendarDataManager = /** @class */ (function () {
7003        function CalendarDataManager(props) {
7004            var _this = this;
7005            this.computeOptionsData = memoize(this._computeOptionsData);
7006            this.computeCurrentViewData = memoize(this._computeCurrentViewData);
7007            this.organizeRawLocales = memoize(organizeRawLocales);
7008            this.buildLocale = memoize(buildLocale);
7009            this.buildPluginHooks = buildBuildPluginHooks();
7010            this.buildDateEnv = memoize(buildDateEnv$1);
7011            this.buildTheme = memoize(buildTheme);
7012            this.parseToolbars = memoize(parseToolbars);
7013            this.buildViewSpecs = memoize(buildViewSpecs);
7014            this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator);
7015            this.buildViewApi = memoize(buildViewApi);
7016            this.buildViewUiProps = memoizeObjArg(buildViewUiProps);
7017            this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual);
7018            this.buildEventUiBases = memoize(buildEventUiBases);
7019            this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours);
7020            this.buildTitle = memoize(buildTitle);
7021            this.emitter = new Emitter();
7022            this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));
7023            this.currentCalendarOptionsInput = {};
7024            this.currentCalendarOptionsRefined = {};
7025            this.currentViewOptionsInput = {};
7026            this.currentViewOptionsRefined = {};
7027            this.currentCalendarOptionsRefiners = {};
7028            this.getCurrentData = function () { return _this.data; };
7029            this.dispatch = function (action) {
7030                _this.actionRunner.request(action); // protects against recursive calls to _handleAction
7031            };
7032            this.props = props;
7033            this.actionRunner.pause();
7034            var dynamicOptionOverrides = {};
7035            var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
7036            var currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;
7037            var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
7038            // wire things up
7039            // TODO: not DRY
7040            props.calendarApi.currentDataManager = this;
7041            this.emitter.setThisContext(props.calendarApi);
7042            this.emitter.setOptions(currentViewData.options);
7043            var currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv);
7044            var dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
7045            if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) {
7046                currentDate = dateProfile.currentRange.start;
7047            }
7048            var calendarContext = {
7049                dateEnv: optionsData.dateEnv,
7050                options: optionsData.calendarOptions,
7051                pluginHooks: optionsData.pluginHooks,
7052                calendarApi: props.calendarApi,
7053                dispatch: this.dispatch,
7054                emitter: this.emitter,
7055                getCurrentData: this.getCurrentData,
7056            };
7057            // needs to be after setThisContext
7058            for (var _i = 0, _a = optionsData.pluginHooks.contextInit; _i < _a.length; _i++) {
7059                var callback = _a[_i];
7060                callback(calendarContext);
7061            }
7062            // NOT DRY
7063            var eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext);
7064            var initialState = {
7065                dynamicOptionOverrides: dynamicOptionOverrides,
7066                currentViewType: currentViewType,
7067                currentDate: currentDate,
7068                dateProfile: dateProfile,
7069                businessHours: this.parseContextBusinessHours(calendarContext),
7070                eventSources: eventSources,
7071                eventUiBases: {},
7072                eventStore: createEmptyEventStore(),
7073                renderableEventStore: createEmptyEventStore(),
7074                dateSelection: null,
7075                eventSelection: '',
7076                eventDrag: null,
7077                eventResize: null,
7078                selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig,
7079            };
7080            var contextAndState = __assign(__assign({}, calendarContext), initialState);
7081            for (var _b = 0, _c = optionsData.pluginHooks.reducers; _b < _c.length; _b++) {
7082                var reducer = _c[_b];
7083                __assign(initialState, reducer(null, null, contextAndState));
7084            }
7085            if (computeIsLoading(initialState, calendarContext)) {
7086                this.emitter.trigger('loading', true); // NOT DRY
7087            }
7088            this.state = initialState;
7089            this.updateData();
7090            this.actionRunner.resume();
7091        }
7092        CalendarDataManager.prototype.resetOptions = function (optionOverrides, append) {
7093            var props = this.props;
7094            props.optionOverrides = append
7095                ? __assign(__assign({}, props.optionOverrides), optionOverrides) : optionOverrides;
7096            this.actionRunner.request({
7097                type: 'NOTHING',
7098            });
7099        };
7100        CalendarDataManager.prototype._handleAction = function (action) {
7101            var _a = this, props = _a.props, state = _a.state, emitter = _a.emitter;
7102            var dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action);
7103            var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
7104            var currentViewType = reduceViewType(state.currentViewType, action);
7105            var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
7106            // wire things up
7107            // TODO: not DRY
7108            props.calendarApi.currentDataManager = this;
7109            emitter.setThisContext(props.calendarApi);
7110            emitter.setOptions(currentViewData.options);
7111            var calendarContext = {
7112                dateEnv: optionsData.dateEnv,
7113                options: optionsData.calendarOptions,
7114                pluginHooks: optionsData.pluginHooks,
7115                calendarApi: props.calendarApi,
7116                dispatch: this.dispatch,
7117                emitter: emitter,
7118                getCurrentData: this.getCurrentData,
7119            };
7120            var currentDate = state.currentDate, dateProfile = state.dateProfile;
7121            if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack
7122                dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
7123            }
7124            currentDate = reduceCurrentDate(currentDate, action);
7125            dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator);
7126            if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) {
7127                currentDate = dateProfile.currentRange.start;
7128            }
7129            var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext);
7130            var eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext);
7131            var isEventsLoading = computeEventSourcesLoading(eventSources);
7131 // BAD. also called in this func in computeIsLoading
7132            var renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ?
7133                (state.renderableEventStore || eventStore) : // try from previous state
7134                eventStore;
7135            var _b = this.buildViewUiProps(calendarContext), eventUiSingleBase = _b.eventUiSingleBase, selectionConfig = _b.selectionConfig; // will memoize obj
7136            var eventUiBySource = this.buildEventUiBySource(eventSources);
7137            var eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
7138            var newState = {
7139                dynamicOptionOverrides: dynamicOptionOverrides,
7140                currentViewType: currentViewType,
7141                currentDate: currentDate,
7142                dateProfile: dateProfile,
7143                eventSources: eventSources,
7144                eventStore: eventStore,
7145                renderableEventStore: renderableEventStore,
7146                selectionConfig: selectionConfig,
7147                eventUiBases: eventUiBases,
7148                businessHours: this.parseContextBusinessHours(calendarContext),
7149                dateSelection: reduceDateSelection(state.dateSelection, action),
7150                eventSelection: reduceSelectedEvent(state.eventSelection, action),
7151                eventDrag: reduceEventDrag(state.eventDrag, action),
7152                eventResize: reduceEventResize(state.eventResize, action),
7153            };
7154            var contextAndState = __assign(__assign({}, calendarContext), newState);
7155            for (var _i = 0, _c = optionsData.pluginHooks.reducers; _i < _c.length; _i++) {
7156                var reducer = _c[_i];
7157                __assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value
7158            }
7159            var wasLoading = computeIsLoading(state, calendarContext);
7160            var isLoading = computeIsLoading(newState, calendarContext);
7161            // TODO: use propSetHandlers in plugin system
7162            if (!wasLoading && isLoading) {
7163                emitter.trigger('loading', true);
7164            }
7165            else if (wasLoading && !isLoading) {
7166                emitter.trigger('loading', false);
7167            }
7168            this.state = newState;
7169            if (props.onAction) {
7170                props.onAction(action);
7171            }
7172        };
7173        CalendarDataManager.prototype.updateData = function () {
7174            var _a = this, props = _a.props, state = _a.state;
7175            var oldData = this.data;
7176            var optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);
7177            var currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);
7178            var data = this.data = __assign(__assign(__assign({ viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state);
7179            var changeHandlers = optionsData.pluginHooks.optionChangeHandlers;
7180            var oldCalendarOptions = oldData && oldData.calendarOptions;
7181            var newCalendarOptions = optionsData.calendarOptions;
7182            if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) {
7183                if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) {
7184                    // hack
7185                    state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data);
7186                    state.eventStore = data.eventStore = rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv);
7187                }
7188                for (var optionName in changeHandlers) {
7189                    if (oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) {
7190                        changeHandlers[optionName](newCalendarOptions[optionName], data);
7191                    }
7192                }
7193            }
7194            if (props.onData) {
7195                props.onData(data);
7196            }
7197        };
7198        CalendarDataManager.prototype._computeOptionsData = function (optionOverrides, dynamicOptionOverrides, calendarApi) {
7199            // TODO: blacklist options that are handled by optionChangeHandlers
7200            var _a = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, pluginHooks = _a.pluginHooks, localeDefaults = _a.localeDefaults, availableLocaleData = _a.availableLocaleData, extra = _a.extra;
7201            warnUnknownOptions(extra);
7202            var dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator);
7203            var viewSpecs = this.buildViewSpecs(pluginHooks.views, optionOverrides, dynamicOptionOverrides, localeDefaults);
7204            var theme = this.buildTheme(refinedOptions, pluginHooks);
7205            var toolbarConfig = this.parseToolbars(refinedOptions, optionOverrides, theme, viewSpecs, calendarApi);
7206            return {
7207                calendarOptions: refinedOptions,
7208                pluginHooks: pluginHooks,
7209                dateEnv: dateEnv,
7210                viewSpecs: viewSpecs,
7211                theme: theme,
7212                toolbarConfig: toolbarConfig,
7213                localeDefaults: localeDefaults,
7214                availableRawLocales: availableLocaleData.map,
7215            };
7216        };
7217        // always called from behind a memoizer
7218        CalendarDataManager.prototype.processRawCalendarOptions = function (optionOverrides, dynamicOptionOverrides) {
7219            var _a = mergeRawOptions([
7220                BASE_OPTION_DEFAULTS,
7221                optionOverrides,
7222                dynamicOptionOverrides,
7223            ]), locales = _a.locales, locale = _a.locale;
7224            var availableLocaleData = this.organizeRawLocales(locales);
7225            var availableRawLocales = availableLocaleData.map;
7226            var localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options;
7227            var pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins);
7228            var refiners = this.currentCalendarOptionsRefiners = __assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7229            var extra = {};
7230            var raw = mergeRawOptions([
7231                BASE_OPTION_DEFAULTS,
7232                localeDefaults,
7233                optionOverrides,
7234                dynamicOptionOverrides,
7235            ]);
7236            var refined = {};
7237            var currentRaw = this.currentCalendarOptionsInput;
7238            var currentRefined = this.currentCalendarOptionsRefined;
7239            var anyChanges = false;
7240            for (var optionName in raw) {
7241                if (optionName !== 'plugins') { // because plugins is special-cased
7242                    if (raw[optionName] === currentRaw[optionName] ||
7243                        (COMPLEX_OPTION_COMPARATORS[optionName] &&
7244                            (optionName in currentRaw) &&
7245                            COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName]))) {
7246                        refined[optionName] = currentRefined[optionName];
7247                    }
7248                    else if (refiners[optionName]) {
7249                        refined[optionName] = refiners[optionName](raw[optionName]);
7250                        anyChanges = true;
7251                    }
7252                    else {
7253                        extra[optionName] = currentRaw[optionName];
7254                    }
7255                }
7256            }
7257            if (anyChanges) {
7258                this.currentCalendarOptionsInput = raw;
7259                this.currentCalendarOptionsRefined = refined;
7260            }
7261            return {
7262                rawOptions: this.currentCalendarOptionsInput,
7263                refinedOptions: this.currentCalendarOptionsRefined,
7264                pluginHooks: pluginHooks,
7265                availableLocaleData: availableLocaleData,
7266                localeDefaults: localeDefaults,
7267                extra: extra,
7268            };
7269        };
7270        CalendarDataManager.prototype._computeCurrentViewData = function (viewType, optionsData, optionOverrides, dynamicOptionOverrides) {
7271            var viewSpec = optionsData.viewSpecs[viewType];
7272            if (!viewSpec) {
7273                throw new Error("viewType \"" + viewType + "\" is not available. Please make sure you've loaded all neccessary plugins");
7274            }
7275            var _a = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, extra = _a.extra;
7276            warnUnknownOptions(extra);
7277            var dateProfileGenerator = this.buildDateProfileGenerator({
7278                dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,
7279                duration: viewSpec.duration,
7280                durationUnit: viewSpec.durationUnit,
7281                usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,
7282                dateEnv: optionsData.dateEnv,
7283                calendarApi: this.props.calendarApi,
7284                slotMinTime: refinedOptions.slotMinTime,
7285                slotMaxTime: refinedOptions.slotMaxTime,
7286                showNonCurrentDates: refinedOptions.showNonCurrentDates,
7287                dayCount: refinedOptions.dayCount,
7288                dateAlignment: refinedOptions.dateAlignment,
7289                dateIncrement: refinedOptions.dateIncrement,
7290                hiddenDays: refinedOptions.hiddenDays,
7291                weekends: refinedOptions.weekends,
7292                nowInput: refinedOptions.now,
7293                validRangeInput: refinedOptions.validRange,
7294                visibleRangeInput: refinedOptions.visibleRange,
7295                monthMode: refinedOptions.monthMode,
7296                fixedWeekCount: refinedOptions.fixedWeekCount,
7297            });
7298            var viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv);
7299            return { viewSpec: viewSpec, options: refinedOptions, dateProfileGenerator: dateProfileGenerator, viewApi: viewApi };
7300        };
7301        CalendarDataManager.prototype.processRawViewOptions = function (viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) {
7302            var raw = mergeRawOptions([
7303                BASE_OPTION_DEFAULTS,
7304                viewSpec.optionDefaults,
7305                localeDefaults,
7306                optionOverrides,
7307                viewSpec.optionOverrides,
7308                dynamicOptionOverrides,
7309            ]);
7310            var refiners = __assign(__assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7311            var refined = {};
7312            var currentRaw = this.currentViewOptionsInput;
7313            var currentRefined = this.currentViewOptionsRefined;
7314            var anyChanges = false;
7315            var extra = {};
7316            for (var optionName in raw) {
7317                if (raw[optionName] === currentRaw[optionName]) {
7318                    refined[optionName] = currentRefined[optionName];
7319                }
7320                else {
7321                    if (raw[optionName] === this.currentCalendarOptionsInput[optionName]) {
7322                        if (optionName in this.currentCalendarOptionsRefined) { // might be an "extra" prop
7323                            refined[optionName] = this.currentCalendarOptionsRefined[optionName];
7324                        }
7325                    }
7326                    else if (refiners[optionName]) {
7327                        refined[optionName] = refiners[optionName](raw[optionName]);
7328                    }
7329                    else {
7330                        extra[optionName] = raw[optionName];
7331                    }
7332                    anyChanges = true;
7333                }
7334            }
7335            if (anyChanges) {
7336                this.currentViewOptionsInput = raw;
7337                this.currentViewOptionsRefined = refined;
7338            }
7339            return {
7340                rawOptions: this.currentViewOptionsInput,
7341                refinedOptions: this.currentViewOptionsRefined,
7342                extra: extra,
7343            };
7344        };
7345        return CalendarDataManager;
7346    }());
7347    function buildDateEnv$1(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) {
7348        var locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map);
7349        return new DateEnv({
7350            calendarSystem: 'gregory',
7351            timeZone: timeZone,
7352            namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl,
7353            locale: locale,
7354            weekNumberCalculation: weekNumberCalculation,
7355            firstDay: firstDay,
7356            weekText: weekText,
7357            cmdFormatter: pluginHooks.cmdFormatter,
7358            defaultSeparator: defaultSeparator,
7359        });
7360    }
7361    function buildTheme(options, pluginHooks) {
7362        var ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme;
7363        return new ThemeClass(options);
7364    }
7365    function buildDateProfileGenerator(props) {
7366        var DateProfileGeneratorClass = props.dateProfileGeneratorClass || DateProfileGenerator;
7367        return new DateProfileGeneratorClass(props);
7368    }
7369    function buildViewApi(type, getCurrentData, dateEnv) {
7370        return new ViewApi(type, getCurrentData, dateEnv);
7371    }
7372    function buildEventUiBySource(eventSources) {
7373        return mapHash(eventSources, function (eventSource) { return eventSource.ui; });
7374    }
7375    function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
7376        var eventUiBases = { '': eventUiSingleBase };
7377        for (var defId in eventDefs) {
7378            var def = eventDefs[defId];
7379            if (def.sourceId && eventUiBySource[def.sourceId]) {
7380                eventUiBases[defId] = eventUiBySource[def.sourceId];
7381            }
7382        }
7383        return eventUiBases;
7384    }
7385    function buildViewUiProps(calendarContext) {
7386        var options = calendarContext.options;
7387        return {
7388            eventUiSingleBase: createEventUi({
7389                display: options.eventDisplay,
7390                editable: options.editable,
7391                startEditable: options.eventStartEditable,
7392                durationEditable: options.eventDurationEditable,
7393                constraint: options.eventConstraint,
7394                overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined,
7395                allow: options.eventAllow,
7396                backgroundColor: options.eventBackgroundColor,
7397                borderColor: options.eventBorderColor,
7398                textColor: options.eventTextColor,
7399                color: options.eventColor,
7400            }, calendarContext),
7401            selectionConfig: createEventUi({
7402                constraint: options.selectConstraint,
7403                overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined,
7404                allow: options.selectAllow,
7405            }, calendarContext),
7406        };
7407    }
7408    function computeIsLoading(state, context) {
7409        for (var _i = 0, _a = context.pluginHooks.isLoadingFuncs; _i < _a.length; _i++) {
7410            var isLoadingFunc = _a[_i];
7411            if (isLoadingFunc(state)) {
7412                return true;
7413            }
7414        }
7415        return false;
7416    }
7417    function parseContextBusinessHours(calendarContext) {
7418        return parseBusinessHours(calendarContext.options.businessHours, calendarContext);
7419    }
7420    function warnUnknownOptions(options, viewName) {
7421        for (var optionName in options) {
7422            console.warn("Unknown option '" + optionName + "'" +
7423                (viewName ? " for view '" + viewName + "'" : ''));
7424        }
7425    }
7426
7427    // TODO: move this to react plugin?
7428    var CalendarDataProvider = /** @class */ (function (_super) {
7429        __extends(CalendarDataProvider, _super);
7430        function CalendarDataProvider(props) {
7431            var _this = _super.call(this, props) || this;
7432            _this.handleData = function (data) {
7433                if (!_this.dataManager) { // still within initial run, before assignment in constructor
7434                    // eslint-disable-next-line react/no-direct-mutation-state
7435                    _this.state = data; // can't use setState yet
7436                }
7437                else {
7438                    _this.setState(data);
7439                }
7440            };
7441            _this.dataManager = new CalendarDataManager({
7442                optionOverrides: props.optionOverrides,
7443                calendarApi: props.calendarApi,
7444                onData: _this.handleData,
7445            });
7446            return _this;
7447        }
7448        CalendarDataProvider.prototype.render = function () {
7449            return this.props.children(this.state);
7450        };
7451        CalendarDataProvider.prototype.componentDidUpdate = function (prevProps) {
7452            var newOptionOverrides = this.props.optionOverrides;
7453            if (newOptionOverrides !== prevProps.optionOverrides) { // prevent recursive handleData
7454                this.dataManager.resetOptions(newOptionOverrides);
7455            }
7456        };
7457        return CalendarDataProvider;
7458    }(Component));
7459
7460    // HELPERS
7461    /*
7462    if nextDayThreshold is specified, slicing is done in an all-day fashion.
7463    you can get nextDayThreshold from context.nextDayThreshold
7464    */
7465    function sliceEvents(props, allDay) {
7466        return sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;
7467    }
7468
7469    var NamedTimeZoneImpl = /** @class */ (function () {
7470        function NamedTimeZoneImpl(timeZoneName) {
7471            this.timeZoneName = timeZoneName;
7472        }
7473        return NamedTimeZoneImpl;
7474    }());
7475
7476    var Interaction = /** @class */ (function () {
7477        function Interaction(settings) {
7478            this.component = settings.component;
7479        }
7480        Interaction.prototype.destroy = function () {
7481        };
7482        return Interaction;
7483    }());
7484    function parseInteractionSettings(component, input) {
7485        return {
7486            component: component,
7487            el: input.el,
7488            useEventCenter: input.useEventCenter != null ? input.useEventCenter : true,
7489        };
7490    }
7491    function interactionSettingsToStore(settings) {
7492        var _a;
7493        return _a = {},
7494            _a[settings.component.uid] = settings,
7495            _a;
7496    }
7497    // global state
7498    var interactionSettingsStore = {};
7499
7500    /*
7501    An abstraction for a dragging interaction originating on an event.
7502    Does higher-level things than PointerDragger, such as possibly:
7503    - a "mirror" that moves with the pointer
7504    - a minimum number of pixels or other criteria for a true drag to begin
7505
7506    subclasses must emit:
7507    - pointerdown
7508    - dragstart
7509    - dragmove
7510    - pointerup
7511    - dragend
7512    */
7513    var ElementDragging = /** @class */ (function () {
7514        function ElementDragging(el, selector) {
7515            this.emitter = new Emitter();
7516        }
7517        ElementDragging.prototype.destroy = function () {
7518        };
7519        ElementDragging.prototype.setMirrorIsVisible = function (bool) {
7520            // optional if subclass doesn't want to support a mirror
7521        };
7522        ElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
7523            // optional if subclass doesn't want to support a mirror
7524        };
7525        ElementDragging.prototype.setAutoScrollEnabled = function (bool) {
7526            // optional
7527        };
7528        return ElementDragging;
7529    }());
7530
7531    // TODO: get rid of this in favor of options system,
7532    // tho it's really easy to access this globally rather than pass thru options.
7533    var config = {};
7534
7535    /*
7536    Information about what will happen when an external element is dragged-and-dropped
7537    onto a calendar. Contains information for creating an event.
7538    */
7539    var DRAG_META_REFINERS = {
7540        startTime: createDuration,
7541        duration: createDuration,
7542        create: Boolean,
7543        sourceId: String,
7544    };
7545    function parseDragMeta(raw) {
7546        var _a = refineProps(raw, DRAG_META_REFINERS), refined = _a.refined, extra = _a.extra;
7547        return {
7548            startTime: refined.startTime || null,
7549            duration: refined.duration || null,
7550            create: refined.create != null ? refined.create : true,
7551            sourceId: refined.sourceId,
7552            leftoverProps: extra,
7553        };
7554    }
7555
7556    var ToolbarSection = /** @class */ (function (_super) {
7557        __extends(ToolbarSection, _super);
7558        function ToolbarSection() {
7559            return _super !== null && _super.apply(this, arguments) || this;
7560        }
7561        ToolbarSection.prototype.render = function () {
7562            var _this = this;
7563            var children = this.props.widgetGroups.map(function (widgetGroup) { return _this.renderWidgetGroup(widgetGroup); });
7564            return createElement.apply(void 0, __spreadArrays(['div', { className: 'fc-toolbar-chunk' }], children));
7565        };
7566        ToolbarSection.prototype.renderWidgetGroup = function (widgetGroup) {
7567            var props = this.props;
7568            var theme = this.context.theme;
7569            var children = [];
7570            var isOnlyButtons = true;
7571            for (var _i = 0, widgetGroup_1 = widgetGroup; _i < widgetGroup_1.length; _i++) {
7572                var widget = widgetGroup_1[_i];
7573                var buttonName = widget.buttonName, buttonClick = widget.buttonClick, buttonText = widget.buttonText, buttonIcon = widget.buttonIcon;
7574                if (buttonName === 'title') {
7575                    isOnlyButtons = false;
7576                    children.push(createElement("h2", { className: "fc-toolbar-title" }, props.title));
7577                }
7578                else {
7579                    var ariaAttrs = buttonIcon ? { 'aria-label': buttonName } : {};
7580                    var buttonClasses = ["fc-" + buttonName + "-button", theme.getClass('button')];
7581                    if (buttonName === props.activeButton) {
7582                        buttonClasses.push(theme.getClass('buttonActive'));
7583                    }
7584                    var isDisabled = (!props.isTodayEnabled && buttonName === 'today') ||
7585                        (!props.isPrevEnabled && buttonName === 'prev') ||
7586                        (!props.isNextEnabled && buttonName === 'next');
7587                    children.push(createElement("button", __assign({ disabled: isDisabled, className: buttonClasses.join(' '), onClick: buttonClick, type: "button" }, ariaAttrs), buttonText || (buttonIcon ? createElement("span", { className: buttonIcon }) : '')));
7588                }
7589            }
7590            if (children.length > 1) {
7591                var groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || '';
7592                return createElement.apply(void 0, __spreadArrays(['div', { className: groupClassName }], children));
7593            }
7594            return children[0];
7595        };
7596        return ToolbarSection;
7597    }(BaseComponent));
7598
7599    var Toolbar = /** @class */ (function (_super) {
7600        __extends(Toolbar, _super);
7601        function Toolbar() {
7602            return _super !== null && _super.apply(this, arguments) || this;
7603        }
7604        Toolbar.prototype.render = function () {
7605            var _a = this.props, model = _a.model, extraClassName = _a.extraClassName;
7606            var forceLtr = false;
7607            var startContent;
7608            var endContent;
7609            var centerContent = model.center;
7610            if (model.left) {
7611                forceLtr = true;
7612                startContent = model.left;
7613            }
7614            else {
7615                startContent = model.start;
7616            }
7617            if (model.right) {
7618                forceLtr = true;
7619                endContent = model.right;
7620            }
7621            else {
7622                endContent = model.end;
7623            }
7624            var classNames = [
7625                extraClassName || '',
7626                'fc-toolbar',
7627                forceLtr ? 'fc-toolbar-ltr' : '',
7628            ];
7629            return (createElement("div", { className: classNames.join(' ') },
7630                this.renderSection('start', startContent || []),
7631                this.renderSection('center', centerContent || []),
7632                this.renderSection('end', endContent || [])));
7633        };
7634        Toolbar.prototype.renderSection = function (key, widgetGroups) {
7635            var props = this.props;
7636            return (createElement(ToolbarSection, { key: key, widgetGroups: widgetGroups, title: props.title, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled }));
7637        };
7638        return Toolbar;
7639    }(BaseComponent));
7640
7641    // TODO: do function component?
7642    var ViewContainer = /** @class */ (function (_super) {
7643        __extends(ViewContainer, _super);
7644        function ViewContainer() {
7645            var _this = _super !== null && _super.apply(this, arguments) || this;
7646            _this.state = {
7647                availableWidth: null,
7648            };
7649            _this.handleEl = function (el) {
7650                _this.el = el;
7651                setRef(_this.props.elRef, el);
7652                _this.updateAvailableWidth();
7653            };
7654            _this.handleResize = function () {
7655                _this.updateAvailableWidth();
7656            };
7657            return _this;
7658        }
7659        ViewContainer.prototype.render = function () {
7660            var _a = this, props = _a.props, state = _a.state;
7661            var aspectRatio = props.aspectRatio;
7662            var classNames = [
7663                'fc-view-harness',
7664                (aspectRatio || props.liquid || props.height)
7665                    ? 'fc-view-harness-active' // harness controls the height
7666                    : 'fc-view-harness-passive',
7667            ];
7668            var height = '';
7669            var paddingBottom = '';
7670            if (aspectRatio) {
7671                if (state.availableWidth !== null) {
7672                    height = state.availableWidth / aspectRatio;
7673                }
7674                else {
7675                    // while waiting to know availableWidth, we can't set height to *zero*
7676                    // because will cause lots of unnecessary scrollbars within scrollgrid.
7677                    // BETTER: don't start rendering ANYTHING yet until we know container width
7678                    // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606)
7679                    paddingBottom = (1 / aspectRatio) * 100 + "%";
7680                }
7681            }
7682            else {
7683                height = props.height || '';
7684            }
7685            return (createElement("div", { ref: this.handleEl, onClick: props.onClick, className: classNames.join(' '), style: { height: height, paddingBottom: paddingBottom } }, props.children));
7686        };
7687        ViewContainer.prototype.componentDidMount = function () {
7688            this.context.addResizeHandler(this.handleResize);
7689        };
7690        ViewContainer.prototype.componentWillUnmount = function () {
7691            this.context.removeResizeHandler(this.handleResize);
7692        };
7693        ViewContainer.prototype.updateAvailableWidth = function () {
7694            if (this.el && // needed. but why?
7695                this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth
7696            ) {
7697                this.setState({ availableWidth: this.el.offsetWidth });
7698            }
7699        };
7700        return ViewContainer;
7701    }(BaseComponent));
7702
7703    /*
7704    Detects when the user clicks on an event within a DateComponent
7705    */
7706    var EventClicking = /** @class */ (function (_super) {
7707        __extends(EventClicking, _super);
7708        function EventClicking(settings) {
7709            var _this = _super.call(this, settings) || this;
7710            _this.handleSegClick = function (ev, segEl) {
7711                var component = _this.component;
7712                var context = component.context;
7713                var seg = getElSeg(segEl);
7714                if (seg && // might be the <div> surrounding the more link
7715                    component.isValidSegDownEl(ev.target)) {
7716                    // our way to simulate a link click for elements that can't be <a> tags
7717                    // grab before trigger fired in case trigger trashes DOM thru rerendering
7718                    var hasUrlContainer = elementClosest(ev.target, '.fc-event-forced-url');
7719                    var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
7720                    context.emitter.trigger('eventClick', {
7721                        el: segEl,
7722                        event: new EventApi(component.context, seg.eventRange.def, seg.eventRange.instance),
7723                        jsEvent: ev,
7724                        view: context.viewApi,
7725                    });
7726                    if (url && !ev.defaultPrevented) {
7727                        window.location.href = url;
7728                    }
7729                }
7730            };
7731            _this.destroy = listenBySelector(settings.el, 'click', '.fc-event', // on both fg and bg events
7732            _this.handleSegClick);
7733            return _this;
7734        }
7735        return EventClicking;
7736    }(Interaction));
7737
7738    /*
7739    Triggers events and adds/removes core classNames when the user's pointer
7740    enters/leaves event-elements of a component.
7741    */
7742    var EventHovering = /** @class */ (function (_super) {
7743        __extends(EventHovering, _super);
7744        function EventHovering(settings) {
7745            var _this = _super.call(this, settings) || this;
7746            // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
7747            _this.handleEventElRemove = function (el) {
7748                if (el === _this.currentSegEl) {
7749                    _this.handleSegLeave(null, _this.currentSegEl);
7750                }
7751            };
7752            _this.handleSegEnter = function (ev, segEl) {
7753                if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
7754                    _this.currentSegEl = segEl;
7755                    _this.triggerEvent('eventMouseEnter', ev, segEl);
7756                }
7757            };
7758            _this.handleSegLeave = function (ev, segEl) {
7759                if (_this.currentSegEl) {
7760                    _this.currentSegEl = null;
7761                    _this.triggerEvent('eventMouseLeave', ev, segEl);
7762                }
7763            };
7764            _this.removeHoverListeners = listenToHoverBySelector(settings.el, '.fc-event', // on both fg and bg events
7765            _this.handleSegEnter, _this.handleSegLeave);
7766            return _this;
7767        }
7768        EventHovering.prototype.destroy = function () {
7769            this.removeHoverListeners();
7770        };
7771        EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) {
7772            var component = this.component;
7773            var context = component.context;
7774            var seg = getElSeg(segEl);
7775            if (!ev || component.isValidSegDownEl(ev.target)) {
7776                context.emitter.trigger(publicEvName, {
7777                    el: segEl,
7778                    event: new EventApi(context, seg.eventRange.def, seg.eventRange.instance),
7779                    jsEvent: ev,
7780                    view: context.viewApi,
7781                });
7782            }
7783        };
7784        return EventHovering;
7785    }(Interaction));
7786
7787    var CalendarContent = /** @class */ (function (_super) {
7788        __extends(CalendarContent, _super);
7789        function CalendarContent() {
7790            var _this = _super !== null && _super.apply(this, arguments) || this;
7791            _this.buildViewContext = memoize(buildViewContext);
7792            _this.buildViewPropTransformers = memoize(buildViewPropTransformers);
7793            _this.buildToolbarProps = memoize(buildToolbarProps);
7794            _this.handleNavLinkClick = buildDelegationHandler('a[data-navlink]', _this._handleNavLinkClick.bind(_this));
7795            _this.headerRef = createRef();
7796            _this.footerRef = createRef();
7797            _this.interactionsStore = {};
7798            // Component Registration
7799            // -----------------------------------------------------------------------------------------------------------------
7800            _this.registerInteractiveComponent = function (component, settingsInput) {
7801                var settings = parseInteractionSettings(component, settingsInput);
7802                var DEFAULT_INTERACTIONS = [
7803                    EventClicking,
7804                    EventHovering,
7805                ];
7806                var interactionClasses = DEFAULT_INTERACTIONS.concat(_this.props.pluginHooks.componentInteractions);
7807                var interactions = interactionClasses.map(function (TheInteractionClass) { return new TheInteractionClass(settings); });
7808                _this.interactionsStore[component.uid] = interactions;
7809                interactionSettingsStore[component.uid] = settings;
7810            };
7811            _this.unregisterInteractiveComponent = function (component) {
7812                for (var _i = 0, _a = _this.interactionsStore[component.uid]; _i < _a.length; _i++) {
7813                    var listener = _a[_i];
7814                    listener.destroy();
7815                }
7816                delete _this.interactionsStore[component.uid];
7817                delete interactionSettingsStore[component.uid];
7818            };
7819            // Resizing
7820            // -----------------------------------------------------------------------------------------------------------------
7821            _this.resizeRunner = new DelayedRunner(function () {
7822                _this.props.emitter.trigger('_resize', true); // should window resizes be considered "forced" ?
7823                _this.props.emitter.trigger('windowResize', { view: _this.props.viewApi });
7824            });
7825            _this.handleWindowResize = function (ev) {
7826                var options = _this.props.options;
7827                if (options.handleWindowResize &&
7828                    ev.target === window // avoid jqui events
7829                ) {
7830                    _this.resizeRunner.request(options.windowResizeDelay);
7831                }
7832            };
7833            return _this;
7834        }
7835        /*
7836        renders INSIDE of an outer div
7837        */
7838        CalendarContent.prototype.render = function () {
7839            var props = this.props;
7840            var toolbarConfig = props.toolbarConfig, options = props.options;
7841            var toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, getNow(props.options.now, props.dateEnv), // TODO: use NowTimer????
7842            props.viewTitle);
7843            var viewVGrow = false;
7844            var viewHeight = '';
7845            var viewAspectRatio;
7846            if (props.isHeightAuto || props.forPrint) {
7847                viewHeight = '';
7848            }
7849            else if (options.height != null) {
7850                viewVGrow = true;
7851            }
7852            else if (options.contentHeight != null) {
7853                viewHeight = options.contentHeight;
7854            }
7855            else {
7856                viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall
7857            }
7858            var viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);
7859            return (createElement(ViewContextType.Provider, { value: viewContext },
7860                toolbarConfig.headerToolbar && (createElement(Toolbar, __assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.headerToolbar }, toolbarProps))),
7861                createElement(ViewContainer, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, onClick: this.handleNavLinkClick },
7862                    this.renderView(props),
7863                    this.buildAppendContent()),
7864                toolbarConfig.footerToolbar && (createElement(Toolbar, __assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footerToolbar }, toolbarProps)))));
7865        };
7866        CalendarContent.prototype.componentDidMount = function () {
7867            var props = this.props;
7868            this.calendarInteractions = props.pluginHooks.calendarInteractions
7869                .map(function (CalendarInteractionClass) { return new CalendarInteractionClass(props); });
7870            window.addEventListener('resize', this.handleWindowResize);
7871            var propSetHandlers = props.pluginHooks.propSetHandlers;
7872            for (var propName in propSetHandlers) {
7873                propSetHandlers[propName](props[propName], props);
7874            }
7875        };
7876        CalendarContent.prototype.componentDidUpdate = function (prevProps) {
7877            var props = this.props;
7878            var propSetHandlers = props.pluginHooks.propSetHandlers;
7879            for (var propName in propSetHandlers) {
7880                if (props[propName] !== prevProps[propName]) {
7881                    propSetHandlers[propName](props[propName], props);
7882                }
7883            }
7884        };
7885        CalendarContent.prototype.componentWillUnmount = function () {
7886            window.removeEventListener('resize', this.handleWindowResize);
7887            this.resizeRunner.clear();
7888            for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) {
7889                var interaction = _a[_i];
7890                interaction.destroy();
7891            }
7892            this.props.emitter.trigger('_unmount');
7893        };
7894        CalendarContent.prototype._handleNavLinkClick = function (ev, anchorEl) {
7895            var _a = this.props, dateEnv = _a.dateEnv, options = _a.options, calendarApi = _a.calendarApi;
7896            var navLinkOptions = anchorEl.getAttribute('data-navlink');
7897            navLinkOptions = navLinkOptions ? JSON.parse(navLinkOptions) : {};
7898            var dateMarker = dateEnv.createMarker(navLinkOptions.date);
7899            var viewType = navLinkOptions.type;
7900            var customAction = viewType === 'day' ? options.navLinkDayClick :
7901                viewType === 'week' ? options.navLinkWeekClick : null;
7902            if (typeof customAction === 'function') {
7903                customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev);
7904            }
7905            else {
7906                if (typeof customAction === 'string') {
7907                    viewType = customAction;
7908                }
7909                calendarApi.zoomTo(dateMarker, viewType);
7910            }
7911        };
7912        CalendarContent.prototype.buildAppendContent = function () {
7913            var props = this.props;
7914            var children = props.pluginHooks.viewContainerAppends.map(function (buildAppendContent) { return buildAppendContent(props); });
7915            return createElement.apply(void 0, __spreadArrays([Fragment, {}], children));
7916        };
7917        CalendarContent.prototype.renderView = function (props) {
7918            var pluginHooks = props.pluginHooks;
7919            var viewSpec = props.viewSpec;
7920            var viewProps = {
7921                dateProfile: props.dateProfile,
7922                businessHours: props.businessHours,
7923                eventStore: props.renderableEventStore,
7924                eventUiBases: props.eventUiBases,
7925                dateSelection: props.dateSelection,
7926                eventSelection: props.eventSelection,
7927                eventDrag: props.eventDrag,
7928                eventResize: props.eventResize,
7929                isHeightAuto: props.isHeightAuto,
7930                forPrint: props.forPrint,
7931            };
7932            var transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers);
7933            for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
7934                var transformer = transformers_1[_i];
7935                __assign(viewProps, transformer.transform(viewProps, props));
7936            }
7937            var ViewComponent = viewSpec.component;
7938            return (createElement(ViewComponent, __assign({}, viewProps)));
7939        };
7940        return CalendarContent;
7941    }(PureComponent));
7942    function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) {
7943        // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid
7944        var todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason
7945        var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false);
7946        var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false);
7947        return {
7948            title: title,
7949            activeButton: viewSpec.type,
7950            isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now),
7951            isPrevEnabled: prevInfo.isValid,
7952            isNextEnabled: nextInfo.isValid,
7953        };
7954    }
7955    // Plugin
7956    // -----------------------------------------------------------------------------------------------------------------
7957    function buildViewPropTransformers(theClasses) {
7958        return theClasses.map(function (TheClass) { return new TheClass(); });
7959    }
7960
7961    var CalendarRoot = /** @class */ (function (_super) {
7962        __extends(CalendarRoot, _super);
7963        function CalendarRoot() {
7964            var _this = _super !== null && _super.apply(this, arguments) || this;
7965            _this.state = {
7966                forPrint: false,
7967            };
7968            _this.handleBeforePrint = function () {
7969                _this.setState({ forPrint: true });
7970            };
7971            _this.handleAfterPrint = function () {
7972                _this.setState({ forPrint: false });
7973            };
7974            return _this;
7975        }
7976        CalendarRoot.prototype.render = function () {
7977            var props = this.props;
7978            var options = props.options;
7979            var forPrint = this.state.forPrint;
7980            var isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto';
7981            var height = (!isHeightAuto && options.height != null) ? options.height : '';
7982            var classNames = [
7983                'fc',
7984                forPrint ? 'fc-media-print' : 'fc-media-screen',
7985                "fc-direction-" + options.direction,
7986                props.theme.getClass('root'),
7987            ];
7988            if (!getCanVGrowWithinCell()) {
7989                classNames.push('fc-liquid-hack');
7990            }
7991            return props.children(classNames, height, isHeightAuto, forPrint);
7992        };
7993        CalendarRoot.prototype.componentDidMount = function () {
7994            var emitter = this.props.emitter;
7995            emitter.on('_beforeprint', this.handleBeforePrint);
7996            emitter.on('_afterprint', this.handleAfterPrint);
7997        };
7998        CalendarRoot.prototype.componentWillUnmount = function () {
7999            var emitter = this.props.emitter;
8000            emitter.off('_beforeprint', this.handleBeforePrint);
8001            emitter.off('_afterprint', this.handleAfterPrint);
8002        };
8003        return CalendarRoot;
8004    }(BaseComponent));
8005
8006    // Computes a default column header formatting string if `colFormat` is not explicitly defined
8007    function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
8008        // if more than one week row, or if there are a lot of columns with not much space,
8009        // put just the day numbers will be in each cell
8010        if (!datesRepDistinctDays || dayCnt > 10) {
8011            return createFormatter({ weekday: 'short' }); // "Sat"
8012        }
8013        if (dayCnt > 1) {
8014            return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12"
8015        }
8016        return createFormatter({ weekday: 'long' }); // "Saturday"
8017    }
8018
8019    var CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no
8020    function renderInner(hookProps) {
8021        return hookProps.text;
8022    }
8023
8024    var TableDateCell = /** @class */ (function (_super) {
8025        __extends(TableDateCell, _super);
8026        function TableDateCell() {
8027            return _super !== null && _super.apply(this, arguments) || this;
8028        }
8029        TableDateCell.prototype.render = function () {
8030            var _a = this.context, dateEnv = _a.dateEnv, options = _a.options, theme = _a.theme, viewApi = _a.viewApi;
8031            var props = this.props;
8032            var date = props.date, dateProfile = props.dateProfile;
8033            var dayMeta = getDateMeta(date, props.todayRange, null, dateProfile);
8034            var classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme));
8035            var text = dateEnv.format(date, props.dayHeaderFormat);
8036            // if colCnt is 1, we are already in a day-view and don't need a navlink
8037            var navLinkAttrs = (options.navLinks && !dayMeta.isDisabled && props.colCnt > 1)
8038                ? { 'data-navlink': buildNavLinkData(date), tabIndex: 0 }
8039                : {};
8040            var hookProps = __assign(__assign(__assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraHookProps), { text: text }), dayMeta);
8041            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-date": !dayMeta.isDisabled ? formatDayString(date) : undefined, colSpan: props.colSpan }, props.extraDataAttrs),
8042                createElement("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && (createElement("a", __assign({ ref: innerElRef, className: [
8043                        'fc-col-header-cell-cushion',
8044                        props.isSticky ? 'fc-sticky' : '',
8045                    ].join(' ') }, navLinkAttrs), innerContent))))); }));
8046        };
8047        return TableDateCell;
8048    }(BaseComponent));
8049
8050    var TableDowCell = /** @class */ (function (_super) {
8051        __extends(TableDowCell, _super);
8052        function TableDowCell() {
8053            return _super !== null && _super.apply(this, arguments) || this;
8054        }
8055        TableDowCell.prototype.render = function () {
8056            var props = this.props;
8057            var _a = this.context, dateEnv = _a.dateEnv, theme = _a.theme, viewApi = _a.viewApi, options = _a.options;
8058            var date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT
8059            var dateMeta = {
8060                dow: props.dow,
8061                isDisabled: false,
8062                isFuture: false,
8063                isPast: false,
8064                isToday: false,
8065                isOther: false,
8066            };
8067            var classNames = [CLASS_NAME].concat(getDayClassNames(dateMeta, theme), props.extraClassNames || []);
8068            var text = dateEnv.format(date, props.dayHeaderFormat);
8069            var hookProps = __assign(__assign(__assign(__assign({ // TODO: make this public?
8070                date: date }, dateMeta), { view: viewApi }), props.extraHookProps), { text: text });
8071            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, className: classNames.concat(customClassNames).join(' '), colSpan: props.colSpan }, props.extraDataAttrs),
8072                createElement("div", { className: "fc-scrollgrid-sync-inner" },
8073                    createElement("a", { className: [
8074                            'fc-col-header-cell-cushion',
8075                            props.isSticky ? 'fc-sticky' : '',
8076                        ].join(' '), ref: innerElRef }, innerContent)))); }));
8077        };
8078        return TableDowCell;
8079    }(BaseComponent));
8080
8081    var NowTimer = /** @class */ (function (_super) {
8082        __extends(NowTimer, _super);
8083        function NowTimer(props, context) {
8084            var _this = _super.call(this, props, context) || this;
8085            _this.initialNowDate = getNow(context.options.now, context.dateEnv);
8086            _this.initialNowQueriedMs = new Date().valueOf();
8087            _this.state = _this.computeTiming().currentState;
8088            return _this;
8089        }
8090        NowTimer.prototype.render = function () {
8091            var _a = this, props = _a.props, state = _a.state;
8092            return props.children(state.nowDate, state.todayRange);
8093        };
8094        NowTimer.prototype.componentDidMount = function () {
8095            this.setTimeout();
8096        };
8097        NowTimer.prototype.componentDidUpdate = function (prevProps) {
8098            if (prevProps.unit !== this.props.unit) {
8099                this.clearTimeout();
8100                this.setTimeout();
8101            }
8102        };
8103        NowTimer.prototype.componentWillUnmount = function () {
8104            this.clearTimeout();
8105        };
8106        NowTimer.prototype.computeTiming = function () {
8107            var _a = this, props = _a.props, context = _a.context;
8108            var unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs);
8109            var currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit);
8110            var nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit));
8111            var waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf();
8112            // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342)
8113            // ensure no longer than a day
8114            waitMs = Math.min(1000 * 60 * 60 * 24, waitMs);
8115            return {
8116                currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) },
8117                nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) },
8118                waitMs: waitMs,
8119            };
8120        };
8121        NowTimer.prototype.setTimeout = function () {
8122            var _this = this;
8123            var _a = this.computeTiming(), nextState = _a.nextState, waitMs = _a.waitMs;
8124            this.timeoutId = setTimeout(function () {
8125                _this.setState(nextState, function () {
8126                    _this.setTimeout();
8127                });
8128            }, waitMs);
8129        };
8130        NowTimer.prototype.clearTimeout = function () {
8131            if (this.timeoutId) {
8132                clearTimeout(this.timeoutId);
8133            }
8134        };
8135        NowTimer.contextType = ViewContextType;
8136        return NowTimer;
8137    }(Component));
8138    function buildDayRange(date) {
8139        var start = startOfDay(date);
8140        var end = addDays(start, 1);
8141        return { start: start, end: end };
8142    }
8143
8144    var DayHeader = /** @class */ (function (_super) {
8145        __extends(DayHeader, _super);
8146        function DayHeader() {
8147            var _this = _super !== null && _super.apply(this, arguments) || this;
8148            _this.createDayHeaderFormatter = memoize(createDayHeaderFormatter);
8149            return _this;
8150        }
8151        DayHeader.prototype.render = function () {
8152            var context = this.context;
8153            var _a = this.props, dates = _a.dates, dateProfile = _a.dateProfile, datesRepDistinctDays = _a.datesRepDistinctDays, renderIntro = _a.renderIntro;
8154            var dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length);
8155            return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement("tr", null,
8156                renderIntro && renderIntro('day'),
8157                dates.map(function (date) { return (datesRepDistinctDays ? (createElement(TableDateCell, { key: date.toISOString(), date: date, dateProfile: dateProfile, todayRange: todayRange, colCnt: dates.length, dayHeaderFormat: dayHeaderFormat })) : (createElement(TableDowCell, { key: date.getUTCDay(), dow: date.getUTCDay(), dayHeaderFormat: dayHeaderFormat }))); }))); }));
8158        };
8159        return DayHeader;
8160    }(BaseComponent));
8161    function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) {
8162        return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt);
8163    }
8164
8165    var DaySeriesModel = /** @class */ (function () {
8166        function DaySeriesModel(range, dateProfileGenerator) {
8167            var date = range.start;
8168            var end = range.end;
8169            var indices = [];
8170            var dates = [];
8171            var dayIndex = -1;
8172            while (date < end) { // loop each day from start to end
8173                if (dateProfileGenerator.isHiddenDay(date)) {
8174                    indices.push(dayIndex + 0.5); // mark that it's between indices
8175                }
8176                else {
8177                    dayIndex += 1;
8178                    indices.push(dayIndex);
8179                    dates.push(date);
8180                }
8181                date = addDays(date, 1);
8182            }
8183            this.dates = dates;
8184            this.indices = indices;
8185            this.cnt = dates.length;
8186        }
8187        DaySeriesModel.prototype.sliceRange = function (range) {
8188            var firstIndex = this.getDateDayIndex(range.start); // inclusive first index
8189            var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
8190            var clippedFirstIndex = Math.max(0, firstIndex);
8191            var clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
8192            // deal with in-between indices
8193            clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
8194            clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
8195            if (clippedFirstIndex <= clippedLastIndex) {
8196                return {
8197                    firstIndex: clippedFirstIndex,
8198                    lastIndex: clippedLastIndex,
8199                    isStart: firstIndex === clippedFirstIndex,
8200                    isEnd: lastIndex === clippedLastIndex,
8201                };
8202            }
8203            return null;
8204        };
8205        // Given a date, returns its chronolocial cell-index from the first cell of the grid.
8206        // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
8207        // If before the first offset, returns a negative number.
8208        // If after the last offset, returns an offset past the last cell offset.
8209        // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
8210        DaySeriesModel.prototype.getDateDayIndex = function (date) {
8211            var indices = this.indices;
8212            var dayOffset = Math.floor(diffDays(this.dates[0], date));
8213            if (dayOffset < 0) {
8214                return indices[0] - 1;
8215            }
8216            if (dayOffset >= indices.length) {
8217                return indices[indices.length - 1] + 1;
8218            }
8219            return indices[dayOffset];
8220        };
8221        return DaySeriesModel;
8222    }());
8223
8224    var DayTableModel = /** @class */ (function () {
8225        function DayTableModel(daySeries, breakOnWeeks) {
8226            var dates = daySeries.dates;
8227            var daysPerRow;
8228            var firstDay;
8229            var rowCnt;
8230            if (breakOnWeeks) {
8231                // count columns until the day-of-week repeats
8232                firstDay = dates[0].getUTCDay();
8233                for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) {
8234                    if (dates[daysPerRow].getUTCDay() === firstDay) {
8235                        break;
8236                    }
8237                }
8238                rowCnt = Math.ceil(dates.length / daysPerRow);
8239            }
8240            else {
8241                rowCnt = 1;
8242                daysPerRow = dates.length;
8243            }
8244            this.rowCnt = rowCnt;
8245            this.colCnt = daysPerRow;
8246            this.daySeries = daySeries;
8247            this.cells = this.buildCells();
8248            this.headerDates = this.buildHeaderDates();
8249        }
8250        DayTableModel.prototype.buildCells = function () {
8251            var rows = [];
8252            for (var row = 0; row < this.rowCnt; row += 1) {
8253                var cells = [];
8254                for (var col = 0; col < this.colCnt; col += 1) {
8255                    cells.push(this.buildCell(row, col));
8256                }
8257                rows.push(cells);
8258            }
8259            return rows;
8260        };
8261        DayTableModel.prototype.buildCell = function (row, col) {
8262            var date = this.daySeries.dates[row * this.colCnt + col];
8263            return {
8264                key: date.toISOString(),
8265                date: date,
8266            };
8267        };
8268        DayTableModel.prototype.buildHeaderDates = function () {
8269            var dates = [];
8270            for (var col = 0; col < this.colCnt; col += 1) {
8271                dates.push(this.cells[0][col].date);
8272            }
8273            return dates;
8274        };
8275        DayTableModel.prototype.sliceRange = function (range) {
8276            var colCnt = this.colCnt;
8277            var seriesSeg = this.daySeries.sliceRange(range);
8278            var segs = [];
8279            if (seriesSeg) {
8280                var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex;
8281                var index = firstIndex;
8282                while (index <= lastIndex) {
8283                    var row = Math.floor(index / colCnt);
8284                    var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
8285                    segs.push({
8286                        row: row,
8287                        firstCol: index % colCnt,
8288                        lastCol: (nextIndex - 1) % colCnt,
8289                        isStart: seriesSeg.isStart && index === firstIndex,
8290                        isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex,
8291                    });
8292                    index = nextIndex;
8293                }
8294            }
8295            return segs;
8296        };
8297        return DayTableModel;
8298    }());
8299
8300    var Slicer = /** @class */ (function () {
8301        function Slicer() {
8302            this.sliceBusinessHours = memoize(this._sliceBusinessHours);
8303            this.sliceDateSelection = memoize(this._sliceDateSpan);
8304            this.sliceEventStore = memoize(this._sliceEventStore);
8305            this.sliceEventDrag = memoize(this._sliceInteraction);
8306            this.sliceEventResize = memoize(this._sliceInteraction);
8307            this.forceDayIfListItem = false; // hack
8308        }
8309        Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, context) {
8310            var extraArgs = [];
8311            for (var _i = 4; _i < arguments.length; _i++) {
8312                extraArgs[_i - 4] = arguments[_i];
8313            }
8314            var eventUiBases = props.eventUiBases;
8315            var eventSegs = this.sliceEventStore.apply(this, __spreadArrays([props.eventStore, eventUiBases, dateProfile, nextDayThreshold], extraArgs));
8316            return {
8317                dateSelectionSegs: this.sliceDateSelection.apply(this, __spreadArrays([props.dateSelection, eventUiBases, context], extraArgs)),
8318                businessHourSegs: this.sliceBusinessHours.apply(this, __spreadArrays([props.businessHours, dateProfile, nextDayThreshold, context], extraArgs)),
8319                fgEventSegs: eventSegs.fg,
8320                bgEventSegs: eventSegs.bg,
8321                eventDrag: this.sliceEventDrag.apply(this, __spreadArrays([props.eventDrag, eventUiBases, dateProfile, nextDayThreshold], extraArgs)),
8322                eventResize: this.sliceEventResize.apply(this, __spreadArrays([props.eventResize, eventUiBases, dateProfile, nextDayThreshold], extraArgs)),
8323                eventSelection: props.eventSelection,
8324            }; // TODO: give interactionSegs?
8325        };
8326        Slicer.prototype.sliceNowDate = function (// does not memoize
8327        date, context) {
8328            var extraArgs = [];
8329            for (var _i = 2; _i < arguments.length; _i++) {
8330                extraArgs[_i - 2] = arguments[_i];
8331            }
8332            return this._sliceDateSpan.apply(this, __spreadArrays([{ range: { start: date, end: addMs(date, 1) }, allDay: false },
8333                {},
8334                context], extraArgs));
8335        };
8336        Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, context) {
8337            var extraArgs = [];
8338            for (var _i = 4; _i < arguments.length; _i++) {
8339                extraArgs[_i - 4] = arguments[_i];
8340            }
8341            if (!businessHours) {
8342                return [];
8343            }
8344            return this._sliceEventStore.apply(this, __spreadArrays([expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context),
8345                {},
8346                dateProfile,
8347                nextDayThreshold], extraArgs)).bg;
8348        };
8349        Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold) {
8350            var extraArgs = [];
8351            for (var _i = 4; _i < arguments.length; _i++) {
8352                extraArgs[_i - 4] = arguments[_i];
8353            }
8354            if (eventStore) {
8355                var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8356                return {
8357                    bg: this.sliceEventRanges(rangeRes.bg, extraArgs),
8358                    fg: this.sliceEventRanges(rangeRes.fg, extraArgs),
8359                };
8360            }
8361            return { bg: [], fg: [] };
8362        };
8363        Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold) {
8364            var extraArgs = [];
8365            for (var _i = 4; _i < arguments.length; _i++) {
8366                extraArgs[_i - 4] = arguments[_i];
8367            }
8368            if (!interaction) {
8369                return null;
8370            }
8371            var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8372            return {
8373                segs: this.sliceEventRanges(rangeRes.fg, extraArgs),
8374                affectedInstances: interaction.affectedEvents.instances,
8375                isEvent: interaction.isEvent,
8376            };
8377        };
8378        Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, context) {
8379            var extraArgs = [];
8380            for (var _i = 3; _i < arguments.length; _i++) {
8381                extraArgs[_i - 3] = arguments[_i];
8382            }
8383            if (!dateSpan) {
8384                return [];
8385            }
8386            var eventRange = fabricateEventRange(dateSpan, eventUiBases, context);
8387            var segs = this.sliceRange.apply(this, __spreadArrays([dateSpan.range], extraArgs));
8388            for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) {
8389                var seg = segs_1[_a];
8390                seg.eventRange = eventRange;
8391            }
8392            return segs;
8393        };
8394        /*
8395        "complete" seg means it has component and eventRange
8396        */
8397        Slicer.prototype.sliceEventRanges = function (eventRanges, extraArgs) {
8398            var segs = [];
8399            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
8400                var eventRange = eventRanges_1[_i];
8401                segs.push.apply(segs, this.sliceEventRange(eventRange, extraArgs));
8402            }
8403            return segs;
8404        };
8405        /*
8406        "complete" seg means it has component and eventRange
8407        */
8408        Slicer.prototype.sliceEventRange = function (eventRange, extraArgs) {
8409            var dateRange = eventRange.range;
8410            // hack to make multi-day events that are being force-displayed as list-items to take up only one day
8411            if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') {
8412                dateRange = {
8413                    start: dateRange.start,
8414                    end: addDays(dateRange.start, 1),
8415                };
8416            }
8417            var segs = this.sliceRange.apply(this, __spreadArrays([dateRange], extraArgs));
8418            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
8419                var seg = segs_2[_i];
8420                seg.eventRange = eventRange;
8421                seg.isStart = eventRange.isStart && seg.isStart;
8422                seg.isEnd = eventRange.isEnd && seg.isEnd;
8423            }
8424            return segs;
8425        };
8426        return Slicer;
8427    }());
8428    /*
8429    for incorporating slotMinTime/slotMaxTime if appropriate
8430    TODO: should be part of DateProfile!
8431    TimelineDateProfile already does this btw
8432    */
8433    function computeActiveRange(dateProfile, isComponentAllDay) {
8434        var range = dateProfile.activeRange;
8435        if (isComponentAllDay) {
8436            return range;
8437        }
8438        return {
8439            start: addMs(range.start, dateProfile.slotMinTime.milliseconds),
8440            end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5),
8441        };
8442    }
8443
8444    var VISIBLE_HIDDEN_RE = /^(visible|hidden)$/;
8445    var Scroller = /** @class */ (function (_super) {
8446        __extends(Scroller, _super);
8447        function Scroller() {
8448            var _this = _super !== null && _super.apply(this, arguments) || this;
8449            _this.handleEl = function (el) {
8450                _this.el = el;
8451                setRef(_this.props.elRef, el);
8452            };
8453            return _this;
8454        }
8455        Scroller.prototype.render = function () {
8456            var props = this.props;
8457            var liquid = props.liquid, liquidIsAbsolute = props.liquidIsAbsolute;
8458            var isAbsolute = liquid && liquidIsAbsolute;
8459            var className = ['fc-scroller'];
8460            if (liquid) {
8461                if (liquidIsAbsolute) {
8462                    className.push('fc-scroller-liquid-absolute');
8463                }
8464                else {
8465                    className.push('fc-scroller-liquid');
8466                }
8467            }
8468            return (createElement("div", { ref: this.handleEl, className: className.join(' '), style: {
8469                    overflowX: props.overflowX,
8470                    overflowY: props.overflowY,
8471                    left: (isAbsolute && -(props.overcomeLeft || 0)) || '',
8472                    right: (isAbsolute && -(props.overcomeRight || 0
8472)) || '',
8473                    bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '',
8474                    marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '',
8475                    marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '',
8476                    marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '',
8477                    maxHeight: props.maxHeight || '',
8478                } }, props.children));
8479        };
8480        Scroller.prototype.needsXScrolling = function () {
8481            if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
8482                return false;
8483            }
8484            // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers.
8485            // much more reliable to see if children are taller than the scroller, even tho doesn't account for
8486            // inner-child margins and absolute positioning
8487            var el = this.el;
8488            var realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth();
8489            var children = el.children;
8490            for (var i = 0; i < children.length; i += 1) {
8491                var childEl = children[i];
8492                if (childEl.getBoundingClientRect().width > realClientWidth) {
8493                    return true;
8494                }
8495            }
8496            return false;
8497        };
8498        Scroller.prototype.needsYScrolling = function () {
8499            if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
8500                return false;
8501            }
8502            // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers.
8503            // much more reliable to see if children are taller than the scroller, even tho doesn't account for
8504            // inner-child margins and absolute positioning
8505            var el = this.el;
8506            var realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth();
8507            var children = el.children;
8508            for (var i = 0; i < children.length; i += 1) {
8509                var childEl = children[i];
8510                if (childEl.getBoundingClientRect().height > realClientHeight) {
8511                    return true;
8512                }
8513            }
8514            return false;
8515        };
8516        Scroller.prototype.getXScrollbarWidth = function () {
8517            if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
8518                return 0;
8519            }
8520            return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important?
8521        };
8522        Scroller.prototype.getYScrollbarWidth = function () {
8523            if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
8524                return 0;
8525            }
8526            return this.el.offsetWidth - this.el.clientWidth; // only works because we guarantee no borders. TODO: add to CSS with important?
8527        };
8528        return Scroller;
8529    }(BaseComponent));
8530
8531    /*
8532    TODO: somehow infer OtherArgs from masterCallback?
8533    TODO: infer RefType from masterCallback if provided
8534    */
8535    var RefMap = /** @class */ (function () {
8536        function RefMap(masterCallback) {
8537            var _this = this;
8538            this.masterCallback = masterCallback;
8539            this.currentMap = {};
8540            this.depths = {};
8541            this.callbackMap = {};
8542            this.handleValue = function (val, key) {
8543                var _a = _this, depths = _a.depths, currentMap = _a.currentMap;
8544                var removed = false;
8545                var added = false;
8546                if (val !== null) {
8547                    // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore
8548                    removed = (key in currentMap);
8549                    currentMap[key] = val;
8550                    depths[key] = (depths[key] || 0) + 1;
8551                    added = true;
8552                }
8553                else {
8554                    depths[key] -= 1;
8555                    if (!depths[key]) {
8556                        delete currentMap[key];
8557                        delete _this.callbackMap[key];
8558                        removed = true;
8559                    }
8560                }
8561                if (_this.masterCallback) {
8562                    if (removed) {
8563                        _this.masterCallback(null, String(key));
8564                    }
8565                    if (added) {
8566                        _this.masterCallback(val, String(key));
8567                    }
8568                }
8569            };
8570        }
8571        RefMap.prototype.createRef = function (key) {
8572            var _this = this;
8573            var refCallback = this.callbackMap[key];
8574            if (!refCallback) {
8575                refCallback = this.callbackMap[key] = function (val) {
8576                    _this.handleValue(val, String(key));
8577                };
8578            }
8579            return refCallback;
8580        };
8581        // TODO: check callers that don't care about order. should use getAll instead
8582        // NOTE: this method has become less valuable now that we are encouraged to map order by some other index
8583        // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect"
8584        RefMap.prototype.collect = function (startIndex, endIndex, step) {
8585            return collectFromHash(this.currentMap, startIndex, endIndex, step);
8586        };
8587        RefMap.prototype.getAll = function () {
8588            return hashValuesToArray(this.currentMap);
8589        };
8590        return RefMap;
8591    }());
8592
8593    function computeShrinkWidth(chunkEls) {
8594        var shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink');
8595        var largestWidth = 0;
8596        for (var _i = 0, shrinkCells_1 = shrinkCells; _i < shrinkCells_1.length; _i++) {
8597            var shrinkCell = shrinkCells_1[_i];
8598            largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell));
8599        }
8600        return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits
8601    }
8602    function getSectionHasLiquidHeight(props, sectionConfig) {
8603        return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well)
8604    }
8605    function getAllowYScrolling(props, sectionConfig) {
8606        return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars
8607            getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars
8608    }
8609    // TODO: ONLY use `arg`. force out internal function to use same API
8610    function renderChunkContent(sectionConfig, chunkConfig, arg) {
8611        var expandRows = arg.expandRows;
8612        var content = typeof chunkConfig.content === 'function' ?
8613            chunkConfig.content(arg) :
8614            createElement('table', {
8615                className: [
8616                    chunkConfig.tableClassName,
8617                    sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : '',
8618                ].join(' '),
8619                style: {
8620                    minWidth: arg.tableMinWidth,
8621                    width: arg.clientWidth,
8622                    height: expandRows ? arg.clientHeight : '',
8623                },
8624            }, arg.tableColGroupNode, createElement('tbody', {}, typeof chunkConfig.rowContent === 'function' ? chunkConfig.rowContent(arg) : chunkConfig.rowContent));
8625        return content;
8626    }
8627    function isColPropsEqual(cols0, cols1) {
8628        return isArraysEqual(cols0, cols1, isPropsEqual);
8629    }
8630    function renderMicroColGroup(cols, shrinkWidth) {
8631        var colNodes = [];
8632        /*
8633        for ColProps with spans, it would have been great to make a single <col span="">
8634        HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans.
8635        SOLUTION: making individual <col> elements makes Chrome behave.
8636        */
8637        for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) {
8638            var colProps = cols_1[_i];
8639            var span = colProps.span || 1;
8640            for (var i = 0; i < span; i += 1) {
8641                colNodes.push(createElement("col", { style: {
8642                        width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''),
8643                        minWidth: colProps.minWidth || '',
8644                    } }));
8645            }
8646        }
8647        return createElement.apply(void 0, __spreadArrays(['colgroup', {}], colNodes));
8648    }
8649    function sanitizeShrinkWidth(shrinkWidth) {
8650        /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth
8651        4 accounts for 2 2-pixel borders. TODO: better solution? */
8652        return shrinkWidth == null ? 4 : shrinkWidth;
8653    }
8654    function hasShrinkWidth(cols) {
8655        for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) {
8656            var col = cols_2[_i];
8657            if (col.width === 'shrink') {
8658                return true;
8659            }
8660        }
8661        return false;
8662    }
8663    function getScrollGridClassNames(liquid, context) {
8664        var classNames = [
8665            'fc-scrollgrid',
8666            context.theme.getClass('table'),
8667        ];
8668        if (liquid) {
8669            classNames.push('fc-scrollgrid-liquid');
8670        }
8671        return classNames;
8672    }
8673    function getSectionClassNames(sectionConfig, wholeTableVGrow) {
8674        var classNames = [
8675            'fc-scrollgrid-section',
8676            "fc-scrollgrid-section-" + sectionConfig.type,
8677            sectionConfig.className,
8678        ];
8679        if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) {
8680            classNames.push('fc-scrollgrid-section-liquid');
8681        }
8682        if (sectionConfig.isSticky) {
8683            classNames.push('fc-scrollgrid-section-sticky');
8684        }
8685        return classNames;
8686    }
8687    function renderScrollShim(arg) {
8688        return (createElement("div", { className: "fc-scrollgrid-sticky-shim", style: {
8689                width: arg.clientWidth,
8690                minWidth: arg.tableMinWidth,
8691            } }));
8692    }
8693    function getStickyHeaderDates(options) {
8694        var stickyHeaderDates = options.stickyHeaderDates;
8695        if (stickyHeaderDates == null || stickyHeaderDates === 'auto') {
8696            stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto';
8697        }
8698        return stickyHeaderDates;
8699    }
8700    function getStickyFooterScrollbar(options) {
8701        var stickyFooterScrollbar = options.stickyFooterScrollbar;
8702        if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') {
8703            stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto';
8704        }
8705        return stickyFooterScrollbar;
8706    }
8707
8708    var SimpleScrollGrid = /** @class */ (function (_super) {
8709        __extends(SimpleScrollGrid, _super);
8710        function SimpleScrollGrid() {
8711            var _this = _super !== null && _super.apply(this, arguments) || this;
8712            _this.processCols = memoize(function (a) { return a; }, isColPropsEqual); // so we get same `cols` props every time
8713            // yucky to memoize VNodes, but much more efficient for consumers
8714            _this.renderMicroColGroup = memoize(renderMicroColGroup);
8715            _this.scrollerRefs = new RefMap();
8716            _this.scrollerElRefs = new RefMap(_this._handleScrollerEl.bind(_this));
8717            _this.state = {
8718                shrinkWidth: null,
8719                forceYScrollbars: false,
8720                scrollerClientWidths: {},
8721                scrollerClientHeights: {},
8722            };
8723            // TODO: can do a really simple print-view. dont need to join rows
8724            _this.handleSizing = function () {
8725                _this.setState(__assign({ shrinkWidth: _this.computeShrinkWidth() }, _this.computeScrollerDims()));
8726            };
8727            return _this;
8728        }
8729        SimpleScrollGrid.prototype.render = function () {
8730            var _a = this, props = _a.props, state = _a.state, context = _a.context;
8731            var sectionConfigs = props.sections || [];
8732            var cols = this.processCols(props.cols);
8733            var microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth);
8734            var classNames = getScrollGridClassNames(props.liquid, context);
8735            // TODO: make DRY
8736            var configCnt = sectionConfigs.length;
8737            var configI = 0;
8738            var currentConfig;
8739            var headSectionNodes = [];
8740            var bodySectionNodes = [];
8741            var footSectionNodes = [];
8742            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') {
8743                headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode));
8744                configI += 1;
8745            }
8746            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') {
8747                bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode));
8748                configI += 1;
8749            }
8750            while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') {
8751                footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode));
8752                configI += 1;
8753            }
8754            // firefox bug: when setting height on table and there is a thead or tfoot,
8755            // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524)
8756            // use getCanVGrowWithinCell as a way to detect table-stupid firefox.
8757            // if so, use a simpler dom structure, jam everything into a lone tbody.
8758            var isBuggy = !getCanVGrowWithinCell();
8759            return createElement('table', {
8760                className: classNames.join(' '),
8761                style: { height: props.height },
8762            }, Boolean(!isBuggy && headSectionNodes.length) && createElement.apply(void 0, __spreadArrays(['thead', {}
8762], headSectionNodes)), Boolean(!isBuggy && bodySectionNodes.length) && createElement.apply(void 0, __spreadArrays(['tbody', {}], bodySectionNodes)), Boolean(!isBuggy && footSectionNodes.length) && createElement.apply(void 0, __spreadArrays(['tfoot', {}], footSectionNodes)), isBuggy && createElement.apply(void 0, __spreadArrays(['tbody', {}], headSectionNodes, bodySectionNodes, footSectionNodes)));
8763        };
8764        SimpleScrollGrid.prototype.renderSection = function (sectionConfig, microColGroupNode) {
8765            if ('outerContent' in sectionConfig) {
8766                return (createElement(Fragment, { key: sectionConfig.key }, sectionConfig.outerContent));
8767            }
8768            return (createElement("tr", { key: sectionConfig.key, className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk)));
8769        };
8770        SimpleScrollGrid.prototype.renderChunkTd = function (sectionConfig, microColGroupNode, chunkConfig) {
8771            if ('outerContent' in chunkConfig) {
8772                return chunkConfig.outerContent;
8773            }
8774            var props = this.props;
8775            var _a = this.state, forceYScrollbars = _a.forceYScrollbars, scrollerClientWidths = _a.scrollerClientWidths, scrollerClientHeights = _a.scrollerClientHeights;
8776            var needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config?
8777            var isLiquid = getSectionHasLiquidHeight(props, sectionConfig);
8778            // for `!props.liquid` - is WHOLE scrollgrid natural height?
8779            // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars
8780            var overflowY = !props.liquid ? 'visible' :
8781                forceYScrollbars ? 'scroll' :
8782                    !needsYScrolling ? 'hidden' :
8783                        'auto';
8784            var sectionKey = sectionConfig.key;
8785            var content = renderChunkContent(sectionConfig, chunkConfig, {
8786                tableColGroupNode: microColGroupNode,
8787                tableMinWidth: '',
8788                clientWidth: scrollerClientWidths[sectionKey] !== undefined ? scrollerClientWidths[sectionKey] : null,
8789                clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null,
8790                expandRows: sectionConfig.expandRows,
8791                syncRowHeights: false,
8792                rowSyncHeights: [],
8793                reportRowHeightChange: function () { },
8794            });
8795            return (createElement("td", { ref: chunkConfig.elRef },
8796                createElement("div", { className: "fc-scroller-harness" + (isLiquid ? ' fc-scroller-harness-liquid' : '') },
8797                    createElement(Scroller, { ref: this.scrollerRefs.createRef(sectionKey), elRef: this.scrollerElRefs.createRef(sectionKey), overflowY: overflowY, overflowX: !props.liquid ? 'visible' : 'hidden' /* natural height? */, maxHeight: sectionConfig.maxHeight, liquid: isLiquid, liquidIsAbsolute // because its within a harness
8798                        : true }, content))));
8799        };
8800        SimpleScrollGrid.prototype._handleScrollerEl = function (scrollerEl, key) {
8801            var section = getSectionByKey(this.props.sections, key);
8802            if (section) {
8803                setRef(section.chunk.scrollerElRef, scrollerEl);
8804            }
8805        };
8806        SimpleScrollGrid.prototype.componentDidMount = function () {
8807            this.handleSizing();
8808            this.context.addResizeHandler(this.handleSizing);
8809        };
8810        SimpleScrollGrid.prototype.componentDidUpdate = function () {
8811            // TODO: need better solution when state contains non-sizing things
8812            this.handleSizing();
8813        };
8814        SimpleScrollGrid.prototype.componentWillUnmount = function () {
8815            this.context.removeResizeHandler(this.handleSizing);
8816        };
8817        SimpleScrollGrid.prototype.computeShrinkWidth = function () {
8818            return hasShrinkWidth(this.props.cols)
8819                ? computeShrinkWidth(this.scrollerElRefs.getAll())
8820                : 0;
8821        };
8822        SimpleScrollGrid.prototype.computeScrollerDims = function () {
8823            var scrollbarWidth = getScrollbarWidths();
8824            var _a = this, scrollerRefs = _a.scrollerRefs, scrollerElRefs = _a.scrollerElRefs;
8825            var forceYScrollbars = false;
8826            var scrollerClientWidths = {};
8827            var scrollerClientHeights = {};
8828            for (var sectionKey in scrollerRefs.currentMap) {
8829                var scroller = scrollerRefs.currentMap[sectionKey];
8830                if (scroller && scroller.needsYScrolling()) {
8831                    forceYScrollbars = true;
8832                    break;
8833                }
8834            }
8835            for (var _i = 0, _b = this.props.sections; _i < _b.length; _i++) {
8836                var section = _b[_i];
8837                var sectionKey = section.key;
8838                var scrollerEl = scrollerElRefs.currentMap[sectionKey];
8839                if (scrollerEl) {
8840                    var harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders
8841                    scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars
8842                        ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future
8843                        : 0));
8844                    scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height);
8845                }
8846            }
8847            return { forceYScrollbars: forceYScrollbars, scrollerClientWidths: scrollerClientWidths, scrollerClientHeights: scrollerClientHeights };
8848        };
8849        return SimpleScrollGrid;
8850    }(BaseComponent));
8851    SimpleScrollGrid.addStateEquality({
8852        scrollerClientWidths: isPropsEqual,
8853        scrollerClientHeights: isPropsEqual,
8854    });
8855    function getSectionByKey(sections, key) {
8856        for (var _i = 0, sections_1 = sections; _i < sections_1.length; _i++) {
8857            var section = sections_1[_i];
8858            if (section.key === key) {
8859                return section;
8860            }
8861        }
8862        return null;
8863    }
8864
8865    var EventRoot = /** @class */ (function (_super) {
8866        __extends(EventRoot, _super);
8867        function EventRoot() {
8868            var _this = _super !== null && _super.apply(this, arguments) || this;
8869            _this.elRef = createRef();
8870            return _this;
8871        }
8872        EventRoot.prototype.render = function () {
8873            var _a = this, props = _a.props, context = _a.context;
8874            var options = context.options;
8875            var seg = props.seg;
8876            var eventRange = seg.eventRange;
8877            var ui = eventRange.ui;
8878            var hookProps = {
8879                event: new EventApi(context, eventRange.def, eventRange.instance),
8880                view: context.viewApi,
8881                timeText: props.timeText,
8882                textColor: ui.textColor,
8883                backgroundColor: ui.backgroundColor,
8884                borderColor: ui.borderColor,
8885                isDraggable: !props.disableDragging && computeSegDraggable(seg, context),
8886                isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context),
8887                isEndResizable: !props.disableResizing && computeSegEndResizable(seg),
8888                isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting),
8889                isStart: Boolean(seg.isStart),
8890                isEnd: Boolean(seg.isEnd),
8891                isPast: Boolean(props.isPast),
8892                isFuture: Boolean(props.isFuture),
8893                isToday: Boolean(props.isToday),
8894                isSelected: Boolean(props.isSelected),
8895                isDragging: Boolean(props.isDragging),
8896                isResizing: Boolean(props.isResizing),
8897            };
8898            var standardClassNames = getEventClassNames(hookProps).concat(ui.classNames);
8899            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.eventClassNames, content: options.eventContent, defaultContent: props.defaultContent, didMount: options.eventDidMount, willUnmount: options.eventWillUnmount, elRef: this.elRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return props.children(rootElRef, standardClassNames.concat(customClassNames), innerElRef, innerContent, hookProps); }));
8900        };
8901        EventRoot.prototype.componentDidMount = function () {
8902            setElSeg(this.elRef.current, this.props.seg);
8903        };
8904        /*
8905        need to re-assign seg to the element if seg changes, even if the element is the same
8906        */
8907        EventRoot.prototype.componentDidUpdate = function (prevProps) {
8908            var seg = this.props.seg;
8909            if (seg !== prevProps.seg) {
8910                setElSeg(this.elRef.current, seg);
8911            }
8912        };
8913        return EventRoot;
8914    }(BaseComponent));
8915
8916    // should not be a purecomponent
8917    var StandardEvent = /** @class */ (function (_super) {
8918        __extends(StandardEvent, _super);
8919        function StandardEvent() {
8920            return _super !== null && _super.apply(this, arguments) || this;
8921        }
8922        StandardEvent.prototype.render = function () {
8923            var _a = this, props = _a.props, context = _a.context;
8924            var seg = props.seg;
8925            var timeFormat = context.options.eventTimeFormat || props.defaultTimeFormat;
8926            var timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd);
8927            return (createElement(EventRoot, { seg: seg, timeText: timeText, disableDragging: props.disableDragging, disableResizing: props.disableResizing, defaultContent: props.defaultContent || renderInnerContent, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("a", __assign({ className: props.extraClassNames.c
8927oncat(classNames).join(' '), style: {
8928                    borderColor: hookProps.borderColor,
8929                    backgroundColor: hookProps.backgroundColor,
8930                }, ref: rootElRef }, getSegAnchorAttrs(seg)),
8931                createElement("div", { className: "fc-event-main", ref: innerElRef, style: { color: hookProps.textColor } }, innerContent),
8932                hookProps.isStartResizable &&
8933                    createElement("div", { className: "fc-event-resizer fc-event-resizer-start" }),
8934                hookProps.isEndResizable &&
8935                    createElement("div", { className: "fc-event-resizer fc-event-resizer-end" }))); }));
8936        };
8937        return StandardEvent;
8938    }(BaseComponent));
8939    function renderInnerContent(innerProps) {
8940        return (createElement("div", { className: "fc-event-main-frame" },
8941            innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)),
8942            createElement("div", { className: "fc-event-title-container" },
8943                createElement("div", { className: "fc-event-title fc-sticky" }, innerProps.event.title || createElement(Fragment, null, "\u00A0")))));
8944    }
8945    function getSegAnchorAttrs(seg) {
8946        var url = seg.eventRange.def.url;
8947        return url ? { href: url } : {};
8948    }
8949
8950    var NowIndicatorRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) {
8951        var options = context.options;
8952        var hookProps = {
8953            isAxis: props.isAxis,
8954            date: context.dateEnv.toDate(props.date),
8955            view: context.viewApi,
8956        };
8957        return (createElement(RenderHook, { hookProps: hookProps, classNames: options.nowIndicatorClassNames, content: options.nowIndicatorContent, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount }, props.children));
8958    })); };
8959
8960    var DAY_NUM_FORMAT = createFormatter({ day: 'numeric' });
8961    var DayCellContent = /** @class */ (function (_super) {
8962        __extends(DayCellContent, _super);
8963        function DayCellContent() {
8964            return _super !== null && _super.apply(this, arguments) || this;
8965        }
8966        DayCellContent.prototype.render = function () {
8967            var _a = this, props = _a.props, context = _a.context;
8968            var options = context.options;
8969            var hookProps = refineDayCellHookProps({
8970                date: props.date,
8971                dateProfile: props.dateProfile,
8972                todayRange: props.todayRange,
8973                showDayNumber: props.showDayNumber,
8974                extraProps: props.extraHookProps,
8975                viewApi: context.viewApi,
8976                dateEnv: context.dateEnv,
8977            });
8978            return (createElement(ContentHook, { hookProps: hookProps, content: options.dayCellContent, defaultContent: props.defaultContent }, props.children));
8979        };
8980        return DayCellContent;
8981    }(BaseComponent));
8982    function refineDayCellHookProps(raw) {
8983        var date = raw.date, dateEnv = raw.dateEnv;
8984        var dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile);
8985        return __assign(__assign(__assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { dayNumberText: raw.showDayNumber ? dateEnv.format(date, DAY_NUM_FORMAT) : '' }), raw.extraProps);
8986    }
8987
8988    var DayCellRoot = /** @class */ (function (_super) {
8989        __extends(DayCellRoot, _super);
8990        function DayCellRoot() {
8991            var _this = _super !== null && _super.apply(this, arguments) || this;
8992            _this.refineHookProps = memoizeObjArg(refineDayCellHookProps);
8993            _this.normalizeClassNames = buildClassNameNormalizer();
8994            return _this;
8995        }
8996        DayCellRoot.prototype.render = function () {
8997            var _a = this, props = _a.props, context = _a.context;
8998            var options = context.options;
8999            var hookProps = this.refineHookProps({
9000                date: props.date,
9001                dateProfile: props.dateProfile,
9002                todayRange: props.todayRange,
9003                showDayNumber: props.showDayNumber,
9004                extraProps: props.extraHookProps,
9005                viewApi: context.viewApi,
9006                dateEnv: context.dateEnv,
9007            });
9008            var classNames = getDayClassNames(hookProps, context.theme).concat(hookProps.isDisabled
9009                ? [] // don't use custom classNames if disabled
9010                : this.normalizeClassNames(options.dayCellClassNames, hookProps));
9011            var dataAttrs = hookProps.isDisabled ? {} : {
9012                'data-date': formatDayString(props.date),
9013            };
9014            return (createElement(MountHook, { hookProps: hookProps, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, classNames, dataAttrs, hookProps.isDisabled); }));
9015        };
9016        return DayCellRoot;
9017    }(BaseComponent));
9018
9019    function renderFill(fillType) {
9020        return (createElement("div", { className: "fc-" + fillType }));
9021    }
9022    var BgEvent = function (props) { return (createElement(EventRoot, { defaultContent: renderInnerContent$1, seg: props.seg /* uselesss i think */, timeText: "", disableDragging: true, disableResizing: true, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("div", { ref: rootElRef, className: ['fc-bg-event'].concat(classNames).join(' '), style: {
9023            backgroundColor: hookProps.backgroundColor,
9024        } }, innerContent)); })); };
9025    function renderInnerContent$1(props) {
9026        var title = props.event.title;
9027        return title && (createElement("div", { className: "fc-event-title" }, props.event.title));
9028    }
9029
9030    var WeekNumberRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) {
9031        var dateEnv = context.dateEnv, options = context.options;
9032        var date = props.date;
9033        var format = options.weekNumberFormat || props.defaultFormat;
9034        var num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well?
9035        var text = dateEnv.format(date, format);
9036        var hookProps = { num: num, text: text, date: date };
9037        return (createElement(RenderHook, { hookProps: hookProps, classNames: options.weekNumberClassNames, content: options.weekNumberContent, defaultContent: renderInner$1, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount }, props.children));
9038    })); };
9039    function renderInner$1(innerProps) {
9040        return innerProps.text;
9041    }
9042
9043    // exports
9044    // --------------------------------------------------------------------------------------------------
9045    var version = '5.5.1'; // important to type it, so .d.ts has generic string
9046
9047    var Calendar = /** @class */ (function (_super) {
9048        __extends(Calendar, _super);
9049        function Calendar(el, optionOverrides) {
9050            if (optionOverrides === void 0) { optionOverrides = {}; }
9051            var _this = _super.call(this) || this;
9052            _this.isRendering = false;
9053            _this.isRendered = false;
9054            _this.currentClassNames = [];
9055            _this.customContentRenderId = 0; // will affect custom generated classNames?
9056            _this.handleAction = function (action) {
9057                // actions we know we want to render immediately
9058                switch (action.type) {
9059                    case 'SET_EVENT_DRAG':
9060                    case 'SET_EVENT_RESIZE':
9061                        _this.renderRunner.tryDrain();
9062                }
9063            };
9064            _this.handleData = function (data) {
9065                _this.currentData = data;
9066                _this.renderRunner.request(data.calendarOptions.rerenderDelay);
9067            };
9068            _this.handleRenderRequest = function () {
9069                if (_this.isRendering) {
9070                    _this.isRendered = true;
9071                    var currentData_1 = _this.currentData;
9072                    render(createElement(CalendarRoot, { options: currentData_1.calendarOptions, theme: currentData_1.theme, emitter: currentData_1.emitter }, function (classNames, height, isHeightAuto, forPrint) {
9073                        _this.setClassNames(classNames);
9074                        _this.setHeight(height);
9075                        return (createElement(CustomContentRenderContext.Provider, { value: _this.customContentRenderId },
9076                            createElement(CalendarContent, __assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData_1))));
9077                    }), _this.el);
9078                }
9079                else if (_this.isRendered) {
9080                    _this.isRendered = false;
9081                    unmountComponentAtNode$1(_this.el);
9082                    _this.setClassNames([]);
9083                    _this.setHeight('');
9084                }
9085                flushToDom$1();
9086            };
9087            _this.el = el;
9088            _this.renderRunner = new DelayedRunner(_this.handleRenderRequest);
9089            new CalendarDataManager({
9090                optionOverrides: optionOverrides,
9091                calendarApi: _this,
9092                onAction: _this.handleAction,
9093                onData: _this.handleData,
9094            });
9095            return _this;
9096        }
9097        Object.defineProperty(Calendar.prototype, "view", {
9098            get: function () { return this.currentData.viewApi; } // for public API
9099            ,
9100            enumerable: false,
9101            configurable: true
9102        });
9103        Calendar.prototype.render = function () {
9104            var wasRendering = this.isRendering;
9105            if (!wasRendering) {
9106                this.isRendering = true;
9107            }
9108            else {
9109                this.customContentRenderId += 1;
9110            }
9111            this.renderRunner.request();
9112            if (wasRendering) {
9113                this.updateSize();
9114            }
9115        };
9116        Calendar.prototype.destroy = function () {
9117            if (this.isRendering) {
9118                this.isRendering = false;
9119                this.renderRunner.request();
9120            }
9121        };
9122        Calendar.prototype.updateSize = function () {
9123            _super.prototype.updateSize.call(this);
9124            flushToDom$1();
9125        };
9126        Calendar.prototype.batchRendering = function (func) {
9127            this.renderRunner.pause('batchRendering');
9128            func();
9129            this.renderRunner.resume('batchRendering');
9130        };
9131        Calendar.prototype.pauseRendering = function () {
9132            this.renderRunner.pause('pauseRendering');
9133        };
9134        Calendar.prototype.resumeRendering = function () {
9135            this.renderRunner.resume('pauseRendering', true);
9136        };
9137        Calendar.prototype.resetOptions = function (optionOverrides, append) {
9138            this.currentDataManager.resetOptions(optionOverrides, append);
9139        };
9140        Calendar.prototype.setClassNames = function (classNames) {
9141            if (!isArraysEqual(classNames, this.currentClassNames)) {
9142                var classList = this.el.classList;
9143                for (var _i = 0, _a = this.currentClassNames; _i < _a.length; _i++) {
9144                    var className = _a[_i];
9145                    classList.remove(className);
9146                }
9147                for (var _b = 0, classNames_1 = classNames; _b < classNames_1.length; _b++) {
9148                    var className = classNames_1[_b];
9149                    classList.add(className);
9150                }
9151                this.currentClassNames = classNames;
9152            }
9153        };
9154        Calendar.prototype.setHeight = function (height) {
9155            applyStyleProp(this.el, 'height', height);
9156        };
9157        return Calendar;
9158    }(CalendarApi));
9159
9160    config.touchMouseIgnoreWait = 500;
9161    var ignoreMouseDepth = 0;
9162    var listenerCnt = 0;
9163    var isWindowTouchMoveCancelled = false;
9164    /*
9165    Uses a "pointer" abstraction, which monitors UI events for both mouse and touch.
9166    Tracks when the pointer "drags" on a certain element, meaning down+move+up.
9167
9168    Also, tracks if there was touch-scrolling.
9169    Also, can prevent touch-scrolling from happening.
9170    Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.
9171
9172    emits:
9173    - pointerdown
9174    - pointermove
9175    - pointerup
9176    */
9177    var PointerDragging = /** @class */ (function () {
9178        function PointerDragging(containerEl) {
9179            var _this = this;
9180            this.subjectEl = null;
9181            // options that can be directly assigned by caller
9182            this.selector = ''; // will cause subjectEl in all emitted events to be this element
9183            this.handleSelector = '';
9184            this.shouldIgnoreMove = false;
9185            this.shouldWatchScroll = true; // for simulating pointermove on scroll
9186            // internal states
9187            this.isDragging = false;
9188            this.isTouchDragging = false;
9189            this.wasTouchScroll = false;
9190            // Mouse
9191            // ----------------------------------------------------------------------------------------------------
9192            this.handleMouseDown = function (ev) {
9193                if (!_this.shouldIgnoreMouse() &&
9194                    isPrimaryMouseButton(ev) &&
9195                    _this.tryStart(ev)) {
9196                    var pev = _this.createEventFromMouse(ev, true);
9197                    _this.emitter.trigger('pointerdown', pev);
9198                    _this.initScrollWatch(pev);
9199                    if (!_this.shouldIgnoreMove) {
9200                        document.addEventListener('mousemove', _this.handleMouseMove);
9201                    }
9202                    document.addEventListener('mouseup', _this.handleMouseUp);
9203                }
9204            };
9205            this.handleMouseMove = function (ev) {
9206                var pev = _this.createEventFromMouse(ev);
9207                _this.recordCoords(pev);
9208                _this.emitter.trigger('pointermove', pev);
9209            };
9210            this.handleMouseUp = function (ev) {
9211                document.removeEventListener('mousemove', _this.handleMouseMove);
9212                document.removeEventListener('mouseup', _this.handleMouseUp);
9213                _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev));
9214                _this.cleanup(); // call last so that pointerup has access to props
9215            };
9216            // Touch
9217            // ----------------------------------------------------------------------------------------------------
9218            this.handleTouchStart = function (ev) {
9219                if (_this.tryStart(ev)) {
9220                    _this.isTouchDragging = true;
9221                    var pev = _this.createEventFromTouch(ev, true);
9222                    _this.emitter.trigger('pointerdown', pev);
9223                    _this.initScrollWatch(pev);
9224                    // unlike mouse, need to attach to target, not document
9225                    // https://stackoverflow.com/a/45760014
9226                    var targetEl = ev.target;
9227                    if (!_this.shouldIgnoreMove) {
9228                        targetEl.addEventListener('touchmove', _this.handleTouchMove);
9229                    }
9230                    targetEl.addEventListener('touchend', _this.handleTouchEnd);
9231                    targetEl.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end
9232                    // attach a handler to get called when ANY scroll action happens on the page.
9233                    // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
9234                    // http://stackoverflow.com/a/32954565/96342
9235                    window.addEventListener('scroll', _this.handleTouchScroll, true);
9236                }
9237            };
9238            this.handleTouchMove = function (ev) {
9239                var pev = _this.createEventFromTouch(ev);
9240                _this.recordCoords(pev);
9241                _this.emitter.trigger('pointermove', pev);
9242            };
9243            this.handleTouchEnd = function (ev) {
9244                if (_this.isDragging) { // done to guard against touchend followed by touchcancel
9245                    var targetEl = ev.target;
9246                    targetEl.removeEventListener('touchmove', _this.handleTouchMove);
9247                    targetEl.removeEventListener('touchend', _this.handleTouchEnd);
9248                    targetEl.removeEventListener('touchcancel', _this.handleTouchEnd);
9249                    window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true
9250                    _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev));
9251                    _this.cleanup(); // call last so that pointerup has access to props
9252                    _this.isTouchDragging = false;
9253                    startIgnoringMouse();
9254                }
9255            };
9256            this.handleTouchScroll = function () {
9257                _this.wasTouchScroll = true;
9258            };
9259            this.handleScroll = function (ev) {
9260                if (!_this.shouldIgnoreMove) {
9261                    var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX;
9262                    var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY;
9263                    _this.emitter.trigger('pointermove', {
9264                        origEvent: ev,
9265                        isTouch: _this.isTouchDragging,
9266                        subjectEl: _this.subjectEl,
9267                        pageX: pageX,
9268                        pageY: pageY,
9269                        deltaX: pageX - _this.origPageX,
9270                        deltaY: pageY - _this.origPageY,
9271                    });
9272                }
9273            };
9274            this.containerEl = containerEl;
9275            this.emitter = new Emitter();
9276            containerEl.addEventListener('mousedown', this.handleMouseDown);
9277            containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true });
9278            listenerCreated();
9279        }
9280        PointerDragging.prototype.destroy = function () {
9281            this.containerEl.removeEventListener('mousedown', this.handleMouseDown);
9282            this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
9283            listenerDestroyed();
9284        };
9285        PointerDragging.prototype.tryStart = function (ev) {
9286            var subjectEl = this.querySubjectEl(ev);
9287            var downEl = ev.target;
9288            if (subjectEl &&
9289                (!this.handleSelector || elementClosest(downEl, this.handleSelector))) {
9290                this.subjectEl = subjectEl;
9291                this.isDragging = true; // do this first so cancelTouchScroll will work
9292                this.wasTouchScroll = false;
9293                return true;
9294            }
9295            return false;
9296        };
9297        PointerDragging.prototype.cleanup = function () {
9298            isWindowTouchMoveCancelled = false;
9299            this.isDragging = false;
9300            this.subjectEl = null;
9301            // keep wasTouchScroll around for later access
9302            this.destroyScrollWatch();
9303        };
9304        PointerDragging.prototype.querySubjectEl = function (ev) {
9305            if (this.selector) {
9306                return elementClosest(ev.target, this.selector);
9307            }
9308            return this.containerEl;
9309        };
9310        PointerDragging.prototype.shouldIgnoreMouse = function () {
9311            return ignoreMouseDepth || this.isTouchDragging;
9312        };
9313        // can be called by user of this class, to cancel touch-based scrolling for the current drag
9314        PointerDragging.prototype.cancelTouchScroll = function () {
9315            if (this.isDragging) {
9316                isWindowTouchMoveCancelled = true;
9317            }
9318        };
9319        // Scrolling that simulates pointermoves
9320        // ----------------------------------------------------------------------------------------------------
9321        PointerDragging.prototype.initScrollWatch = function (ev) {
9322            if (this.shouldWatchScroll) {
9323                this.recordCoords(ev);
9324                window.addEventListener('scroll', this.handleScroll, true); // useCapture=true
9325            }
9326        };
9327        PointerDragging.prototype.recordCoords = function (ev) {
9328            if (this.shouldWatchScroll) {
9329                this.prevPageX = ev.pageX;
9330                this.prevPageY = ev.pageY;
9331                this.prevScrollX = window.pageXOffset;
9332                this.prevScrollY = window.pageYOffset;
9333            }
9334        };
9335        PointerDragging.prototype.destroyScrollWatch = function () {
9336            if (this.shouldWatchScroll) {
9337                window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true
9338            }
9339        };
9340        // Event Normalization
9341        // ----------------------------------------------------------------------------------------------------
9342        PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) {
9343            var deltaX = 0;
9344            var deltaY = 0;
9345            // TODO: repeat code
9346            if (isFirst) {
9347                this.origPageX = ev.pageX;
9348                this.origPageY = ev.pageY;
9349            }
9350            else {
9351                deltaX = ev.pageX - this.origPageX;
9352                deltaY = ev.pageY - this.origPageY;
9353            }
9354            return {
9355                origEvent: ev,
9356                isTouch: false,
9357                subjectEl: this.subjectEl,
9358                pageX: ev.pageX,
9359                pageY: ev.pageY,
9360                deltaX: deltaX,
9361                deltaY: deltaY,
9362            };
9363        };
9364        PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) {
9365            var touches = ev.touches;
9366            var pageX;
9367            var pageY;
9368            var deltaX = 0;
9369            var deltaY = 0;
9370            // if touch coords available, prefer,
9371            // because FF would give bad ev.pageX ev.pageY
9372            if (touches && touches.length) {
9373                pageX = touches[0].pageX;
9374                pageY = touches[0].pageY;
9375            }
9376            else {
9377                pageX = ev.pageX;
9378                pageY = ev.pageY;
9379            }
9380            // TODO: repeat code
9381            if (isFirst) {
9382                this.origPageX = pageX;
9383                this.origPageY = pageY;
9384            }
9385            else {
9386                deltaX = pageX - this.origPageX;
9387                deltaY = pageY - this.origPageY;
9388            }
9389            return {
9390                origEvent: ev,
9391                isTouch: true,
9392                subjectEl: this.subjectEl,
9393                pageX: pageX,
9394                pageY: pageY,
9395                deltaX: deltaX,
9396                deltaY: deltaY,
9397            };
9398        };
9399        return PointerDragging;
9400    }());
9401    // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
9402    function isPrimaryMouseButton(ev) {
9403        return ev.button === 0 && !ev.ctrlKey;
9404    }
9405    // Ignoring fake mouse events generated by touch
9406    // ----------------------------------------------------------------------------------------------------
9407    function startIgnoringMouse() {
9408        ignoreMouseDepth += 1;
9409        setTimeout(function () {
9410            ignoreMouseDepth -= 1;
9411        }, config.touchMouseIgnoreWait);
9412    }
9413    // We want to attach touchmove as early as possible for Safari
9414    // ----------------------------------------------------------------------------------------------------
9415    function listenerCreated() {
9416        listenerCnt += 1;
9417        if (listenerCnt === 1) {
9418            window.addEventListener('touchmove', onWindowTouchMove, { passive: false });
9419        }
9420    }
9421    function listenerDestroyed() {
9422        listenerCnt -= 1;
9423        if (!listenerCnt) {
9424            window.removeEventListener('touchmove', onWindowTouchMove, { passive: false });
9425        }
9426    }
9427    function onWindowTouchMove(ev) {
9428        if (isWindowTouchMoveCancelled) {
9429            ev.preventDefault();
9430        }
9431    }
9432
9433    /*
9434    An effect in which an element follows the movement of a pointer across the screen.
9435    The moving element is a clone of some other element.
9436    Must call start + handleMove + stop.
9437    */
9438    var ElementMirror = /** @class */ (function () {
9439        function ElementMirror() {
9440            this.isVisible = false; // must be explicitly enabled
9441            this.sourceEl = null;
9442            this.mirrorEl = null;
9443            this.sourceElRect = null; // screen coords relative to viewport
9444            // options that can be set directly by caller
9445            this.parentNode = document.body;
9446            this.zIndex = 9999;
9447            this.revertDuration = 0;
9448        }
9449        ElementMirror.prototype.start = function (sourceEl, pageX, pageY) {
9450            this.sourceEl = sourceEl;
9451            this.sourceElRect = this.sourceEl.getBoundingClientRect();
9452            this.origScreenX = pageX - window.pageXOffset;
9453            this.origScreenY = pageY - window.pageYOffset;
9454            this.deltaX = 0;
9455            this.deltaY = 0;
9456            this.updateElPosition();
9457        };
9458        ElementMirror.prototype.handleMove = function (pageX, pageY) {
9459            this.deltaX = (pageX - window.pageXOffset) - this.origScreenX;
9460            this.deltaY = (pageY - window.pageYOffset) - this.origScreenY;
9461            this.updateElPosition();
9462        };
9463        // can be called before start
9464        ElementMirror.prototype.setIsVisible = function (bool) {
9465            if (bool) {
9466                if (!this.isVisible) {
9467                    if (this.mirrorEl) {
9468                        this.mirrorEl.style.display = '';
9469                    }
9470                    this.isVisible = bool; // needs to happen before updateElPosition
9471                    this.updateElPosition(); // because was not updating the position while invisible
9472                }
9473            }
9474            else if (this.isVisible) {
9475                if (this.mirrorEl) {
9476                    this.mirrorEl.style.display = 'none';
9477                }
9478                this.isVisible = bool;
9479            }
9480        };
9481        // always async
9482        ElementMirror.prototype.stop = function (needsRevertAnimation, callback) {
9483            var _this = this;
9484            var done = function () {
9485                _this.cleanup();
9486                callback();
9487            };
9488            if (needsRevertAnimation &&
9489                this.mirrorEl &&
9490                this.isVisible &&
9491                this.revertDuration && // if 0, transition won't work
9492                (this.deltaX || this.deltaY) // if same coords, transition won't work
9493            ) {
9494                this.doRevertAnimation(done, this.revertDuration);
9495            }
9496            else {
9497                setTimeout(done, 0);
9498            }
9499        };
9500        ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) {
9501            var mirrorEl = this.mirrorEl;
9502            var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened
9503            mirrorEl.style.transition =
9504                'top ' + revertDuration + 'ms,' +
9505                    'left ' + revertDuration + 'ms';
9506            applyStyle(mirrorEl, {
9507                left: finalSourceElRect.left,
9508                top: finalSourceElRect.top,
9509            });
9510            whenTransitionDone(mirrorEl, function () {
9511                mirrorEl.style.transition = '';
9512                callback();
9513            });
9514        };
9515        ElementMirror.prototype.cleanup = function () {
9516            if (this.mirrorEl) {
9517                removeElement(this.mirrorEl);
9518                this.mirrorEl = null;
9519            }
9520            this.sourceEl = null;
9521        };
9522        ElementMirror.prototype.updateElPosition = function () {
9523            if (this.sourceEl && this.isVisible) {
9524                applyStyle(this.getMirrorEl(), {
9525                    left: this.sourceElRect.left + this.deltaX,
9526                    top: this.sourceElRect.top + this.deltaY,
9527                });
9528            }
9529        };
9530        ElementMirror.prototype.getMirrorEl = function () {
9531            var sourceElRect = this.sourceElRect;
9532            var mirrorEl = this.mirrorEl;
9533            if (!mirrorEl) {
9534                mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
9535                // we don't want long taps or any mouse interaction causing selection/menus.
9536                // would use preventSelection(), but that prevents selectstart, causing problems.
9537                mirrorEl.classList.add('fc-unselectable');
9538                mirrorEl.classList.add('fc-event-dragging');
9539                applyStyle(mirrorEl, {
9540                    position: 'fixed',
9541                    zIndex: this.zIndex,
9542                    visibility: '',
9543                    boxSizing: 'border-box',
9544                    width: sourceElRect.right - sourceElRect.left,
9545                    height: sourceElRect.bottom - sourceElRect.top,
9546                    right: 'auto',
9547                    bottom: 'auto',
9548                    margin: 0,
9549                });
9550                this.parentNode.appendChild(mirrorEl);
9551            }
9552            return mirrorEl;
9553        };
9554        return ElementMirror;
9555    }());
9556
9557    /*
9558    Is a cache for a given element's scroll information (all the info that ScrollController stores)
9559    in addition the "client rectangle" of the element.. the area within the scrollbars.
9560
9561    The cache can be in one of two modes:
9562    - doesListening:false - ignores when the container is scrolled by someone else
9563    - doesListening:true - watch for scrolling and update the cache
9564    */
9565    var ScrollGeomCache = /** @class */ (function (_super) {
9566        __extends(ScrollGeomCache, _super);
9567        function ScrollGeomCache(scrollController, doesListening) {
9568            var _this = _super.call(this) || this;
9569            _this.handleScroll = function () {
9570                _this.scrollTop = _this.scrollController.getScrollTop();
9571                _this.scrollLeft = _this.scrollController.getScrollLeft();
9572                _this.handleScrollChange();
9573            };
9574            _this.scrollController = scrollController;
9575            _this.doesListening = doesListening;
9576            _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop();
9577            _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
9578            _this.scrollWidth = scrollController.getScrollWidth();
9579            _this.scrollHeight = scrollController.getScrollHeight();
9580            _this.clientWidth = scrollController.getClientWidth();
9581            _this.clientHeight = scrollController.getClientHeight();
9582            _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values
9583            if (_this.doesListening) {
9584                _this.getEventTarget().addEventListener('scroll', _this.handleScroll);
9585            }
9586            return _this;
9587        }
9588        ScrollGeomCache.prototype.destroy = function () {
9589            if (this.doesListening) {
9590                this.getEventTarget().removeEventListener('scroll', this.handleScroll);
9591            }
9592        };
9593        ScrollGeomCache.prototype.getScrollTop = function () {
9594            return this.scrollTop;
9595        };
9596        ScrollGeomCache.prototype.getScrollLeft = function () {
9597            return this.scrollLeft;
9598        };
9599        ScrollGeomCache.prototype.setScrollTop = function (top) {
9600            this.scrollController.setScrollTop(top);
9601            if (!this.doesListening) {
9602                // we are not relying on the element to normalize out-of-bounds scroll values
9603                // so we need to sanitize ourselves
9604                this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
9605                this.handleScrollChange();
9606            }
9607        };
9608        ScrollGeomCache.prototype.setScrollLeft = function (top) {
9609            this.scrollController.setScrollLeft(top);
9610            if (!this.doesListening) {
9611                // we are not relying on the element to normalize out-of-bounds scroll values
9612                // so we need to sanitize ourselves
9613                this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
9614                this.handleScrollChange();
9615            }
9616        };
9617        ScrollGeomCache.prototype.getClientWidth = function () {
9618            return this.clientWidth;
9619        };
9620        ScrollGeomCache.prototype.getClientHeight = function () {
9621            return this.clientHeight;
9622        };
9623        ScrollGeomCache.prototype.getScrollWidth = function () {
9624            return this.scrollWidth;
9625        };
9626        ScrollGeomCache.prototype.getScrollHeight = function () {
9627            return this.scrollHeight;
9628        };
9629        ScrollGeomCache.prototype.handleScrollChange = function () {
9630        };
9631        return ScrollGeomCache;
9632    }(ScrollController));
9633
9634    var ElementScrollGeomCache = /** @class */ (function (_super) {
9635        __extends(ElementScrollGeomCache, _super);
9636        function ElementScrollGeomCache(el, doesListening) {
9637            return _super.call(this, new ElementScrollController(el), doesListening) || this;
9638        }
9639        ElementScrollGeomCache.prototype.getEventTarget = function () {
9640            return this.scrollController.el;
9641        };
9642        ElementScrollGeomCache.prototype.computeClientRect = function () {
9643            return computeInnerRect(this.scrollController.el);
9644        };
9645        return ElementScrollGeomCache;
9646    }(ScrollGeomCache));
9647
9648    var WindowScrollGeomCache = /** @class */ (function (_super) {
9649        __extends(WindowScrollGeomCache, _super);
9650        function WindowScrollGeomCache(doesListening) {
9651            return _super.call(this, new WindowScrollController(), doesListening) || this;
9652        }
9653        WindowScrollGeomCache.prototype.getEventTarget = function () {
9654            return window;
9655        };
9656        WindowScrollGeomCache.prototype.computeClientRect = function () {
9657            return {
9658                left: this.scrollLeft,
9659                right: this.scrollLeft + this.clientWidth,
9660                top: this.scrollTop,
9661                bottom: this.scrollTop + this.clientHeight,
9662            };
9663        };
9664        // the window is the only scroll object that changes it's rectangle relative
9665        // to the document's topleft as it scrolls
9666        WindowScrollGeomCache.prototype.handleScrollChange = function () {
9667            this.clientRect = this.computeClientRect();
9668        };
9669        return WindowScrollGeomCache;
9670    }(ScrollGeomCache));
9671
9672    // If available we are using native "performance" API instead of "Date"
9673    // Read more about it on MDN:
9674    // https://developer.mozilla.org/en-US/docs/Web/API/Performance
9675    var getTime = typeof performance === 'function' ? performance.now : Date.now;
9676    /*
9677    For a pointer interaction, automatically scrolls certain scroll containers when the pointer
9678    approaches the edge.
9679
9680    The caller must call start + handleMove + stop.
9681    */
9682    var AutoScroller = /** @class */ (function () {
9683        function AutoScroller() {
9684            var _this = this;
9685            // options that can be set by caller
9686            this.isEnabled = true;
9687            this.scrollQuery = [window, '.fc-scroller'];
9688            this.edgeThreshold = 50; // pixels
9689            this.maxVelocity = 300; // pixels per second
9690            // internal state
9691            this.pointerScreenX = null;
9692            this.pointerScreenY = null;
9693            this.isAnimating = false;
9694            this.scrollCaches = null;
9695            // protect against the initial pointerdown being too close to an edge and starting the scroll
9696            this.everMovedUp = false;
9697            this.everMovedDown = false;
9698            this.everMovedLeft = false;
9699            this.everMovedRight = false;
9700            this.animate = function () {
9701                if (_this.isAnimating) { // wasn't cancelled between animation calls
9702                    var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset);
9703                    if (edge) {
9704                        var now = getTime();
9705                        _this.handleSide(edge, (now - _this.msSinceRequest) / 1000);
9706                        _this.requestAnimation(now);
9707                    }
9708                    else {
9709                        _this.isAnimating = false; // will stop animation
9710                    }
9711                }
9712            };
9713        }
9714        AutoScroller.prototype.start = function (pageX, pageY) {
9715            if (this.isEnabled) {
9716                this.scrollCaches = this.buildCaches();
9717                this.pointerScreenX = null;
9718                this.pointerScreenY = null;
9719                this.everMovedUp = false;
9720                this.everMovedDown = false;
9721                this.everMovedLeft = false;
9722                this.everMovedRight = false;
9723                this.handleMove(pageX, pageY);
9724            }
9725        };
9726        AutoScroller.prototype.handleMove = function (pageX, pageY) {
9727            if (this.isEnabled) {
9728                var pointerScreenX = pageX - window.pageXOffset;
9729                var pointerScreenY = pageY - window.pageYOffset;
9730                var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
9731                var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
9732                if (yDelta < 0) {
9733                    this.everMovedUp = true;
9734                }
9735                else if (yDelta > 0) {
9736                    this.everMovedDown = true;
9737                }
9738                if (xDelta < 0) {
9739                    this.everMovedLeft = true;
9740                }
9741                else if (xDelta > 0) {
9742                    this.everMovedRight = true;
9743                }
9744                this.pointerScreenX = pointerScreenX;
9745                this.pointerScreenY = pointerScreenY;
9746                if (!this.isAnimating) {
9747                    this.isAnimating = true;
9748                    this.requestAnimation(getTime());
9749                }
9750            }
9751        };
9752        AutoScroller.prototype.stop = function () {
9753            if (this.isEnabled) {
9754                this.isAnimating = false; // will stop animation
9755                for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
9756                    var scrollCache = _a[_i];
9757                    scrollCache.destroy();
9758                }
9759                this.scrollCaches = null;
9760            }
9761        };
9762        AutoScroller.prototype.requestAnimation = function (now) {
9763            this.msSinceRequest = now;
9764            requestAnimationFrame(this.animate);
9765        };
9766        AutoScroller.prototype.handleSide = function (edge, seconds) {
9767            var scrollCache = edge.scrollCache;
9768            var edgeThreshold = this.edgeThreshold;
9769            var invDistance = edgeThreshold - edge.distance;
9770            var velocity = // the closer to the edge, the faster we scroll
9771             ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic
9772                this.maxVelocity * seconds;
9773            var sign = 1;
9774            switch (edge.name) {
9775                case 'left':
9776                    sign = -1;
9777                // falls through
9778                case 'right':
9779                    scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
9780                    break;
9781                case 'top':
9782                    sign = -1;
9783                // falls through
9784                case 'bottom':
9785                    scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
9786                    break;
9787            }
9788        };
9789        // left/top are relative to document topleft
9790        AutoScroller.prototype.computeBestEdge = function (left, top) {
9791            var edgeThreshold = this.edgeThreshold;
9792            var bestSide = null;
9793            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
9794                var scrollCache = _a[_i];
9795                var rect = scrollCache.clientRect;
9796                var leftDist = left - rect.left;
9797                var rightDist = rect.right - left;
9798                var topDist = top - rect.top;
9799                var bottomDist = rect.bottom - top;
9800                // completely within the rect?
9801                if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
9802                    if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&
9803                        (!bestSide || bestSide.distance > topDist)) {
9804                        bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist };
9805                    }
9806                    if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&
9807                        (!bestSide || bestSide.distance > bottomDist)) {
9808                        bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist };
9809                    }
9810                    if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&
9811                        (!bestSide || bestSide.distance > leftDist)) {
9812                        bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist };
9813                    }
9814                    if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&
9815                        (!bestSide || bestSide.distance > rightDist)) {
9816                        bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist };
9817                    }
9818                }
9819            }
9820            return bestSide;
9821        };
9822        AutoScroller.prototype.buildCaches = function () {
9823            return this.queryScrollEls().map(function (el) {
9824                if (el === window) {
9825                    return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls
9826                }
9827                return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls
9828            });
9829        };
9830        AutoScroller.prototype.queryScrollEls = function () {
9831            var els = [];
9832            for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) {
9833                var query = _a[_i];
9834                if (typeof query === 'object') {
9835                    els.push(query);
9836                }
9837                else {
9838                    els.push.apply(els, Array.prototype.slice.call(document.querySelectorAll(query)));
9839                }
9840            }
9841            return els;
9842        };
9843        return AutoScroller;
9844    }());
9845
9846    /*
9847    Monitors dragging on an element. Has a number of high-level features:
9848    - minimum distance required before dragging
9849    - minimum wait time ("delay") before dragging
9850    - a mirror element that follows the pointer
9851    */
9852    var FeaturefulElementDragging = /** @class */ (function (_super) {
9853        __extends(FeaturefulElementDragging, _super);
9854        function FeaturefulElementDragging(containerEl, selector) {
9855            var _this = _super.call(this, containerEl) || this;
9856            // options that can be directly set by caller
9857            // the caller can also set the PointerDragging's options as well
9858            _this.delay = null;
9859            _this.minDistance = 0;
9860            _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag
9861            _this.mirrorNeedsRevert = false;
9862            _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup
9863            _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation
9864            _this.isDelayEnded = false;
9865            _this.isDistanceSurpassed = false;
9866            _this.delayTimeoutId = null;
9867            _this.onPointerDown = function (ev) {
9868                if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going
9869                    _this.isInteracting = true;
9870                    _this.isDelayEnded = false;
9871                    _this.isDistanceSurpassed = false;
9872                    preventSelection(document.body);
9873                    preventContextMenu(document.body);
9874                    // prevent links from being visited if there's an eventual drag.
9875                    // also prevents selection in older browsers (maybe?).
9876                    // not necessary for touch, besides, browser would complain about passiveness.
9877                    if (!ev.isTouch) {
9878                        ev.origEvent.preventDefault();
9879                    }
9880                    _this.emitter.trigger('pointerdown', ev);
9881                    if (_this.isInteracting && // not destroyed via pointerdown handler
9882                        !_this.pointer.shouldIgnoreMove) {
9883                        // actions related to initiating dragstart+dragmove+dragend...
9884                        _this.mirror.setIsVisible(false); // reset. caller must set-visible
9885                        _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down
9886                        _this.startDelay(ev);
9887                        if (!_this.minDistance) {
9888                            _this.handleDistanceSurpassed(ev);
9889                        }
9890                    }
9891                }
9892            };
9893            _this.onPointerMove = function (ev) {
9894                if (_this.isInteracting) {
9895                    _this.emitter.trigger('pointermove', ev);
9896                    if (!_this.isDistanceSurpassed) {
9897                        var minDistance = _this.minDistance;
9898                        var distanceSq = void 0; // current distance from the origin, squared
9899                        var deltaX = ev.deltaX, deltaY = ev.deltaY;
9900                        distanceSq = deltaX * deltaX + deltaY * deltaY;
9901                        if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
9902                            _this.handleDistanceSurpassed(ev);
9903                        }
9904                    }
9905                    if (_this.isDragging) {
9906                        // a real pointer move? (not one simulated by scrolling)
9907                        if (ev.origEvent.type !== 'scroll') {
9908                            _this.mirror.handleMove(ev.pageX, ev.pageY);
9909                            _this.autoScroller.handleMove(ev.pageX, ev.pageY);
9910                        }
9911                        _this.emitter.trigger('dragmove', ev);
9912                    }
9913                }
9914            };
9915            _this.onPointerUp = function (ev) {
9916                if (_this.isInteracting) {
9917                    _this.isInteracting = false;
9918                    allowSelection(document.body);
9919                    allowContextMenu(document.body);
9920                    _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert
9921                    if (_this.isDragging) {
9922                        _this.autoScroller.stop();
9923                        _this.tryStopDrag(ev); // which will stop the mirror
9924                    }
9925                    if (_this.delayTimeoutId) {
9926                        clearTimeout(_this.delayTimeoutId);
9927                        _this.delayTimeoutId = null;
9928                    }
9929                }
9930            };
9931            var pointer = _this.pointer = new PointerDragging(containerEl);
9932            pointer.emitter.on('pointerdown', _this.onPointerDown);
9933            pointer.emitter.on('pointermove', _this.onPointerMove);
9934            pointer.emitter.on('pointerup', _this.onPointerUp);
9935            if (selector) {
9936                pointer.selector = selector;
9937            }
9938            _this.mirror = new ElementMirror();
9939            _this.autoScroller = new AutoScroller();
9940            return _this;
9941        }
9942        FeaturefulElementDragging.prototype.destroy = function () {
9943            this.pointer.destroy();
9944            // HACK: simulate a pointer-up to end the current drag
9945            // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire)
9946            this.onPointerUp({});
9947        };
9948        FeaturefulElementDragging.prototype.startDelay = function (ev) {
9949            var _this = this;
9950            if (typeof this.delay === 'number') {
9951                this.delayTimeoutId = setTimeout(function () {
9952                    _this.delayTimeoutId = null;
9953                    _this.handleDelayEnd(ev);
9954                }, this.delay); // not assignable to number!
9955            }
9956            else {
9957                this.handleDelayEnd(ev);
9958            }
9959        };
9960        FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) {
9961            this.isDelayEnded = true;
9962            this.tryStartDrag(ev);
9963        };
9964        FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) {
9965            this.isDistanceSurpassed = true;
9966            this.tryStartDrag(ev);
9967        };
9968        FeaturefulElementDragging.prototype.tryStartDrag = function (ev) {
9969            if (this.isDelayEnded && this.isDistanceSurpassed) {
9970                if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
9971                    this.isDragging = true;
9972                    this.mirrorNeedsRevert = false;
9973                    this.autoScroller.start(ev.pageX, ev.pageY);
9974                    this.emitter.trigger('dragstart', ev);
9975                    if (this.touchScrollAllowed === false) {
9976                        this.pointer.cancelTouchScroll();
9977                    }
9978                }
9979            }
9980        };
9981        FeaturefulElementDragging.prototype.tryStopDrag = function (ev) {
9982            // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events
9983            // that come from the document to fire beforehand. much more convenient this way.
9984            this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev));
9985        };
9986        FeaturefulElementDragging.prototype.stopDrag = function (ev) {
9987            this.isDragging = false;
9988            this.emitter.trigger('dragend', ev);
9989        };
9990        // fill in the implementations...
9991        FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) {
9992            this.pointer.shouldIgnoreMove = bool;
9993        };
9994        FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) {
9995            this.mirror.setIsVisible(bool);
9996        };
9997        FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
9998            this.mirrorNeedsRevert = bool;
9999        };
10000        FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) {
10001            this.autoScroller.isEnabled = bool;
10002        };
10003        return FeaturefulElementDragging;
10004    }(ElementDragging));
10005
10006    /*
10007    When this class is instantiated, it records the offset of an element (relative to the document topleft),
10008    and continues to monitor scrolling, updating the cached coordinates if it needs to.
10009    Does not access the DOM after instantiation, so highly performant.
10010
10011    Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element
10012    and an determine if a given point is inside the combined clipping rectangle.
10013    */
10014    var OffsetTracker = /** @class */ (function () {
10015        function OffsetTracker(el) {
10016            this.origRect = computeRect(el);
10017            // will work fine for divs that have overflow:hidden
10018            this.scrollCaches = getClippingParents(el).map(function (scrollEl) { return new ElementScrollGeomCache(scrollEl, true); });
10019        }
10020        OffsetTracker.prototype.destroy = function () {
10021            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10022                var scrollCache = _a[_i];
10023                scrollCache.destroy();
10024            }
10025        };
10026        OffsetTracker.prototype.computeLeft = function () {
10027            var left = this.origRect.left;
10028            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10029                var scrollCache = _a[_i];
10030                left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
10031            }
10032            return left;
10033        };
10034        OffsetTracker.prototype.computeTop = function () {
10035            var top = this.origRect.top;
10036            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10037                var scrollCache = _a[_i];
10038                top += scrollCache.origScrollTop - scrollCache.getScrollTop();
10039            }
10040            return top;
10041        };
10042        OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) {
10043            var point = { left: pageX, top: pageY };
10044            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
10045                var scrollCache = _a[_i];
10046                if (!isIgnoredClipping(scrollCache.getEventTarget()) &&
10047                    !pointInsideRect(point, scrollCache.clientRect)) {
10048                    return false;
10049                }
10050            }
10051            return true;
10052        };
10053        return OffsetTracker;
10054    }());
10055    // certain clipping containers should never constrain interactions, like <html> and <body>
10056    // https://github.com/fullcalendar/fullcalendar/issues/3615
10057    function isIgnoredClipping(node) {
10058        var tagName = node.tagName;
10059        return tagName === 'HTML' || tagName === 'BODY';
10060    }
10061
10062    /*
10063    Tracks movement over multiple droppable areas (aka "hits")
10064    that exist in one or more DateComponents.
10065    Relies on an existing draggable.
10066
10067    emits:
10068    - pointerdown
10069    - dragstart
10070    - hitchange - fires initially, even if not over a hit
10071    - pointerup
10072    - (hitchange - again, to null, if ended over a hit)
10073    - dragend
10074    */
10075    var HitDragging = /** @class */ (function () {
10076        function HitDragging(dragging, droppableStore) {
10077            var _this = this;
10078            // options that can be set by caller
10079            this.useSubjectCenter = false;
10080            this.requireInitial = true; // if doesn't start out on a hit, won't emit any events
10081            this.initialHit = null;
10082            this.movingHit = null;
10083            this.finalHit = null; // won't ever be populated if shouldIgnoreMove
10084            this.handlePointerDown = function (ev) {
10085                var dragging = _this.dragging;
10086                _this.initialHit = null;
10087                _this.movingHit = null;
10088                _this.finalHit = null;
10089                _this.prepareHits();
10090                _this.processFirstCoord(ev);
10091                if (_this.initialHit || !_this.requireInitial) {
10092                    dragging.setIgnoreMove(false);
10093                    // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
10094                    _this.emitter.trigger('pointerdown', ev);
10095                }
10096                else {
10097                    dragging.setIgnoreMove(true);
10098                }
10099            };
10100            this.handleDragStart = function (ev) {
10101                _this.emitter.trigger('dragstart', ev);
10102                _this.handleMove(ev, true); // force = fire even if initially null
10103            };
10104            this.handleDragMove = function (ev) {
10105                _this.emitter.trigger('dragmove', ev);
10106                _this.handleMove(ev);
10107            };
10108            this.handlePointerUp = function (ev) {
10109                _this.releaseHits();
10110                _this.emitter.trigger('pointerup', ev);
10111            };
10112            this.handleDragEnd = function (ev) {
10113                if (_this.movingHit) {
10114                    _this.emitter.trigger('hitupdate', null, true, ev);
10115                }
10116                _this.finalHit = _this.movingHit;
10117                _this.movingHit = null;
10118                _this.emitter.trigger('dragend', ev);
10119            };
10120            this.droppableStore = droppableStore;
10121            dragging.emitter.on('pointerdown', this.handlePointerDown);
10122            dragging.emitter.on('dragstart', this.handleDragStart);
10123            dragging.emitter.on('dragmove', this.handleDragMove);
10124            dragging.emitter.on('pointerup', this.handlePointerUp);
10125            dragging.emitter.on('dragend', this.handleDragEnd);
10126            this.dragging = dragging;
10127            this.emitter = new Emitter();
10128        }
10129        // sets initialHit
10130        // sets coordAdjust
10131        HitDragging.prototype.processFirstCoord = function (ev) {
10132            var origPoint = { left: ev.pageX, top: ev.pageY };
10133            var adjustedPoint = origPoint;
10134            var subjectEl = ev.subjectEl;
10135            var subjectRect;
10136            if (subjectEl !== document) {
10137                subjectRect = computeRect(subjectEl);
10138                adjustedPoint = constrainPoint(adjustedPoint, subjectRect);
10139            }
10140            var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
10141            if (initialHit) {
10142                if (this.useSubjectCenter && subjectRect) {
10143                    var slicedSubjectRect = intersectRects(subjectRect, initialHit.rect);
10144                    if (slicedSubjectRect) {
10145                        adjustedPoint = getRectCenter(slicedSubjectRect);
10146                    }
10147                }
10148                this.coordAdjust = diffPoints(adjustedPoint, origPoint);
10149            }
10150            else {
10151                this.coordAdjust = { left: 0, top: 0 };
10152            }
10153        };
10154        HitDragging.prototype.handleMove = function (ev, forceHandle) {
10155            var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
10156            if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
10157                this.movingHit = hit;
10158                this.emitter.trigger('hitupdate', hit, false, ev);
10159            }
10160        };
10161        HitDragging.prototype.prepareHits = function () {
10162            this.offsetTrackers = mapHash(this.droppableStore, function (interactionSettings) {
10163                interactionSettings.component.prepareHits();
10164                return new OffsetTracker(interactionSettings.el);
10165            });
10166        };
10167        HitDragging.prototype.releaseHits = function () {
10168            var offsetTrackers = this.offsetTrackers;
10169            for (var id in offsetTrackers) {
10170                offsetTrackers[id].destroy();
10171            }
10172            this.offsetTrackers = {};
10173        };
10174        HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) {
10175            var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers;
10176            var bestHit = null;
10177            for (var id in droppableStore) {
10178                var component = droppableStore[id].component;
10179                var offsetTracker = offsetTrackers[id];
10180                if (offsetTracker && // wasn't destroyed mid-drag
10181                    offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
10182                    var originLeft = offsetTracker.computeLeft();
10183                    var originTop = offsetTracker.computeTop();
10184                    var positionLeft = offsetLeft - originLeft;
10185                    var positionTop = offsetTop - originTop;
10186                    var origRect = offsetTracker.origRect;
10187                    var width = origRect.right - origRect.left;
10188                    var height = origRect.bottom - origRect.top;
10189                    if (
10190                    // must be within the element's bounds
10191                    positionLeft >= 0 && positionLeft < width &&
10192                        positionTop >= 0 && positionTop < height) {
10193                        var hit = component.queryHit(positionLeft, positionTop, width, height);
10194                        var dateProfile = component.context.getCurrentData().dateProfile;
10195                        if (hit &&
10196                            (
10197                            // make sure the hit is within activeRange, meaning it's not a deal cell
10198                            rangeContainsRange(dateProfile.activeRange, hit.dateSpan.range)) &&
10199                            (!bestHit || hit.layer > bestHit.layer)) {
10200                            // TODO: better way to re-orient rectangle
10201                            hit.rect.left += originLeft;
10202                            hit.rect.right += originLeft;
10203                            hit.rect.top += originTop;
10204                            hit.rect.bottom += originTop;
10205                            bestHit = hit;
10206                        }
10207                    }
10208                }
10209            }
10210            return bestHit;
10211        };
10212        return HitDragging;
10213    }());
10214    function isHitsEqual(hit0, hit1) {
10215        if (!hit0 && !hit1) {
10216            return true;
10217        }
10218        if (Boolean(hit0) !== Boolean(hit1)) {
10219            return false;
10220        }
10221        return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan);
10222    }
10223
10224    function buildDatePointApiWithContext(dateSpan, context) {
10225        var props = {};
10226        for (var _i = 0, _a = context.pluginHooks.datePointTransforms; _i < _a.length; _i++) {
10227            var transform = _a[_i];
10228            __assign(props, transform(dateSpan, context));
10229        }
10230        __assign(props, buildDatePointApi(dateSpan, context.dateEnv));
10231        return props;
10232    }
10233    function buildDatePointApi(span, dateEnv) {
10234        return {
10235            date: dateEnv.toDate(span.range.start),
10236            dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
10237            allDay: span.allDay,
10238        };
10239    }
10240
10241    /*
10242    Monitors when the user clicks on a specific date/time of a component.
10243    A pointerdown+pointerup on the same "hit" constitutes a click.
10244    */
10245    var DateClicking = /** @class */ (function (_super) {
10246        __extends(DateClicking, _super);
10247        function DateClicking(settings) {
10248            var _this = _super.call(this, settings) || this;
10249            _this.handlePointerDown = function (pev) {
10250                var dragging = _this.dragging;
10251                var downEl = pev.origEvent.target;
10252                // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired
10253                dragging.setIgnoreMove(!_this.component.isValidDateDownEl(downEl));
10254            };
10255            // won't even fire if moving was ignored
10256            _this.handleDragEnd = function (ev) {
10257                var component = _this.component;
10258                var pointer = _this.dragging.pointer;
10259                if (!pointer.wasTouchScroll) {
10260                    var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit;
10261                    if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
10262                        var context = component.context;
10263                        var arg = __assign(__assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view });
10264                        context.emitter.trigger('dateClick', arg);
10265                    }
10266                }
10267            };
10268            // we DO want to watch pointer moves because otherwise finalHit won't get populated
10269            _this.dragging = new FeaturefulElementDragging(settings.el);
10270            _this.dragging.autoScroller.isEnabled = false;
10271            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
10272            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10273            hitDragging.emitter.on('dragend', _this.handleDragEnd);
10274            return _this;
10275        }
10276        DateClicking.prototype.destroy = function () {
10277            this.dragging.destroy();
10278        };
10279        return DateClicking;
10280    }(Interaction));
10281
10282    /*
10283    Tracks when the user selects a portion of time of a component,
10284    constituted by a drag over date cells, with a possible delay at the beginning of the drag.
10285    */
10286    var DateSelecting = /** @class */ (function (_super) {
10287        __extends(DateSelecting, _super);
10288        function DateSelecting(settings) {
10289            var _this = _super.call(this, settings) || this;
10290            _this.dragSelection = null;
10291            _this.handlePointerDown = function (ev) {
10292                var _a = _this, component = _a.component, dragging = _a.dragging;
10293                var options = component.context.options;
10294                var canSelect = options.selectable &&
10295                    component.isValidDateDownEl(ev.origEvent.target);
10296                // don't bother to watch expensive moves if component won't do selection
10297                dragging.setIgnoreMove(!canSelect);
10298                // if touch, require user to hold down
10299                dragging.delay = ev.isTouch ? getComponentTouchDelay(component) : null;
10300            };
10301            _this.handleDragStart = function (ev) {
10302                _this.component.context.calendarApi.unselect(ev); // unselect previous selections
10303            };
10304            _this.handleHitUpdate = function (hit, isFinal) {
10305                var context = _this.component.context;
10306                var dragSelection = null;
10307                var isInvalid = false;
10308                if (hit) {
10309                    dragSelection = joinHitsIntoSelection(_this.hitDragging.initialHit, hit, context.pluginHooks.dateSelectionTransformers);
10310                    if (!dragSelection || !_this.component.isDateSelectionValid(dragSelection)) {
10311                        isInvalid = true;
10312                        dragSelection = null;
10313                    }
10314                }
10315                if (dragSelection) {
10316                    context.dispatch({ type: 'SELECT_DATES', selection: dragSelection });
10317                }
10318                else if (!isFinal) { // only unselect if moved away while dragging
10319                    context.dispatch({ type: 'UNSELECT_DATES' });
10320                }
10321                if (!isInvalid) {
10322                    enableCursor();
10323                }
10324                else {
10325                    disableCursor();
10326                }
10327                if (!isFinal) {
10328                    _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging
10329                }
10330            };
10331            _this.handlePointerUp = function (pev) {
10332                if (_this.dragSelection) {
10333                    // selection is already rendered, so just need to report selection
10334                    triggerDateSelect(_this.dragSelection, pev, _this.component.context);
10335                    _this.dragSelection = null;
10336                }
10337            };
10338            var component = settings.component;
10339            var options = component.context.options;
10340            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
10341            dragging.touchScrollAllowed = false;
10342            dragging.minDistance = options.selectMinDistance || 0;
10343            dragging.autoScroller.isEnabled = options.dragScroll;
10344            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
10345            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10346            hitDragging.emitter.on('dragstart', _this.handleDragStart);
10347            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
10348            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
10349            return _this;
10350        }
10351        DateSelecting.prototype.destroy = function () {
10352            this.dragging.destroy();
10353        };
10354        return DateSelecting;
10355    }(Interaction));
10356    function getComponentTouchDelay(component) {
10357        var options = component.context.options;
10358        var delay = options.selectLongPressDelay;
10359        if (delay == null) {
10360            delay = options.longPressDelay;
10361        }
10362        return delay;
10363    }
10364    function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
10365        var dateSpan0 = hit0.dateSpan;
10366        var dateSpan1 = hit1.dateSpan;
10367        var ms = [
10368            dateSpan0.range.start,
10369            dateSpan0.range.end,
10370            dateSpan1.range.start,
10371            dateSpan1.range.end,
10372        ];
10373        ms.sort(compareNumbers);
10374        var props = {};
10375        for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) {
10376            var transformer = dateSelectionTransformers_1[_i];
10377            var res = transformer(hit0, hit1);
10378            if (res === false) {
10379                return null;
10380            }
10381            if (res) {
10382                __assign(props, res);
10383            }
10384        }
10385        props.range = { start: ms[0], end: ms[3] };
10386        props.allDay = dateSpan0.allDay;
10387        return props;
10388    }
10389
10390    var EventDragging = /** @class */ (function (_super) {
10391        __extends(EventDragging, _super);
10392        function EventDragging(settings) {
10393            var _this = _super.call(this, settings) || this;
10394            // internal state
10395            _this.subjectEl = null;
10396            _this.subjectSeg = null; // the seg being selected/dragged
10397            _this.isDragging = false;
10398            _this.eventRange = null;
10399            _this.relevantEvents = null; // the events being dragged
10400            _this.receivingContext = null;
10401            _this.validMutation = null;
10402            _this.mutatedRelevantEvents = null;
10403            _this.handlePointerDown = function (ev) {
10404                var origTarget = ev.origEvent.target;
10405                var _a = _this, component = _a.component, dragging = _a.dragging;
10406                var mirror = dragging.mirror;
10407                var options = component.context.options;
10408                var initialContext = component.context;
10409                _this.subjectEl = ev.subjectEl;
10410                var subjectSeg = _this.subjectSeg = getElSeg(ev.subjectEl);
10411                var eventRange = _this.eventRange = subjectSeg.eventRange;
10412                var eventInstanceId = eventRange.instance.instanceId;
10413                _this.relevantEvents = getRelevantEvents(initialContext.getCurrentData().eventStore, eventInstanceId);
10414                dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance;
10415                dragging.delay =
10416                    // only do a touch delay if touch and this event hasn't been selected yet
10417                    (ev.isTouch && eventInstanceId !== component.props.eventSelection) ?
10418                        getComponentTouchDelay$1(component) :
10419                        null;
10420                if (options.fixedMirrorParent) {
10421                    mirror.parentNode = options.fixedMirrorParent;
10422                }
10423                else {
10424                    mirror.parentNode = elementClosest(origTarget, '.fc');
10425                }
10426                mirror.revertDuration = options.dragRevertDuration;
10427                var isValid = component.isValidSegDownEl(origTarget) &&
10428                    !elementClosest(origTarget, '.fc-event-resizer'); // NOT on a resizer
10429                dragging.setIgnoreMove(!isValid);
10430                // disable dragging for elements that are resizable (ie, selectable)
10431                // but are not draggable
10432                _this.isDragging = isValid &&
10433                    ev.subjectEl.classList.contains('fc-event-draggable');
10434            };
10435            _this.handleDragStart = function (ev) {
10436                var initialContext = _this.component.context;
10437                var eventRange = _this.eventRange;
10438                var eventInstanceId = eventRange.instance.instanceId;
10439                if (ev.isTouch) {
10440                    // need to select a different event?
10441                    if (eventInstanceId !== _this.component.props.eventSelection) {
10442                        initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId });
10443                    }
10444                }
10445                else {
10446                    // if now using mouse, but was previous touch interaction, clear selected event
10447                    initialContext.dispatch({ type: 'UNSELECT_EVENT' });
10448                }
10449                if (_this.isDragging) {
10450                    initialContext.calendarApi.unselect(ev); // unselect *date* selection
10451                    initialContext.emitter.trigger('eventDragStart', {
10452                        el: _this.subjectEl,
10453                        event: new EventApi(initialContext, eventRange.def, eventRange.instance),
10454                        jsEvent: ev.origEvent,
10455                        view: initialContext.viewApi,
10456                    });
10457                }
10458            };
10459            _this.handleHitUpdate = function (hit, isFinal) {
10460                if (!_this.isDragging) {
10461                    return;
10462                }
10463                var relevantEvents = _this.relevantEvents;
10464                var initialHit = _this.hitDragging.initialHit;
10465                var initialContext = _this.component.context;
10466                // states based on new hit
10467                var receivingContext = null;
10468                var mutation = null;
10469                var mutatedRelevantEvents = null;
10470                var isInvalid = false;
10471                var interaction = {
10472                    affectedEvents: relevantEvents,
10473                    mutatedEvents: createEmptyEventStore(),
10474                    isEvent: true,
10475                };
10476                if (hit) {
10477                    var receivingComponent = hit.component;
10478                    receivingContext = receivingComponent.context;
10479                    var receivingOptions = receivingContext.options;
10480                    if (initialContext === receivingContext ||
10481                        (receivingOptions.editable && receivingOptions.droppable)) {
10482                        mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers);
10483                        if (mutation) {
10484                            mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext);
10485                            interaction.mutatedEvents = mutatedRelevantEvents;
10486                            if (!receivingComponent.isInteractionValid(interaction)) {
10487                                isInvalid = true;
10488                                mutation = null;
10489                                mutatedRelevantEvents = null;
10490                                interaction.mutatedEvents = createEmptyEventStore();
10491                            }
10492                        }
10493                    }
10494                    else {
10495                        receivingContext = null;
10496                    }
10497                }
10498                _this.displayDrag(receivingContext, interaction);
10499                if (!isInvalid) {
10500                    enableCursor();
10501                }
10502                else {
10503                    disableCursor();
10504                }
10505                if (!isFinal) {
10506                    if (initialContext === receivingContext && // TODO: write test for this
10507                        isHitsEqual(initialHit, hit)) {
10508                        mutation = null;
10509                    }
10510                    _this.dragging.setMirrorNeedsRevert(!mutation);
10511                    // render the mirror if no already-rendered mirror
10512                    // TODO: wish we could somehow wait for dispatch to guarantee render
10513                    _this.dragging.setMirrorIsVisible(!hit || !document.querySelector('.fc-event-mirror'));
10514                    // assign states based on new hit
10515                    _this.receivingContext = receivingContext;
10516                    _this.validMutation = mutation;
10517                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
10518                }
10519            };
10520            _this.handlePointerUp = function () {
10521                if (!_this.isDragging) {
10522                    _this.cleanup(); // because handleDragEnd won't fire
10523                }
10524            };
10525            _this.handleDragEnd = function (ev) {
10526                if (_this.isDragging) {
10527                    var initialContext_1 = _this.component.context;
10528                    var initialView = initialContext_1.viewApi;
10529                    var _a = _this, receivingContext_1 = _a.receivingContext, validMutation = _a.validMutation;
10530                    var eventDef = _this.eventRange.def;
10531                    var eventInstance = _this.eventRange.instance;
10532                    var eventApi = new EventApi(initialContext_1, eventDef, eventInstance);
10533                    var relevantEvents_1 = _this.relevantEvents;
10534                    var mutatedRelevantEvents_1 = _this.mutatedRelevantEvents;
10535                    var finalHit = _this.hitDragging.finalHit;
10536                    _this.clearDrag(); // must happen after revert animation
10537                    initialContext_1.emitter.trigger('eventDragStop', {
10538                        el: _this.subjectEl,
10539                        event: eventApi,
10540                        jsEvent: ev.origEvent,
10541                        view: initialView,
10542                    });
10543                    if (validMutation) {
10544                        // dropped within same calendar
10545                        if (receivingContext_1 === initialContext_1) {
10546                            var updatedEventApi = new EventApi(initialContext_1, mutatedRelevantEvents_1.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents_1.instances[eventInstance.instanceId] : null);
10547                            initialContext_1.dispatch({
10548                                type: 'MERGE_EVENTS',
10549                                eventStore: mutatedRelevantEvents_1,
10550                            });
10551                            var eventChangeArg = {
10552                                oldEvent: eventApi,
10553                                event: updatedEventApi,
10554                                relatedEvents: buildEventApis(mutatedRelevantEvents_1, initialContext_1, eventInstance),
10555                                revert: function () {
10556                                    initialContext_1.dispatch({
10557                                        type: 'MERGE_EVENTS',
10558                                        eventStore: relevantEvents_1,
10559                                    });
10560                                },
10561                            };
10562                            var transformed = {};
10563                            for (var _i = 0, _b = initialContext_1.getCurrentData().pluginHooks.eventDropTransformers; _i < _b.length; _i++) {
10564                                var transformer = _b[_i];
10565                                __assign(transformed, transformer(validMutation, initialContext_1));
10566                            }
10567                            initialContext_1.emitter.trigger('eventDrop', __assign(__assign(__assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView }));
10568                            initialContext_1.emitter.trigger('eventChange', eventChangeArg);
10569                            // dropped in different calendar
10570                        }
10571                        else if (receivingContext_1) {
10572                            var eventRemoveArg = {
10573                                event: eventApi,
10574                                relatedEvents: buildEventApis(relevantEvents_1, initialContext_1, eventInstance),
10575                                revert: function () {
10576                                    initialContext_1.dispatch({
10577                                        type: 'MERGE_EVENTS',
10578                                        eventStore: relevantEvents_1,
10579                                    });
10580                                },
10581                            };
10582                            initialContext_1.emitter.trigger('eventLeave', __assign(__assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView }));
10583                            initialContext_1.dispatch({
10584                                type: 'REMOVE_EVENTS',
10585                                eventStore: relevantEvents_1,
10586                            });
10587                            initialContext_1.emitter.trigger('eventRemove', eventRemoveArg);
10588                            var addedEventDef = mutatedRelevantEvents_1.defs[eventDef.defId];
10589                            var addedEventInstance = mutatedRelevantEvents_1.instances[eventInstance.instanceId];
10590                            var addedEventApi = new EventApi(receivingContext_1, addedEventDef, addedEventInstance);
10591                            receivingContext_1.dispatch({
10592                                type: 'MERGE_EVENTS',
10593                                eventStore: mutatedRelevantEvents_1,
10594                            });
10595                            var eventAddArg = {
10596                                event: addedEventApi,
10597                                relatedEvents: buildEventApis(mutatedRelevantEvents_1, receivingContext_1, addedEventInstance),
10598                                revert: function () {
10599                                    receivingContext_1.dispatch({
10600                                        type: 'REMOVE_EVENTS',
10601                                        eventStore: mutatedRelevantEvents_1,
10602                                    });
10603                                },
10604                            };
10605                            receivingContext_1.emitter.trigger('eventAdd', eventAddArg);
10606                            if (ev.isTouch) {
10607                                receivingContext_1.dispatch({
10608                                    type: 'SELECT_EVENT',
10609                                    eventInstanceId: eventInstance.instanceId,
10610                                });
10611                            }
10612                            receivingContext_1.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext_1)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.component.context.viewApi }));
10613                            receivingContext_1.emitter.trigger('eventReceive', __assign(__assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.component.context.viewApi }));
10614                        }
10615                    }
10616                    else {
10617                        initialContext_1.emitter.trigger('_noEventDrop');
10618                    }
10619                }
10620                _this.cleanup();
10621            };
10622            var component = _this.component;
10623            var options = component.context.options;
10624            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
10625            dragging.pointer.selector = EventDragging.SELECTOR;
10626            dragging.touchScrollAllowed = false;
10627            dragging.autoScroller.isEnabled = options.dragScroll;
10628            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsStore);
10629            hitDragging.useSubjectCenter = settings.useEventCenter;
10630            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10631            hitDragging.emitter.on('dragstart', _this.handleDragStart);
10632            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
10633            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
10634            hitDragging.emitter.on('dragend', _this.handleDragEnd);
10635            return _this;
10636        }
10637        EventDragging.prototype.destroy = function () {
10638            this.dragging.destroy();
10639        };
10640        // render a drag state on the next receivingCalendar
10641        EventDragging.prototype.displayDrag = function (nextContext, state) {
10642            var initialContext = this.component.context;
10643            var prevContext = this.receivingContext;
10644            // does the previous calendar need to be cleared?
10645            if (prevContext && prevContext !== nextContext) {
10646                // does the initial calendar need to be cleared?
10647                // if so, don't clear all the way. we still need to to hide the affectedEvents
10648                if (prevContext === initialContext) {
10649                    prevContext.dispatch({
10650                        type: 'SET_EVENT_DRAG',
10651                        state: {
10652                            affectedEvents: state.affectedEvents,
10653                            mutatedEvents: createEmptyEventStore(),
10654                            isEvent: true,
10655                        },
10656                    });
10657                    // completely clear the old calendar if it wasn't the initial
10658                }
10659                else {
10660                    prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
10661                }
10662            }
10663            if (nextContext) {
10664                nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state });
10665            }
10666        };
10667        EventDragging.prototype.clearDrag = function () {
10668            var initialCalendar = this.component.context;
10669            var receivingContext = this.receivingContext;
10670            if (receivingContext) {
10671                receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
10672            }
10673            // the initial calendar might have an dummy drag state from displayDrag
10674            if (initialCalendar !== receivingContext) {
10675                initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
10676            }
10677        };
10678        EventDragging.prototype.cleanup = function () {
10679            this.subjectSeg = null;
10680            this.isDragging = false;
10681            this.eventRange = null;
10682            this.relevantEvents = null;
10683            this.receivingContext = null;
10684            this.validMutation = null;
10685            this.mutatedRelevantEvents = null;
10686        };
10687        // TODO: test this in IE11
10688        // QUESTION: why do we need it on the resizable???
10689        EventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable';
10690        return EventDragging;
10691    }(Interaction));
10692    function computeEventMutation(hit0, hit1, massagers) {
10693        var dateSpan0 = hit0.dateSpan;
10694        var dateSpan1 = hit1.dateSpan;
10695        var date0 = dateSpan0.range.start;
10696        var date1 = dateSpan1.range.start;
10697        var standardProps = {};
10698        if (dateSpan0.allDay !== dateSpan1.allDay) {
10699            standardProps.allDay = dateSpan1.allDay;
10700            standardProps.hasEnd = hit1.component.context.options.allDayMaintainDuration;
10701            if (dateSpan1.allDay) {
10702                // means date1 is already start-of-day,
10703                // but date0 needs to be converted
10704                date0 = startOfDay(date0);
10705            }
10706        }
10707        var delta = diffDates(date0, date1, hit0.component.context.dateEnv, hit0.component === hit1.component ?
10708            hit0.component.largeUnit :
10709            null);
10710        if (delta.milliseconds) { // has hours/minutes/seconds
10711            standardProps.allDay = false;
10712        }
10713        var mutation = {
10714            datesDelta: delta,
10715            standardProps: standardProps,
10716        };
10717        for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) {
10718            var massager = massagers_1[_i];
10719            massager(mutation, hit0, hit1);
10720        }
10721        return mutation;
10722    }
10723    function getComponentTouchDelay$1(component) {
10724        var options = component.context.options;
10725        var delay = options.eventLongPressDelay;
10726        if (delay == null) {
10727            delay = options.longPressDelay;
10728        }
10729        return delay;
10730    }
10731
10732    var EventResizing = /** @class */ (function (_super) {
10733        __extends(EventResizing, _super);
10734        function EventResizing(settings) {
10735            var _this = _super.call(this, settings) || this;
10736            // internal state
10737            _this.draggingSegEl = null;
10738            _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?
10739            _this.eventRange = null;
10740            _this.relevantEvents = null;
10741            _this.validMutation = null;
10742            _this.mutatedRelevantEvents = null;
10743            _this.handlePointerDown = function (ev) {
10744                var component = _this.component;
10745                var segEl = _this.querySegEl(ev);
10746                var seg = getElSeg(segEl);
10747                var eventRange = _this.eventRange = seg.eventRange;
10748                _this.dragging.minDistance = component.context.options.eventDragMinDistance;
10749                // if touch, need to be working with a selected event
10750                _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) ||
10751                    (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId));
10752            };
10753            _this.handleDragStart = function (ev) {
10754                var context = _this.component.context;
10755                var eventRange = _this.eventRange;
10756                _this.relevantEvents = getRelevantEvents(context.getCurrentData().eventStore, _this.eventRange.instance.instanceId);
10757                var segEl = _this.querySegEl(ev);
10758                _this.draggingSegEl = segEl;
10759                _this.draggingSeg = getElSeg(segEl);
10760                context.calendarApi.unselect();
10761                context.emitter.trigger('eventResizeStart', {
10762                    el: segEl,
10763                    event: new EventApi(context, eventRange.def, eventRange.instance),
10764                    jsEvent: ev.origEvent,
10765                    view: context.viewApi,
10766                });
10767            };
10768            _this.handleHitUpdate = function (hit, isFinal, ev) {
10769                var context = _this.component.context;
10770                var relevantEvents = _this.relevantEvents;
10771                var initialHit = _this.hitDragging.initialHit;
10772                var eventInstance = _this.eventRange.instance;
10773                var mutation = null;
10774                var mutatedRelevantEvents = null;
10775                var isInvalid = false;
10776                var interaction = {
10777                    affectedEvents: relevantEvents,
10778                    mutatedEvents: createEmptyEventStore(),
10779                    isEvent: true,
10780                };
10781                if (hit) {
10782                    mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range, context.pluginHooks.eventResizeJoinTransforms);
10783                }
10784                if (mutation) {
10785                    mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context);
10786                    interaction.mutatedEvents = mutatedRelevantEvents;
10787                    if (!_this.component.isInteractionValid(interaction)) {
10788                        isInvalid = true;
10789                        mutation = null;
10790                        mutatedRelevantEvents = null;
10791                        interaction.mutatedEvents = null;
10792                    }
10793                }
10794                if (mutatedRelevantEvents) {
10795                    context.dispatch({
10796                        type: 'SET_EVENT_RESIZE',
10797                        state: interaction,
10798                    });
10799                }
10800                else {
10801                    context.dispatch({ type: 'UNSET_EVENT_RESIZE' });
10802                }
10803                if (!isInvalid) {
10804                    enableCursor();
10805                }
10806                else {
10807                    disableCursor();
10808                }
10809                if (!isFinal) {
10810                    if (mutation && isHitsEqual(initialHit, hit)) {
10811                        mutation = null;
10812                    }
10813                    _this.validMutation = mutation;
10814                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
10815                }
10816            };
10817            _this.handleDragEnd = function (ev) {
10818                var context = _this.component.context;
10819                var eventDef = _this.eventRange.def;
10820                var eventInstance = _this.eventRange.instance;
10821                var eventApi = new EventApi(context, eventDef, eventInstance);
10822                var relevantEvents = _this.relevantEvents;
10823                var mutatedRelevantEvents = _this.mutatedRelevantEvents;
10824                context.emitter.trigger('eventResizeStop', {
10825                    el: _this.draggingSegEl,
10826                    event: eventApi,
10827                    jsEvent: ev.origEvent,
10828                    view: context.viewApi,
10829                });
10830                if (_this.validMutation) {
10831                    var updatedEventApi = new EventApi(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);
10832                    context.dispatch({
10833                        type: 'MERGE_EVENTS',
10834                        eventStore: mutatedRelevantEvents,
10835                    });
10836                    var eventChangeArg = {
10837                        oldEvent: eventApi,
10838                        event: updatedEventApi,
10839                        relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance),
10840                        revert: function () {
10841                            context.dispatch({
10842                                type: 'MERGE_EVENTS',
10843                                eventStore: relevantEvents,
10844                            });
10845                        },
10846                    };
10847                    context.emitter.trigger('eventResize', __assign(__assign({}, eventChangeArg), { el: _this.draggingSegEl, startDelta: _this.validMutation.startDelta || createDuration(0), endDelta: _this.validMutation.endDelta || createDuration(0), jsEvent: ev.origEvent, view: context.viewApi }));
10848                    context.emitter.trigger('eventChange', eventChangeArg);
10849                }
10850                else {
10851                    context.emitter.trigger('_noEventResize');
10852                }
10853                // reset all internal state
10854                _this.draggingSeg = null;
10855                _this.relevantEvents = null;
10856                _this.validMutation = null;
10857                // okay to keep eventInstance around. useful to set it in handlePointerDown
10858            };
10859            var component = settings.component;
10860            var dragging = _this.dragging = new FeaturefulElementDragging(settings.el);
10861            dragging.pointer.selector = '.fc-event-resizer';
10862            dragging.touchScrollAllowed = false;
10863            dragging.autoScroller.isEnabled = component.context.options.dragScroll;
10864            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings));
10865            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
10866            hitDragging.emitter.on('dragstart', _this.handleDragStart);
10867            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
10868            hitDragging.emitter.on('dragend', _this.handleDragEnd);
10869            return _this;
10870        }
10871        EventResizing.prototype.destroy = function () {
10872            this.dragging.destroy();
10873        };
10874        EventResizing.prototype.querySegEl = function (ev) {
10875            return elementClosest(ev.subjectEl, '.fc-event');
10876        };
10877        return EventResizing;
10878    }(Interaction));
10879    function computeMutation(hit0, hit1, isFromStart, instanceRange, transforms) {
10880        var dateEnv = hit0.component.context.dateEnv;
10881        var date0 = hit0.dateSpan.range.start;
10882        var date1 = hit1.dateSpan.range.start;
10883        var delta = diffDates(date0, date1, dateEnv, hit0.component.largeUnit);
10884        var props = {};
10885        for (var _i = 0, transforms_1 = transforms; _i < transforms_1.length; _i++) {
10886            var transform = transforms_1[_i];
10887            var res = transform(hit0, hit1);
10888            if (res === false) {
10889                return null;
10890            }
10891            if (res) {
10892                __assign(props, res);
10893            }
10894        }
10895        if (isFromStart) {
10896            if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
10897                props.startDelta = delta;
10898                return props;
10899            }
10900        }
10901        else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
10902            props.endDelta = delta;
10903            return props;
10904        }
10905        return null;
10906    }
10907
10908    var UnselectAuto = /** @class */ (function () {
10909        function UnselectAuto(context) {
10910            var _this = this;
10911            this.context = context;
10912            this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system
10913            this.matchesCancel = false;
10914            this.matchesEvent = false;
10915            this.onSelect = function (selectInfo) {
10916                if (selectInfo.jsEvent) {
10917                    _this.isRecentPointerDateSelect = true;
10918                }
10919            };
10920            this.onDocumentPointerDown = function (pev) {
10921                var unselectCancel = _this.context.options.unselectCancel;
10922                var downEl = pev.origEvent.target;
10923                _this.matchesCancel = !!elementClosest(downEl, unselectCancel);
10924                _this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR); // interaction started on an event?
10925            };
10926            this.onDocumentPointerUp = function (pev) {
10927                var context = _this.context;
10928                var documentPointer = _this.documentPointer;
10929                var calendarState = context.getCurrentData();
10930                // touch-scrolling should never unfocus any type of selection
10931                if (!documentPointer.wasTouchScroll) {
10932                    if (calendarState.dateSelection && // an existing date selection?
10933                        !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?
10934                    ) {
10935                        var unselectAuto = context.options.unselectAuto;
10936                        if (unselectAuto && (!unselectAuto || !_this.matchesCancel)) {
10937                            context.calendarApi.unselect(pev);
10938                        }
10939                    }
10940                    if (calendarState.eventSelection && // an existing event selected?
10941                        !_this.matchesEvent // interaction DIDN'T start on an event
10942                    ) {
10943                        context.dispatch({ type: 'UNSELECT_EVENT' });
10944                    }
10945                }
10946                _this.isRecentPointerDateSelect = false;
10947            };
10948            var documentPointer = this.documentPointer = new PointerDragging(document);
10949            documentPointer.shouldIgnoreMove = true;
10950            documentPointer.shouldWatchScroll = false;
10951            documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown);
10952            documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);
10953            /*
10954            TODO: better way to know about whether there was a selection with the pointer
10955            */
10956            context.emitter.on('select', this.onSelect);
10957        }
10958        UnselectAuto.prototype.destroy = function () {
10959            this.context.emitter.off('select', this.onSelect);
10960            this.documentPointer.destroy();
10961        };
10962        return UnselectAuto;
10963    }());
10964
10965    var OPTION_REFINERS = {
10966        fixedMirrorParent: identity,
10967    };
10968    var LISTENER_REFINERS = {
10969        dateClick: identity,
10970        eventDragStart: identity,
10971        eventDragStop: identity,
10972        eventDrop: identity,
10973        eventResizeStart: identity,
10974        eventResizeStop: identity,
10975        eventResize: identity,
10976        drop: identity,
10977        eventReceive: identity,
10978        eventLeave: identity,
10979    };
10980
10981    /*
10982    Given an already instantiated draggable object for one-or-more elements,
10983    Interprets any dragging as an attempt to drag an events that lives outside
10984    of a calendar onto a calendar.
10985    */
10986    var ExternalElementDragging = /** @class */ (function () {
10987        function ExternalElementDragging(dragging, suppliedDragMeta) {
10988            var _this = this;
10989            this.receivingContext = null;
10990            this.droppableEvent = null; // will exist for all drags, even if create:false
10991            this.suppliedDragMeta = null;
10992            this.dragMeta = null;
10993            this.handleDragStart = function (ev) {
10994                _this.dragMeta = _this.buildDragMeta(ev.subjectEl);
10995            };
10996            this.handleHitUpdate = function (hit, isFinal, ev) {
10997                var dragging = _this.hitDragging.dragging;
10998                var receivingContext = null;
10999                var droppableEvent = null;
11000                var isInvalid = false;
11001                var interaction = {
11002                    affectedEvents: createEmptyEventStore(),
11003                    mutatedEvents: createEmptyEventStore(),
11004                    isEvent: _this.dragMeta.create,
11005                };
11006                if (hit) {
11007                    receivingContext = hit.component.context;
11008                    if (_this.canDropElOnCalendar(ev.subjectEl, receivingContext)) {
11009                        droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingContext);
11010                        interaction.mutatedEvents = eventTupleToStore(droppableEvent);
11011                        isInvalid = !isInteractionValid(interaction, receivingContext);
11012                        if (isInvalid) {
11013                            interaction.mutatedEvents = createEmptyEventStore();
11014                            droppableEvent = null;
11015                        }
11016                    }
11017                }
11018                _this.displayDrag(receivingContext, interaction);
11019                // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)
11020                // TODO: wish we could somehow wait for dispatch to guarantee render
11021                dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror'));
11022                if (!isInvalid) {
11023                    enableCursor();
11024                }
11025                else {
11026                    disableCursor();
11027                }
11028                if (!isFinal) {
11029                    dragging.setMirrorNeedsRevert(!droppableEvent);
11030                    _this.receivingContext = receivingContext;
11031                    _this.droppableEvent = droppableEvent;
11032                }
11033            };
11034            this.handleDragEnd = function (pev) {
11035                var _a = _this, receivingContext = _a.receivingContext, droppableEvent = _a.droppableEvent;
11036                _this.clearDrag();
11037                if (receivingContext && droppableEvent) {
11038                    var finalHit = _this.hitDragging.finalHit;
11039                    var finalView = finalHit.component.context.viewApi;
11040                    var dragMeta = _this.dragMeta;
11041                    receivingContext.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView }));
11042                    if (dragMeta.create) {
11043                        var addingEvents_1 = eventTupleToStore(droppableEvent);
11044                        receivingContext.dispatch({
11045                            type: 'MERGE_EVENTS',
11046                            eventStore: addingEvents_1,
11047                        });
11048                        if (pev.isTouch) {
11049                            receivingContext.dispatch({
11050                                type: 'SELECT_EVENT',
11051                                eventInstanceId: droppableEvent.instance.instanceId,
11052                            });
11053                        }
11054                        // signal that an external event landed
11055                        receivingContext.emitter.trigger('eventReceive', {
11056                            event: new EventApi(receivingContext, droppableEvent.def, droppableEvent.instance),
11057                            relatedEvents: [],
11058                            revert: function () {
11059                                receivingContext.dispatch({
11060                                    type: 'REMOVE_EVENTS',
11061                                    eventStore: addingEvents_1,
11062                                });
11063                            },
11064                            draggedEl: pev.subjectEl,
11065                            view: finalView,
11066                        });
11067                    }
11068                }
11069                _this.receivingContext = null;
11070                _this.droppableEvent = null;
11071            };
11072            var hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore);
11073            hitDragging.requireInitial = false; // will start outside of a component
11074            hitDragging.emitter.on('dragstart', this.handleDragStart);
11075            hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
11076            hitDragging.emitter.on('dragend', this.handleDragEnd);
11077            this.suppliedDragMeta = suppliedDragMeta;
11078        }
11079        ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) {
11080            if (typeof this.suppliedDragMeta === 'object') {
11081                return parseDragMeta(this.suppliedDragMeta);
11082            }
11083            if (typeof this.suppliedDragMeta === 'function') {
11084                return parseDragMeta(this.suppliedDragMeta(subjectEl));
11085            }
11086            return getDragMetaFromEl(subjectEl);
11087        };
11088        ExternalElementDragging.prototype.displayDrag = function (nextContext, state) {
11089            var prevContext = this.receivingContext;
11090            if (prevContext && prevContext !== nextContext) {
11091                prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
11092            }
11093            if (nextContext) {
11094                nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state });
11095            }
11096        };
11097        ExternalElementDragging.prototype.clearDrag = function () {
11098            if (this.receivingContext) {
11099                this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });
11100            }
11101        };
11102        ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingContext) {
11103            var dropAccept = receivingContext.options.dropAccept;
11104            if (typeof dropAccept === 'function') {
11105                return dropAccept.call(receivingContext.calendarApi, el);
11106            }
11107            if (typeof dropAccept === 'string' && dropAccept) {
11108                return Boolean(elementMatches(el, dropAccept));
11109            }
11110            return true;
11111        };
11112        return ExternalElementDragging;
11113    }());
11114    // Utils for computing event store from the DragMeta
11115    // ----------------------------------------------------------------------------------------------------
11116    function computeEventForDateSpan(dateSpan, dragMeta, context) {
11117        var defProps = __assign({}, dragMeta.leftoverProps);
11118        for (var _i = 0, _a = context.pluginHooks.externalDefTransforms; _i < _a.length; _i++) {
11119            var transform = _a[_i];
11120            __assign(defProps, transform(dateSpan, dragMeta));
11121        }
11122        var _b = refineEventDef(defProps, context), refined = _b.refined, extra = _b.extra;
11123        var def = parseEventDef(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd
11124        context);
11125        var start = dateSpan.range.start;
11126        // only rely on time info if drop zone is all-day,
11127        // otherwise, we already know the time
11128        if (dateSpan.allDay && dragMeta.startTime) {
11129            start = context.dateEnv.add(start, dragMeta.startTime);
11130        }
11131        var end = dragMeta.duration ?
11132            context.dateEnv.add(start, dragMeta.duration) :
11133            getDefaultEventEnd(dateSpan.allDay, start, context);
11134        var instance = createEventInstance(def.defId, { start: start, end: end });
11135        return { def: def, instance: instance };
11136    }
11137    // Utils for extracting data from element
11138    // ----------------------------------------------------------------------------------------------------
11139    function getDragMetaFromEl(el) {
11140        var str = getEmbeddedElData(el, 'event');
11141        var obj = str ?
11142            JSON.parse(str) :
11143            { create: false }; // if no embedded data, assume no event creation
11144        return parseDragMeta(obj);
11145    }
11146    config.dataAttrPrefix = '';
11147    function getEmbeddedElData(el, name) {
11148        var prefix = config.dataAttrPrefix;
11149        var prefixedName = (prefix ? prefix + '-' : '') + name;
11150        return el.getAttribute('data-' + prefixedName) || '';
11151    }
11152
11153    /*
11154    Makes an element (that is *external* to any calendar) draggable.
11155    Can pass in data that determines how an event will be created when dropped onto a calendar.
11156    Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.
11157    */
11158    var ExternalDraggable = /** @class */ (function () {
11159        function ExternalDraggable(el, settings) {
11160            var _this = this;
11161            if (settings === void 0) { settings = {}; }
11162            this.handlePointerDown = function (ev) {
11163                var dragging = _this.dragging;
11164                var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay;
11165                dragging.minDistance =
11166                    minDistance != null ?
11167                        minDistance :
11168                        (ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance);
11169                dragging.delay =
11170                    ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv
11171                        (longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay) :
11172                        0;
11173            };
11174            this.handleDragStart = function (ev) {
11175                if (ev.isTouch &&
11176                    _this.dragging.delay &&
11177                    ev.subjectEl.classList.contains('fc-event')) {
11178                    _this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected');
11179                }
11180            };
11181            this.settings = settings;
11182            var dragging = this.dragging = new FeaturefulElementDragging(el);
11183            dragging.touchScrollAllowed = false;
11184            if (settings.itemSelector != null) {
11185                dragging.pointer.selector = settings.itemSelector;
11186            }
11187            if (settings.appendTo != null) {
11188                dragging.mirror.parentNode = settings.appendTo; // TODO: write tests
11189            }
11190            dragging.emitter.on('pointerdown', this.handlePointerDown);
11191            dragging.emitter.on('dragstart', this.handleDragStart);
11192            new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new
11193        }
11194        ExternalDraggable.prototype.destroy = function () {
11195            this.dragging.destroy();
11196        };
11197        return ExternalDraggable;
11198    }());
11199
11200    /*
11201    Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements.
11202    The third-party system is responsible for drawing the visuals effects of the drag.
11203    This class simply monitors for pointer movements and fires events.
11204    It also has the ability to hide the moving element (the "mirror") during the drag.
11205    */
11206    var InferredElementDragging = /** @class */ (function (_super) {
11207        __extends(InferredElementDragging, _super);
11208        function InferredElementDragging(containerEl) {
11209            var _this = _super.call(this, containerEl) || this;
11210            _this.shouldIgnoreMove = false;
11211            _this.mirrorSelector = '';
11212            _this.currentMirrorEl = null;
11213            _this.handlePointerDown = function (ev) {
11214                _this.emitter.trigger('pointerdown', ev);
11215                if (!_this.shouldIgnoreMove) {
11216                    // fire dragstart right away. does not support delay or min-distance
11217                    _this.emitter.trigger('dragstart', ev);
11218                }
11219            };
11220            _this.handlePointerMove = function (ev) {
11221                if (!_this.shouldIgnoreMove) {
11222                    _this.emitter.trigger('dragmove', ev);
11223                }
11224            };
11225            _this.handlePointerUp = function (ev) {
11226                _this.emitter.trigger('pointerup', ev);
11227                if (!_this.shouldIgnoreMove) {
11228                    // fire dragend right away. does not support a revert animation
11229                    _this.emitter.trigger('dragend', ev);
11230                }
11231            };
11232            var pointer = _this.pointer = new PointerDragging(containerEl);
11233            pointer.emitter.on('pointerdown', _this.handlePointerDown);
11234            pointer.emitter.on('pointermove', _this.handlePointerMove);
11235            pointer.emitter.on('pointerup', _this.handlePointerUp);
11236            return _this;
11237        }
11238        InferredElementDragging.prototype.destroy = function () {
11239            this.pointer.destroy();
11240        };
11241        InferredElementDragging.prototype.setIgnoreMove = function (bool) {
11242            this.shouldIgnoreMove = bool;
11243        };
11244        InferredElementDragging.prototype.setMirrorIsVisible = function (bool) {
11245            if (bool) {
11246                // restore a previously hidden element.
11247                // use the reference in case the selector class has already been removed.
11248                if (this.currentMirrorEl) {
11249                    this.currentMirrorEl.style.visibility = '';
11250                    this.currentMirrorEl = null;
11251                }
11252            }
11253            else {
11254                var mirrorEl = this.mirrorSelector ?
11255                    document.querySelector(this.mirrorSelector) :
11256                    null;
11257                if (mirrorEl) {
11258                    this.currentMirrorEl = mirrorEl;
11259                    mirrorEl.style.visibility = 'hidden';
11260                }
11261            }
11262        };
11263        return InferredElementDragging;
11264    }(ElementDragging));
11265
11266    /*
11267    Bridges third-party drag-n-drop systems with FullCalendar.
11268    Must be instantiated and destroyed by caller.
11269    */
11270    var ThirdPartyDraggable = /** @class */ (function () {
11271        function ThirdPartyDraggable(containerOrSettings, settings) {
11272            var containerEl = document;
11273            if (
11274            // wish we could just test instanceof EventTarget, but doesn't work in IE11
11275            containerOrSettings === document ||
11276                containerOrSettings instanceof Element) {
11277                containerEl = containerOrSettings;
11278                settings = settings || {};
11279            }
11280            else {
11281                settings = (containerOrSettings || {});
11282            }
11283            var dragging = this.dragging = new InferredElementDragging(containerEl);
11284            if (typeof settings.itemSelector === 'string') {
11285                dragging.pointer.selector = settings.itemSelector;
11286            }
11287            else if (containerEl === document) {
11288                dragging.pointer.selector = '[data-event]';
11289            }
11290            if (typeof settings.mirrorSelector === 'string') {
11291                dragging.mirrorSelector = settings.mirrorSelector;
11292            }
11293            new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new
11294        }
11295        ThirdPartyDraggable.prototype.destroy = function () {
11296            this.dragging.destroy();
11297        };
11298        return ThirdPartyDraggable;
11299    }());
11300
11301    var interactionPlugin = createPlugin({
11302        componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing],
11303        calendarInteractions: [UnselectAuto],
11304        elementDraggingImpl: FeaturefulElementDragging,
11305        optionRefiners: OPTION_REFINERS,
11306        listenerRefiners: LISTENER_REFINERS,
11307    });
11308
11309    /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
11310    ----------------------------------------------------------------------------------------------------------------------*/
11311    // It is a manager for a Table subcomponent, which does most of the heavy lifting.
11312    // It is responsible for managing width/height.
11313    var TableView = /** @class */ (function (_super) {
11314        __extends(TableView, _super);
11315        function TableView() {
11316            var _this = _super !== null && _super.apply(this, arguments) || this;
11317            _this.headerElRef = createRef();
11318            return _this;
11319        }
11320        TableView.prototype.renderSimpleLayout = function (headerRowContent, bodyContent) {
11321            var _a = this, props = _a.props, context = _a.context;
11322            var sections = [];
11323            var stickyHeaderDates = getStickyHeaderDates(context.options);
11324            if (headerRowContent) {
11325                sections.push({
11326                    type: 'header',
11327                    key: 'header',
11328                    isSticky: stickyHeaderDates,
11329                    chunk: {
11330                        elRef: this.headerElRef,
11331                        tableClassName: 'fc-col-header',
11332                        rowContent: headerRowContent,
11333                    },
11334                });
11335            }
11336            sections.push({
11337                type: 'body',
11338                key: 'body',
11339                liquid: true,
11340                chunk: { content: bodyContent },
11341            });
11342            return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygri
11342d'].concat(classNames).join(' ') },
11343                createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, cols: [] /* TODO: make optional? */, sections: sections }))); }));
11344        };
11345        TableView.prototype.renderHScrollLayout = function (headerRowContent, bodyContent, colCnt, dayMinWidth) {
11346            var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
11347            if (!ScrollGrid) {
11348                throw new Error('No ScrollGrid implementation');
11349            }
11350            var _a = this, props = _a.props, context = _a.context;
11351            var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options);
11352            var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options);
11353            var sections = [];
11354            if (headerRowContent) {
11355                sections.push({
11356                    type: 'header',
11357                    key: 'header',
11358                    isSticky: stickyHeaderDates,
11359                    chunks: [{
11360                            key: 'main',
11361                            elRef: this.headerElRef,
11362                            tableClassName: 'fc-col-header',
11363                            rowContent: headerRowContent,
11364                        }],
11365                });
11366            }
11367            sections.push({
11368                type: 'body',
11369                key: 'body',
11370                liquid: true,
11371                chunks: [{
11372                        key: 'main',
11373                        content: bodyContent,
11374                    }],
11375            });
11376            if (stickyFooterScrollbar) {
11377                sections.push({
11378                    type: 'footer',
11379                    key: 'footer',
11380                    isSticky: true,
11381                    chunks: [{
11382                            key: 'main',
11383                            content: renderScrollShim,
11384                        }],
11385                });
11386            }
11387            return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') },
11388                createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections }))); }));
11389        };
11390        return TableView;
11391    }(DateComponent));
11392
11393    function splitSegsByRow(segs, rowCnt) {
11394        var byRow = [];
11395        for (var i = 0; i < rowCnt; i += 1) {
11396            byRow[i] = [];
11397        }
11398        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
11399            var seg = segs_1[_i];
11400            byRow[seg.row].push(seg);
11401        }
11402        return byRow;
11403    }
11404    function splitSegsByFirstCol(segs, colCnt) {
11405        var byCol = [];
11406        for (var i = 0; i < colCnt; i += 1) {
11407            byCol[i] = [];
11408        }
11409        for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
11410            var seg = segs_2[_i];
11411            byCol[seg.firstCol].push(seg);
11412        }
11413        return byCol;
11414    }
11415    function splitInteractionByRow(ui, rowCnt) {
11416        var byRow = [];
11417        if (!ui) {
11418            for (var i = 0; i < rowCnt; i += 1) {
11419                byRow[i] = null;
11420            }
11421        }
11422        else {
11423            for (var i = 0; i < rowCnt; i += 1) {
11424                byRow[i] = {
11425                    affectedInstances: ui.affectedInstances,
11426                    isEvent: ui.isEvent,
11427                    segs: [],
11428                };
11429            }
11430            for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
11431                var seg = _a[_i];
11432                byRow[seg.row].segs.push(seg);
11433            }
11434        }
11435        return byRow;
11436    }
11437
11438    var TableCellTop = /** @class */ (function (_super) {
11439        __extends(TableCellTop, _super);
11440        function TableCellTop() {
11441            return _super !== null && _super.apply(this, arguments) || this;
11442        }
11443        TableCellTop.prototype.render = function () {
11444            var props = this.props;
11445            var navLinkAttrs = this.context.options.navLinks
11446                ? { 'data-navlink': buildNavLinkData(props.date), tabIndex: 0 }
11447                : {};
11448            return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, defaultContent: renderTopInner }, function (innerElRef, innerContent) { return ((innerContent || props.forceDayTop) && (createElement("div", { className: "fc-daygri
11448d-day-top", ref: innerElRef },
11449                createElement("a", __assign({ className: "fc-daygrid-day-number" }, navLinkAttrs), innerContent || createElement(Fragment, null, "\u00A0"))))); }));
11450        };
11451        return TableCellTop;
11452    }(BaseComponent));
11453    function renderTopInner(props) {
11454        return props.dayNumberText;
11455    }
11456
11457    var DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: 'narrow' });
11458    var TableCell = /** @class */ (function (_super) {
11459        __extends(TableCell, _super);
11460        function TableCell() {
11461            var _this = _super !== null && _super.apply(this, arguments) || this;
11462            _this.handleRootEl = function (el) {
11463                _this.rootEl = el;
11464                setRef(_this.props.elRef, el);
11465            };
11466            _this.handleMoreLinkClick = function (ev) {
11467                var props = _this.props;
11468                if (props.onMoreClick) {
11469                    var allSegs = props.segsByEachCol;
11470                    var hiddenSegs = allSegs.filter(function (seg) { return props.segIsHidden[seg.eventRange.instance.instanceId]; });
11471                    props.onMoreClick({
11472                        date: props.date,
11473                        allSegs: allSegs,
11474                        hiddenSegs: hiddenSegs,
11475                        moreCnt: props.moreCnt,
11476                        dayEl: _this.rootEl,
11477                        ev: ev,
11478                    });
11479                }
11480            };
11481            return _this;
11482        }
11483        TableCell.prototype.render = function () {
11484            var _this = this;
11485            var _a = this.context, options = _a.options, viewApi = _a.viewApi;
11486            var props = this.props;
11487            var date = props.date, dateProfile = props.dateProfile;
11488            var hookProps = {
11489                num: props.moreCnt,
11490                text: props.buildMoreLinkText(props.moreCnt),
11491                view: viewApi,
11492            };
11493            var navLinkAttrs = options.navLinks
11494                ? { 'data-navlink': buildNavLinkData(date, 'week'), tabIndex: 0 }
11495                : {};
11496            return (createElement(DayCellRoot, { date: date, dateProfile: dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, elRef: this.handleRootEl }, function (dayElRef, dayClassNames, rootDataAttrs, isDisabled) { return (createElement("td", __assign({ ref: dayElRef, className: ['fc-daygrid-day'].concat(dayClassNames, props.extraClassNames || []).join(' ') }, rootDataAttrs, props.extraDataAttrs),
11497                createElement("div", { className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", ref: props.innerElRef /* different from hook system! RENAME */ },
11498                    props.showWeekNumber && (createElement(WeekNumberRoot, { date: date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, function (weekElRef, weekClassNames, innerElRef, innerContent) { return (createElement("a", __assign({ ref: weekElRef, className: ['fc-daygrid-week-number'].concat(weekClassNames).join(' ') }, navLinkAttrs), innerContent)); })),
11499                    !isDisabled && (createElement(TableCellTop, { date: date, dateProfile: dateProfile, showDayNumber: props.showDayNumber, forceDayTop: props.forceDayTop, todayRange: props.todayRange, extraHookProps: props.extraHookProps })),
11500                    createElement("div", { className: "fc-daygrid-day-events", ref: props.fgContentElRef, style: { paddingBottom: props.fgPaddingBottom } },
11501                        props.fgContent,
11502                        Boolean(props.moreCnt) && (createElement("div", { className: "fc-daygrid-day-bottom", style: { marginTop: props.moreMarginTop } },
11503                            createElement(RenderHook, { hookProps: hookProps, classNames: options.moreLinkClassNames, content: options.moreLinkContent, defaultContent: renderMoreLinkInner, didMount: options.moreLinkDidMount, willUnmount: options.moreLinkWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("a", { ref: rootElRef, className: ['fc-daygrid-more-link'].concat(classNames).join(' '), onClick: _this.handleMoreLinkClick }, innerContent)); })))),
11504                    createElement("div", { className: "fc-daygri
11504d-day-bg" }, props.bgContent)))); }));
11505        };
11506        return TableCell;
11507    }(DateComponent));
11508    TableCell.addPropsEquality({
11509        onMoreClick: true,
11510    });
11511    function renderMoreLinkInner(props) {
11512        return props.text;
11513    }
11514
11515    var DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({
11516        hour: 'numeric',
11517        minute: '2-digit',
11518        omitZeroMinute: true,
11519        meridiem: 'narrow',
11520    });
11521    function hasListItemDisplay(seg) {
11522        var display = seg.eventRange.ui.display;
11523        return display === 'list-item' || (display === 'auto' &&
11524            !seg.eventRange.def.allDay &&
11525            seg.firstCol === seg.lastCol && // can't be multi-day
11526            seg.isStart && // "
11527            seg.isEnd // "
11528        );
11529    }
11530
11531    var TableListItemEvent = /** @class */ (function (_super) {
11532        __extends(TableListItemEvent, _super);
11533        function TableListItemEvent() {
11534            return _super !== null && _super.apply(this, arguments) || this;
11535        }
11536        TableListItemEvent.prototype.render = function () {
11537            var _a = this, props = _a.props, context = _a.context;
11538            var timeFormat = context.options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT;
11539            var timeText = buildSegTimeText(props.seg, timeFormat, context, true, props.defaultDisplayEventEnd);
11540            return (createElement(EventRoot, { seg: props.seg, timeText: timeText, defaultContent: renderInnerContent$2, isDragging: props.isDragging, isResizing: false, isDateSelecting: false, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent) { return ( // we don't use styles!
11541            createElement("a", __assign({ className: ['fc-daygrid-event', 'fc-daygri
11541d-dot-event'].concat(classNames).join(' '), ref: rootElRef }, getSegAnchorAttrs$1(props.seg)), innerContent)); }));
11542        };
11543        return TableListItemEvent;
11544    }(BaseComponent));
11545    function renderInnerContent$2(innerProps) {
11546        return (createElement(Fragment, null,
11547            createElement("div", { className: "fc-daygrid-event-dot", style: { borderColor: innerProps.borderColor || innerProps.backgroundColor } }),
11548            innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)),
11549            createElement("div", { className: "fc-event-title" }, innerProps.event.title || createElement(Fragment, null, "\u00A0"))));
11550    }
11551    function getSegAnchorAttrs$1(seg) {
11552        var url = seg.eventRange.def.url;
11553        return url ? { href: url } : {};
11554    }
11555
11556    var TableBlockEvent = /** @class */ (function (_super) {
11557        __extends(TableBlockEvent, _super);
11558        function TableBlockEvent() {
11559            return _super !== null && _super.apply(this, arguments) || this;
11560        }
11561        TableBlockEvent.prototype.render = function () {
11562            var props = this.props;
11563            return (createElement(StandardEvent, __assign({}
11563, props, { extraClassNames: ['fc-daygrid-event', 'fc-daygrid-block-event', 'fc-h-event'], defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, defaultDisplayEventEnd: props.defaultDisplayEventEnd, disableResizing: !props.seg.eventRange.def.allDay })));
11564        };
11565        return TableBlockEvent;
11566    }(BaseComponent));
11567
11568    function computeFgSegPlacement(// for one row. TODO: print mode?
11569    cellModels, segs, dayMaxEvents, dayMaxEventRows, eventHeights, maxContentHeight, colCnt, eventOrderSpecs) {
11570        var colPlacements = []; // if event spans multiple cols, its present in each col
11571        var moreCnts = []; // by-col
11572        var segIsHidden = {};
11573        var segTops = {}; // always populated for each seg
11574        var segMarginTops = {}; // simetimes populated for each seg
11575        var moreTops = {};
11576        var paddingBottoms = {}; // for each cell's inner-wrapper div
11577        for (var i = 0; i < colCnt; i += 1) {
11578            colPlacements.push([]);
11579            moreCnts.push(0);
11580        }
11581        segs = sortEventSegs(segs, eventOrderSpecs);
11582        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
11583            var seg = segs_1[_i];
11584            var instanceId = seg.eventRange.instance.instanceId;
11585            var eventHeight = eventHeights[instanceId + ':' + seg.firstCol];
11586            placeSeg(seg, eventHeight || 0); // will keep colPlacements sorted by top
11587        }
11588        if (dayMaxEvents === true || dayMaxEventRows === true) {
11589            limitByMaxHeight(moreCnts, segIsHidden, colPlacements, maxContentHeight); // populates moreCnts/segIsHidden
11590        }
11591        else if (typeof dayMaxEvents === 'number') {
11592            limitByMaxEvents(moreCnts, segIsHidden, colPlacements, dayMaxEvents); // populates moreCnts/segIsHidden
11593        }
11594        else if (typeof dayMaxEventRows === 'number') {
11595            limitByMaxRows(moreCnts, segIsHidden, colPlacements, dayMaxEventRows); // populates moreCnts/segIsHidden
11596        }
11597        // computes segTops/segMarginTops/moreTops/paddingBottoms
11598        for (var col = 0; col < colCnt; col += 1) {
11599            var placements = colPlacements[col];
11600            var currentNonAbsBottom = 0;
11601            var currentAbsHeight = 0;
11602            for (var _a = 0, placements_1 = placements; _a < placements_1.length; _a++) {
11603                var placement = placements_1[_a];
11604                var seg = placement.seg;
11605                if (!segIsHidden[seg.eventRange.instance.instanceId]) {
11606                    segTops[seg.eventRange.instance.instanceId] = placement.top; // from top of container
11607                    if (seg.firstCol === seg.lastCol && seg.isStart && seg.isEnd) { // TODO: simpler way? NOT DRY
11608                        segMarginTops[seg.eventRange.instance.instanceId] =
11609                            placement.top - currentNonAbsBottom; // from previous seg bottom
11610                        currentAbsHeight = 0;
11611                        currentNonAbsBottom = placement.bottom;
11612                    }
11613                    else { // multi-col event, abs positioned
11614                        currentAbsHeight = placement.bottom - currentNonAbsBottom;
11615                    }
11616                }
11617            }
11618            if (currentAbsHeight) {
11619                if (moreCnts[col]) {
11620                    moreTops[col] = currentAbsHeight;
11621                }
11622                else {
11623                    paddingBottoms[col] = currentAbsHeight;
11624                }
11625            }
11626        }
11627        function placeSeg(seg, segHeight) {
11628            if (!tryPlaceSegAt(seg, segHeight, 0)) {
11629                for (var col = seg.firstCol; col <= seg.lastCol; col += 1) {
11630                    for (var _i = 0, _a = colPlacements[col]; _i < _a.length; _i++) { // will repeat multi-day segs!!!!!!! bad!!!!!!
11631                        var placement = _a[_i];
11632                        if (tryPlaceSegAt(seg, segHeight, placement.bottom)) {
11633                            return;
11634                        }
11635                    }
11636                }
11637            }
11638        }
11639        function tryPlaceSegAt(seg, segHeight, top) {
11640            if (canPlaceSegAt(seg, segHeight, top)) {
11641                for (var col = seg.firstCol; col <= seg.lastCol; col += 1) {
11642                    var placements = colPlacements[col];
11643                    var insertionIndex = 0;
11644                    while (insertionIndex < placements.length &&
11645                        top >= placements[insertionIndex].top) {
11646                        insertionIndex += 1;
11647                    }
11648                    placements.splice(insertionIndex, 0, {
11649                        seg: seg,
11650                        top: top,
11651                        bottom: top + segHeight,
11652                    });
11653                }
11654                return true;
11655            }
11656            return false;
11657        }
11658        function canPlaceSegAt(seg, segHeight, top) {
11659            for (var col = seg.firstCol; col <= seg.lastCol; col += 1) {
11660                for (var _i = 0, _a = colPlacements[col]; _i < _a.length; _i++) {
11661                    var placement = _a[_i];
11662                    if (top < placement.bottom && top + segHeight > placement.top) { // collide?
11663                        return false;
11664                    }
11665                }
11666            }
11667            return true;
11668        }
11669        // what does this do!?
11670        for (var instanceIdAndFirstCol in eventHeights) {
11671            if (!eventHeights[instanceIdAndFirstCol]) {
11672                segIsHidden[instanceIdAndFirstCol.split(':')[0]] = true;
11673            }
11674        }
11675        var segsByFirstCol = colPlacements.map(extractFirstColSegs); // operates on the sorted cols
11676        var segsByEachCol = colPlacements.map(function (placements, col) {
11677            var segsForCols = extractAllColSegs(placements);
11678            segsForCols = resliceDaySegs(segsForCols, cellModels[col].date, col);
11679            return segsForCols;
11680        });
11681        return {
11682            segsByFirstCol: segsByFirstCol,
11683            segsByEachCol: segsByEachCol,
11684            segIsHidden: segIsHidden,
11685            segTops: segTops,
11686            segMarginTops: segMarginTops,
11687            moreCnts: moreCnts,
11688            moreTops: moreTops,
11689            paddingBottoms: paddingBottoms,
11690        };
11691    }
11692    function extractFirstColSegs(oneColPlacements, col) {
11693        var segs = [];
11694        for (var _i = 0, oneColPlacements_1 = oneColPlacements; _i < oneColPlacements_1.length; _i++) {
11695            var placement = oneColPlacements_1[_i];
11696            if (placement.seg.firstCol === col) {
11697                segs.push(placement.seg);
11698            }
11699        }
11700        return segs;
11701    }
11702    function extractAllColSegs(oneColPlacements) {
11703        var segs = [];
11704        for (var _i = 0, oneColPlacements_2 = oneColPlacements; _i < oneColPlacements_2.length; _i++) {
11705            var placement = oneColPlacements_2[_i];
11706            segs.push(placement.seg);
11707        }
11708        return segs;
11709    }
11710    function limitByMaxHeight(hiddenCnts, segIsHidden, colPlacements, maxContentHeight) {
11711        limitEvents(hiddenCnts, segIsHidden, colPlacements, true, function (placement) { return placement.bottom <= maxContentHeight; });
11712    }
11713    function limitByMaxEvents(hiddenCnts, segIsHidden, colPlacements, dayMaxEvents) {
11714        limitEvents(hiddenCnts, segIsHidden, colPlacements, false, function (placement, levelIndex) { return levelIndex < dayMaxEvents; });
11715    }
11716    function limitByMaxRows(hiddenCnts, segIsHidden, colPlacements, dayMaxEventRows) {
11717        limitEvents(hiddenCnts, segIsHidden, colPlacements, true, function (placement, levelIndex) { return levelIndex < dayMaxEventRows; });
11718    }
11719    /*
11720    populates the given hiddenCnts/segIsHidden, which are supplied empty.
11721    TODO: return them instead
11722    */
11723    function limitEvents(hiddenCnts, segIsHidden, colPlacements, _moreLinkConsumesLevel, isPlacementInBounds) {
11724        var colCnt = hiddenCnts.length;
11725        var segIsVisible = {}; // TODO: instead, use segIsHidden with true/false?
11726        var visibleColPlacements = []; // will mirror colPlacements
11727        for (var col = 0; col < colCnt; col += 1) {
11728            visibleColPlacements.push([]);
11729        }
11730        for (var col = 0; col < colCnt; col += 1) {
11731            var placements = colPlacements[col];
11732            var level = 0;
11733            for (var _i = 0, placements_2 = placements; _i < placements_2.length; _i++) {
11734                var placement = placements_2[_i];
11735                if (isPlacementInBounds(placement, level)) {
11736                    recordVisible(placement);
11737                }
11738                else {
11739                    recordHidden(placement, level, _moreLinkConsumesLevel);
11740                }
11741                // only considered a level if the seg had height
11742                if (placement.top !== placement.bottom) {
11743                    level += 1;
11744                }
11745            }
11746        }
11747        function recordVisible(placement) {
11748            var seg = placement.seg;
11749            var instanceId = seg.eventRange.instance.instanceId;
11750            if (!segIsVisible[instanceId]) {
11751                segIsVisible[instanceId] = true;
11752                for (var col = seg.firstCol; col <= seg.lastCol; col += 1) {
11753                    var destPlacements = visibleColPlacements[col];
11754                    var newPosition = 0;
11755                    // insert while keeping top sorted in each column
11756                    while (newPosition < destPlacements.length &&
11757                        placement.top >= destPlacements[newPosition].top) {
11758                        newPosition += 1;
11759                    }
11760                    destPlacements.splice(newPosition, 0, placement);
11761                }
11762            }
11763        }
11764        function recordHidden(placement, currentLevel, moreLinkConsumesLevel) {
11765            var seg = placement.seg;
11766            var instanceId = seg.eventRange.instance.instanceId;
11767            if (!segIsHidden[instanceId]) {
11768                segIsHidden[instanceId] = true;
11769                for (var col = seg.firstCol; col <= seg.lastCol; col += 1) {
11770                    hiddenCnts[col] += 1;
11771                    var hiddenCnt = hiddenCnts[col];
11772                    if (moreLinkConsumesLevel && hiddenCnt === 1 && currentLevel > 0) {
11773                        var doomedLevel = currentLevel - 1;
11774                        while (visibleColPlacements[col].length > doomedLevel) {
11775                            recordHidden(visibleColPlacements[col].pop(), // removes
11776                            visibleColPlacements[col].length, // will execute after the pop. will be the index of the removed placement
11777                            false);
11778                        }
11779                    }
11780                }
11781            }
11782        }
11783    }
11784    // Given the events within an array of segment objects, reslice them to be in a single day
11785    function resliceDaySegs(segs, dayDate, colIndex) {
11786        var dayStart = dayDate;
11787        var dayEnd = addDays(dayStart, 1);
11788        var dayRange = { start: dayStart, end: dayEnd };
11789        var newSegs = [];
11790        for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
11791            var seg = segs_2[_i];
11792            var eventRange = seg.eventRange;
11793            var origRange = eventRange.range;
11794            var slicedRange = intersectRanges(origRange, dayRange);
11795            if (slicedRange) {
11796                newSegs.push(__assign(__assign({}, seg), { firstCol: colIndex, lastCol: colIndex, eventRange: {
11797                        def: eventRange.def,
11798                        ui: __assign(__assign({}, eventRange.ui), { durationEditable: false }),
11799                        instance: eventRange.instance,
11800                        range: slicedRange,
11801                    }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }));
11802            }
11803        }
11804        return newSegs;
11805    }
11806
11807    var TableRow = /** @class */ (function (_super) {
11808        __extends(TableRow, _super);
11809        function TableRow() {
11810            var _this = _super !== null && _super.apply(this, arguments) || this;
11811            _this.cellElRefs = new RefMap(); // the <td>
11812            _this.frameElRefs = new RefMap(); // the fc-daygrid-day-frame
11813            _this.fgElRefs = new RefMap(); // the fc-daygrid-day-events
11814            _this.segHarnessRefs = new RefMap(); // indexed by "instanceId:firstCol"
11815            _this.rootElRef = createRef();
11816            _this.state = {
11817                framePositions: null,
11818                maxContentHeight: null,
11819                segHeights: {},
11820            };
11821            return _this;
11822        }
11823        TableRow.prototype.render = function () {
11824            var _this = this;
11825            var _a = this, props = _a.props, state = _a.state, context = _a.context;
11826            var colCnt = props.cells.length;
11827            var businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt);
11828            var bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt);
11829            var highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt);
11830            var mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt);
11831            var _b = computeFgSegPlacement(props.cells, props.fgEventSegs, props.dayMaxEvents, props.dayMaxEventRows, state.segHeights, state.maxContentHeight, colCnt, context.options.eventOrder), paddingBottoms = _b.paddingBottoms, segsByFirstCol = _b.segsByFirstCol, segsByEachCol = _b.segsByEachCol, segIsHidden = _b.segIsHidden, segTops = _b.segTops, segMarginTops = _b.segMarginTops, moreCnts = _b.moreCnts, moreTops = _b.moreTops;
11832            var selectedInstanceHash = // TODO: messy way to compute this
11833             (props.eventDrag && props.eventDrag.affectedInstances) ||
11834                (props.eventResize && props.eventResize.affectedInstances) ||
11835                {};
11836            return (createElement("tr", { ref: this.rootElRef },
11837                props.renderIntro && props.renderIntro(),
11838                props.cells.map(function (cell, col) {
11839                    var normalFgNodes = _this.renderFgSegs(segsByFirstCol[col], segIsHidden, segTops, segMarginTops, selectedInstanceHash, props.todayRange);
11840                    var mirrorFgNodes = _this.renderFgSegs(mirrorSegsByCol[col], {}, segTops, // use same tops as real rendering
11841                    {}, {}, props.todayRange, Boolean(props.eventDrag), Boolean(props.eventResize), false);
11842                    return (createElement(TableCell, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), innerElRef: _this.frameElRefs.createRef(cell.key) /* FF <td> problem, but okay to use for left/right. TODO: rename prop */, dateProfile: props.dateProfile, date: cell.date, showDayNumber: props.showDayNumbers, showWeekNumber: props.showWeekNumbers && col === 0, forceDayTop: props.showWeekNumbers /* even displaying weeknum for row, not necessarily day */, todayRange: props.todayRange, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, moreCnt: moreCnts[col], buildMoreLinkText: props.buildMoreLinkText, onMoreClick: function (arg) {
11843                            props.onMoreClick(__assign(__assign({}, arg), { fromCol: col }));
11844                        }, segIsHidden: segIsHidden, moreMarginTop: moreTops[col] /* rename */, segsByEachCol: segsByEachCol[col], fgPaddingBottom: paddingBottoms[col], fgContentElRef: _this.fgElRefs.createRef(cell.key), fgContent: ( // Fragment scopes the keys
11845                        createElement(Fragment, null,
11846                            createElement(Fragment, null, normalFgNodes),
11847                            createElement(Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys
11848                        createElement(Fragment, null,
11849                            _this.renderFillSegs(highlightSegsByCol[col], 'highlight'),
11850                            _this.renderFillSegs(businessHoursByCol[col], 'non-business'),
11851                            _this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))) }));
11852                })));
11853        };
11854        TableRow.prototype.componentDidMount = function () {
11855            this.updateSizing(true);
11856        };
11857        TableRow.prototype.componentDidUpdate = function (prevProps, prevState) {
11858            var currentProps = this.props;
11859            this.updateSizing(!isPropsEqual(prevProps, currentProps));
11860        };
11861        TableRow.prototype.getHighlightSegs = function () {
11862            var props = this.props;
11863            if (props.eventDrag && props.eventDrag.segs.length) { // messy check
11864                return props.eventDrag.segs;
11865            }
11866            if (props.eventResize && props.eventResize.segs.length) { // messy check
11867                return props.eventResize.segs;
11868            }
11869            return props.dateSelectionSegs;
11870        };
11871        TableRow.prototype.getMirrorSegs = function () {
11872            var props = this.props;
11873            if (props.eventResize && props.eventResize.segs.length) { // messy check
11874                return props.eventResize.segs;
11875            }
11876            return [];
11877        };
11878        TableRow.prototype.renderFgSegs = function (segs, segIsHidden, // does NOT mean display:hidden
11879        segTops, segMarginTops, selectedInstanceHash, todayRange, isDragging, isResizing, isDateSelecting) {
11880            var context = this.context;
11881            var eventSelection = this.props.eventSelection;
11882            var framePositions = this.state.framePositions;
11883            var defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1
11884            var nodes = [];
11885            if (framePositions) {
11886                for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
11887                    var seg = segs_1[_i];
11888                    var instanceId = seg.eventRange.instance.instanceId;
11889                    var isMirror = isDragging || isResizing || isDateSelecting;
11890                    var isSelected = selectedInstanceHash[instanceId];
11891                    var isInvisible = segIsHidden[instanceId] || isSelected;
11892                    // TODO: simpler way? NOT DRY
11893                    var isAbsolute = segIsHidden[instanceId] || isMirror || seg.firstCol !== seg.lastCol || !seg.isStart || !seg.isEnd;
11894                    var marginTop = void 0;
11895                    var top_1 = void 0;
11896                    var left = void 0;
11897                    var right = void 0;
11898                    if (isAbsolute) {
11899                        top_1 = segTops[instanceId];
11900                        if (context.isRtl) {
11901                            right = 0;
11902                            left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol];
11903                        }
11904                        else {
11905                            left = 0;
11906                            right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol];
11907                        }
11908                    }
11909                    else {
11910                        marginTop = segMarginTops[instanceId];
11911                    }
11912                    /*
11913                    known bug: events that are force to be list-item but span multiple days still take up space in later columns
11914                    */
11915                    nodes.push(createElement("div", { className: 'fc-daygri
11915d-event-harness' + (isAbsolute ? ' fc-daygrid-event-harness-abs' : ''), key: instanceId, 
11916                        // in print mode when in mult cols, could collide
11917                        ref: isMirror ? null : this.segHarnessRefs.createRef(instanceId + ':' + seg.firstCol), style: {
11918                            visibility: isInvisible ? 'hidden' : '',
11919                            marginTop: marginTop || '',
11920                            top: top_1 || '',
11921                            left: left || '',
11922                            right: right || '',
11923                        } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange))))));
11924                }
11925            }
11926            return nodes;
11927        };
11928        TableRow.prototype.renderFillSegs = function (segs, fillType) {
11929            var isRtl = this.context.isRtl;
11930            var todayRange = this.props.todayRange;
11931            var framePositions = this.state.framePositions;
11932            var nodes = [];
11933            if (framePositions) {
11934                for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
11935                    var seg = segs_2[_i];
11936                    var leftRightCss = isRtl ? {
11937                        right: 0,
11938                        left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol],
11939                    } : {
11940                        left: 0,
11941                        right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol],
11942                    };
11943                    nodes.push(createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-daygrid-bg-harness", style: leftRightCss }, fillType === 'bg-event' ?
11944                        createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, todayRange))) :
11945                        renderFill(fillType)));
11946                }
11947            }
11948            return createElement.apply(void 0, __spreadArrays([Fragment, {}], nodes));
11949        };
11950        TableRow.prototype.updateSizing = function (isExternalSizingChange) {
11951            var _a = this, props = _a.props, frameElRefs = _a.frameElRefs;
11952            if (props.clientWidth !== null) { // positioning ready?
11953                if (isExternalSizingChange) {
11954                    var frameEls = props.cells.map(function (cell) { return frameElRefs.currentMap[cell.key]; });
11955                    if (frameEls.length) {
11956                        var originEl = this.rootElRef.current;
11957                        this.setState({
11958                            framePositions: new PositionCache(originEl, frameEls, true, // isHorizontal
11959                            false),
11960                        });
11961                    }
11962                }
11963                var limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;
11964                this.setState({
11965                    segHeights: this.computeSegHeights(),
11966                    maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null,
11967                });
11968            }
11969        };
11970        TableRow.prototype.computeSegHeights = function () {
11971            return mapHash(this.segHarnessRefs.currentMap, function (eventHarnessEl) { return (eventHarnessEl.getBoundingClientRect().height); });
11972        };
11973        TableRow.prototype.computeMaxContentHeight = function () {
11974            var firstKey = this.props.cells[0].key;
11975            var cellEl = this.cellElRefs.currentMap[firstKey];
11976            var fcContainerEl = this.fgElRefs.currentMap[firstKey];
11977            return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top;
11978        };
11979        TableRow.prototype.getCellEls = function () {
11980            var elMap = this.cellElRefs.currentMap;
11981            return this.props.cells.map(function (cell) { return elMap[cell.key]; });
11982        };
11983        return TableRow;
11984    }(DateComponent));
11985    TableRow.addPropsEquality({
11986        onMoreClick: true,
11987    });
11988    TableRow.addStateEquality({
11989        segHeights: isPropsEqual,
11990    });
11991
11992    var PADDING_FROM_VIEWPORT = 10;
11993    var SCROLL_DEBOUNCE = 10;
11994    var Popover = /** @class */ (function (_super) {
11995        __extends(Popover, _super);
11996        function Popover() {
11997            var _this = _super !== null && _super.apply(this, arguments) || this;
11998            _this.repositioner = new DelayedRunner(_this.updateSize.bind(_this));
11999            _this.handleRootEl = function (el) {
12000                _this.rootEl = el;
12001                if (_this.props.elRef) {
12002                    setRef(_this.props.elRef, el);
12003                }
12004            };
12005            // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
12006            _this.handleDocumentMousedown = function (ev) {
12007                var onClose = _this.props.onClose;
12008                // only hide the popover if the click happened outside the popover
12009                if (onClose && !_this.rootEl.contains(ev.target)) {
12010                    onClose();
12011                }
12012            };
12013            _this.handleDocumentScroll = function () {
12014                _this.repositioner.request(SCROLL_DEBOUNCE);
12015            };
12016            _this.handleCloseClick = function () {
12017                var onClose = _this.props.onClose;
12018                if (onClose) {
12019                    onClose();
12020                }
12021            };
12022            return _this;
12023        }
12024        Popover.prototype.render = function () {
12025            var theme = this.context.theme;
12026            var props = this.props;
12027            var classNames = [
12028                'fc-popover',
12029                theme.getClass('popover'),
12030            ].concat(props.extraClassNames || []);
12031            return (createElement("div", __assign({ className: classNames.join(' ') }, props.extraAttrs, { ref: this.handleRootEl }),
12032                createElement("div", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') },
12033                    createElement("span", { className: "fc-popover-title" }, props.title),
12034                    createElement("span", { className: 'fc-popover-close ' + theme.getIconClass('close'), onClick: this.handleCloseClick })),
12035                createElement("div", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)));
12036        };
12037        Popover.prototype.componentDidMount = function () {
12038            document.addEventListener('mousedown', this.handleDocumentMousedown);
12039            document.addEventListener('scroll', this.handleDocumentScroll);
12040            this.updateSize();
12041        };
12042        Popover.prototype.componentWillUnmount = function () {
12043            document.removeEventListener('mousedown', this.handleDocumentMousedown);
12044            document.removeEventListener('scroll', this.handleDocumentScroll);
12045        };
12046        // TODO: adjust on window resize
12047        /*
12048        NOTE: the popover is position:fixed, so coordinates are relative to the viewport
12049        NOTE: the PARENT calls this as well, on window resize. we would have wanted to use the repositioner,
12050              but need to ensure that all other components have updated size first (for alignmentEl)
12051        */
12052        Popover.prototype.updateSize = function () {
12053            var _a = this.props, alignmentEl = _a.alignmentEl, topAlignmentEl = _a.topAlignmentEl;
12054            var rootEl = this.rootEl;
12055            if (!rootEl) {
12056                return;
12056 // not sure why this was null, but we shouldn't let external components call updateSize() anyway
12057            }
12058            var dims = rootEl.getBoundingClientRect(); // only used for width,height
12059            var alignment = alignmentEl.getBoundingClientRect();
12060            var top = topAlignmentEl ? topAlignmentEl.getBoundingClientRect().top : alignment.top;
12061            top = Math.min(top, window.innerHeight - dims.height - PADDING_FROM_VIEWPORT);
12062            top = Math.max(top, PADDING_FROM_VIEWPORT);
12063            var left;
12064            if (this.context.isRtl) {
12065                left = alignment.right - dims.width;
12066            }
12067            else {
12068                left = alignment.left;
12069            }
12070            left = Math.min(left, window.innerWidth - dims.width - PADDING_FROM_VIEWPORT);
12071            left = Math.max(left, PADDING_FROM_VIEWPORT);
12072            applyStyle(rootEl, { top: top, left: left });
12073        };
12074        return Popover;
12075    }(BaseComponent));
12076
12077    var MorePopover = /** @class */ (function (_super) {
12078        __extends(MorePopover, _super);
12079        function MorePopover() {
12080            var _this = _super !== null && _super.apply(this, arguments) || this;
12081            _this.rootElRef = createRef();
12082            return _this;
12083        }
12084        MorePopover.prototype.render = function () {
12085            var _a = this.context, options = _a.options, dateEnv = _a.dateEnv;
12086            var props = this.props;
12087            var date = props.date, hiddenInstances = props.hiddenInstances, todayRange = props.todayRange, dateProfile = props.dateProfile, selectedInstanceId = props.selectedInstanceId;
12088            var title = dateEnv.format(date, options.dayPopoverFormat);
12089            return (createElement(DayCellRoot, { date: date, dateProfile: dateProfile, todayRange: todayRange, elRef: this.rootElRef }, function (rootElRef, dayClassNames, dataAttrs) { return (createElement(Popover, { elRef: rootElRef, title: title, extraClassNames: ['fc-more-popover'].concat(dayClassNames), extraAttrs: dataAttrs, onClose: props.onCloseClick, alignmentEl: props.alignmentEl, topAlignmentEl: props.topAlignmentEl },
12090                createElement(DayCellContent, { date: date, dateProfile: dateProfile, todayRange: todayRange }, function (innerElRef, innerContent) { return (innerContent &&
12091                    createElement("div", { className: "fc-more-popover-misc", ref: innerElRef }, innerContent)); }),
12092                props.segs.map(function (seg) {
12093                    var instanceId = seg.eventRange.instance.instanceId;
12094                    return (createElement("div", { className: "fc-daygrid-event-harness", key: instanceId, style: {
12095                            visibility: hiddenInstances[instanceId] ? 'hidden' : '',
12096                        } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: false, isSelected: instanceId === selectedInstanceId, defaultDisplayEventEnd: false }, getSegMeta(seg, todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === selectedInstanceId, defaultDisplayEventEnd: false }, getSegMeta(seg, todayRange))))));
12097                }))); }));
12098        };
12099        MorePopover.prototype.positionToHit = function (positionLeft, positionTop, originEl) {
12100            var rootEl = this.rootElRef.current;
12101            if (!originEl || !rootEl) { // why?
12102                return null;
12103            }
12104            var originRect = originEl.getBoundingClientRect();
12105            var elRect = rootEl.getBoundingClientRect();
12106            var newOriginLeft = elRect.left - originRect.left;
12107            var newOriginTop = elRect.top - originRect.top;
12108            var localLeft = positionLeft - newOriginLeft;
12109            var localTop = positionTop - newOriginTop;
12110            var date = this.props.date;
12111            if ( // ugly way to detect intersection
12112            localLeft >= 0 && localLeft < elRect.width &&
12113                localTop >= 0 && localTop < elRect.height) {
12114                return {
12115                    dateSpan: {
12116                        allDay: true,
12117                        range: { start: date, end: addDays(date, 1) },
12118                    },
12119                    dayEl: rootEl,
12120                    relativeRect: {
12121                        left: newOriginLeft,
12122                        top: newOriginTop,
12123                        right: elRect.width,
12124                        bottom: elRect.height,
12125                    },
12126                    layer: 1,
12127                };
12128            }
12129            return null;
12130        };
12131        return MorePopover;
12132    }(DateComponent));
12133
12134    var Table = /** @class */ (function (_super) {
12135        __extends(Table, _super);
12136        function Table() {
12137            var _this = _super !== null && _super.apply(this, arguments) || this;
12138            _this.splitBusinessHourSegs = memoize(splitSegsByRow);
12139            _this.splitBgEventSegs = memoize(splitSegsByRow);
12140            _this.splitFgEventSegs = memoize(splitSegsByRow);
12141            _this.splitDateSelectionSegs = memoize(splitSegsByRow);
12142            _this.splitEventDrag = memoize(splitInteractionByRow);
12143            _this.splitEventResize = memoize(splitInteractionByRow);
12144            _this.buildBuildMoreLinkText = memoize(buildBuildMoreLinkText);
12145            _this.morePopoverRef = createRef();
12146            _this.rowRefs = new RefMap();
12147            _this.state = {
12148                morePopoverState: null,
12149            };
12150            _this.handleRootEl = function (rootEl) {
12151                _this.rootEl = rootEl;
12152                setRef(_this.props.elRef, rootEl);
12153            };
12154            // TODO: bad names "more link click" versus "more click"
12155            _this.handleMoreLinkClick = function (arg) {
12156                var context = _this.context;
12157                var dateEnv = context.dateEnv;
12158                var clickOption = context.options.moreLinkClick;
12159                function segForPublic(seg) {
12160                    var _a = seg.eventRange, def = _a.def, instance = _a.instance, range = _a.range;
12161                    return {
12162                        event: new EventApi(context, def, instance),
12163                        start: dateEnv.toDate(range.start),
12164                        end: dateEnv.toDate(range.end),
12165                        isStart: seg.isStart,
12166                        isEnd: seg.isEnd,
12167                    };
12168                }
12169                if (typeof clickOption === 'function') {
12170                    clickOption = clickOption({
12171                        date: dateEnv.toDate(arg.date),
12172                        allDay: true,
12173                        allSegs: arg.allSegs.map(segForPublic),
12174                        hiddenSegs: arg.hiddenSegs.map(segForPublic),
12175                        jsEvent: arg.ev,
12176                        view: context.viewApi,
12177                    }); // hack to handle void
12178                }
12179                if (!clickOption || clickOption === 'popover') {
12180                    _this.setState({
12181                        morePopoverState: __assign(__assign({}, arg), { currentFgEventSegs: _this.props.fgEventSegs, fromRow: arg.fromRow, fromCol: arg.fromCol }),
12182                    });
12183                }
12184                else if (typeof clickOption === 'string') { // a view n
12184ame
12185                    context.calendarApi.zoomTo(arg.date, clickOption);
12186                }
12187            };
12188            _this.handleMorePopoverClose = function () {
12189                _this.setState({
12190                    morePopoverState: null,
12191                });
12192            };
12193            return _this;
12194        }
12195        Table.prototype.render = function () {
12196            var _this = this;
12197            var props = this.props;
12198            var dateProfile = props.dateProfile, dayMaxEventRows = props.dayMaxEventRows, dayMaxEvents = props.dayMaxEvents, expandRows = props.expandRows;
12199            var morePopoverState = this.state.morePopoverState;
12200            var rowCnt = props.cells.length;
12201            var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt);
12202            var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt);
12203            var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt);
12204            var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt);
12205            var eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt);
12206            var eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt);
12207            var buildMoreLinkText = this.buildBuildMoreLinkText(this.context.options.moreLinkText);
12208            var limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true;
12209            // if rows can't expand to fill fixed height, can't do balanced-height event limit
12210            // TODO: best place to normalize these options?
12211            if (limitViaBalanced && !expandRows) {
12212                limitViaBalanced = false;
12213                dayMaxEventRows = null;
12214                dayMaxEvents = null;
12215            }
12216            var classNames = [
12217                'fc-daygrid-body',
12218                limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced',
12219                expandRows ? '' : 'fc-daygrid-body-natural',
12220            ];
12221            return (createElement("div", { className: classNames.join(' '), ref: this.handleRootEl, style: {
12222                    // these props are important to give this wrapper correct dimensions for interactions
12223                    // TODO: if we set it here, can we avoid giving to inner tables?
12224                    width: props.clientWidth,
12225                    minWidth: props.tableMinWidth,
12226                } },
12227                createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement(Fragment, null,
12228                    createElement("table", { className: "fc-scrollgrid-sync-table", style: {
12229                            width: props.clientWidth,
12230                            minWidth: props.tableMinWidth,
12231                            height: expandRows ? props.clientHeight : '',
12232                        } },
12233                        props.colGroupNode,
12234                        createElement("tbody", null, props.cells.map(function (cells, row) { return (createElement(TableRow, { ref: _this.rowRefs.createRef(row), key: cells.length
12235                                ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */
12236                                : row // in case there are no cells (like when resource view is loading)
12237                            , showDayNumbers: rowCnt > 1, showWeekNumbers: props.showWeekNumbers, todayRange: todayRange, dateProfile: dateProfile, cells: cells, renderIntro: props.renderRowIntro, businessHourSegs: businessHourSegsByRow[row], eventSelection: props.eventSelection, bgEventSegs: bgEventSegsByRow[row].filter(isSegAllDay) /* hack */, fgEventSegs: fgEventSegsByRow[row], dateSelectionSegs: dateSelectionSegsByRow[row], eventDrag: eventDragByRow[row], eventResize: eventResizeByRow[row], dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows, clientWidth: props.clientWidth, clientHeight: props.clientHeight, buildMoreLinkText: buildMoreLinkText, onMoreClick: function (arg) {
12238                                _this.handleMoreLinkClick(__assign(__assign({}, arg), { fromRow: row }));
12239                            } })); }))),
12240                    (!props.forPrint && morePopoverState && morePopoverState.currentFgEventSegs === props.fgEventSegs) && (createElement(MorePopover, { ref: _this.morePopoverRef, date: morePopoverState.date, dateProfile: dateProfile, segs: morePopoverState.allSegs, alignmentEl: morePopoverState.dayEl, topAlignmentEl: rowCnt === 1 ? props.headerAlignElRef.current : null, onCloseClick: _this.handleMorePopoverClose, selectedInstanceId: props.eventSelection, hiddenInstances: // yuck
12241                        (props.eventDrag ? props.eventDrag.affectedInstances : null) ||
12242                            (props.eventResize ? props.eventResize.affectedInstances : null) ||
12243                            {}, todayRange: todayRange })))); })));
12244        };
12245        // Hit System
12246        // ----------------------------------------------------------------------------------------------------
12247        Table.prototype.prepareHits = function () {
12248            this.rowPositions = new PositionCache(this.rootEl, this.rowRefs.collect().map(function (rowObj) { return rowObj.getCellEls()[0]; }), // first cell el in each row. TODO: not optimal
12249            false, true);
12250            this.colPositions = new PositionCache(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row
12251            true, // horizontal
12252            false);
12253        };
12254        Table.prototype.positionToHit = function (leftPosition, topPosition) {
12255            var morePopover = this.morePopoverRef.current;
12256            var morePopoverHit = morePopover ? morePopover.positionToHit(leftPosition, topPosition, this.rootEl) : null;
12257            var morePopoverState = this.state.morePopoverState;
12258            if (morePopoverHit) {
12259                return __assign({ row: morePopoverState.fromRow, col: morePopoverState.fromCol }, morePopoverHit);
12260            }
12261            var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions;
12262            var col = colPositions.leftToIndex(leftPosition);
12263            var row = rowPositions.topToIndex(topPosition);
12264            if (row != null && col != null) {
12265                return {
12266                    row: row,
12267                    col: col,
12268                    dateSpan: {
12269                        range: this.getCellRange(row, col),
12270                        allDay: true,
12271                    },
12272                    dayEl: this.getCellEl(row, col),
12273                    relativeRect: {
12274                        left: colPositions.lefts[col],
12275                        right: colPositions.rights[col],
12276                        top: rowPositions.tops[row],
12277                        bottom: rowPositions.bottoms[row],
12278                    },
12279                };
12280            }
12281            return null;
12282        };
12283        Table.prototype.getCellEl = function (row, col) {
12284            return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal
12285        };
12286        Table.prototype.getCellRange = function (row, col) {
12287            var start = this.props.cells[row][col].date;
12288            var end = addDays(start, 1);
12289            return { start: start, end: end };
12290        };
12291        return Table;
12292    }(DateComponent));
12293    function buildBuildMoreLinkText(moreLinkTextInput) {
12294        if (typeof moreLinkTextInput === 'function') {
12295            return moreLinkTextInput;
12296        }
12297        return function (num) { return "+" + num + " " + moreLinkTextInput; };
12298    }
12299    function isSegAllDay(seg) {
12300        return seg.eventRange.def.allDay;
12301    }
12302
12303    var DayTableSlicer = /** @class */ (function (_super) {
12304        __extends(DayTableSlicer, _super);
12305        function DayTableSlicer() {
12306            var _this = _super !== null && _super.apply(this, arguments) || this;
12307            _this.forceDayIfListItem = true;
12308            return _this;
12309        }
12310        DayTableSlicer.prototype.sliceRange = function (dateRange, dayTableModel) {
12311            return dayTableModel.sliceRange(dateRange);
12312        };
12313        return DayTableSlicer;
12314    }(Slicer));
12315
12316    var DayTable = /** @class */ (function (_super) {
12317        __extends(DayTable, _super);
12318        function DayTable() {
12319            var _this = _super !== null && _super.apply(this, arguments) || this;
12320            _this.slicer = new DayTableSlicer();
12321            _this.tableRef = createRef();
12322            _this.handleRootEl = function (rootEl) {
12323                if (rootEl) {
12324                    _this.context.registerInteractiveComponent(_this, { el: rootEl });
12325                }
12326                else {
12327                    _this.context.unregisterInteractiveComponent(_this);
12328                }
12329            };
12330            return _this;
12331        }
12332        DayTable.prototype.render = function () {
12333            var _a = this, props = _a.props, context = _a.context;
12334            return (createElement(Table, __assign({ ref: this.tableRef, elRef: this.handleRootEl }, this.slicer.sliceProps(props, props.dateProfile, props.nextDayThreshold, context, props.dayTableModel), { dateProfile: props.dateProfile, cells: props.dayTableModel.cells, colGroupNode: props.colGroupNode, tableMinWidth: props.tableMinWidth, renderRowIntro: props.renderRowIntro, dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows, showWeekNumbers: props.showWeekNumbers, expandRows: props.expandRows, headerAlignElRef: props.headerAlignElRef, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint })));
12335        };
12336        DayTable.prototype.prepareHits = function () {
12337            this.tableRef.current.prepareHits();
12338        };
12339        DayTable.prototype.queryHit = function (positionLeft, positionTop) {
12340            var rawHit = this.tableRef.current.positionToHit(positionLeft, positionTop);
12341            if (rawHit) {
12342                return {
12343                    component: this,
12344                    dateSpan: rawHit.dateSpan,
12345                    dayEl: rawHit.dayEl,
12346                    rect: {
12347                        left: rawHit.relativeRect.left,
12348                        right: rawHit.relativeRect.right,
12349                        top: rawHit.relativeRect.top,
12350                        bottom: rawHit.relativeRect.bottom,
12351                    },
12352                    layer: 0,
12353                };
12354            }
12355            return null;
12356        };
12357        return DayTable;
12358    }(DateComponent));
12359
12360    var DayTableView = /** @class */ (function (_super) {
12361        __extends(DayTableView, _super);
12362        function DayTableView() {
12363            var _this = _super !== null && _super.apply(this, arguments) || this;
12364            _this.buildDayTableModel = memoize(buildDayTableModel);
12365            _this.headerRef = createRef();
12366            _this.tableRef = createRef();
12367            return _this;
12368        }
12369        DayTableView.prototype.render = function () {
12370            var _this = this;
12371            var _a = this.context, options = _a.options, dateProfileGenerator = _a.dateProfileGenerator;
12372            var props = this.props;
12373            var dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator);
12374            var headerContent = options.dayHeaders && (createElement(DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 }));
12375            var bodyContent = function (contentArg) { return (createElement(DayTable, { ref: _this.tableRef, dateProfile: props.dateProfile, dayTableModel: dayTableModel, businessHours: props.businessHours, dateSelection: props.dateSelection, eventStore: props.eventStore, eventUiBases: props.eventUiBases, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, nextDayThreshold: options.nextDayThreshold, colGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, dayMaxEvents: options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows, showWeekNumbers: options.weekNumbers, expandRows: !props.isHeightAuto, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint })); };
12376            return options.dayMinWidth
12377                ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth)
12378                : this.renderSimpleLayout(headerContent, bodyContent);
12379        };
12380        return DayTableView;
12381    }(TableView));
12382    function buildDayTableModel(dateProfile, dateProfileGenerator) {
12383        var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
12384        return new DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
12385    }
12386
12387    var TableDateProfileGenerator = /** @class */ (function (_super) {
12388        __extends(TableDateProfileGenerator, _super);
12389        function TableDateProfileGenerator() {
12390            return _super !== null && _super.apply(this, arguments) || this;
12391        }
12392        // Computes the date range that will be rendered.
12393        TableDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
12394            var dateEnv = this.props.dateEnv;
12395            var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay);
12396            var start = renderRange.start;
12397            var end = renderRange.end;
12398            var endOfWeek;
12399            // year and month views should be aligned with weeks. this is already done for week
12400            if (/^(year|month)$/.test(currentRangeUnit)) {
12401                start = dateEnv.startOfWeek(start);
12402                // make end-of-week if not already
12403                endOfWeek = dateEnv.startOfWeek(end);
12404                if (endOfWeek.valueOf() !== end.valueOf()) {
12405                    end = addWeeks(endOfWeek, 1);
12406                }
12407            }
12408            // ensure 6 weeks
12409            if (this.props.monthMode &&
12410                this.props.fixedWeekCount) {
12411                var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
12412                diffWeeks(start, end));
12413                end = addWeeks(end, 6 - rowCnt);
12414            }
12415            return { start: start, end: end };
12416        };
12417        return TableDateProfileGenerator;
12418    }(DateProfileGenerator));
12419
12420    var OPTION_REFINERS$1 = {
12421        moreLinkClick: identity,
12422        moreLinkClassNames: identity,
12423        moreLinkContent: identity,
12424        moreLinkDidMount: identity,
12425        moreLinkWillUnmount: identity,
12426    };
12427
12428    var dayGridPlugin = createPlugin({
12429        initialView: 'dayGridMonth',
12430        optionRefiners: OPTION_REFINERS$1,
12431        views: {
12432            dayGrid: {
12433                component: DayTableView,
12434                dateProfileGeneratorClass: TableDateProfileGenerator,
12435            },
12436            dayGridDay: {
12437                type: 'dayGrid',
12438                duration: { days: 1 },
12439            },
12440            dayGridWeek: {
12441                type: 'dayGrid',
12442                duration: { weeks: 1 },
12443            },
12444            dayGridMonth: {
12445                type: 'dayGrid',
12446                duration: { months: 1 },
12447                monthMode: true,
12448                fixedWeekCount: true,
12449            },
12450        },
12451    });
12452
12453    var AllDaySplitter = /** @class */ (function (_super) {
12454        __extends(AllDaySplitter, _super);
12455        function AllDaySplitter() {
12456            return _super !== null && _super.apply(this, arguments) || this;
12457        }
12458        AllDaySplitter.prototype.getKeyInfo = function () {
12459            return {
12460                allDay: {},
12461                timed: {},
12462            };
12463        };
12464        AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
12465            if (dateSpan.allDay) {
12466                return ['allDay'];
12467            }
12468            return ['timed'];
12469        };
12470        AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
12471            if (!eventDef.allDay) {
12472                return ['timed'];
12473            }
12474            if (hasBgRendering(eventDef)) {
12475                return ['timed', 'allDay'];
12476            }
12477            return ['allDay'];
12478        };
12479        return AllDaySplitter;
12480    }(Splitter));
12481
12482    var DEFAULT_SLAT_LABEL_FORMAT = createFormatter({
12483        hour: 'numeric',
12484        minute: '2-digit',
12485        omitZeroMinute: true,
12486        meridiem: 'short',
12487    });
12488    function TimeColsAxisCell(props) {
12489        var classNames = [
12490            'fc-timegrid-slot',
12491            'fc-timegrid-slot-label',
12492            props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor',
12493        ];
12494        return (createElement(ViewContextType.Consumer, null, function (context) {
12495            if (!props.isLabeled) {
12496                return (createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr }));
12497            }
12498            var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi;
12499            var labelFormat = // TODO: fully pre-parse
12500             options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT :
12501                Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) :
12502                    createFormatter(options.slotLabelFormat);
12503            var hookProps = {
12504                level: 0,
12505                time: props.time,
12506                date: dateEnv.toDate(props.date),
12507                view: viewApi,
12508                text: dateEnv.format(props.date, labelFormat),
12509            };
12510            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLabelClassNames, content: options.slotLabelContent, defaultContent: renderInnerContent$3, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.c
12510oncat(customClassNames).join(' '), "data-time": props.isoTimeStr },
12511                createElement("div", { className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame" },
12512                    createElement("div", { className: "fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion", ref: innerElRef }, innerContent)))); }));
12513        }));
12514    }
12515    function renderInnerContent$3(props) {
12516        return props.text;
12517    }
12518
12519    var TimeBodyAxis = /** @class */ (function (_super) {
12520        __extends(TimeBodyAxis, _super);
12521        function TimeBodyAxis() {
12522            return _super !== null && _super.apply(this, arguments) || this;
12523        }
12524        TimeBodyAxis.prototype.render = function () {
12525            return this.props.slatMetas.map(function (slatMeta) { return (createElement("tr", { key: slatMeta.key },
12526                createElement(TimeColsAxisCell, __assign({}, slatMeta)))); });
12527        };
12528        return TimeBodyAxis;
12529    }(BaseComponent));
12530
12531    var DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: 'short' });
12532    var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5;
12533    var TimeColsView = /** @class */ (function (_super) {
12534        __extends(TimeColsView, _super);
12535        function TimeColsView() {
12536            var _this = _super !== null && _super.apply(this, arguments) || this;
12537            _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses
12538            _this.headerElRef = createRef();
12539            _this.rootElRef = createRef();
12540            _this.scrollerElRef = createRef();
12541            _this.state = {
12542                slatCoords: null,
12543            };
12544            _this.handleScrollTopRequest = function (scrollTop) {
12545                var scrollerEl = _this.scrollerElRef.current;
12546                if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer
12547                    scrollerEl.scrollTop = scrollTop;
12548                }
12549            };
12550            /* Header Render Methods
12551            ------------------------------------------------------------------------------------------------------------------*/
12552            _this.renderHeadAxis = function (rowKey, frameHeight) {
12553                if (frameHeight === void 0) { frameHeight = ''; }
12554                var options = _this.context.options;
12555                var dateProfile = _this.props.dateProfile;
12556                var range = dateProfile.renderRange;
12557                var dayCnt = diffDays(range.start, range.end);
12558                var navLinkAttrs = (options.navLinks && dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it)
12559                    ? { 'data-navlink': buildNavLinkData(range.start, 'week'), tabIndex: 0 }
12560                    : {};
12561                if (options.weekNumbers && rowKey === 'day') {
12562                    return (createElement(WeekNumberRoot, { date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT$1 }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("th", { ref: rootElRef, className: [
12563                            'fc-timegrid-axis',
12564                            'fc-scrollgrid-shrink',
12565                        ].concat(classNames).join(' ') },
12566                        createElement("div", { className: "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid", style: { height: frameHeight } },
12567                            createElement("a", __assign({ ref: innerElRef, className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner" }, navLinkAttrs), innerContent)))); }));
12568                }
12569                return (createElement("th", { className: "fc-timegrid-axis" },
12570                    createElement("div", { className: "fc-timegrid-axis-frame", style: { height: frameHeight } })));
12571            };
12572            /* Table Component Render Methods
12573            ------------------------------------------------------------------------------------------------------------------*/
12574            // only a one-way height sync. we don't send the axis inner-content height to the DayGrid,
12575            // but DayGrid still needs to have classNames on inner elements in order to measure.
12576            _this.renderTableRowAxis = function (rowHeight) {
12577                var _a = _this.context, options = _a.options, viewApi = _a.viewApi;
12578                var hookProps = {
12579                    text: options.allDayText,
12580                    view: viewApi,
12581                };
12582                return (
12583                // TODO: make reusable hook. used in list view too
12584                createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: [
12585                        'fc-timegrid-axis',
12586                        'fc-scrollgrid-shrink',
12587                    ].concat(classNames).join(' ') },
12588                    createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } },
12589                        createElement("span", { className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", ref: innerElRef }, innerContent)))); }));
12590            };
12591            _this.handleSlatCoords = function (slatCoords) {
12592                _this.setState({ slatCoords: slatCoords });
12593            };
12594            return _this;
12595        }
12596        // rendering
12597        // ----------------------------------------------------------------------------------------------------
12598        TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) {
12599            var _a = this, context = _a.context, props = _a.props;
12600            var sections = [];
12601            var stickyHeaderDates = getStickyHeaderDates(context.options);
12602            if (headerRowContent) {
12603                sections.push({
12604                    type: 'header',
12605                    key: 'header',
12606                    isSticky: stickyHeaderDates,
12607                    chunk: {
12608                        elRef: this.headerElRef,
12609                        tableClassName: 'fc-col-header',
12610                        rowContent: headerRowContent,
12611                    },
12612                });
12613            }
12614            if (allDayContent) {
12615                sections.push({
12616                    type: 'body',
12617                    key: 'all-day',
12618                    chunk: { content: allDayContent },
12619                });
12620                sections.push({
12621                    type: 'body',
12622                    key: 'all-day-divider',
12623                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
12624                    createElement("tr", { className: "fc-scrollgrid-section" },
12625                        createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),
12626                });
12627            }
12628            sections.push({
12629                type: 'body',
12630                key: 'body',
12631                liquid: true,
12632                expandRows: Boolean(context.options.expandRows),
12633                chunk: {
12634                    scrollerElRef: this.scrollerElRef,
12635                    content: timeContent,
12636                },
12637            });
12638            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef },
12639                createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); }));
12640        };
12641        TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) {
12642            var _this = this;
12643            var ScrollGrid = this.context.pluginHooks.scrollGridImpl;
12644            if (!ScrollGrid) {
12645                throw new Error('No ScrollGrid implementation');
12646            }
12647            var _a = this, context = _a.context, props = _a.props;
12648            var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options);
12649            var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options);
12650            var sections = [];
12651            if (headerRowContent) {
12652                sections.push({
12653                    type: 'header',
12654                    key: 'header',
12655                    isSticky: stickyHeaderDates,
12656                    syncRowHeights: true,
12657                    chunks: [
12658                        {
12659                            key: 'axis',
12660                            rowContent: function (arg) { return (createElement("tr", null, _this.renderHeadAxis('day', arg.rowSyncHeights[0]))); },
12661                        },
12662                        {
12663                            key: 'cols',
12664                            elRef: this.headerElRef,
12665                            tableClassName: 'fc-col-header',
12666                            rowContent: headerRowContent,
12667                        },
12668                    ],
12669                });
12670            }
12671            if (allDayContent) {
12672                sections.push({
12673                    type: 'body',
12674                    key: 'all-day',
12675                    syncRowHeights: true,
12676                    chunks: [
12677                        {
12678                            key: 'axis',
12679                            rowContent: function (contentArg) { return (createElement("tr", null, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); },
12680                        },
12681                        {
12682                            key: 'cols',
12683                            content: allDayContent,
12684                        },
12685                    ],
12686                });
12687                sections.push({
12688                    key: 'all-day-divider',
12689                    type: 'body',
12690                    outerContent: ( // TODO: rename to cellContent so don't need to define <tr>?
12691                    createElement("tr", { className: "fc-scrollgrid-section" },
12692                        createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),
12693                });
12694            }
12695            var isNowIndicator = context.options.nowIndicator;
12696            sections.push({
12697                type: 'body',
12698                key: 'body',
12699                liquid: true,
12700                expandRows: Boolean(context.options.expandRows),
12701                chunks: [
12702                    {
12703                        key: 'axis',
12704                        content: function (arg) { return (
12705                        // TODO: make this now-indicator arrow more DRY with TimeColsContent
12706                        createElement("div", { className: "fc-timegrid-axis-chunk" },
12707                            createElement("table", { style: { height: arg.expandRows ? arg.clientHeight : '' } },
12708                                arg.tableColGroupNode,
12709                                createElement("tbody", null,
12710                                    createElement(TimeBodyAxis, { slatMetas: slatMetas }))),
12711                            createElement("div", { className: "fc-timegrid-now-indicator-container" },
12712                                createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) {
12713                                    var nowIndicatorTop = isNowIndicator &&
12714                                        slatCoords &&
12715                                        slatCoords.safeComputeTop(nowDate); // might return void
12716                                    if (typeof nowIndicatorTop === 'number') {
12717                                        return (createElement(NowIndicatorRoot, { isAxis: true, date: nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); }));
12718                                    }
12719                                    return null;
12720                                })))); },
12721                    },
12722                    {
12723                        key: 'cols',
12724                        scrollerElRef: this.scrollerElRef,
12725                        content: timeContent,
12726                    },
12727                ],
12728            });
12729            if (stickyFooterScrollbar) {
12730                sections.push({
12731                    key: 'footer',
12732                    type: 'footer',
12733                    isSticky: true,
12734                    chunks: [
12735                        {
12736                            key: 'axis',
12737                            content: renderScrollShim,
12738                        },
12739                        {
12740                            key: 'cols',
12741                            content: renderScrollShim,
12742                        },
12743                    ],
12744                });
12745            }
12746            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].
12746concat(classNames).join(' '), ref: rootElRef },
12747                createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, colGroups: [
12748                        { width: 'shrink', cols: [{ width: 'shrink' }] },
12749                        { cols: [{ span: colCnt, minWidth: dayMinWidth }] },
12750                    ], sections: sections }))); }));
12751        };
12752        /* Dimensions
12753        ------------------------------------------------------------------------------------------------------------------*/
12754        TimeColsView.prototype.getAllDayMaxEventProps = function () {
12755            var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows;
12756            if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto?
12757                dayMaxEvents = undefined;
12758                dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number
12759            }
12760            return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows };
12761        };
12762        return TimeColsView;
12763    }(DateComponent));
12764    function renderAllDayInner(hookProps) {
12765        return hookProps.text;
12766    }
12767
12768    var TimeColsSlatsCoords = /** @class */ (function () {
12769        function TimeColsSlatsCoords(positions, dateProfile, slotDuration) {
12770            this.positions = positions;
12771            this.dateProfile = dateProfile;
12772            this.slotDuration = slotDuration;
12773        }
12774        TimeColsSlatsCoords.prototype.safeComputeTop = function (date) {
12775            var dateProfile = this.dateProfile;
12776            if (rangeContainsMarker(dateProfile.currentRange, date)) {
12777                var startOfDayDate = startOfDay(date);
12778                var timeMs = date.valueOf() - startOfDayDate.valueOf();
12779                if (timeMs >= asRoughMs(dateProfile.slotMinTime) &&
12780                    timeMs < asRoughMs(dateProfile.slotMaxTime)) {
12781                    return this.computeTimeTop(createDuration(timeMs));
12782                }
12783            }
12784            return null;
12785        };
12786        // Computes the top coordinate, relative to the bounds of the grid, of the given date.
12787        // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
12788        TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) {
12789            if (!startOfDayDate) {
12790                startOfDayDate = startOfDay(when);
12791            }
12792            return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf()));
12793        };
12794        // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
12795        // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform.
12796        // Eventually allow computation with arbirary slat dates.
12797        TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) {
12798            var _a = this, positions = _a.positions, dateProfile = _a.dateProfile;
12799            var len = positions.els.length;
12800            // floating-point value of # of slots covered
12801            var slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration);
12802            var slatIndex;
12803            var slatRemainder;
12804            // compute a floating-point number for how many slats should be progressed through.
12805            // from 0 to number of slats (inclusive)
12806            // constrained because slotMinTime/slotMaxTime might be customized.
12807            slatCoverage = Math.max(0, slatCoverage);
12808            slatCoverage = Math.min(len, slatCoverage);
12809            // an integer index of the furthest whole slat
12810            // from 0 to number slats (*exclusive*, so len-1)
12811            slatIndex = Math.floor(slatCoverage);
12812            slatIndex = Math.min(slatIndex, len - 1);
12813            // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
12814            // could be 1.0 if slatCoverage is covering *all* the slots
12815            slatRemainder = slatCoverage - slatIndex;
12816            return positions.tops[slatIndex] +
12817                positions.getHeight(slatIndex) * slatRemainder;
12818        };
12819        return TimeColsSlatsCoords;
12820    }());
12821
12822    var TimeColsSlatsBody = /** @class */ (function (_super) {
12823        __extends(TimeColsSlatsBody, _super);
12824        function TimeColsSlatsBody() {
12825            return _super !== null && _super.apply(this, arguments) || this;
12826        }
12827        TimeColsSlatsBody.prototype.render = function () {
12828            var _a = this, props = _a.props, context = _a.context;
12829            var options = context.options;
12830            var slatElRefs = props.slatElRefs;
12831            return (createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) {
12832                var hookProps = {
12833                    time: slatMeta.time,
12834                    date: context.dateEnv.toDate(slatMeta.date),
12835                    view: context.viewApi,
12836                };
12837                var classNames = [
12838                    'fc-timegrid-slot',
12839                    'fc-timegrid-slot-lane',
12840                    slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor',
12841                ];
12842                return (createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) },
12843                    props.axis && (createElement(TimeColsAxisCell, __assign({}, slatMeta))),
12844                    createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLaneClassNames, content: options.slotLaneContent, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.c
12844oncat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); })));
12845            })));
12846        };
12847        return TimeColsSlatsBody;
12848    }(BaseComponent));
12849
12850    /*
12851    for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
12852    */
12853    var TimeColsSlats = /** @class */ (function (_super) {
12854        __extends(TimeColsSlats, _super);
12855        function TimeColsSlats() {
12856            var _this = _super !== null && _super.apply(this, arguments) || this;
12857            _this.rootElRef = createRef();
12858            _this.slatElRefs = new RefMap();
12859            return _this;
12860        }
12861        TimeColsSlats.prototype.render = function () {
12862            var _a = this, props = _a.props, context = _a.context;
12863            return (createElement("div", { className: "fc-timegrid-slots", ref: this.rootElRef },
12864                createElement("table", { className: context.theme.getClass('table'), style: {
12865                        minWidth: props.tableMinWidth,
12866                        width: props.clientWidth,
12867                        height: props.minHeight,
12868                    } },
12869                    props.tableColGroupNode /* relies on there only being a single <col> for the axis */,
12870                    createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas }))));
12871        };
12872        TimeColsSlats.prototype.componentDidMount = function () {
12873            this.updateSizing();
12874        };
12875        TimeColsSlats.prototype.componentDidUpdate = function () {
12876            this.updateSizing();
12877        };
12878        TimeColsSlats.prototype.componentWillUnmount = function () {
12879            if (this.props.onCoords) {
12880                this.props.onCoords(null);
12881            }
12882        };
12883        TimeColsSlats.prototype.updateSizing = function () {
12884            var _a = this, context = _a.context, props = _a.props;
12885            if (props.onCoords &&
12886                props.clientWidth !== null // means sizing has stabilized
12887            ) {
12888                var rootEl = this.rootElRef.current;
12889                if (rootEl.offsetHeight) { // not hidden by css
12890                    props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration));
12891                }
12892            }
12893        };
12894        return TimeColsSlats;
12895    }(BaseComponent));
12896    function collectSlatEls(elMap, slatMetas) {
12897        return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; });
12898    }
12899
12900    function splitSegsByCol(segs, colCnt) {
12901        var segsByCol = [];
12902        var i;
12903        for (i = 0; i < colCnt; i += 1) {
12904            segsByCol.push([]);
12905        }
12906        if (segs) {
12907            for (i = 0; i < segs.length; i += 1) {
12908                segsByCol[segs[i].col].push(segs[i]);
12909            }
12910        }
12911        return segsByCol;
12912    }
12913    function splitInteractionByCol(ui, colCnt) {
12914        var byRow = [];
12915        if (!ui) {
12916            for (var i = 0; i < colCnt; i += 1) {
12917                byRow[i] = null;
12918            }
12919        }
12920        else {
12921            for (var i = 0; i < colCnt; i += 1) {
12922                byRow[i] = {
12923                    affectedInstances: ui.affectedInstances,
12924                    isEvent: ui.isEvent,
12925                    segs: [],
12926                };
12927            }
12928            for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) {
12929                var seg = _a[_i];
12930                byRow[seg.col].segs.push(seg);
12931            }
12932        }
12933        return byRow;
12934    }
12935
12936    // UNFORTUNATELY, assigns results to the top/bottom/level/forwardCoord/backwardCoord props of the actual segs.
12937    // TODO: return hash (by instanceId) of results
12938    function computeSegCoords(segs, dayDate, slatCoords, eventMinHeight, eventOrderSpecs) {
12939        computeSegVerticals(segs, dayDate, slatCoords, eventMinHeight);
12940        return computeSegHorizontals(segs, eventOrderSpecs); // requires top/bottom from computeSegVerticals
12941    }
12942    // For each segment in an array, computes and assigns its top and bottom properties
12943    function computeSegVerticals(segs, dayDate, slatCoords, eventMinHeight) {
12944        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
12945            var seg = segs_1[_i];
12946            seg.top = slatCoords.computeDateTop(seg.start, dayDate);
12947            seg.bottom = Math.max(seg.top + (eventMinHeight || 0
12947), // yuck
12948            slatCoords.computeDateTop(seg.end, dayDate));
12949        }
12950    }
12951    // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
12952    // Assumed the segs are already ordered.
12953    // NOTE: Also reorders the given array by date!
12954    function computeSegHorizontals(segs, eventOrderSpecs) {
12955        // IMPORTANT TO CLEAR OLD RESULTS :(
12956        for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
12957            var seg = segs_2[_i];
12958            seg.level = null;
12959            seg.forwardCoord = null;
12960            seg.backwardCoord = null;
12961            seg.forwardPressure = null;
12962        }
12963        segs = sortEventSegs(segs, eventOrderSpecs);
12964        var level0;
12965        var levels = buildSlotSegLevels(segs);
12966        computeForwardSlotSegs(levels);
12967        if ((level0 = levels[0])) {
12968            for (var _a = 0, level0_1 = level0; _a < level0_1.length; _a++) {
12969                var seg = level0_1[_a];
12970                computeSlotSegPressures(seg);
12971            }
12972            for (var _b = 0, level0_2 = level0; _b < level0_2.length; _b++) {
12973                var seg = level0_2[_b];
12974                computeSegForwardBack(seg, 0, 0, eventOrderSpecs);
12975            }
12976        }
12977        return segs;
12978    }
12979    // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
12980    // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
12981    function buildSlotSegLevels(segs) {
12982        var levels = [];
12983        var i;
12984        var seg;
12985        var j;
12986        for (i = 0; i < segs.length; i += 1) {
12987            seg = segs[i];
12988            // go through all the levels and stop on the first level where there are no collisions
12989            for (j = 0; j < levels.length; j += 1) {
12990                if (!computeSlotSegCollisions(seg, levels[j]).length) {
12991                    break;
12992                }
12993            }
12994            seg.level = j;
12995            (levels[j] || (levels[j] = [])).push(seg);
12996        }
12997        return levels;
12998    }
12999    // Find all the segments in `otherSegs` that vertically collide with `seg`.
13000    // Append into an optionally-supplied `results` array and return.
13001    function computeSlotSegCollisions(seg, otherSegs, results) {
13002        if (results === void 0) { results = []; }
13003        for (var i = 0; i < otherSegs.length; i += 1) {
13004            if (isSlotSegCollision(seg, otherSegs[i])) {
13005                results.push(otherSegs[i]);
13006            }
13007        }
13008        return results;
13009    }
13010    // Do these segments occupy the same vertical space?
13011    function isSlotSegCollision(seg1, seg2) {
13012        return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
13013    }
13014    // For every segment, figure out the other segments that are in subsequent
13015    // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
13016    function computeForwardSlotSegs(levels) {
13017        var i;
13018        var level;
13019        var j;
13020        var seg;
13021        var k;
13022        for (i = 0; i < levels.length; i += 1) {
13023            level = levels[i];
13024            for (j = 0; j < level.length; j += 1) {
13025                seg = level[j];
13026                seg.forwardSegs = [];
13027                for (k = i + 1; k < levels.length; k += 1) {
13028                    computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
13029                }
13030            }
13031        }
13032    }
13033    // Figure out which path forward (via seg.forwardSegs) results in the longest path until
13034    // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
13035    function computeSlotSegPressures(seg) {
13036        var forwardSegs = seg.forwardSegs;
13037        var forwardPressure = 0;
13038        var i;
13039        var forwardSeg;
13040        if (seg.forwardPressure == null) { // not already computed
13041            for (i = 0; i < forwardSegs.length; i += 1) {
13042                forwardSeg = forwardSegs[i];
13043                // figure out the child's maximum forward path
13044                computeSlotSegPressures(forwardSeg);
13045                // either use the existing maximum, or use the child's forward pressure
13046                // plus one (for the forwardSeg itself)
13047                forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
13048            }
13049            seg.forwardPressure = forwardPressure;
13050        }
13051    }
13052    // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
13053    // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
13054    // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
13055    //
13056    // The segment might be part of a "series", which means consecutive segments with the same pressure
13057    // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
13058    // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
13059    // coordinate of the first segment in the series.
13060    function computeSegForwardBack(seg, seriesBackwardPressure, seriesBackwardCoord, eventOrderSpecs) {
13061        var forwardSegs = seg.forwardSegs;
13062        var i;
13063        if (seg.forwardCoord == null) { // not already computed
13064            if (!forwardSegs.length) {
13065                // if there are no forward segments, this segment should butt up against the edge
13066                seg.forwardCoord = 1;
13067            }
13068            else {
13069                // sort highest pressure first
13070                sortForwardSegs(forwardSegs, eventOrderSpecs);
13071                // this segment's forwardCoord will be calculated from the backwardCoord of the
13072                // highest-pressure forward segment.
13073                computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord, eventOrderSpecs);
13074                seg.forwardCoord = forwardSegs[0].backwardCoord;
13075            }
13076            // calculate the backwardCoord from the forwardCoord. consider the series
13077            seg.backwardCoord = seg.forwardCoord -
13078                (seg.forwardCoord - seriesBackwardCoord) / // available width for series
13079                    (seriesBackwardPressure + 1); // # of segments in the series
13080            // use this segment's coordinates to computed the coordinates of the less-pressurized
13081            // forward segments
13082            for (i = 0; i < forwardSegs.length; i += 1) {
13083                computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord, eventOrderSpecs);
13084            }
13085        }
13086    }
13087    function sortForwardSegs(forwardSegs, eventOrderSpecs) {
13088        var objs = forwardSegs.map(buildTimeGridSegCompareObj);
13089        var specs = [
13090            // put higher-pressure first
13091            { field: 'forwardPressure', order: -1 },
13092            // put segments that are closer to initial edge first (and favor ones with no coords yet)
13093            { field: 'backwardCoord', order: 1 },
13094        ].concat(eventOrderSpecs);
13095        objs.sort(function (obj0, obj1) { return compareByFieldSpecs(obj0, obj1, specs); });
13096        return objs.map(function (c) { return c._seg; });
13097    }
13098    function buildTimeGridSegCompareObj(seg) {
13099        var obj = buildSegCompareObj(seg);
13100        obj.forwardPressure = seg.forwardPressure;
13101        obj.backwardCoord = seg.backwardCoord;
13102        return obj;
13103    }
13104
13105    var DEFAULT_TIME_FORMAT = createFormatter({
13106        hour: 'numeric',
13107        minute: '2-digit',
13108        meridiem: false,
13109    });
13110    var TimeColEvent = /** @class */ (function (_super) {
13111        __extends(TimeColEvent, _super);
13112        function TimeColEvent() {
13113            return _super !== null && _super.apply(this, arguments) || this;
13114        }
13115        TimeColEvent.prototype.render = function () {
13116            var classNames = [
13117                'fc-timegrid-event',
13118                'fc-v-event',
13119            ];
13120            if (this.props.isCondensed) {
13121                classNames.push('fc-timegrid-event-condensed');
13122            }
13123            return (createElement(StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT, extraClassNames: classNames })));
13124        };
13125        return TimeColEvent;
13126    }(BaseComponent));
13127
13128    var TimeColMisc = /** @class */ (function (_super) {
13129        __extends(TimeColMisc, _super);
13130        function TimeColMisc() {
13131            return _super !== null && _super.apply(this, arguments) || this;
13132        }
13133        TimeColMisc.prototype.render = function () {
13134            var props = this.props;
13135            return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent &&
13136                createElement("div", { className: "fc-timegrid-col-misc", ref: innerElRef }, innerContent)); }));
13137        };
13138        return TimeColMisc;
13139    }(BaseComponent));
13140
13141    config.timeGridEventCondensedHeight = 30;
13142    var TimeCol = /** @class */ (function (_super) {
13143        __extends(TimeCol, _super);
13144        function TimeCol() {
13145            return _super !== null && _super.apply(this, arguments) || this;
13146        }
13147        TimeCol.prototype.render = function () {
13148            var _this = this;
13149            var _a = this, props = _a.props, context = _a.context;
13150            var isSelectMirror = context.options.selectMirror;
13151            var mirrorSegs = (props.eventDrag && props.eventDrag.segs) ||
13152                (props.eventResize && props.eventResize.segs) ||
13153                (isSelectMirror && props.dateSelectionSegs) ||
13154                [];
13155            var interactionAffectedInstances = // TODO: messy way to compute this
13156             (props.eventDrag && props.eventDrag.affectedInstances) ||
13157                (props.eventResize && props.eventResize.affectedInstances) ||
13158                {};
13159            return (createElement(DayCellRoot, { elRef: props.elRef, date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (rootElRef, classNames, dataAttrs) { return (createElement("td", __assign({ ref: rootElRef, className: ['fc-timegrid-col'].concat(classNames, props.extraClassNames || []).join(' ') }, dataAttrs, props.extraDataAttrs),
13160                createElement("div", { className: "fc-timegrid-col-frame" },
13161                    createElement("div", { className: "fc-timegrid-col-bg" },
13162                        _this.renderFillSegs(props.businessHourSegs, 'non-business'),
13163                        _this.renderFillSegs(props.bgEventSegs, 'bg-event'),
13164                        _this.renderFillSegs(props.dateSelectionSegs, 'highlight')),
13165                    createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(props.fgEventSegs, interactionAffectedInstances)),
13166                    createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))),
13167                    createElement("div", { className: "fc-timegrid-now-indicator-container" }, _this.renderNowIndicator(props.nowIndicatorSegs)),
13168                    createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); }));
13169        };
13170        TimeCol.prototype.renderFgSegs = function (segs, segIsInvisible, isDragging, isResizing, isDateSelecting) {
13171            var props = this.props;
13172            if (props.forPrint) {
13173                return this.renderPrintFgSegs(segs);
13174            }
13175            if (props.slatCoords) {
13176                return this.renderPositionedFgSegs(segs, segIsInvisible, isDragging, isResizing, isDateSelecting);
13177            }
13178            return null;
13179        };
13180        TimeCol.prototype.renderPrintFgSegs = function (segs) {
13181            var _a = this, props = _a.props, context = _a.context;
13182            // not DRY
13183            segs = sortEventSegs(segs, context.options.eventOrder);
13184            return segs.map(function (seg) { return (createElement("div", { className: "fc-timegrid-event-harness", key: seg.eventRange.instance.instanceId },
13185                createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isCondensed: fal
13185se }, getSegMeta(seg, props.todayRange, props.nowDate))))); });
13186        };
13187        TimeCol.prototype.renderPositionedFgSegs = function (segs, segIsInvisible, isDragging, isResizing, isDateSelecting) {
13188            var _this = this;
13189            var _a = this, context = _a.context, props = _a.props;
13190            // assigns TO THE SEGS THEMSELVES
13191            // also, receives resorted array
13192            segs = computeSegCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight, context.options.eventOrder);
13193            return segs.map(function (seg) {
13194                var instanceId = seg.eventRange.instance.instanceId;
13195                var isMirror = isDragging || isResizing || isDateSelecting;
13196                var positionCss = isMirror
13197                    // will span entire column width
13198                    // also, won't assign z-index, which is good, fc-event-mirror will overpower other harnesses
13199                    ? __assign({ left: 0, right: 0 }, _this.computeSegTopBottomCss(seg)) : _this.computeFgSegPositionCss(seg);
13200                return (createElement("div", { className: 'fc-timegrid-event-harness' + (seg.level > 0 ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign({ visibility: segIsInvisible[instanceId] ? 'hidden' : '' }, positionCss) },
13201                    createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === props.eventSelection, isCondensed: (seg.bottom - seg.top) < config.timeGridEventCondensedHeight }, getSegMeta(seg, props.todayRange, props.nowDate)))));
13202            });
13203        };
13204        TimeCol.prototype.renderFillSegs = function (segs, fillType) {
13205            var _this = this;
13206            var _a = this, context = _a.context, props = _a.props;
13207            if (!props.slatCoords) {
13208                return null;
13209            }
13210            // BAD: assigns TO THE SEGS THEMSELVES
13211            computeSegVerticals(segs, props.date, props.slatCoords, context.options.eventMinHeight);
13212            var children = segs.map(function (seg) { return (createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-timegrid-bg-harness", style: _this.computeSegTopBottomCss(seg) }, fillType === 'bg-event' ?
13213                createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, props.todayRange, props.nowDate))) :
13214                renderFill(fillType))); });
13215            return createElement(Fragment, null, children);
13216        };
13217        TimeCol.prototype.renderNowIndicator = function (segs) {
13218            var _a = this.props, slatCoords = _a.slatCoords, date = _a.date;
13219            if (!slatCoords) {
13220                return null;
13221            }
13222            return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date, 
13223                // key doesn't matter. will only ever be one
13224                key: i }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-line'].concat(classNames).join(' '), style: { top: slatCoords.computeDateTop(seg.start, date) } }, innerContent)); })); });
13225        };
13226        TimeCol.prototype.computeFgSegPositionCss = function (seg) {
13227            var _a = this.context, isRtl = _a.isRtl, options = _a.options;
13228            var shouldOverlap = options.slotEventOverlap;
13229            var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
13230            var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
13231            var left; // amount of space from left edge, a fraction of the total width
13232            var right; // amount of space from right edge, a fraction of the total width
13233            if (shouldOverlap) {
13234                // double the width, but don't go beyond the maximum forward coordinate (1.0)
13235                forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
13236            }
13237            if (isRtl) {
13238                left = 1 - forwardCoord;
13239                right = backwardCoord;
13240            }
13241            else {
13242                left = backwardCoord;
13243                right = 1 - forwardCoord;
13244            }
13245            var props = {
13246                zIndex: seg.level + 1,
13247                left: left * 100 + '%',
13248                right: right * 100 + '%',
13249            };
13250            if (shouldOverlap && seg.forwardPressure) {
13251                // add padding to the edge so that forward stacked events don't cover the resizer's icon
13252                props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
13253            }
13254            return __assign(__assign({}
13254, props), this.computeSegTopBottomCss(seg));
13255        };
13256        TimeCol.prototype.computeSegTopBottomCss = function (seg) {
13257            return {
13258                top: seg.top,
13259                bottom: -seg.bottom,
13260            };
13261        };
13262        return TimeCol;
13263    }(BaseComponent));
13264
13265    var TimeColsContent = /** @class */ (function (_super) {
13266        __extends(TimeColsContent, _super);
13267        function TimeColsContent() {
13268            var _this = _super !== null && _super.apply(this, arguments) || this;
13269            _this.splitFgEventSegs = memoize(splitSegsByCol);
13270            _this.splitBgEventSegs = memoize(splitSegsByCol);
13271            _this.splitBusinessHourSegs = memoize(splitSegsByCol);
13272            _this.splitNowIndicatorSegs = memoize(splitSegsByCol);
13273            _this.splitDateSelectionSegs = memoize(splitSegsByCol);
13274            _this.splitEventDrag = memoize(splitInteractionByCol);
13275            _this.splitEventResize = memoize(splitInteractionByCol);
13276            _this.rootElRef = createRef();
13277            _this.cellElRefs = new RefMap();
13278            return _this;
13279        }
13280        TimeColsContent.prototype.render = function () {
13281            var _this = this;
13282            var _a = this, props = _a.props, context = _a.context;
13283            var nowIndicatorTop = context.options.nowIndicator &&
13284                props.slatCoords &&
13285                props.slatCoords.safeComputeTop(props.nowDate); // might return void
13286            var colCnt = props.cells.length;
13287            var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt);
13288            var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt);
13289            var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt);
13290            var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt);
13291            var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt);
13292            var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt);
13293            var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt);
13294            return (createElement("div", { className: "fc-timegrid-cols", ref: this.rootElRef },
13295                createElement("table", { style: {
13296                        minWidth: props.tableMinWidth,
13297                        width: props.clientWidth,
13298                    } },
13299                    props.tableColGroupNode,
13300                    createElement("tbody", null,
13301                        createElement("tr", null,
13302                            props.axis && (createElement("td", { className: "fc-timegrid-col fc-timegrid-axis" },
13303                                createElement("div", { className: "fc-timegrid-col-frame" },
13304                                    createElement("div", { className: "fc-timegrid-now-indicator-container" }, typeof nowIndicatorTop === 'number' && (createElement(NowIndicatorRoot, { isAxis: true, date: props.nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); })))))),
13305                            props.cells.map(function (cell, i) { return (createElement(TimeCol, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, fgEventSegs: fgEventSegsByRow[i], bgEventSegs: bgEventSegsByRow[i], businessHourSegs: businessHourSegsByRow[i], nowIndicatorSegs: nowIndicatorSegsByRow[i], dateSelectionSegs: dateSelectionSegsByRow[i], eventDrag: eventDragByRow[i], eventResize: eventResizeByRow[i], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint })); }))))));
13306        };
13307        TimeColsContent.prototype.componentDidMount = function () {
13308            this.updateCoords();
13309        };
13310        TimeColsContent.prototype.componentDidUpdate = function () {
13311            this.updateCoords();
13312        };
13313        TimeColsContent.prototype.updateCoords = function () {
13314            var props = this.props;
13315            if (props.onColCoords &&
13316                props.clientWidth !== null // means sizing has stabilized
13317            ) {
13318                props.onColCoords(new PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal
13319                false));
13320            }
13321        };
13322        return TimeColsContent;
13323    }(BaseComponent));
13324    function collectCellEls(elMap, cells) {
13325        return cells.map(function (cell) { return elMap[cell.key]; });
13326    }
13327
13328    /* A component that renders one or more columns of vertical time slots
13329    ----------------------------------------------------------------------------------------------------------------------*/
13330    var TimeCols = /** @class */ (function (_super) {
13331        __extends(TimeCols, _super);
13332        function TimeCols() {
13333            var _this = _super !== null && _super.apply(this, arguments) || this;
13334            _this.processSlotOptions = memoize(processSlotOptions);
13335            _this.state = {
13336                slatCoords: null,
13337            };
13338            _this.handleScrollRequest = function (request) {
13339                var onScrollTopRequest = _this.props.onScrollTopRequest;
13340                var slatCoords = _this.state.slatCoords;
13341                if (onScrollTopRequest && slatCoords) {
13342                    if (request.time) {
13343                        var top_1 = slatCoords.computeTimeTop(request.time);
13344                        top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further
13345                        if (top_1) {
13346                            top_1 += 1; // to overcome top border that slots beyond the first have. looks better
13347                        }
13348                        onScrollTopRequest(top_1);
13349                    }
13350                    return true;
13351                }
13352                return false;
13353            };
13354            _this.handleColCoords = function (colCoords) {
13355                _this.colCoords = colCoords;
13356            };
13357            _this.handleSlatCoords = function (slatCoords) {
13358                _this.setState({ slatCoords: slatCoords });
13359                if (_this.props.onSlatCoords) {
13360                    _this.props.onSlatCoords(slatCoords);
13361                }
13362            };
13363            return _this;
13364        }
13365        TimeCols.prototype.render = function () {
13366            var _a = this, props = _a.props, state = _a.state;
13367            return (createElement("div", { className: "fc-timegrid-body", ref: props.rootElRef, style: {
13368                    // these props are important to give this wrapper correct dimensions for interactions
13369                    // TODO: if we set it here, can we avoid giving to inner tables?
13370                    width: props.clientWidth,
13371                    minWidth: props.tableMinWidth,
13372                } },
13373                createElement(TimeColsSlats, { axis: props.axis, dateProfile: props.dateProfile, slatMetas: props.slatMetas, clientWidth: props.clientWidth, minHeight: props.expandRows ? props.clientHeight : '', tableMinWidth: props.tableMinWidth, tableColGroupNode: props.axis ? props.tableColGroupNode : null /* axis depends on the colgroup's shrinking */, onCoords: this.handleSlatCoords }),
13374                createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bg
13374EventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange, nowDate: props.nowDate, nowIndicatorSegs: props.nowIndicatorSegs, clientWidth: props.clientWidth, tableMinWidth: props.tableMinWidth, tableColGroupNode: props.tableColGroupNode, slatCoords: state.slatCoords, onColCoords: this.handleColCoords, forPrint: props.forPrint })));
13375        };
13376        TimeCols.prototype.componentDidMount = function () {
13377            this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest);
13378        };
13379        TimeCols.prototype.componentDidUpdate = function (prevProps) {
13380            this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile);
13381        };
13382        TimeCols.prototype.componentWillUnmount = function () {
13383            this.scrollResponder.detach();
13384        };
13385        TimeCols.prototype.positionToHit = function (positionLeft, positionTop) {
13386            var _a = this.context, dateEnv = _a.dateEnv, options = _a.options;
13387            var colCoords = this.colCoords;
13388            var dateProfile = this.props.dateProfile;
13389            var slatCoords = this.state.slatCoords;
13390            var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot;
13391            var colIndex = colCoords.leftToIndex(positionLeft);
13392            var slatIndex = slatCoords.positions.topToIndex(positionTop);
13393            if (colIndex != null && slatIndex != null) {
13394                var slatTop = slatCoords.positions.tops[slatIndex];
13395                var slatHeight = slatCoords.positions.getHeight(slatIndex);
13396                var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
13397                var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
13398                var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
13399                var dayDate = this.props.cells[colIndex].date;
13400                var time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex));
13401                var start = dateEnv.add(dayDate, time);
13402                var end = dateEnv.add(start, snapDuration);
13403                return {
13404                    col: colIndex,
13405                    dateSpan: {
13406                        range: { start: start, end: end },
13407                        allDay: false,
13408                    },
13409                    dayEl: colCoords.els[colIndex],
13410                    relativeRect: {
13411                        left: colCoords.lefts[colIndex],
13412                        right: colCoords.rights[colIndex],
13413                        top: slatTop,
13414                        bottom: slatTop + slatHeight,
13415                    },
13416                };
13417            }
13418            return null;
13419        };
13420        return TimeCols;
13421    }(BaseComponent));
13422    function processSlotOptions(slotDuration, snapDurationOverride) {
13423        var snapDuration = snapDurationOverride || slotDuration;
13424        var snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration);
13425        if (snapsPerSlot === null) {
13426            snapDuration = slotDuration;
13427            snapsPerSlot = 1;
13428            // TODO: say warning?
13429        }
13430        return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot };
13431    }
13432
13433    var DayTimeColsSlicer = /** @class */ (function (_super) {
13434        __extends(DayTimeColsSlicer, _super);
13435        function DayTimeColsSlicer() {
13436            return _super !== null && _super.apply(this, arguments) || this;
13437        }
13438        DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) {
13439            var segs = [];
13440            for (var col = 0; col < dayRanges.length; col += 1) {
13441                var segRange = intersectRanges(range, dayRanges[col]);
13442                if (segRange) {
13443                    segs.push({
13444                        start: segRange.start,
13445                        end: segRange.end,
13446                        isStart: segRange.start.valueOf() === range.start.valueOf(),
13447                        isEnd: segRange.end.valueOf() === range.end.valueOf(),
13448                        col: col,
13449                    });
13450                }
13451            }
13452            return segs;
13453        };
13454        return DayTimeColsSlicer;
13455    }(Slicer));
13456
13457    var DayTimeCols = /** @class */ (function (_super) {
13458        __extends(DayTimeCols, _super);
13459        function DayTimeCols() {
13460            var _this = _super !== null && _super.apply(this, arguments) || this;
13461            _this.buildDayRanges = memoize(buildDayRanges);
13462            _this.slicer = new DayTimeColsSlicer();
13463            _this.timeColsRef = createRef();
13464            _this.handleRootEl = function (rootEl) {
13465                if (rootEl) {
13466                    _this.context.registerInteractiveComponent(_this, { el: rootEl });
13467                }
13468                else {
13469                    _this.context.unregisterInteractiveComponent(_this);
13470                }
13471            };
13472            return _this;
13473        }
13474        DayTimeCols.prototype.render = function () {
13475            var _this = this;
13476            var _a = this, props = _a.props, context = _a.context;
13477            var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel;
13478            var isNowIndicator = context.options.nowIndicator;
13479            var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv);
13480            // give it the first row of cells
13481            // TODO: would move this further down hierarchy, but sliceNowDate needs it
13482            return (createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' }, function (nowDate, todayRange) { return (createElement(TimeCols, __assign({ ref: _this.timeColsRef, rootElRef: _this.handleRootEl }, _this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile: dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate: n
13482owDate, nowIndicatorSegs: isNowIndicator && _this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); }));
13483        };
13484        DayTimeCols.prototype.queryHit = function (positionLeft, positionTop) {
13485            var rawHit = this.timeColsRef.current.positionToHit(positionLeft, positionTop);
13486            if (rawHit) {
13487                return {
13488                    component: this,
13489                    dateSpan: rawHit.dateSpan,
13490                    dayEl: rawHit.dayEl,
13491                    rect: {
13492                        left: rawHit.relativeRect.left,
13493                        right: rawHit.relativeRect.right,
13494                        top: rawHit.relativeRect.top,
13495                        bottom: rawHit.relativeRect.bottom,
13496                    },
13497                    layer: 0,
13498                };
13499            }
13500            return null;
13501        };
13502        return DayTimeCols;
13503    }(DateComponent));
13504    function buildDayRanges(dayTableModel, dateProfile, dateEnv) {
13505        var ranges = [];
13506        for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) {
13507            var date = _a[_i];
13508            ranges.push({
13509                start: dateEnv.add(date, dateProfile.slotMinTime),
13510                end: dateEnv.add(date, dateProfile.slotMaxTime),
13511            });
13512        }
13513        return ranges;
13514    }
13515
13516    // potential nice values for the slot-duration and interval-duration
13517    // from largest to smallest
13518    var STOCK_SUB_DURATIONS = [
13519        { hours: 1 },
13520        { minutes: 30 },
13521        { minutes: 15 },
13522        { seconds: 30 },
13523        { seconds: 15 },
13524    ];
13525    function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) {
13526        var dayStart = new Date(0);
13527        var slatTime = slotMinTime;
13528        var slatIterator = createDuration(0);
13529        var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration);
13530        var metas = [];
13531        while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) {
13532            var date = dateEnv.add(dayStart, slatTime);
13533            var isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null;
13534            metas.push({
13535                date: date,
13536                time: slatTime,
13537                key: date.toISOString(),
13538                isoTimeStr: formatIsoTimeString(date),
13539                isLabeled: isLabeled,
13540            });
13541            slatTime = addDurations(slatTime, slotDuration);
13542            slatIterator = addDurations(slatIterator, slotDuration);
13543        }
13544        return metas;
13545    }
13546    // Computes an automatic value for slotLabelInterval
13547    function computeLabelInterval(slotDuration) {
13548        var i;
13549        var labelInterval;
13550        var slotsPerLabel;
13551        // find the smallest stock label interval that results in more than one slots-per-label
13552        for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) {
13553            labelInterval = createDuration(STOCK_SUB_DURATIONS[i]);
13554            slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);
13555            if (slotsPerLabel !== null && slotsPerLabel > 1) {
13556                return labelInterval;
13557            }
13558        }
13559        return slotDuration; // fall back
13560    }
13561
13562    var DayTimeColsView = /** @class */ (function (_super) {
13563        __extends(DayTimeColsView, _super);
13564        function DayTimeColsView() {
13565            var _this = _super !== null && _super.apply(this, arguments) || this;
13566            _this.buildTimeColsModel = memoize(buildTimeColsModel);
13567            _this.buildSlatMetas = memoize(buildSlatMetas);
13568            return _this;
13569        }
13570        DayTimeColsView.prototype.render = function () {
13571            var _this = this;
13572            var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator;
13573            var props = this.props;
13574            var dateProfile = props.dateProfile;
13575            var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator);
13576            var splitProps = this.allDaySplitter.splitProps(props);
13577            var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv);
13578            var dayMinWidth = options.dayMinWidth;
13579            var hasAttachedAxis = !dayMinWidth;
13580            var hasDetachedAxis = dayMinWidth;
13581            var headerContent = options.dayHeaders && (createElement(DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null }));
13582            var allDayContent = (options.allDaySlot !== false) && (function (contentArg) { return (createElement(DayTable, __assign({}, splitProps.allDay, { dateProfile: dateProfile, dayTableModel: dayTableModel, nextDayThreshold: options.nextDayThreshold, tableMinWidth: contentArg.tableMinWidth, colGroupNode: contentArg.tableColGroupNode, renderRowIntro: hasAttachedAxis ? _this.renderTableRowAxis : null, showWeekNumbers: false, expandRows: false, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }, _this.getAllDayMaxEventProps()))); });
13583            var timeGridContent = function (contentArg) { return (createElement(DayTimeCols, __assign({}, splitProps.timed, { dayTableModel: dayTableModel, dateProfile: dateProfile, axis: hasAttachedAxis, slotDuration: options.slotDuration, slatMetas: slatMetas, forPrint: props.forPrint, tableColGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, onSlatCoords: _this.handleSlatCoords, expandRows: contentArg.expandRows, onScrollTopRequest: _this.handleScrollTopRequest }))); };
13584            return hasDetachedAxis
13585                ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords)
13586                : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent);
13587        };
13588        return DayTimeColsView;
13589    }(TimeColsView));
13590    function buildTimeColsModel(dateProfile, dateProfileGenerator) {
13591        var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator);
13592        return new DayTableModel(daySeries, false);
13593    }
13594
13595    var OPTION_REFINERS$2 = {
13596        allDaySlot: Boolean,
13597    };
13598
13599    var timeGridPlugin = createPlugin({
13600        initialView: 'timeGridWeek',
13601        optionRefiners: OPTION_REFINERS$2,
13602        views: {
13603            timeGrid: {
13604                component: DayTimeColsView,
13605                usesMinMaxTime: true,
13606                allDaySlot: true,
13607                slotDuration: '00:30:00',
13608                slotEventOverlap: true,
13609            },
13610            timeGridDay: {
13611                type: 'timeGrid',
13612                duration: { days: 1 },
13613            },
13614            timeGridWeek: {
13615                type: 'timeGrid',
13616                duration: { weeks: 1 },
13617            },
13618        },
13619    });
13620
13621    var ListViewHeaderRow = /** @class */ (function (_super) {
13622        __extends(ListViewHeaderRow, _super);
13623        function ListViewHeaderRow() {
13624            return _super !== null && _super.apply(this, arguments) || this;
13625        }
13626        ListViewHeaderRow.prototype.render = function () {
13627            var _a = this.props, dayDate = _a.dayDate, todayRange = _a.todayRange;
13628            var _b = this.context, theme = _b.theme, dateEnv = _b.dateEnv, options = _b.options, viewApi = _b.viewApi;
13629            var dayMeta = getDateMeta(dayDate, todayRange);
13630            // will ever be falsy?
13631            var text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : '';
13632            // will ever be falsy? also, BAD NAME "alt"
13633            var sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : '';
13634            var navLinkData = options.navLinks
13635                ? buildNavLinkData(dayDate)
13636                : null;
13637            var hookProps = __assign({ date: dateEnv.toDate(dayDate), view: viewApi, text: text,
13638                sideText: sideText,
13639                navLinkData: navLinkData }, dayMeta);
13640            var classNames = ['fc-list-day'].concat(getDayClassNames(dayMeta, theme));
13641            // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too)
13642            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInnerContent$4, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("tr", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-date": formatDayString(dayDate) },
13643                createElement("th", { colSpan: 3 },
13644                    createElement("div", { className: 'fc-list-day-cushion ' + theme.getClass('tableCellShaded'), ref: innerElRef }, innerContent)))); }));
13645        };
13646        return ListViewHeaderRow;
13647    }(BaseComponent));
13648    function renderInnerContent$4(props) {
13649        var navLinkAttrs = props.navLinkData // is there a type for this?
13650            ? { 'data-navlink': props.navLinkData, tabIndex: 0 }
13651            : {};
13652        return (createElement(Fragment, null,
13653            props.text && (createElement("a", __assign({ className: "fc-list-day-text" }, navLinkAttrs), props.text)),
13654            props.sideText && (createElement("a", __assign({ className: "fc-list-day-side-text" }, navLinkAttrs), props.sideText))));
13655    }
13656
13657    var DEFAULT_TIME_FORMAT$1 = createFormatter({
13658        hour: 'numeric',
13659        minute: '2-digit',
13660        meridiem: 'short',
13661    });
13662    var ListViewEventRow = /** @class */ (function (_super) {
13663        __extends(ListViewEventRow, _super);
13664        function ListViewEventRow() {
13665            return _super !== null && _super.apply(this, arguments) || this;
13666        }
13667        ListViewEventRow.prototype.render = function () {
13668            var _a = this, props = _a.props, context = _a.context;
13669            var seg = props.seg;
13670            var timeFormat = context.options.eventTimeFormat || DEFAULT_TIME_FORMAT$1;
13671            return (createElement(EventRoot, { seg: seg, timeText: "" // BAD. because of all-day content
13672                , disableDragging: true, disableResizing: true, defaultContent: renderEventInnerContent, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday, isSelected: props.isSelected, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("tr", { className: ['fc-list-event', hookProps.event.url ? 'fc-event-forced-url' : ''].concat(classNames).join(' '), ref: rootElRef },
13673                buildTimeContent(seg, timeFormat, context),
13674                createElement("td", { className: "fc-list-event-graphic" },
13675                    createElement("span", { className: "fc-list-event-dot", style: { borderColor: hookProps.borderColor || hookProps.backgroundColor } })),
13676                createElement("td", { className: "fc-list-event-title", ref: innerElRef }, innerContent))); }));
13677        };
13678        return ListViewEventRow;
13679    }(BaseComponent));
13680    function renderEventInnerContent(props) {
13681        var event = props.event;
13682        var url = event.url;
13683        var anchorAttrs = url ? { href: url } : {};
13684        return (createElement("a", __assign({}, anchorAttrs), event.title));
13685    }
13686    function buildTimeContent(seg, timeFormat, context) {
13687        var options = context.options;
13688        if (options.displayEventTime !== false) {
13689            var eventDef = seg.eventRange.def;
13690            var eventInstance = seg.eventRange.instance;
13691            var doAllDay = false;
13692            var timeText = void 0;
13693            if (eventDef.allDay) {
13694                doAllDay = true;
13695            }
13696            else if (isMultiDayRange(seg.eventRange.range)) { // TODO: use (!isStart || !isEnd) instead?
13697                if (seg.isStart) {
13698                    timeText = buildSegTimeText(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end);
13699                }
13700                else if (seg.isEnd) {
13701                    timeText = buildSegTimeText(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end);
13702                }
13703                else {
13704                    doAllDay = true;
13705                }
13706            }
13707            else {
13708                timeText = buildSegTimeText(seg, timeFormat, context);
13709            }
13710            if (doAllDay) {
13711                var hookProps = {
13712                    text: context.options.allDayText,
13713                    view: context.viewApi,
13714                };
13715                return (createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner$1, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { className: ['fc-list-event-time'].concat(classNames).join(' '), ref: rootElRef }, innerContent)); }));
13716            }
13717            return (createElement("td", { className: "fc-list-event-time" }, timeText));
13718        }
13719        return null;
13720    }
13721    function renderAllDayInner$1(hookProps) {
13722        return hookProps.text;
13723    }
13724
13725    /*
13726    Responsible for the scroller, and forwarding event-related actions into the "grid".
13727    */
13728    var ListView = /** @class */ (function (_super) {
13729        __extends(ListView, _super);
13730        function ListView() {
13731            var _this = _super !== null && _super.apply(this, arguments) || this;
13732            _this.computeDateVars = memoize(computeDateVars);
13733            _this.eventStoreToSegs = memoize(_this._eventStoreToSegs);
13734            _this.setRootEl = function (rootEl) {
13735                if (rootEl) {
13736                    _this.context.registerInteractiveComponent(_this, {
13737                        el: rootEl,
13738                    });
13739                }
13740                else {
13741                    _this.context.unregisterInteractiveComponent(_this);
13742                }
13743            };
13744            return _this;
13745        }
13746        ListView.prototype.render = function () {
13747            var _this = this;
13748            var _a = this, props = _a.props, context = _a.context;
13749            var extraClassNames = [
13750                'fc-list',
13751                context.theme.getClass('table'),
13752                context.options.stickyHeaderDates !== false ? 'fc-list-sticky' : '',
13753            ];
13754            var _b = this.computeDateVars(props.dateProfile), dayDates = _b.dayDates, dayRanges = _b.dayRanges;
13755            var eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);
13756            return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.setRootEl }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: extraClassNames.concat(classNames).join(' ') },
13757                createElement(Scroller, { liquid: !props.isHeightAuto, overflowX: props.isHeightAuto ? 'visible' : 'hidden', overflowY: props.isHeightAuto ? 'visible' : 'auto' }, eventSegs.length > 0 ?
13758                    _this.renderSegList(eventSegs, dayDates) :
13759                    _this.renderEmptyMessage()))); }));
13760        };
13761        ListView.prototype.renderEmptyMessage = function () {
13762            var _a = this.context, options = _a.options, viewApi = _a.viewApi;
13763            var hookProps = {
13764                text: options.noEventsText,
13765                view: viewApi,
13766            };
13767            return (createElement(RenderHook, { hookProps: hookProps, classNames: options.noEventsClassNames, content: options.noEventsContent, defaultContent: renderNoEventsInner, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { className: ['fc-list-empty'].concat(classNames).join(' '), ref: rootElRef },
13768                createElement("div", { className: "fc-list-empty-cushion", ref: innerElRef }, innerContent))); }));
13769        };
13770        ListView.prototype.renderSegList = function (allSegs, dayDates) {
13771            var _a = this.context, theme = _a.theme, options = _a.options;
13772            var segsByDay = groupSegsByDay(allSegs); // sparse array
13773            return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) {
13774                var innerNodes = [];
13775                for (var dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) {
13776                    var daySegs = segsByDay[dayIndex];
13777                    if (daySegs) { // sparse array, so might be undefined
13778                        var dayStr = dayDates[dayIndex].toISOString();
13779                        // append a day header
13780                        innerNodes.push(createElement(ListViewHeaderRow, { key: dayStr, dayDate: dayDates[dayIndex], todayRange: todayRange }));
13781                        daySegs = sortEventSegs(daySegs, options.eventOrder);
13782                        for (var _i = 0, daySegs_1 = daySegs; _i < daySegs_1.length; _i++) {
13783                            var seg = daySegs_1[_i];
13784                            innerNodes.push(createElement(ListViewEventRow, __assign({ key: dayStr + ':' + seg.eventRange.instance.instanceId /* are multiple segs for an instanceId */, seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false }, getSegMeta(seg, todayRange, nowDate))));
13785                        }
13786                    }
13787                }
13788                return (createElement("table", { className: 'fc-list-table ' + theme.getClass('table') },
13789                    createElement("tbody", null, innerNodes)));
13790            }));
13791        };
13792        ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) {
13793            return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);
13794        };
13795        ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) {
13796            var segs = [];
13797            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
13798                var eventRange = eventRanges_1[_i];
13799                segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges));
13800            }
13801            return segs;
13802        };
13803        ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) {
13804            var dateEnv = this.context.dateEnv;
13805            var nextDayThreshold = this.context.options.nextDayThreshold;
13806            var range = eventRange.range;
13807            var allDay = eventRange.def.allDay;
13808            var dayIndex;
13809            var segRange;
13810            var seg;
13811            var segs = [];
13812            for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) {
13813                segRange = intersectRanges(range, dayRanges[dayIndex]);
13814                if (segRange) {
13815                    seg = {
13816                        component: this,
13817                        eventRange: eventRange,
13818                        start: segRange.start,
13819                        end: segRange.end,
13820                        isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(),
13821                        isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(),
13822                        dayIndex: dayIndex,
13823                    };
13824                    segs.push(seg);
13825                    // detect when range won't go fully into the next day,
13826                    // and mutate the latest seg to the be the end.
13827                    if (!seg.isEnd && !allDay &&
13828                        dayIndex + 1 < dayRanges.length &&
13829                        range.end <
13830                            dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) {
13831                        seg.end = range.end;
13832                        seg.isEnd = true;
13833                        break;
13834                    }
13835                }
13836            }
13837            return segs;
13838        };
13839        return ListView;
13840    }(DateComponent));
13841    function renderNoEventsInner(hookProps) {
13842        return hookProps.text;
13843    }
13844    function computeDateVars(dateProfile) {
13845        var dayStart = startOfDay(dateProfile.renderRange.start);
13846        var viewEnd = dateProfile.renderRange.end;
13847        var dayDates = [];
13848        var dayRanges = [];
13849        while (dayStart < viewEnd) {
13850            dayDates.push(dayStart);
13851            dayRanges.push({
13852                start: dayStart,
13853                end: addDays(dayStart, 1),
13854            });
13855            dayStart = addDays(dayStart, 1);
13856        }
13857        return { dayDates: dayDates, dayRanges: dayRanges };
13858    }
13859    // Returns a sparse array of arrays, segs grouped by their dayIndex
13860    function groupSegsByDay(segs) {
13861        var segsByDay = []; // sparse array
13862        var i;
13863        var seg;
13864        for (i = 0; i < segs.length; i += 1) {
13865            seg = segs[i];
13866            (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
13867                .push(seg);
13868        }
13869        return segsByDay;
13870    }
13871
13872    var OPTION_REFINERS$3 = {
13873        listDayFormat: createFalsableFormatter,
13874        listDaySideFormat: createFalsableFormatter,
13875        noEventsClassNames: identity,
13876        noEventsContent: identity,
13877        noEventsDidMount: identity,
13878        noEventsWillUnmount: identity,
13879    };
13880    function createFalsableFormatter(input) {
13881        return input === false ? null : createFormatter(input);
13882    }
13883
13884    var listPlugin = createPlugin({
13885        optionRefiners: OPTION_REFINERS$3,
13886        views: {
13887            list: {
13888                component: ListView,
13889                buttonTextKey: 'list',
13890                listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' },
13891            },
13892            listDay: {
13893                type: 'list',
13894                duration: { days: 1 },
13895                listDayFormat: { weekday: 'long' },
13896            },
13897            listWeek: {
13898                type: 'list',
13899                duration: { weeks: 1 },
13900                listDayFormat: { weekday: 'long' },
13901                listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' },
13902            },
13903            listMonth: {
13904                type: 'list',
13905                duration: { month: 1 },
13906                listDaySideFormat: { weekday: 'long' },
13907            },
13908            listYear: {
13909                type: 'list',
13910                duration: { year: 1 },
13911                listDaySideFormat: { weekday: 'long' },
13912            },
13913        },
13914    });
13915
13916    var BootstrapTheme = /** @class */ (function (_super) {
13917        __extends(BootstrapTheme, _super);
13918        function BootstrapTheme() {
13919            return _super !== null && _super.apply(this, arguments) || this;
13920        }
13921        return BootstrapTheme;
13922    }(Theme));
13923    BootstrapTheme.prototype.classes = {
13924        root: 'fc-theme-bootstrap',
13925        table: 'table-bordered',
13926        tableCellShaded: 'table-active',
13927        buttonGroup: 'btn-group',
13928        button: 'btn btn-primary',
13929        buttonActive: 'active',
13930        popover: 'popover',
13931        popoverHeader: 'popover-header',
13932        popoverContent: 'popover-body',
13933    };
13934    BootstrapTheme.prototype.baseIconClass = 'fa';
13935    BootstrapTheme.prototype.iconClasses = {
13936        close: 'fa-times',
13937        prev: 'fa-chevron-left',
13938        next: 'fa-chevron-right',
13939        prevYear: 'fa-angle-double-left',
13940        nextYear: 'fa-angle-double-right',
13941    };
13942    BootstrapTheme.prototype.rtlIconClasses = {
13943        prev: 'fa-chevron-right',
13944        next: 'fa-chevron-left',
13945        prevYear: 'fa-angle-double-right',
13946        nextYear: 'fa-angle-double-left',
13947    };
13948    BootstrapTheme.prototype.iconOverrideOption = 'bootstrapFontAwesome';
13948 // TODO: make TS-friendly. move the option-processing into this plugin
13949    BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome';
13950    BootstrapTheme.prototype.iconOverridePrefix = 'fa-';
13951    var plugin = createPlugin({
13952        themeClasses: {
13953            bootstrap: BootstrapTheme,
13954        },
13955    });
13956
13957    // rename this file to options.ts like other packages?
13958    var OPTION_REFINERS$4 = {
13959        googleCalendarApiKey: String,
13960    };
13961
13962    var EVENT_SOURCE_REFINERS$1 = {
13963        googleCalendarApiKey: String,
13964        googleCalendarId: String,
13965        googleCalendarApiBase: String,
13966        extraParams: identity,
13967    };
13968
13969    // TODO: expose somehow
13970    var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';
13971    var eventSourceDef$3 = {
13972        parseMeta: function (refined) {
13973            var googleCalendarId = refined.googleCalendarId;
13974            if (!googleCalendarId && refined.url) {
13975                googleCalendarId = parseGoogleCalendarId(refined.url);
13976            }
13977            if (googleCalendarId) {
13978                return {
13979                    googleCalendarId: googleCalendarId,
13980                    googleCalendarApiKey: refined.googleCalendarApiKey,
13981                    googleCalendarApiBase: refined.googleCalendarApiBase,
13982                    extraParams: refined.extraParams,
13983                };
13984            }
13985            return null;
13986        },
13987        fetch: function (arg, onSuccess, onFailure) {
13988            var _a = arg.context, dateEnv = _a.dateEnv, options = _a.options;
13989            var meta = arg.eventSource.meta;
13990            var apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey;
13991            if (!apiKey) {
13992                onFailure({
13993                    message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/',
13994                });
13995            }
13996            else {
13997                var url = buildUrl(meta);
13998                // TODO: make DRY with json-feed-event-source
13999                var extraParams = meta.extraParams;
14000                var extraParamsObj = typeof extraParams === 'function' ? extraParams() : extraParams;
14001                var requestParams_1 = buildRequestParams$1(arg.range, apiKey, extraParamsObj, dateEnv);
14002                requestJson('GET', url, requestParams_1, function (body, xhr) {
14003                    if (body.error) {
14004                        onFailure({
14005                            message: 'Google Calendar API: ' + body.error.message,
14006                            errors: body.error.errors,
14007                            xhr: xhr,
14008                        });
14009                    }
14010                    else {
14011                        onSuccess({
14012                            rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone),
14013                            xhr: xhr,
14014                        });
14015                    }
14016                }, function (message, xhr) {
14017                    onFailure({ message: message, xhr: xhr });
14018                });
14019            }
14020        },
14021    };
14022    function parseGoogleCalendarId(url) {
14023        var match;
14024        // detect if the ID was specified as a single string.
14025        // will match calendars like "[email protected]" in addition to person email calendars.
14026        if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) {
14027            return url;
14028        }
14029        if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(url)) ||
14030            (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url))) {
14031            return decodeURIComponent(match[1]);
14032        }
14033        return null;
14034    }
14035    function buildUrl(meta) {
14036        var apiBase = meta.googleCalendarApiBase;
14037        if (!apiBase) {
14038            apiBase = API_BASE;
14039        }
14040        return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events';
14041    }
14042    function buildRequestParams$1(range, apiKey, extraParams, dateEnv) {
14043        var params;
14044        var startStr;
14045        var endStr;
14046        if (dateEnv.canComputeOffset) {
14047            // strings will naturally have offsets, which GCal needs
14048            startStr = dateEnv.formatIso(range.start);
14049            endStr = dateEnv.formatIso(range.end);
14050        }
14051        else {
14052            // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day
14053            // from the UTC day-start to guarantee we're getting all the events
14054            // (start/end will be UTC-coerced dates, so toISOString is okay)
14055            startStr = addDays(range.start, -1).toISOString();
14056            endStr = addDays(range.end, 1).toISOString();
14057        }
14058        params = __assign(__assign({}, (extraParams || {})), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 });
14059        if (dateEnv.timeZone !== 'local') {
14060            params.timeZone = dateEnv.timeZone;
14061        }
14062        return params;
14063    }
14064    function gcalItemsToRawEventDefs(items, gcalTimezone) {
14065        return items.map(function (item) { return gcalItemToRawEventDef(item, gcalTimezone); });
14066    }
14067    function gcalItemToRawEventDef(item, gcalTimezone) {
14068        var url = item.htmlLink || null;
14069        // make the URLs for each event show times in the correct timezone
14070        if (url && gcalTimezone) {
14071            url = injectQsComponent(url, 'ctz=' + gcalTimezone);
14072        }
14073        return {
14074            id: item.id,
14075            title: item.summary,
14076            start: item.start.dateTime || item.start.date,
14077            end: item.end.dateTime || item.end.date,
14078            url: url,
14079            location: item.location,
14080            description: item.description,
14081        };
14082    }
14083    // Injects a string like "arg=value" into the querystring of a URL
14084    // TODO: move to a general util file?
14085    function injectQsComponent(url, component) {
14086        // inject it after the querystring but before the fragment
14087        return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { return (qs ? qs + '&' : '?') + component + hash; });
14088    }
14089    var googleCalendarPlugin = createPlugin({
14090        eventSourceDefs: [eventSourceDef$3],
14091        optionRefiners: OPTION_REFINERS$4,
14092        eventSourceRefiners: EVENT_SOURCE_REFINERS$1,
14093    });
14094
14095    globalPlugins.push(interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, plugin, googleCalendarPlugin);
14096
14097    exports.BASE_OPTION_DEFAULTS = BASE_OPTION_DEFAULTS;
14098    exports.BASE_OPTION_REFINERS = BASE_OPTION_REFINERS;
14099    exports.BaseComponent = BaseComponent;
14100    exports.BgEvent = BgEvent;
14101    exports.BootstrapTheme = BootstrapTheme;
14102    exports.Calendar = Calendar;
14103    exports.CalendarApi = CalendarApi;
14104    exports.CalendarContent = CalendarContent;
14105    exports.CalendarDataManager = CalendarDataManager;
14106    exports.CalendarDataProvider = CalendarDataProvider;
14107    exports.CalendarRoot = CalendarRoot;
14108    exports.Component = Component;
14109    exports.ContentHook = ContentHook;
14110    exports.CustomContentRenderContext = CustomContentRenderContext;
14111    exports.DateComponent = DateComponent;
14112    exports.DateEnv = DateEnv;
14113    exports.DateProfileGenerator = DateProfileGenerator;
14114    exports.DayCellContent = DayCellContent;
14115    exports.DayCellRoot = DayCellRoot;
14116    exports.DayGridView = DayTableView;
14117    exports.DayHeader = DayHeader;
14118    exports.DaySeriesModel = DaySeriesModel;
14119    exports.DayTable = DayTable;
14120    exports.DayTableModel = DayTableModel;
14121    exports.DayTableSlicer = DayTableSlicer;
14122    exports.DayTimeCols = DayTimeCols;
14123    exports.DayTimeColsSlicer = DayTimeColsSlicer;
14124    exports.DayTimeColsView = DayTimeColsView;
14125    exports.DelayedRunner = DelayedRunner;
14126    exports.Draggable = ExternalDraggable;
14127    exports.ElementDragging = ElementDragging;
14128    exports.ElementScrollController = ElementScrollController;
14129    exports.Emitter = Emitter;
14130    exports.EventApi = EventApi;
14131    exports.EventRoot = EventRoot;
14132    exports.EventSourceApi = EventSourceApi;
14133    exports.FeaturefulElementDragging = FeaturefulElementDragging;
14134    exports.Fragment = Fragment;
14135    exports.Interaction = Interaction;
14136    exports.ListView = ListView;
14137    exports.MountHook = MountHook;
14138    exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
14139    exports.NowIndicatorRoot = NowIndicatorRoot;
14140    exports.NowTimer = NowTimer;
14141    exports.PointerDragging = PointerDragging;
14142    exports.PositionCache = PositionCache;
14143    exports.RefMap = RefMap;
14144    exports.RenderHook = RenderHook;
14145    exports.ScrollController = ScrollController;
14146    exports.ScrollResponder = ScrollResponder;
14147    exports.Scroller = Scroller;
14148    exports.SimpleScrollGrid = SimpleScrollGrid;
14149    exports.Slicer = Slicer;
14150    exports.Splitter = Splitter;
14151    exports.StandardEvent = StandardEvent;
14152    exports.Table = Table;
14153    exports.TableDateCell = TableDateCell;
14154    exports.TableDowCell = TableDowCell;
14155    exports.TableView = TableView;
14156    exports.Theme = Theme;
14157    exports.ThirdPartyDraggable = ThirdPartyDraggable;
14158    exports.TimeCols = TimeCols;
14159    exports.TimeColsSlatsCoords = TimeColsSlatsCoords;
14160    exports.TimeColsView = TimeColsView;
14161    exports.ViewApi = ViewApi;
14162    exports.ViewContextType = ViewContextType;
14163    exports.ViewRoot = ViewRoot;
14164    exports.WeekNumberRoot = WeekNumberRoot;
14165    exports.WindowScrollController = WindowScrollController;
14166    exports.addDays = addDays;
14167    exports.addDurations = addDurations;
14168    exports.addMs = addMs;
14169    exports.addWeeks = addWeeks;
14170    exports.allowContextMenu = allowContextMenu;
14171    exports.allowSelection = allowSelection;
14172    exports.applyMutationToEventStore = applyMutationToEventStore;
14173    exports.applyStyle = applyStyle;
14174    exports.applyStyleProp = applyStyleProp;
14175    exports.asCleanDays = asCleanDays;
14176    exports.asRoughMinutes = asRoughMinutes;
14177    exports.asRoughMs = asRoughMs;
14178    exports.asRoughSeconds = asRoughSeconds;
14179    exports.buildClassNameNormalizer = buildClassNameNormalizer;
14180    exports.buildDayRanges = buildDayRanges;
14181    exports.buildDayTableModel = buildDayTableModel;
14182    exports.buildEventApis = buildEventApis;
14183    exports.buildEventRangeKey = buildEventRangeKey;
14184    exports.buildHashFromArray = buildHashFromArray;
14185    exports.buildNavLinkData = buildNavLinkData;
14186    exports.buildSegCompareObj = buildSegCompareObj;
14187    exports.buildSegTimeText = buildSegTimeText;
14188    exports.buildSlatMetas = buildSlatMetas;
14189    exports.buildTimeColsModel = buildTimeColsModel;
14190    exports.collectFromHash = collectFromHash;
14191    exports.combineEventUis = combineEventUis;
14192    exports.compareByFieldSpec = compareByFieldSpec;
14193    exports.compareByFieldSpecs = compareByFieldSpecs;
14194    exports.compareNumbers = compareNumbers;
14195    exports.compareObjs = compareObjs;
14196    exports.computeEdges = computeEdges;
14197    exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat;
14198    exports.computeHeightAndMargins = computeHeightAndMargins;
14199    exports.computeInnerRect = computeInnerRect;
14200    exports.computeRect = computeRect;
14201    exports.computeSegDraggable = computeSegDraggable;
14202    exports.computeSegEndResizable = computeSegEndResizable;
14203    exports.computeSegStartResizable = computeSegStartResizable;
14204    exports.computeShrinkWidth = computeShrinkWidth;
14205    exports.computeSmallestCellWidth = computeSmallestCellWidth;
14206    exports.computeVisibleDayRange = computeVisibleDayRange;
14207    exports.config = config;
14208    exports.constrainPoint = constrainPoint;
14209    exports.createContext = createContext$1;
14210    exports.createDuration = createDuration;
14211    exports.createElement = createElement;
14212    exports.createEmptyEventStore = createEmptyEventStore;
14213    exports.createEventInstance = createEventInstance;
14214    exports.createEventUi = createEventUi;
14215    exports.createFormatter = createFormatter;
14216    exports.createPlugin = createPlugin;
14217    exports.createRef = createRef;
14218    exports.diffDates = diffDates;
14219    exports.diffDayAndTime = diffDayAndTime;
14220    exports.diffDays = diffDays;
14221    exports.diffPoints = diffPoints;
14222    exports.diffWeeks = diffWeeks;
14223    exports.diffWholeDays = diffWholeDays;
14224    exports.diffWholeWeeks = diffWholeWeeks;
14225    exports.disableCursor = disableCursor;
14226    exports.elementClosest = elementClosest;
14227    exports.elementMatches = elementMatches;
14228    exports.enableCursor = enableCursor;
14229    exports.eventTupleToStore = eventTupleToStore;
14230    exports.filterEventStoreDefs = filterEventStoreDefs;
14231    exports.filterHash = filterHash;
14232    exports.findDirectChildren = findDirectChildren;
14233    exports.findElements = findElements;
14234    exports.flexibleCompare = flexibleCompare;
14235    exports.flushToDom = flushToDom$1;
14236    exports.formatDate = formatDate;
14237    exports.formatDayString = formatDayString;
14238    exports.formatIsoTimeString = formatIsoTimeString;
14239    exports.formatRange = formatRange;
14240    exports.getAllowYScrolling = getAllowYScrolling;
14241    exports.getCanVGrowWithinCell = getCanVGrowWithinCell;
14242    exports.getClippingParents = getClippingParents;
14243    exports.getDateMeta = getDateMeta;
14244    exports.getDayClassNames = getDayClassNames;
14245    exports.getDefaultEventEnd = getDefaultEventEnd;
14246    exports.getElSeg = getElSeg;
14247    exports.getEventClassNames = getEventClassNames;
14248    exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft;
14249    exports.getRectCenter = getRectCenter;
14250    exports.getRelevantEvents = getRelevantEvents;
14251    exports.getScrollGridClassNames = getScrollGridClassNames;
14252    exports.getScrollbarWidths = getScrollbarWidths;
14253    exports.getSectionClassNames = getSectionClassNames;
14254    exports.getSectionHasLiquidHeight = getSectionHasLiquidHeight;
14255    exports.getSegMeta = getSegMeta;
14256    exports.getSlotClassNames = getSlotClassNames;
14257    exports.getStickyFooterScrollbar = getStickyFooterScrollbar;
14258    exports.getStickyHeaderDates = getStickyHeaderDates;
14259    exports.getUnequalProps = getUnequalProps;
14260    exports.globalLocales = globalLocales;
14261    exports.globalPlugins = globalPlugins;
14262    exports.greatestDurationDenominator = greatestDurationDenominator;
14263    exports.guid = guid;
14264    exports.hasBgRendering = hasBgRendering;
14265    exports.hasShrinkWidth = hasShrinkWidth;
14266    exports.identity = identity;
14267    exports.interactionSettingsStore = interactionSettingsStore;
14268    exports.interactionSettingsToStore = interactionSettingsToStore;
14269    exports.intersectRanges = intersectRanges;
14270    exports.intersectRects = intersectRects;
14271    exports.isArraysEqual = isArraysEqual;
14272    exports.isColPropsEqual = isColPropsEqual;
14273    exports.isDateSpansEqual = isDateSpansEqual;
14274    exports.isInt = isInt;
14275    exports.isInteractionValid = isInteractionValid;
14276    exports.isMultiDayRange = isMultiDayRange;
14277    exports.isPropsEqual = isPropsEqual;
14278    exports.isPropsValid = isPropsValid;
14279    exports.isValidDate = isValidDate;
14280    exports.listenBySelector = listenBySelector;
14281    exports.mapHash = mapHash;
14282    exports.memoize = memoize;
14283    exports.memoizeArraylike = memoizeArraylike;
14284    exports.memoizeHashlike = memoizeHashlike;
14285    exports.memoizeObjArg = memoizeObjArg;
14286    exports.mergeEventStores = mergeEventStores;
14287    exports.multiplyDuration = multiplyDuration;
14288    exports.padStart = padStart;
14289    exports.parseBusinessHours = parseBusinessHours;
14290    exports.parseClassNames = parseClassNames;
14291    exports.parseDragMeta = parseDragMeta;
14292    exports.parseEventDef = parseEventDef;
14293    exports.parseFieldSpecs = parseFieldSpecs;
14294    exports.parseMarker = parse;
14295    exports.pointInsideRect = pointInsideRect;
14296    exports.preventContextMenu = preventContextMenu;
14297    exports.preventDefault = preventDefault;
14298    exports.preventSelection = preventSelection;
14299    exports.rangeContainsMarker = rangeContainsMarker;
14300    exports.rangeContainsRange = rangeContainsRange;
14301    exports.rangesEqual = rangesEqual;
14302    exports.rangesIntersect = rangesIntersect;
14303    exports.refineEventDef = refineEventDef;
14304    exports.refineProps = refineProps;
14305    exports.removeElement = removeElement;
14306    exports.removeExact = removeExact;
14307    exports.render = render;
14308    exports.renderChunkContent = renderChunkContent;
14309    exports.renderFill = renderFill;
14310    exports.renderMicroColGroup = renderMicroColGroup;
14311    exports.renderScrollShim = renderScrollShim;
14312    exports.requestJson = requestJson;
14313    exports.sanitizeShrinkWidth = sanitizeShrinkWidth;
14314    exports.setElSeg = setElSeg;
14315    exports.setRef = setRef;
14316    exports.sliceEventStore = sliceEventStore;
14317    exports.sliceEvents = sliceEvents;
14318    exports.sortEventSegs = sortEventSegs;
14319    exports.startOfDay = startOfDay;
14320    exports.translateRect = translateRect;
14321    exports.triggerDateSelect = triggerDateSelect;
14322    exports.unmountComponentAtNode = unmountComponentAtNode$1;
14323    exports.unpromisify = unpromisify;
14324    exports.version = version;
14325    exports.whenTransitionDone = whenTransitionDone;
14326    exports.wholeDivideDurations = wholeDivideDurations;
14327
14328    Object.defineProperty(exports, '__esModule', { value: true });
14329
14330    return exports;
14331
14332}({}));

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.