PageSourceSearch

https://regensen.dk/js/bundle.min.js?v=1.7

js regensen.dk collected 2026-10-02 22:32:05 UTC 1,443,662 bytes, 39,967 lines download raw bytes

1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2/*!
3FullCalendar Bootstrap Plugin v4.3.0
4Docs & License: https://fullcalendar.io/
5(c) 2019 Adam Shaw
6*/
7
8(function (global, factory) {
9    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
10    typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
11    (global = global || self, factory(global.FullCalendarBootstrap = {}, global.FullCalendar));
12}(this, function (exports, core) { 'use strict';
13
14    /*! *****************************************************************************
15    Copyright (c) Microsoft Corporation. All rights reserved.
16    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
17    this file except in compliance with the License. You may obtain a copy of the
18    License at http://www.apache.org/licenses/LICENSE-2.0
19
20    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
22    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
23    MERCHANTABLITY OR NON-INFRINGEMENT.
24
25    See the Apache Version 2.0 License for specific language governing permissions
26    and limitations under the License.
27    ***************************************************************************** */
28    /* global Reflect, Promise */
29
30    var extendStatics = function(d, b) {
31        extendStatics = Object.setPrototypeOf ||
32            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
33            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
34        return extendStatics(d, b);
35    };
36
37    function __extends(d, b) {
38        extendStatics(d, b);
39        function __() { this.constructor = d; }
40        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
41    }
42
43    var BootstrapTheme = /** @class */ (function (_super) {
44        __extends(BootstrapTheme, _super);
45        function BootstrapTheme() {
46            return _super !== null && _super.apply(this, arguments) || this;
47        }
48        return BootstrapTheme;
49    }(core.Theme));
50    BootstrapTheme.prototype.classes = {
51        widget: 'fc-bootstrap',
52        tableGrid: 'table-bordered',
53        tableList: 'table',
54        tableListHeading: 'table-active',
55        buttonGroup: 'btn-group',
56        button: 'btn btn-primary',
57        buttonActive: 'active',
58        today: 'alert alert-info',
59        popover: 'card card-primary',
60        popoverHeader: 'card-header',
61        popoverContent: 'card-body',
62        // day grid
63        // for left/right border color when border is inset from edges (all-day in timeGrid view)
64        // avoid `table` class b/c don't want margins/padding/structure. only border color.
65        headerRow: 'table-bordered',
66        dayRow: 'table-bordered',
67        // list view
68        listView: 'card card-primary'
69    };
70    BootstrapTheme.prototype.baseIconClass = 'fa';
71    BootstrapTheme.prototype.iconClasses = {
72        close: 'fa-times',
73        prev: 'fa-chevron-left',
74        next: 'fa-chevron-right',
75        prevYear: 'fa-angle-double-left',
76        nextYear: 'fa-angle-double-right'
77    };
78    BootstrapTheme.prototype.iconOverrideOption = 'bootstrapFontAwesome';
79    BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome';
80    BootstrapTheme.prototype.iconOverridePrefix = 'fa-';
81    var main = core.createPlugin({
82        themeClasses: {
83            bootstrap: BootstrapTheme
84        }
85    });
86
87    exports.BootstrapTheme = BootstrapTheme;
88    exports.default = main;
89
90    Object.defineProperty(exports, '__esModule', { value: true });
91
92}));
93
94},{"@fullcalendar/core":2}],2:[function(require,module,exports){
95/*!
96FullCalendar Core Package v4.3.1
97Docs & License: https://fullcalendar.io/
98(c) 2019 Adam Shaw
99*/
100
101(function (global, factory) {
102    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
103    typeof define === 'function' && define.amd ? define(['exports'], factory) :
104    (global = global || self, factory(global.FullCalendar = {}));
105}(this, function (exports) { 'use strict';
106
107    // Creating
108    // ----------------------------------------------------------------------------------------------------------------
109    var elementPropHash = {
110        className: true,
111        colSpan: true,
112        rowSpan: true
113    };
114    var containerTagHash = {
115        '<tr': 'tbody',
116        '<td': 'tr'
117    };
118    function createElement(tagName, attrs, content) {
119        var el = document.createElement(tagName);
120        if (attrs) {
121            for (var attrName in attrs) {
122                if (attrName === 'style') {
123                    applyStyle(el, attrs[attrName]);
124                }
125                else if (elementPropHash[attrName]) {
126                    el[attrName] = attrs[attrName];
127                }
128                else {
129                    el.setAttribute(attrName, attrs[attrName]);
130                }
131            }
132        }
133        if (typeof content === 'string') {
134            el.innerHTML = content; // shortcut. no need to process HTML in any way
135        }
136        else if (content != null) {
137            appendToElement(el, content);
138        }
139        return el;
140    }
141    function htmlToElement(html) {
142        html = html.trim();
143        var container = document.createElement(computeContainerTag(html));
144        container.innerHTML = html;
145        return container.firstChild;
146    }
147    function htmlToElements(html) {
148        return Array.prototype.slice.call(htmlToNodeList(html));
149    }
150    function htmlToNodeList(html) {
151        html = html.trim();
152        var container = document.createElement(computeContainerTag(html));
153        container.innerHTML = html;
154        return container.childNodes;
155    }
156    // assumes html already trimmed and tag names are lowercase
157    function computeContainerTag(html) {
158        return containerTagHash[html.substr(0, 3) // faster than using regex
159        ] || 'div';
160    }
161    function appendToElement(el, content) {
162        var childNodes = normalizeContent(content);
163        for (var i = 0; i < childNodes.length; i++) {
164            el.appendChild(childNodes[i]);
165        }
166    }
167    function prependToElement(parent, content) {
168        var newEls = normalizeContent(content);
169        var afterEl = parent.firstChild || null; // if no firstChild, will append to end, but that's okay, b/c there were no children
170        for (var i = 0; i < newEls.length; i++) {
171            parent.insertBefore(newEls[i], afterEl);
172        }
173    }
174    function insertAfterElement(refEl, content) {
175        var newEls = normalizeContent(content);
176        var afterEl = refEl.nextSibling || null;
177        for (var i = 0; i < newEls.length; i++) {
178            refEl.parentNode.insertBefore(newEls[i], afterEl);
179        }
180    }
181    function normalizeContent(content) {
182        var els;
183        if (typeof content === 'string') {
184            els = htmlToElements(content);
185        }
186        else if (content instanceof Node) {
187            els = [content];
188        }
189        else { // Node[] or NodeList
190            els = Array.prototype.slice.call(content);
191        }
192        return els;
193    }
194    function removeElement(el) {
195        if (el.parentNode) {
196            el.parentNode.removeChild(el);
197        }
198    }
199    // Querying
200    // ----------------------------------------------------------------------------------------------------------------
201    // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
202    var matchesMethod = Element.prototype.matches ||
203        Element.prototype.matchesSelector ||
204        Element.prototype.msMatchesSelector;
205    var closestMethod = Element.prototype.closest || function (selector) {
206        // polyfill
207        var el = this;
208        if (!document.documentElement.contains(el)) {
209            return null;
210        }
211        do {
212            if (elementMatches(el, selector)) {
213                return el;
214            }
215            el = el.parentElement || el.parentNode;
216        } while (el !== null && el.nodeType === 1);
217        return null;
218    };
219    function elementClosest(el, selector) {
220        return closestMethod.call(el, selector);
221    }
222    function elementMatches(el, selector) {
223        return matchesMethod.call(el, selector);
224    }
225    // accepts multiple subject els
226    // returns a real array. good for methods like forEach
227    function findElements(container, selector) {
228        var containers = container instanceof HTMLElement ? [container] : container;
229        var allMatches = [];
230        for (var i = 0; i < containers.length; i++) {
231            var matches = containers[i].querySelectorAll(selector);
232            for (var j = 0; j < matches.length; j++) {
233                allMatches.push(matches[j]);
234            }
235        }
236        return allMatches;
237    }
238    // accepts multiple subject els
239    // only queries direct child elements
240    function findChildren(parent, selector) {
241        var parents = parent instanceof HTMLElement ? [parent] : parent;
242        var allMatches = [];
243        for (var i = 0; i < parents.length; i++) {
244            var childNodes = parents[i].children; // only ever elements
245            for (var j = 0; j < childNodes.length; j++) {
246                var childNode = childNodes[j];
247                if (!selector || elementMatches(childNode, selector)) {
248                    allMatches.push(childNode);
249                }
250            }
251        }
252        return allMatches;
253    }
254    // Attributes
255    // ----------------------------------------------------------------------------------------------------------------
256    function forceClassName(el, className, bool) {
257        if (bool) {
258            el.classList.add(className);
259        }
260        else {
261            el.classList.remove(className);
262        }
263    }
264    // Style
265    // ----------------------------------------------------------------------------------------------------------------
266    var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;
267    function applyStyle(el, props) {
268        for (var propName in props) {
269            applyStyleProp(el, propName, props[propName]);
270        }
271    }
272    function applyStyleProp(el, name, val) {
273        if (val == null) {
274            el.style[name] = '';
275        }
276        else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
277            el.style[name] = val + 'px';
278        }
279        else {
280            el.style[name] = val;
281        }
282    }
283
284    function pointInsideRect(point, rect) {
285        return point.left >= rect.left &&
286            point.left < rect.right &&
287            point.top >
287= rect.top &&
288            point.top < rect.bottom;
289    }
290    // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
291    function intersectRects(rect1, rect2) {
292        var res = {
293            left: Math.max(rect1.left, rect2.left),
294            right: Math.min(rect1.right, rect2.right),
295            top: Math.max(rect1.top, rect2.top),
296            bottom: Math.min(rect1.bottom, rect2.bottom)
297        };
298        if (res.left < res.right && res.top < res.bottom) {
299            return res;
300        }
301        return false;
302    }
303    function translateRect(rect, deltaX, deltaY) {
304        return {
305            left: rect.left + deltaX,
306            right: rect.right + deltaX,
307            top: rect.top + deltaY,
308            bottom: rect.bottom + deltaY
309        };
310    }
311    // Returns a new point that will have been moved to reside within the given rectangle
312    function constrainPoint(point, rect) {
313        return {
314            left: Math.min(Math.max(point.left, rect.left), rect.right),
315            top: Math.min(Math.max(point.top, rect.top), rect.bottom)
316        };
317    }
318    // Returns a point that is the center of the given rectangle
319    function getRectCenter(rect) {
320        return {
321            left: (rect.left + rect.right) / 2,
322            top: (rect.top + rect.bottom) / 2
323        };
324    }
325    // Subtracts point2's coordinates from point1's coordinates, returning a delta
326    function diffPoints(point1, point2) {
327        return {
328            left: point1.left - point2.left,
329            top: point1.top - point2.top
330        };
331    }
332
333    // Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side
334    var isRtlScrollbarOnLeft = null;
335    function getIsRtlScrollbarOnLeft() {
336        if (isRtlScrollbarOnLeft === null) {
337            isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();
338        }
339        return isRtlScrollbarOnLeft;
340    }
341    function computeIsRtlScrollbarOnLeft() {
342        var outerEl = createElement('div', {
343            style: {
344                position: 'absolute',
345                top: -1000,
346                left: 0,
347                border: 0,
348                padding: 0,
349                overflow: 'scroll',
350                direction: 'rtl'
351            }
352        }, '<div></div>');
353        document.body.appendChild(outerEl);
354        var innerEl = outerEl.firstChild;
355        var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;
356        removeElement(outerEl);
357        return res;
358    }
359    // The scrollbar width computations in computeEdges are sometimes flawed when it comes to
360    // retina displays, rounding, and IE11. Massage them into a usable value.
361    function sanitizeScrollbarWidth(width) {
362        width = Math.max(0, width); // no negatives
363        width = Math.round(width);
364        return width;
365    }
366
367    function computeEdges(el, getPadding) {
368        if (getPadding === void 0) { getPadding = false; }
369        var computedStyle = window.getComputedStyle(el);
370        var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
371        var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
372        var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
373        var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
374        // must use offset(Width|Height) because compatible with client(Width|Height)
375        var scrollbarLeftRight = sanitizeScrollbarWidth(el.offsetWidth - el.clientWidth - borderLeft - borderRight);
376        var scrollbarBottom = sanitizeScrollbarWidth(el.offsetHeight - el.clientHeight - borderTop - borderBottom);
377        var res = {
378            borderLeft: borderLeft,
379            borderRight: borderRight,
380            borderTop: borderTop,
381            borderBottom: borderBottom,
382            scrollbarBottom: scrollbarBottom,
383            scrollbarLeft: 0,
384            scrollbarRight: 0
385        };
386        if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side?
387            res.scrollbarLeft = scrollbarLeftRight;
388        }
389        else {
390            res.scrollbarRight = scrollbarLeftRight;
391        }
392        if (getPadding) {
393            res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
394            res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
395            res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
396            res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
397        }
398        return res;
399    }
400    function computeInnerRect(el, goWithinPadding) {
401        if (goWithinPadding === void 0) { goWithinPadding = false; }
402        var outerRect = computeRect(el);
403        var edges = computeEdges(el, goWithinPadding);
404        var res = {
405            left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
406            right: outerRect.right - edges.borderRight - edges.scrollbarRight,
407            top: outerRect.top + edges.borderTop,
408            bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom
409        };
410        if (goWithinPadding) {
411            res.left += edges.paddingLeft;
412            res.right -= edges.paddingRight;
413            res.top += edges.paddingTop;
414            res.bottom -= edges.paddingBottom;
415        }
416        return res;
417    }
418    function computeRect(el) {
419        var rect = el.getBoundingClientRect();
420        return {
421            left: rect.left + window.pageXOffset,
422            top: rect.top + window.pageYOffset,
423            right: rect.right + window.pageXOffset,
424            bottom: rect.bottom + window.pageYOffset
425        };
426    }
427    function computeViewportRect() {
428        return {
429            left: window.pageXOffset,
430            right: window.pageXOffset + document.documentElement.clientWidth,
431            top: window.pageYOffset,
432            bottom: window.pageYOffset + document.documentElement.clientHeight
433        };
434    }
435    function computeHeightAndMargins(el) {
436        return el.getBoundingClientRect().height + computeVMargins(el);
437    }
438    function computeVMargins(el) {
439        var computed = window.getComputedStyle(el);
440        return parseInt(computed.marginTop, 10) +
441            parseInt(computed.marginBottom, 10);
442    }
443    // does not return window
444    function getClippingParents(el) {
445        var parents = [];
446        while (el instanceof HTMLElement) { // will stop when gets to document or null
447            var computedStyle = window.getComputedStyle(el);
448            if (computedStyle.position === 'fixed') {
449                break;
450            }
451            if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
452                parents.push(el);
453            }
454            el = el.parentNode;
455        }
456        return parents;
457    }
458    function computeClippingRect(el) {
459        return getClippingParents(el)
460            .map(function (el) {
461            return computeInnerRect(el);
462        })
463            .concat(computeViewportRect())
464            .reduce(function (rect0, rect1) {
465            return intersectRects(rect0, rect1) || rect1; // should always intersect
466        });
467    }
468
469    // Stops a mouse/touch event from doing it's native browser action
470    function preventDefault(ev) {
471        ev.preventDefault();
472    }
473    // Event Delegation
474    // ----------------------------------------------------------------------------------------------------------------
475    function listenBySelector(container, eventType, selector, handler) {
476        function realHandler(ev) {
477            var matchedChild = elementClosest(ev.target, selector);
478            if (matchedChild) {
479                handler.call(matchedChild, ev, matchedChild);
480            }
481        }
482        container.addEventListener(eventType, realHandler);
483        return function () {
484            container.removeEventListener(eventType, realHandler);
485        };
486    }
487    function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
488        var currentMatchedChild;
489        return listenBySelector(container, 'mouseover', selector, function (ev, matchedChild) {
490            if (matchedChild !== currentMatchedChild) {
491                currentMatchedChild = matchedChild;
492                onMouseEnter(ev, matchedChild);
493                var realOnMouseLeave_1 = function (ev) {
494                    currentMatchedChild = null;
495                    onMouseLeave(ev, matchedChild);
496                    matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1);
497                };
498                // listen to the next mouseleave, and then unattach
499                matchedChild.addEventListener('mouseleave', realOnMouseLeave_1);
500            }
501        });
502    }
503    // Animation
504    // ----------------------------------------------------------------------------------------------------------------
505    var transitionEventNames = [
506        'webkitTransitionEnd',
507        'otransitionend',
508        'oTransitionEnd',
509        'msTransitionEnd',
510        'transitionend'
511    ];
512    // triggered only when the next single subsequent transition finishes
513    function whenTransitionDone(el, callback) {
514        var realCallback = function (ev) {
515            callback(ev);
516            transitionEventNames.forEach(function (eventName) {
517                el.removeEventListener(eventName, realCallback);
518            });
519        };
520        transitionEventNames.forEach(function (eventName) {
521            el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes
522        });
523    }
524
525    var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
526    // Adding
527    function addWeeks(m, n) {
528        var a = dateToUtcArray(m);
529        a[2] += n * 7;
530        return arrayToUtcDate(a);
531    }
532    function addDays(m, n) {
533        var a = dateToUtcArray(m);
534        a[2] += n;
535        return arrayToUtcDate(a);
536    }
537    function addMs(m, n) {
538        var a = dateToUtcArray(m);
539        a[6] += n;
540        return arrayToUtcDate(a);
541    }
542    // Diffing (all return floats)
543    function diffWeeks(m0, m1) {
544        return diffDays(m0, m1) / 7;
545    }
546    function diffDays(m0, m1) {
547        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
548    }
549    function diffHours(m0, m1) {
550        return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
551    }
552    function diffMinutes(m0, m1) {
553        return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
554    }
555    function diffSeconds(m0, m1) {
556        return (m1.valueOf() - m0.valueOf()) / 1000;
557    }
558    function diffDayAndTime(m0, m1) {
559        var m0day = startOfDay(m0);
560        var m1day = startOfDay(m1);
561        return {
562            years: 0,
563            months: 0,
564            days: Math.round(diffDays(m0day, m1day)),
565            milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf())
566        };
567    }
568    // Diffing Whole Units
569    function diffWholeWeeks(m0, m1) {
570        var d = diffWholeDays(m0, m1);
571        if (d !== null && d % 7 === 0) {
572            return d / 7;
573        }
574        return null;
575    }
576    function diffWholeDays(m0, m1) {
577        if (timeAsMs(m0) === timeAsMs(m1)) {
578            return Math.round(diffDays(m0, m1));
579        }
580        return null;
581    }
582    // Start-Of
583    function startOfDay(m) {
584        return arrayToUtcDate([
585            m.getUTCFullYear(),
586            m.getUTCMonth(),
587            m.getUTCDate()
588        ]);
589    }
590    function startOfHour(m) {
591        return arrayToUtcDate([
592            m.getUTCFullYear(),
593            m.getUTCMonth(),
594            m.getUTCDate(),
595            m.getUTCHours()
596        ]);
597    }
598    function startOfMinute(m) {
599        return arrayToUtcDate([
600            m.getUTCFullYear(),
601            m.getUTCMonth(),
602            m.getUTCDate(),
603            m.getUTCHours(),
604            m.getUTCMinutes()
605        ]);
606    }
607    function startOfSecond(m) {
608        return arrayToUtcDate([
609            m.getUTCFullYear(),
610            m.getUTCMonth(),
611            m.getUTCDate(),
612            m.getUTCHours(),
613            m.getUTCMinutes(),
614            m.getUTCSeconds()
615        ]);
616    }
617    // Week Computation
618    function weekOfYear(marker, dow, doy) {
619        var y = marker.getUTCFullYear();
620        var w = weekOfGivenYear(marker, y, dow, doy);
621        if (w < 1) {
622            return weekOfGivenYear(marker, y - 1, dow, doy);
623        }
624        var nextW = weekOfGivenYear(marker, y + 1, dow, doy);
625        if (nextW >= 1) {
626            return Math.min(w, nextW);
627        }
628        return w;
629    }
630    function weekOfGivenYear(marker, year, dow, doy) {
631        var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
632        var dayStart = startOfDay(marker);
633        var days = Math.round(diffDays(firstWeekStart, dayStart));
634        return Math.floor(days / 7) + 1; // zero-indexed
635    }
636    // start-of-first-week - start-of-year
637    function firstWeekOffset(year, dow, doy) {
638        // first-week day -- which january is always in the first week (4 for iso, 1 for other)
639        var fwd = 7 + dow - doy;
640        // first-week day local weekday -- which local weekday is fwd
641        var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
642        return -fwdlw + fwd - 1;
643    }
644    // Array Conversion
645    function dateToLocalArray(date) {
646        return [
647            date.getFullYear(),
648            date.getMonth(),
649            date.getDate(),
650            date.getHours(),
651            date.getMinutes(),
652            date.getSeconds(),
653            date.getMilliseconds()
654        ];
655    }
656    function arrayToLocalDate(a) {
657        return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month
658        a[3] || 0, a[4] || 0, a[5] || 0);
659    }
660    function dateToUtcArray(date) {
661        return [
662            date.getUTCFullYear(),
663            date.getUTCMonth(),
664            date.getUTCDate(),
665            date.getUTCHours(),
666            date.getUTCMinutes(),
667            date.getUTCSeconds(),
668            date.getUTCMilliseconds()
669        ];
670    }
671    function arrayToUtcDate(a) {
672        // according to web standards (and Safari), a month index is required.
673        // massage if only given a year.
674        if (a.length === 1) {
675            a = a.concat([0]);
676        }
677        return new Date(Date.UTC.apply(Date, a));
678    }
679    // Other Utils
680    function isValidDate(m) {
681        return !isNaN(m.valueOf());
682    }
683    function timeAsMs(m) {
684        return m.getUTCHours() * 1000 * 60 * 60 +
685            m.getUTCMinutes() * 1000 * 60 +
686            m.getUTCSeconds() * 1000 +
687            m.getUTCMilliseconds();
688    }
689
690    var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
691    var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
692    // Parsing and Creation
693    function createDuration(input, unit) {
694        var _a;
695        if (typeof input === 'string') {
696            return parseString(input);
697        }
698        else if (typeof input === 'object' && input) { // non-null object
699            return normalizeObject(input);
700        }
701        else if (typeof input === 'number') {
702            return normalizeObject((_a = {}, _a[unit || 'milliseconds'] = input, _a));
703        }
704        else {
705            return null;
706        }
707    }
708    function parseString(s) {
709        var m = PARSE_RE.exec(s);
710        if (m) {
711            var sign = m[1] ? -1 : 1;
712            return {
713                years: 0,
714                months: 0,
715                days: sign * (m[2] ? parseInt(m[2], 10) : 0),
716                milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours
717                    (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes
718                    (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds
719                    (m[6] ? parseInt(m[6], 10) : 0) // ms
720                )
721            };
722        }
723        return null;
724    }
725    function normalizeObject(obj) {
726        return {
727            years: obj.years || obj.year || 0,
728            months: obj.months || obj.month || 0,
729            days: (obj.days || obj.day || 0) +
730                getWeeksFromInput(obj) * 7,
731            milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours
732                (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes
733                (obj.seconds || obj.second || 0) * 1000 + // seconds
734                (obj.milliseconds || obj.millisecond || obj.ms || 0) // ms
735        };
736    }
737    function getWeeksFromInput(obj) {
738        return obj.weeks || obj.week || 0;
739    }
740    // Equality
741    function durationsEqual(d0, d1) {
742        return d0.years === d1.years &&
743            d0.months === d1.months &&
744            d0.days === d1.days &&
745            d0.milliseconds === d1.milliseconds;
746    }
747    function isSingleDay(dur) {
748        return dur.years === 0 && dur.months === 0 && dur.days === 1 && dur.milliseconds === 0;
749    }
750    // Simple Math
751    function addDurations(d0, d1) {
752        return {
753            years: d0.years + d1.years,
754            months: d0.months + d1.months,
755            days: d0.days + d1.days,
756            milliseconds: d0.milliseconds + d1.milliseconds
757        };
758    }
759    function subtractDurations(d1, d0) {
760        return {
761            years: d1.years - d0.years,
762            months: d1.months - d0.months,
763            days: d1.days - d0.days,
764            milliseconds: d1.milliseconds - d0.milliseconds
765        };
766    }
767    function multiplyDuration(d, n) {
768        return {
769            years: d.years * n,
770            months: d.months * n,
771            days: d.days * n,
772            milliseconds: d.milliseconds * n
773        };
774    }
775    // Conversions
776    // "Rough" because they are based on average-case Gregorian months/years
777    function asRoughYears(dur) {
778        return asRoughDays(dur) / 365;
779    }
780    function asRoughMonths(dur) {
781        return asRoughDays(dur) / 30;
782    }
783    function asRoughDays(dur) {
784        return asRoughMs(dur) / 864e5;
785    }
786    function asRoughMinutes(dur) {
787        return asRoughMs(dur) / (1000 * 60);
788    }
789    function asRoughSeconds(dur) {
790        return asRoughMs(dur) / 1000;
791    }
792    function asRoughMs(dur) {
793        return dur.years * (365 * 864e5) +
794            dur.months * (30 * 864e5) +
795            dur.days * 864e5 +
796            dur.milliseconds;
797    }
798    // Advanced Math
799    function wholeDivideDurations(numerator, denominator) {
800        var res = null;
801        for (var i = 0; i < INTERNAL_UNITS.length; i++) {
802            var unit = INTERNAL_UNITS[i];
803            if (denominator[unit]) {
804                var localRes = numerator[unit] / denominator[unit];
805                if (!isInt(localRes) || (res !== null && res !== localRes)) {
806                    return null;
807                }
808                res = localRes;
809            }
810            else if (numerator[unit]) {
811                // needs to divide by something but can't!
812                return null;
813            }
814        }
815        return res;
816    }
817    function greatestDurationDenominator(dur, dontReturnWeeks) {
818        var ms = dur.milliseconds;
819        if (ms) {
820            if (ms % 1000 !== 0) {
821                return { unit: 'millisecond', value: ms };
822            }
823            if (ms % (1000 * 60) !== 0) {
824                return { unit: 'second', value: ms / 1000 };
825            }
826            if (ms % (1000 * 60 * 60) !== 0) {
827                return { unit: 'minute', value: ms / (1000 * 60) };
828            }
829            if (ms) {
830                return { unit: 'hour', value: ms / (1000 * 60 * 60) };
831            }
832        }
833        if (dur.days) {
834            if (!dontReturnWeeks && dur.days % 7 === 0) {
835                return { unit: 'week', value: dur.days / 7 };
836            }
837            return { unit: 'day', value: dur.days };
838        }
839        if (dur.months) {
840            return { unit: 'month', value: dur.months };
841        }
842        if (dur.years) {
843            return { unit: 'year', value: dur.years };
844        }
845        return { unit: 'millisecond', value: 0 };
846    }
847
848    /* FullCalendar-specific DOM Utilities
849    ----------------------------------------------------------------------------------------------------------------------*/
850    // Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left
851    // and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.
852    function compensateScroll(rowEl, scrollbarWidths) {
853        if (scrollbarWidths.left) {
854            applyStyle(rowEl, {
855                borderLeftWidth: 1,
856                marginLeft: scrollbarWidths.left - 1
857            });
858        }
859        if (scrollbarWidths.right) {
860            applyStyle(rowEl, {
861                borderRightWidth: 1,
862                marginRight: scrollbarWidths.right - 1
863            });
864        }
865    }
866    // Undoes compensateScroll and restores all borders/margins
867    function uncompensateScroll(rowEl) {
868        applyStyle(rowEl, {
869            marginLeft: '',
870            marginRight: '',
871            borderLeftWidth: '',
872            borderRightWidth: ''
873        });
874    }
875    // Make the mouse cursor express that an event is not allowed in the current area
876    function disableCursor() {
877        document.body.classList.add('fc-not-allowed');
878    }
879    // Returns the mouse cursor to its original look
880    function enableCursor() {
881        document.body.classList.remove('fc-not-allowed');
882    }
883    // Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.
884    // By default, all elements that are shorter than the recommended height are expanded uniformly, not considering
885    // any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and
886    // reduces the available height.
887    function distributeHeight(els, availableHeight, shouldRedistribute) {
888        // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,
889        // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.
890        var minOffset1 = Math.floor(availableHeight / els.length); // for non-last element
891        var minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE*
892        var flexEls = []; // elements that are allowed to expand. array of DOM nodes
893        var flexOffsets = []; // amount of vertical space it takes up
894        var flexHeights = []; // actual css height
895        var usedHeight = 0;
896        undistributeHeight(els); // give all elements their natural height
897        // find elements that are below the recommended height (expandable).
898        // important to query for heights in a single first pass (to avoid reflow oscillation).
899        els.forEach(function (el, i) {
900            var minOffset = i === els.length - 1 ? minOffset2 : minOffset1;
901            var naturalHeight = el.getBoundingClientRect().height;
902            var naturalOffset = naturalHeight + computeVMargins(el);
903            if (naturalOffset < minOffset) {
904                flexEls.push(el);
905                flexOffsets.push(naturalOffset);
906                flexHeights.push(naturalHeight);
907            }
908            else {
909                // this element stretches past recommended height (non-expandable). mark the space as occupied.
910                usedHeight += naturalOffset;
911            }
912        });
913        // readjust the recommended height to only consider the height available to non-maxed-out rows.
914        if (shouldRedistribute) {
915            availableHeight -= usedHeight;
916            minOffset1 = Math.floor(availableHeight / flexEls.length);
917            minOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE*
918        }
919        // assign heights to all expandable elements
920        flexEls.forEach(function (el, i) {
921            var minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1;
922            var naturalOffset = flexOffsets[i];
923            var naturalHeight = flexHeights[i];
924            var newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding
925            if (naturalOffset < minOffset) { // we check this again because redistribution might have changed things
926                el.style.height = newHeight + 'px';
927            }
928        });
929    }
930    // Undoes distrubuteHeight, restoring all els to their natural height
931    function undistributeHeight(els) {
932        els.forEach(function (el) {
933            el.style.height = '';
934        });
935    }
936    // Given `els`, a set of <td> cells, find the cell with the largest natural width and set the widths of all the
937    // cells to be that width.
938    // PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline
939    function matchCellWidths(els) {
940        var maxInnerWidth = 0;
941        els.forEach(function (el) {
942            var innerEl = el.firstChild; // hopefully an element
943            if (innerEl instanceof HTMLElement) {
944                var innerWidth_1 = innerEl.getBoundingClientRect().width;
945                if (innerWidth_1 > maxInnerWidth) {
946                    maxInnerWidth = innerWidth_1;
947                }
948            }
949        });
950        maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance
951        els.forEach(function (el) {
952            el.style.width = maxInnerWidth + 'px';
953        });
954        return maxInnerWidth;
955    }
956    // Given one element that resides inside another,
957    // Subtracts the height of the inner element from the outer element.
958    function subtractInnerElHeight(outerEl, innerEl) {
959        // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
960        var reflowStyleProps = {
961            position: 'relative',
962            left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll
963        };
964        applyStyle(outerEl, reflowStyleProps);
965        applyStyle(innerEl, reflowStyleProps);
966        var diff = // grab the dimensions
967         outerEl.getBoundingClientRect().height -
968            innerEl.getBoundingClientRect().height;
969        // undo hack
970        var resetStyleProps = { position: '', left: '' };
971        applyStyle(outerEl, resetStyleProps);
972        applyStyle(innerEl, resetStyleProps);
973        return diff;
974    }
975    /* Selection
976    ----------------------------------------------------------------------------------------------------------------------*/
977    function preventSelection(el) {
978        el.classList.add('fc-unselectable');
979        el.addEventListener('selectstart', preventDefault);
980    }
981    function allowSelection(el) {
982        el.classList.remove('fc-unselectable');
983        el.removeEventListener('selectstart', preventDefault);
984    }
985    /* Context Menu
986    ----------------------------------------------------------------------------------------------------------------------*/
987    function preventContextMenu(el) {
988        el.addEventListener('contextmenu', preventDefault);
989    }
990    function allowContextMenu(el) {
991        el.removeEventListener('contextmenu', preventDefault);
992    }
993    /* Object Ordering by Field
994    ----------------------------------------------------------------------------------------------------------------------*/
995    function parseFieldSpecs(input) {
996        var specs = [];
997        var tokens = [];
998        var i;
999        var token;
1000        if (typeof input === 'string') {
1001            tokens = input.split(/\s*,\s*/);
1002        }
1003        else if (typeof input === 'function') {
1004            tokens = [input];
1005        }
1006        else if (Array.isArray(input)) {
1007            tokens = input;
1008        }
1009        for (i = 0; i < tokens.length; i++) {
1010            token = tokens[i];
1011            if (typeof token === 'string') {
1012                specs.push(token.charAt(0) === '-' ?
1013                    { field: token.substring(1), order: -1 } :
1014                    { field: token, order: 1 });
1015            }
1016            else if (typeof token === 'function') {
1017                specs.push({ func: token });
1018            }
1019        }
1020        return specs;
1021    }
1022    function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
1023        var i;
1024        var cmp;
1025        for (i = 0; i < fieldSpecs.length; i++) {
1026            cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
1027            if (cmp) {
1028                return cmp;
1029            }
1030        }
1031        return 0;
1032    }
1033    function compareByFieldSpec(obj0, obj1, fieldSpec) {
1034        if (fieldSpec.func) {
1035            return fieldSpec.func(obj0, obj1);
1036        }
1037        return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])
1038            * (fieldSpec.order || 1);
1039    }
1040    function flexibleCompare(a, b) {
1041        if (!a && !b) {
1042            return 0;
1043        }
1044        if (b == null) {
1045            return -1;
1046        }
1047        if (a == null) {
1048            return 1;
1049        }
1050        if (typeof a === 'string' || typeof b === 'string') {
1051            return String(a).localeCompare(String(b));
1052        }
1053        return a - b;
1054    }
1055    /* String Utilities
1056    ----------------------------------------------------------------------------------------------------------------------*/
1057    function capitaliseFirstLetter(str) {
1058        return str.charAt(0).toUpperCase() + str.slice(1);
1059    }
1060    function padStart(val, len) {
1061        var s = String(val);
1062        return '000'.substr(0, len - s.length) + s;
1063    }
1064    /* Number Utilities
1065    ----------------------------------------------------------------------------------------------------------------------*/
1066    function compareNumbers(a, b) {
1067        return a - b;
1068    }
1069    function isInt(n) {
1070        return n % 1 === 0;
1071    }
1072    /* Weird Utilities
1073    ----------------------------------------------------------------------------------------------------------------------*/
1074    function applyAll(functions, thisObj, args) {
1075        if (typeof functions === 'function') { // supplied a single function
1076            functions = [functions];
1077        }
1078        if (functions) {
1079            var i = void 0;
1080            var ret = void 0;
1081            for (i = 0; i < functions.length; i++) {
1082                ret = functions[i].apply(thisObj, args) || ret;
1083            }
1084            return ret;
1085        }
1086    }
1087    function firstDefined() {
1088        var args = [];
1089        for (var _i = 0; _i < arguments.length; _i++) {
1090            args[_i] = arguments[_i];
1091        }
1092        for (var i = 0; i < args.length; i++) {
1093            if (args[i] !== undefined) {
1094                return args[i];
1095            }
1096        }
1097    }
1098    // Returns a function, that, as long as it continues to be invoked, will not
1099    // be triggered. The function will be called after it stops being called for
1100    // N milliseconds. If `immediate` is passed, trigger the function on the
1101    // leading edge, instead of the trailing.
1102    // https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714
1103    function debounce(func, wait) {
1104        var timeout;
1105        var args;
1106        var context;
1107        var timestamp;
1108        var result;
1109        var later = function () {
1110            var last = new Date().valueOf() - timestamp;
1111            if (last < wait) {
1112                timeout = setTimeout(later, wait - last);
1113            }
1114            else {
1115                timeout = null;
1116                result = func.apply(context, args);
1117                context = args = null;
1118            }
1119        };
1120        return function () {
1121            context = this;
1122            args = arguments;
1123            timestamp = new Date().valueOf();
1124            if (!timeout) {
1125                timeout = setTimeout(later, wait);
1126            }
1127            return result;
1128        };
1129    }
1130    // Number and Boolean are only types that defaults or not computed for
1131    // TODO: write more comments
1132    function refineProps(rawProps, processors, defaults, leftoverProps) {
1133        if (defaults === void 0) { defaults = {}; }
1134        var refined = {};
1135        for (var key in processors) {
1136            var processor = processors[key];
1137            if (rawProps[key] !== undefined) {
1138                // found
1139                if (processor === Function) {
1140                    refined[key] = typeof rawProps[key] === 'function' ? rawProps[key] : null;
1141                }
1142                else if (processor) { // a refining function?
1143                    refined[key] = processor(rawProps[key]);
1144                }
1145                else {
1146                    refined[key] = rawProps[key];
1147                }
1148            }
1149            else if (defaults[key] !== undefined) {
1150                // there's an explicit default
1151                refined[key] = defaults[key];
1152            }
1153            else {
1154                // must compute a default
1155                if (processor === String) {
1156                    refined[key] = ''; // empty string is default for String
1157                }
1158                else if (!processor || processor === Number || processor === Boolean || processor === Function) {
1159                    refined[key] = null; // assign null for other non-custom processor funcs
1160                }
1161                else {
1162                    refined[key] = processor(null); // run the custom processor func
1163                }
1164            }
1165        }
1166        if (leftoverProps) {
1167            for (var key in rawProps) {
1168                if (processors[key] === undefined) {
1169                    leftoverProps[key] = rawProps[key];
1170                }
1171            }
1172        }
1173        return refined;
1174    }
1175    /* Date stuff that doesn't belong in datelib core
1176    ----------------------------------------------------------------------------------------------------------------------*/
1177    // given a timed range, computes an all-day range that has the same exact duration,
1178    // but whose start time is aligned with the start of the day.
1179    function computeAlignedDayRange(timedRange) {
1180        var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
1181        var start = startOfDay(timedRange.start);
1182        var end = addDays(start, dayCnt);
1183        return { start: start, end: end };
1184    }
1185    // given a timed range, computes an all-day range based on how for the end date bleeds into the next day
1186    // TODO: give nextDayThreshold a default arg
1187    function computeVisibleDayRange(timedRange, nextDayThreshold) {
1188        if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); }
1189        var startDay = null;
1190        var endDay = null;
1191        if (timedRange.end) {
1192            endDay = startOfDay(timedRange.end);
1193            var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`
1194            // If the end time is actually inclusively part of the next day and is equal to or
1195            // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
1196            // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
1197            if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
1198                endDay = addDays(endDay, 1);
1199            }
1200        }
1201        if (timedRange.start) {
1202            startDay = startOfDay(timedRange.start); // the beginning of the day the range starts
1203            // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
1204            if (endDay && endDay <= startDay) {
1205                endDay = addDays(startDay, 1);
1206            }
1207        }
1208        return { start: startDay, end: endDay };
1209    }
1210    // spans from one day into another?
1211    function isMultiDayRange(range) {
1212        var visibleRange = computeVisibleDayRange(range);
1213        return diffDays(visibleRange.start, visibleRange.end) > 1;
1214    }
1215    function diffDates(date0, date1, dateEnv, largeUnit) {
1216        if (largeUnit === 'year') {
1217            return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
1218        }
1219        else if (largeUnit === 'month') {
1220            return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
1221        }
1222        else {
1223            return diffDayAndTime(date0, date1); // returns a duration
1224        }
1225    }
1226
1227    /*! *****************************************************************************
1228    Copyright (c) Microsoft Corporation. All rights reserved.
1229    Licensed under the Apache License, Version 2.0 (the "License");
1229 you may not use
1230    this file except in compliance with the License. You may obtain a copy of the
1231    License at http://www.apache.org/licenses/LICENSE-2.0
1232
1233    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1234    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
1235    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
1236    MERCHANTABLITY OR NON-INFRINGEMENT.
1237
1238    See the Apache Version 2.0 License for specific language governing permissions
1239    and limitations under the License.
1240    ***************************************************************************** */
1241    /* global Reflect, Promise */
1242
1243    var extendStatics = function(d, b) {
1244        extendStatics = Object.setPrototypeOf ||
1245            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
1246            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
1247        return extendStatics(d, b);
1248    };
1249
1250    function __extends(d, b) {
1251        extendStatics(d, b);
1252        function __() { this.constructor = d; }
1253        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
1254    }
1255
1256    var __assign = function() {
1257        __assign = Object.assign || function __assign(t) {
1258            for (var s, i = 1, n = arguments.length; i < n; i++) {
1259                s = arguments[i];
1260                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
1261            }
1262            return t;
1263        };
1264        return __assign.apply(this, arguments);
1265    };
1266
1267    function parseRecurring(eventInput, allDayDefault, dateEnv, recurringTypes, leftovers) {
1268        for (var i = 0; i < recurringTypes.length; i++) {
1269            var localLeftovers = {};
1270            var parsed = recurringTypes[i].parse(eventInput, localLeftovers, dateEnv);
1271            if (parsed) {
1272                var allDay = localLeftovers.allDay;
1273                delete localLeftovers.allDay; // remove from leftovers
1274                if (allDay == null) {
1275                    allDay = allDayDefault;
1276                    if (allDay == null) {
1277                        allDay = parsed.allDayGuess;
1278                        if (allDay == null) {
1279                            allDay = false;
1280                        }
1281                    }
1282                }
1283                __assign(leftovers, localLeftovers);
1284                return {
1285                    allDay: allDay,
1286                    duration: parsed.duration,
1287                    typeData: parsed.typeData,
1288                    typeId: i
1289                };
1290            }
1291        }
1292        return null;
1293    }
1294    /*
1295    Event MUST have a recurringDef
1296    */
1297    function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) {
1298        var typeDef = recurringTypes[eventDef.recurringDef.typeId];
1299        var markers = typeDef.expand(eventDef.recurringDef.typeData, {
1300            start: dateEnv.subtract(framingRange.start, duration),
1301            end: framingRange.end
1302        }, dateEnv);
1303        // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to
1304        if (eventDef.allDay) {
1305            markers = markers.map(startOfDay);
1306        }
1307        return markers;
1308    }
1309
1310    var hasOwnProperty = Object.prototype.hasOwnProperty;
1311    // Merges an array of objects into a single object.
1312    // The second argument allows for an array of property names who's object values will be merged together.
1313    function mergeProps(propObjs, complexProps) {
1314        var dest = {};
1315        var i;
1316        var name;
1317        var complexObjs;
1318        var j;
1319        var val;
1320        var props;
1321        if (complexProps) {
1322            for (i = 0; i < complexProps.length; i++) {
1323                name = complexProps[i];
1324                complexObjs = [];
1325                // collect the trailing object values, stopping when a non-object is discovered
1326                for (j = propObjs.length - 1; j >= 0; j--) {
1327                    val = propObjs[j][name];
1328                    if (typeof val === 'object' && val) { // non-null object
1329                        complexObjs.unshift(val);
1330                    }
1331                    else if (val !== undefined) {
1332                        dest[name] = val; // if there were no objects, this value will be used
1333                        break;
1334                    }
1335                }
1336                // if the trailing values were objects, use the merged value
1337                if (complexObjs.length) {
1338                    dest[name] = mergeProps(complexObjs);
1339                }
1340            }
1341        }
1342        // copy values into the destination, going from last to first
1343        for (i = propObjs.length - 1; i >= 0; i--) {
1344            props = propObjs[i];
1345            for (name in props) {
1346                if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign
1347                    dest[name] = props[name];
1348                }
1349            }
1350        }
1351        return dest;
1352    }
1353    function filterHash(hash, func) {
1354        var filtered = {};
1355        for (var key in hash) {
1356            if (func(hash[key], key)) {
1357                filtered[key] = hash[key];
1358            }
1359        }
1360        return filtered;
1361    }
1362    function mapHash(hash, func) {
1363        var newHash = {};
1364        for (var key in hash) {
1365            newHash[key] = func(hash[key], key);
1366        }
1367        return newHash;
1368    }
1369    function arrayToHash(a) {
1370        var hash = {};
1371        for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
1372            var item = a_1[_i];
1373            hash[item] = true;
1374        }
1375        return hash;
1376    }
1377    function hashValuesToArray(obj) {
1378        var a = [];
1379        for (var key in obj) {
1380            a.push(obj[key]);
1381        }
1382        return a;
1383    }
1384    function isPropsEqual(obj0, obj1) {
1385        for (var key in obj0) {
1386            if (hasOwnProperty.call(obj0, key)) {
1387                if (!(key in obj1)) {
1388                    return false;
1389                }
1390            }
1391        }
1392        for (var key in obj1) {
1393            if (hasOwnProperty.call(obj1, key)) {
1394                if (obj0[key] !== obj1[key]) {
1395                    return false;
1396                }
1397            }
1398        }
1399        return true;
1400    }
1401
1402    function parseEvents(rawEvents, sourceId, calendar, allowOpenRange) {
1403        var eventStore = createEmptyEventStore();
1404        for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) {
1405            var rawEvent = rawEvents_1[_i];
1406            var tuple = parseEvent(rawEvent, sourceId, calendar, allowOpenRange);
1407            if (tuple) {
1408                eventTupleToStore(tuple, eventStore);
1409            }
1410        }
1411        return eventStore;
1412    }
1413    function eventTupleToStore(tuple, eventStore) {
1414        if (eventStore === void 0) { eventStore = createEmptyEventStore(); }
1415        eventStore.defs[tuple.def.defId] = tuple.def;
1416        if (tuple.instance) {
1417            eventStore.instances[tuple.instance.instanceId] = tuple.instance;
1418        }
1419        return eventStore;
1420    }
1421    function expandRecurring(eventStore, framingRange, calendar) {
1422        var dateEnv = calendar.dateEnv;
1423        var defs = eventStore.defs, instances = eventStore.instances;
1424        // remove existing recurring instances
1425        instances = filterHash(instances, function (instance) {
1426            return !defs[instance.defId].recurringDef;
1427        });
1428        for (var defId in defs) {
1429            var def = defs[defId];
1430            if (def.recurringDef) {
1431                var duration = def.recurringDef.duration;
1432                if (!duration) {
1433                    duration = def.allDay ?
1434                        calendar.defaultAllDayEventDuration :
1435                        calendar.defaultTimedEventDuration;
1436                }
1437                var starts = expandRecurringRanges(def, duration, framingRange, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes);
1438                for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) {
1439                    var start = starts_1[_i];
1440                    var instance = createEventInstance(defId, {
1441                        start: start,
1442                        end: dateEnv.add(start, duration)
1443                    });
1444                    instances[instance.instanceId] = instance;
1445                }
1446            }
1447        }
1448        return { defs: defs, instances: instances };
1449    }
1450    // retrieves events that have the same groupId as the instance specified by `instanceId`
1451    // or they are the same as the instance.
1452    // why might instanceId not be in the store? an event from another calendar?
1453    function getRelevantEvents(eventStore, instanceId) {
1454        var instance = eventStore.instances[instanceId];
1455        if (instance) {
1456            var def_1 = eventStore.defs[instance.defId];
1457            // get events/instances with same group
1458            var newStore = filterEventStoreDefs(eventStore, function (lookDef) {
1459                return isEventDefsGrouped(def_1, lookDef);
1460            });
1461            // add the original
1462            // TODO: wish we could use eventTupleToStore or something like it
1463            newStore.defs[def_1.defId] = def_1;
1464            newStore.instances[instance.instanceId] = instance;
1465            return newStore;
1466        }
1467        return createEmptyEventStore();
1468    }
1469    function isEventDefsGrouped(def0, def1) {
1470        return Boolean(def0.groupId && def0.groupId === def1.groupId);
1471    }
1472    function transformRawEvents(rawEvents, eventSource, calendar) {
1473        var calEachTransform = calendar.opt('eventDataTransform');
1474        var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
1475        if (sourceEachTransform) {
1476            rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
1477        }
1478        if (calEachTransform) {
1479            rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
1480        }
1481        return rawEvents;
1482    }
1483    function transformEachRawEvent(rawEvents, func) {
1484        var refinedEvents;
1485        if (!func) {
1486            refinedEvents = rawEvents;
1487        }
1488        else {
1489            refinedEvents = [];
1490            for (var _i = 0, rawEvents_2 = rawEvents; _i < rawEvents_2.length; _i++) {
1491                var rawEvent = rawEvents_2[_i];
1492                var refinedEvent = func(rawEvent);
1493                if (refinedEvent) {
1494                    refinedEvents.push(refinedEvent);
1495                }
1496                else if (refinedEvent == null) {
1497                    refinedEvents.push(rawEvent);
1498                } // if a different falsy value, do nothing
1499            }
1500        }
1501        return refinedEvents;
1502    }
1503    function createEmptyEventStore() {
1504        return { defs: {}, instances: {} };
1505    }
1506    function mergeEventStores(store0, store1) {
1507        return {
1508            defs: __assign({}, store0.defs, store1.defs),
1509            instances: __assign({}, store0.instances, store1.instances)
1510        };
1511    }
1512    function filterEventStoreDefs(eventStore, filterFunc) {
1513        var defs = filterHash(eventStore.defs, filterFunc);
1514        var instances = filterHash(eventStore.instances, function (instance) {
1515            return defs[instance.defId]; // still exists?
1516        });
1517        return { defs: defs, instances: instances };
1518    }
1519
1520    function parseRange(input, dateEnv) {
1521        var start = null;
1522        var end = null;
1523        if (input.start) {
1524            start = dateEnv.createMarker(input.start);
1525        }
1526        if (input.end) {
1527            end = dateEnv.createMarker(input.end);
1528        }
1529        if (!start && !end) {
1530            return null;
1531        }
1532        if (start && end && end < start) {
1533            return null;
1534        }
1535        return { start: start, end: end };
1536    }
1537    // SIDE-EFFECT: will mutate ranges.
1538    // Will return a new array result.
1539    function invertRanges(ranges, constraintRange) {
1540        var invertedRanges = [];
1541        var start = constraintRange.start; // the end of the previous range. the start of the new range
1542        var i;
1543        var dateRange;
1544        // ranges need to be in order. required for our date-walking algorithm
1545        ranges.sort(compareRanges);
1546        for (i = 0; i < ranges.length; i++) {
1547            dateRange = ranges[i];
1548            // add the span of time before the event (if there is any)
1549            if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)
1550                invertedRanges.push({ start: start, end: dateRange.start });
1551            }
1552            if (dateRange.end > start) {
1553                start = dateRange.end;
1554            }
1555        }
1556        // add the span of time after the last event (if there is any)
1557        if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)
1558            invertedRanges.push({ start: start, end: constraintRange.end });
1559        }
1560        return invertedRanges;
1561    }
1562    function compareRanges(range0, range1) {
1563        return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
1564    }
1565    function intersectRanges(range0, range1) {
1566        var start = range0.start;
1567        var end = range0.end;
1568        var newRange = null;
1569        if (range1.start !== null) {
1570            if (start === null) {
1571                start = range1.start;
1572            }
1573            else {
1574                start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
1575            }
1576        }
1577        if (range1.end != null) {
1578            if (end === null) {
1579                end = range1.end;
1580            }
1581            else {
1582                end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
1583            }
1584        }
1585        if (start === null || end === null || start < end) {
1586            newRange = { start: start, end: end };
1587        }
1588        return newRange;
1589    }
1590    function rangesEqual(range0, range1) {
1591        return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
1592            (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
1593    }
1594    function rangesIntersect(range0, range1) {
1595        return (range0.end === null || range1.start === null || range0.end > range1.start) &&
1596            (range0.start === null || range1.end === null || range0.start < range1.end);
1597    }
1598    function rangeContainsRange(outerRange, innerRange) {
1599        return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
1600            (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
1601    }
1602    function rangeContainsMarker(range, date) {
1603        return (range.start === null || date >= range.start) &&
1604            (range.end === null || date < range.end);
1605    }
1606    // If the given date is not within the given range, move it inside.
1607    // (If it's past the end, make it one millisecond before the end).
1608    function constrainMarkerToRange(date, range) {
1609        if (range.start != null && date < range.start) {
1610            return range.start;
1611        }
1612        if (range.end != null && date >= range.end) {
1613            return new Date(range.end.valueOf() - 1);
1614        }
1615        return date;
1616    }
1617
1618    function removeExact(array, exactVal) {
1619        var removeCnt = 0;
1620        var i = 0;
1621        while (i < array.length) {
1622            if (array[i] === exactVal) {
1623                array.splice(i, 1);
1624                removeCnt++;
1625            }
1626            else {
1627                i++;
1628            }
1629        }
1630        return removeCnt;
1631    }
1632    function isArraysEqual(a0, a1) {
1633        var len = a0.length;
1634        var i;
1635        if (len !== a1.length) { // not array? or not same length?
1636            return false;
1637        }
1638        for (i = 0; i < len; i++) {
1639            if (a0[i] !== a1[i]) {
1640                return false;
1641            }
1642        }
1643        return true;
1644    }
1645
1646    function memoize(workerFunc) {
1647        var args;
1648        var res;
1649        return function () {
1650            if (!args || !isArraysEqual(args, arguments)) {
1651                args = arguments;
1652                res = workerFunc.apply(this, arguments);
1653            }
1654            return res;
1655        };
1656    }
1657    /*
1658    always executes the workerFunc, but if the result is equal to the previous result,
1659    return the previous result instead.
1660    */
1661    function memoizeOutput(workerFunc, equalityFunc) {
1662        var cachedRes = null;
1663        return function () {
1664            var newRes = workerFunc.apply(this, arguments);
1665            if (cachedRes === null || !(cachedRes === newRes || equalityFunc(cachedRes, newRes))) {
1666                cachedRes = newRes;
1667            }
1668            return cachedRes;
1669        };
1670    }
1671
1672    var EXTENDED_SETTINGS_AND_SEVERITIES = {
1673        week: 3,
1674        separator: 0,
1675        omitZeroMinute: 0,
1676        meridiem: 0,
1677        omitCommas: 0
1678    };
1679    var STANDARD_DATE_PROP_SEVERITIES = {
1680        timeZoneName: 7,
1681        era: 6,
1682        year: 5,
1683        month: 4,
1684        day: 2,
1685        weekday: 2,
1686        hour: 1,
1687        minute: 1,
1688        second: 1
1689    };
1690    var MERIDIEM_RE = /\s*([ap])\.?m\.?/i; // eats up leading spaces too
1691    var COMMA_RE = /,/g; // we need re for globalness
1692    var MULTI_SPACE_RE = /\s+/g;
1693    var LTR_RE = /\u200e/g; // control character
1694    var UTC_RE = /UTC|GMT/;
1695    var NativeFormatter = /** @class */ (function () {
1696        function NativeFormatter(formatSettings) {
1697            var standardDateProps = {};
1698            var extendedSettings = {};
1699            var severity = 0;
1700            for (var name_1 in formatSettings) {
1701                if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) {
1702                    extendedSettings[name_1] = formatSettings[name_1];
1703                    severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity);
1704                }
1705                else {
1706                    standardDateProps[name_1] = formatSettings[name_1];
1707                    if (name_1 in STANDARD_DATE_PROP_SEVERITIES) {
1708                        severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity);
1709                    }
1710                }
1711            }
1712            this.standardDateProps = standardDateProps;
1713            this.extendedSettings = extendedSettings;
1714            this.severity = severity;
1715            this.buildFormattingFunc = memoize(buildFormattingFunc);
1716        }
1717        NativeFormatter.prototype.format = function (date, context) {
1718            return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
1719        };
1720        NativeFormatter.prototype.formatRange = function (start, end, context) {
1721            var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings;
1722            var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
1723            if (!diffSeverity) {
1724                return this.format(start, context);
1725            }
1726            var biggestUnitForPartial = diffSeverity;
1727            if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time
1728                (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&
1729                (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&
1730                (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
1731                biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time
1732            }
1733            var full0 = this.format(start, context);
1734            var full1 = this.format(end, context);
1735            if (full0 === full1) {
1736                return full0;
1737            }
1738            var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForParti
1738al);
1739            var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
1740            var partial0 = partialFormattingFunc(start);
1741            var partial1 = partialFormattingFunc(end);
1742            var insertion = findCommonInsertion(full0, partial0, full1, partial1);
1743            var separator = extendedSettings.separator || '';
1744            if (insertion) {
1745                return insertion.before + partial0 + separator + partial1 + insertion.after;
1746            }
1747            return full0 + separator + full1;
1748        };
1749        NativeFormatter.prototype.getLargestUnit = function () {
1750            switch (this.severity) {
1751                case 7:
1752                case 6:
1753                case 5:
1754                    return 'year';
1755                case 4:
1756                    return 'month';
1757                case 3:
1758                    return 'week';
1759                default:
1760                    return 'day';
1761            }
1762        };
1763        return NativeFormatter;
1764    }());
1765    function buildFormattingFunc(standardDateProps, extendedSettings, context) {
1766        var standardDatePropCnt = Object.keys(standardDateProps).length;
1767        if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
1768            return function (date) {
1769                return formatTimeZoneOffset(date.timeZoneOffset);
1770            };
1771        }
1772        if (standardDatePropCnt === 0 && extendedSettings.week) {
1773            return function (date) {
1774                return formatWeekNumber(context.computeWeekNumber(date.marker), context.weekLabel, context.locale, extendedSettings.week);
1775            };
1776        }
1777        return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
1778    }
1779    function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
1780        standardDateProps = __assign({}, standardDateProps); // copy
1781        extendedSettings = __assign({}, extendedSettings); // copy
1782        sanitizeSettings(standardDateProps, extendedSettings);
1783        standardDateProps.timeZone = 'UTC'; // we leverage the only guaranteed timeZone for our UTC markers
1784        var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
1785        var zeroFormat; // needed?
1786        if (extendedSettings.omitZeroMinute) {
1787            var zeroProps = __assign({}, standardDateProps);
1788            delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings
1789            zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
1790        }
1791        return function (date) {
1792            var marker = date.marker;
1793            var format;
1794            if (zeroFormat && !marker.getUTCMinutes()) {
1795                format = zeroFormat;
1796            }
1797            else {
1798                format = normalFormat;
1799            }
1800            var s = format.format(marker);
1801            return postProcess(s, date, standardDateProps, extendedSettings, context);
1802        };
1803    }
1804    function sanitizeSettings(standardDateProps, extendedSettings) {
1805        // deal with a browser inconsistency where formatting the timezone
1806        // requires that the hour/minute be present.
1807        if (standardDateProps.timeZoneName) {
1808            if (!standardDateProps.hour) {
1809                standardDateProps.hour = '2-digit';
1810            }
1811            if (!standardDateProps.minute) {
1812                standardDateProps.minute = '2-digit';
1813            }
1814        }
1815        // only support short timezone names
1816        if (standardDateProps.timeZoneName === 'long') {
1817            standardDateProps.timeZoneName = 'short';
1818        }
1819        // if requesting to display seconds, MUST display minutes
1820        if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
1821            delete extendedSettings.omitZeroMinute;
1822        }
1823    }
1824    function postProcess(s, date, standardDateProps, extendedSettings, context) {
1825        s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes
1826        if (standardDateProps.timeZoneName === 'short') {
1827            s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?
1828                'UTC' : // important to normalize for IE, which does "GMT"
1829                formatTimeZoneOffset(date.timeZoneOffset));
1830        }
1831        if (extendedSettings.omitCommas) {
1832            s = s.replace(COMMA_RE, '').trim();
1833        }
1834        if (extendedSettings.omitZeroMinute) {
1835            s = s.replace(':00', ''); // zeroFormat doesn't always achieve this
1836        }
1837        // ^ do anything that might create adjacent spaces before this point,
1838        // because MERIDIEM_RE likes to eat up loading spaces
1839        if (extendedSettings.meridiem === false) {
1840            s = s.replace(MERIDIEM_RE, '').trim();
1841        }
1842        else if (extendedSettings.meridiem === 'narrow') { // a/p
1843            s = s.replace(MERIDIEM_RE, function (m0, m1) {
1844                return m1.toLocaleLowerCase();
1845            });
1846        }
1847        else if (extendedSettings.meridiem === 'short') { // am/pm
1848            s = s.replace(MERIDIEM_RE, function (m0, m1) {
1849                return m1.toLocaleLowerCase() + 'm';
1850            });
1851        }
1852        else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase
1853            s = s.replace(MERIDIEM_RE, function (m0) {
1854                return m0.toLocaleLowerCase();
1855            });
1856        }
1857        s = s.replace(MULTI_SPACE_RE, ' ');
1858        s = s.trim();
1859        return s;
1860    }
1861    function injectTzoStr(s, tzoStr) {
1862        var replaced = false;
1863        s = s.replace(UTC_RE, function () {
1864            replaced = true;
1865            return tzoStr;
1866        });
1867        // IE11 doesn't include UTC/GMT in the original string, so append to end
1868        if (!replaced) {
1869            s += ' ' + tzoStr;
1870        }
1871        return s;
1872    }
1873    function formatWeekNumber(num, weekLabel, locale, display) {
1874        var parts = [];
1875        if (display === 'narrow') {
1876            parts.push(weekLabel);
1877        }
1878        else if (display === 'short') {
1879            parts.push(weekLabel, ' ');
1880        }
1881        // otherwise, considered 'numeric'
1882        parts.push(locale.simpleNumberFormat.format(num));
1883        if (locale.options.isRtl) { // TODO: use control characters instead?
1884            parts.reverse();
1885        }
1886        return parts.join('');
1887    }
1888    // Range Formatting Utils
1889    // 0 = exactly the same
1890    // 1 = different by time
1891    // and bigger
1892    function computeMarkerDiffSeverity(d0, d1, ca) {
1893        if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
1894            return 5;
1895        }
1896        if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
1897            return 4;
1898        }
1899        if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
1900            return 2;
1901        }
1902        if (timeAsMs(d0) !== timeAsMs(d1)) {
1903            return 1;
1904        }
1905        return 0;
1906    }
1907    function computePartialFormattingOptions(options, biggestUnit) {
1908        var partialOptions = {};
1909        for (var name_2 in options) {
1910            if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)
1911                STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) {
1912                partialOptions[name_2] = options[name_2];
1913            }
1914        }
1915        return partialOptions;
1916    }
1917    function findCommonInsertion(full0, partial0, full1, partial1) {
1918        var i0 = 0;
1919        while (i0 < full0.length) {
1920            var found0 = full0.indexOf(partial0, i0);
1921            if (found0 === -1) {
1922                break;
1923            }
1924            var before0 = full0.substr(0, found0);
1925            i0 = found0 + partial0.length;
1926            var after0 = full0.substr(i0);
1927            var i1 = 0;
1928            while (i1 < full1.length) {
1929                var found1 = full1.indexOf(partial1, i1);
1930                if (found1 === -1) {
1931                    break;
1932                }
1933                var before1 = full1.substr(0, found1);
1934                i1 = found1 + partial1.length;
1935                var after1 = full1.substr(i1);
1936                if (before0 === before1 && after0 === after1) {
1937                    return {
1938                        before: before0,
1939                        after: after0
1940                    };
1941                }
1942            }
1943        }
1944        return null;
1945    }
1946
1947    /*
1948    TODO: fix the terminology of "formatter" vs "formatting func"
1949    */
1950    /*
1951    At the time of instantiation, this object does not know which cmd-formatting system it will use.
1952    It receives this at the time of formatting, as a setting.
1953    */
1954    var CmdFormatter = /** @class */ (function () {
1955        function CmdFormatter(cmdStr, separator) {
1956            this.cmdStr = cmdStr;
1957            this.separator = separator;
1958        }
1959        CmdFormatter.prototype.format = function (date, context) {
1960            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, this.separator));
1961        };
1962        CmdFormatter.prototype.formatRange = function (start, end, context) {
1963            return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, this.separator));
1964        };
1965        return CmdFormatter;
1966    }());
1967
1968    var FuncFormatter = /** @class */ (function () {
1969        function FuncFormatter(func) {
1970            this.func = func;
1971        }
1972        FuncFormatter.prototype.format = function (date, context) {
1973            return this.func(createVerboseFormattingArg(date, null, context));
1974        };
1975        FuncFormatter.prototype.formatRange = function (start, end, context) {
1976            return this.func(createVerboseFormattingArg(start, end, context));
1977        };
1978        return FuncFormatter;
1979    }());
1980
1981    // Formatter Object Creation
1982    function createFormatter(input, defaultSeparator) {
1983        if (typeof input === 'object' && input) { // non-null object
1984            if (typeof defaultSeparator === 'string') {
1985                input = __assign({ separator: defaultSeparator }, input);
1986            }
1987            return new NativeFormatter(input);
1988        }
1989        else if (typeof input === 'string') {
1990            return new CmdFormatter(input, defaultSeparator);
1991        }
1992        else if (typeof input === 'function') {
1993            return new FuncFormatter(input);
1994        }
1995    }
1996    // String Utils
1997    // timeZoneOffset is in minutes
1998    function buildIsoString(marker, timeZoneOffset, stripZeroTime) {
1999        if (stripZeroTime === void 0) { stripZeroTime = false; }
2000        var s = marker.toISOString();
2001        s = s.replace('.000', '');
2002        if (stripZeroTime) {
2003            s = s.replace('T00:00:00Z', '');
2004        }
2005        if (s.length > 10) { // time part wasn't stripped, can add timezone info
2006            if (timeZoneOffset == null) {
2007                s = s.replace('Z', '');
2008            }
2009            else if (timeZoneOffset !== 0) {
2010                s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
2011            }
2012            // otherwise, its UTC-0 and we want to keep the Z
2013        }
2014        return s;
2015    }
2016    function formatIsoTimeString(marker) {
2017        return padStart(marker.getUTCHours(), 2) + ':' +
2018            padStart(marker.getUTCMinutes(), 2) + ':' +
2019            padStart(marker.getUTCSeconds(), 2);
2020    }
2021    function formatTimeZoneOffset(minutes, doIso) {
2022        if (doIso === void 0) { doIso = false; }
2023        var sign = minutes < 0 ? '-' : '+';
2024        var abs = Math.abs(minutes);
2025        var hours = Math.floor(abs / 60);
2026        var mins = Math.round(abs % 60);
2027        if (doIso) {
2028            return sign + padStart(hours, 2) + ':' + padStart(mins, 2);
2029        }
2030        else {
2031            return 'GMT' + sign + hours + (mins ? ':' + padStart(mins, 2) : '');
2032        }
2033    }
2034    // Arg Utils
2035    function createVerboseFormattingArg(start, end, context, separator) {
2036        var startInfo = expandZonedMarker(start, context.calendarSystem);
2037        var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
2038        return {
2039            date: startInfo,
2040            start: startInfo,
2041            end: endInfo,
2042            timeZone: context.timeZone,
2043            localeCodes: context.locale.codes,
2044            separator: separator
2045        };
2046    }
2047    function expandZonedMarker(dateInfo, calendarSystem) {
2048        var a = calendarSystem.markerToArray(dateInfo.marker);
2049        return {
2050            marker: dateInfo.marker,
2051            timeZoneOffset: dateInfo.timeZoneOffset,
2052            array: a,
2053            year: a[0],
2054            month: a[1],
2055            day: a[2],
2056            hour: a[3],
2057            minute: a[4],
2058            second: a[5],
2059            millisecond: a[6]
2060        };
2061    }
2062
2063    var EventSourceApi = /** @class */ (function () {
2064        function EventSourceApi(calendar, internalEventSource) {
2065            this.calendar = calendar;
2066            this.internalEventSource = internalEventSource;
2067        }
2068        EventSourceApi.prototype.remove = function () {
2069            this.calendar.dispatch({
2070                type: 'REMOVE_EVENT_SOURCE',
2071                sourceId: this.internalEventSource.sourceId
2072            });
2073        };
2074        EventSourceApi.prototype.refetch = function () {
2075            this.calendar.dispatch({
2076                type: 'FETCH_EVENT_SOURCES',
2077                sourceIds: [this.internalEventSource.sourceId]
2078            });
2079        };
2080        Object.defineProperty(EventSourceApi.prototype, "id", {
2081            get: function () {
2082                return this.internalEventSource.publicId;
2083            },
2084            enumerable: true,
2085            configurable: true
2086        });
2087        Object.defineProperty(EventSourceApi.prototype, "url", {
2088            // only relevant to json-feed event sources
2089            get: function () {
2090                return this.internalEventSource.meta.url;
2091            },
2092            enumerable: true,
2093            configurable: true
2094        });
2095        return EventSourceApi;
2096    }());
2097
2098    var EventApi = /** @class */ (function () {
2099        function EventApi(calendar, def, instance) {
2100            this._calendar = calendar;
2101            this._def = def;
2102            this._instance = instance || null;
2103        }
2104        /*
2105        TODO: make event struct more responsible for this
2106        */
2107        EventApi.prototype.setProp = function (name, val) {
2108            var _a, _b;
2109            if (name in DATE_PROPS) ;
2110            else if (name in NON_DATE_PROPS) {
2111                if (typeof NON_DATE_PROPS[name] === 'function') {
2112                    val = NON_DATE_PROPS[name](val);
2113                }
2114                this.mutate({
2115                    standardProps: (_a = {}, _a[name] = val, _a)
2116                });
2117            }
2118            else if (name in UNSCOPED_EVENT_UI_PROPS) {
2119                var ui = void 0;
2120                if (typeof UNSCOPED_EVENT_UI_PROPS[name] === 'function') {
2121                    val = UNSCOPED_EVENT_UI_PROPS[name](val);
2122                }
2123                if (name === 'color') {
2124                    ui = { backgroundColor: val, borderColor: val };
2125                }
2126                else if (name === 'editable') {
2127                    ui = { startEditable: val, durationEditable: val };
2128                }
2129                else {
2130                    ui = (_b = {}, _b[name] = val, _b);
2131                }
2132                this.mutate({
2133                    standardProps: { ui: ui }
2134                });
2135            }
2136        };
2137        EventApi.prototype.setExtendedProp = function (name, val) {
2138            var _a;
2139            this.mutate({
2140                extendedProps: (_a = {}, _a[name] = val, _a)
2141            });
2142        };
2143        EventApi.prototype.setStart = function (startInput, options) {
2144            if (options === void 0) { options = {}; }
2145            var dateEnv = this._calendar.dateEnv;
2146            var start = dateEnv.createMarker(startInput);
2147            if (start && this._instance) { // TODO: warning if parsed bad
2148                var instanceRange = this._instance.range;
2149                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?
2150                if (options.maintainDuration) {
2151                    this.mutate({ datesDelta: startDelta });
2152                }
2153                else {
2154                    this.mutate({ startDelta: startDelta });
2155                }
2156            }
2157        };
2158        EventApi.prototype.setEnd = function (endInput, options) {
2159            if (options === void 0) { options = {}; }
2160            var dateEnv = this._calendar.dateEnv;
2161            var end;
2162            if (endInput != null) {
2163                end = dateEnv.createMarker(endInput);
2164                if (!end) {
2165                    return; // TODO: warning if parsed bad
2166                }
2167            }
2168            if (this._instance) {
2169                if (end) {
2170                    var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
2171                    this.mutate({ endDelta: endDelta });
2172                }
2173                else {
2174                    this.mutate({ standardProps: { hasEnd: false } });
2175                }
2176            }
2177        };
2178        EventApi.prototype.setDates = function (startInput, endInput, options) {
2179            if (options === void 0) { options = {}; }
2180            var dateEnv = this._calendar.dateEnv;
2181            var standardProps = { allDay: options.allDay };
2182            var start = dateEnv.createMarker(startInput);
2183            var end;
2184            if (!start) {
2185                return; // TODO: warning if parsed bad
2186            }
2187            if (endInput != null) {
2188                end = dateEnv.createMarker(endInput);
2189                if (!end) { // TODO: warning if parsed bad
2190                    return;
2191                }
2192            }
2193            if (this._instance) {
2194                var instanceRange = this._instance.range;
2195                // when computing the diff for an event being converted to all-day,
2196                // compute diff off of the all-day values the way event-mutation does.
2197                if (options.allDay === true) {
2198                    instanceRange = computeAlignedDayRange(instanceRange);
2199                }
2200                var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
2201                if (end) {
2202                    var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
2203                    if (durationsEqual(startDelta, endDelta)) {
2204                        this.mutate({ datesDelta: startDelta, standardProps: standardProps });
2205                    }
2206                    else {
2207                        this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps });
2208                    }
2209                }
2210                else { // means "clear the end"
2211                    standardProps.hasEnd = false;
2212                    this.mutate({ datesDelta: startDelta, standardProps: standardProps });
2213                }
2214            }
2215        };
2216        EventApi.prototype.moveStart = function (deltaInput) {
2217            var delta = createDuration(deltaInput);
2218            if (delta) { // TODO: warning if parsed bad
2219                this.mutate({ startDelta: delta });
2220            }
2221        };
2222        EventApi.prototype.moveEnd = function (deltaInput) {
2223            var delta = createDuration(deltaInput);
2224            if (delta) { // TODO: warning if parsed bad
2225                this.mutate({ endDelta: delta });
2226            }
2227        };
2228        EventApi.prototype.moveDates = function (deltaInput) {
2229            var delta = createDuration(deltaInput);
2230            if (delta) { // TODO: warning if parsed bad
2231                this.mutate({ datesDelta: delta });
2232            }
2233        };
2234        EventApi.prototype.setAllDay = function (allDay, options) {
2235            if (options === void 0) { options = {}; }
2236            var standardProps = { allDay: allDay };
2237            var maintainDuration = options.maintainDuration;
2238            if (maintainDuration == null) {
2239                maintainDuration = this._calendar.opt('allDayMaintainDuration');
2240            }
2241            if (this._def.allDay !== allDay) {
2242                standardProps.hasEnd = maintainDuration;
2243            }
2244            this.mutate({ standardProps: standardProps });
2245        };
2246        EventApi.prototype.formatRange = function (formatInput) {
2247            var dateEnv = this._calendar.dateEnv;
2248            var instance = this._instance;
2249            var formatter = createFormatter(formatInput, this._calendar.opt('defaultRangeSeparator'));
2250            if (this._def.hasEnd) {
2251                return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
2252                    forcedStartTzo: instance.forcedStartTzo,
2253                    forcedEndTzo: instance.forcedEndTzo
2254                });
2255            }
2256            else {
2257                return dateEnv.format(instance.range.start, formatter, {
2258                    forcedTzo: instance.forcedStartTzo
2259                });
2260            }
2261        };
2262        EventApi.prototype.mutate = function (mutation) {
2263            var def = this._def;
2264            var instance = this._instance;
2265            if (instance) {
2266                this._calendar.dispatch({
2267                    type: 'MUTATE_EVENTS',
2268                    instanceId: instance.instanceId,
2269                    mutation: mutation,
2270                    fromApi: true
2271                });
2272                var eventStore = this._calendar.state.eventStore;
2273                this._def = eventStore.defs[def.defId];
2274                this._instance = eventStore.instances[instance.instanceId];
2275            }
2276        };
2277        EventApi.prototype.remove = function () {
2278            this._calendar.dispatch({
2279                type: 'REMOVE_EVENT_DEF',
2280                defId: this._def.defId
2281            });
2282        };
2283        Object.defineProperty(EventApi.prototype, "source", {
2284            get: function () {
2285                var sourceId = this._def.sourceId;
2286                if (sourceId) {
2287                    return new EventSourceApi(this._calendar, this._calendar.state.eventSources[sourceId]);
2288                }
2289                return null;
2290            },
2291            enumerable: true,
2292            configurable: true
2293        });
2294        Object.defineProperty(EventApi.prototype, "start", {
2295            get: function () {
2296                return this._instance ?
2297                    this._calendar.dateEnv.toDate(this._instance.range.start) :
2298                    null;
2299            },
2300            enumerable: true,
2301            configurable: true
2302        });
2303        Object.defineProperty(EventApi.prototype, "end", {
2304            get: function () {
2305                return (this._instance && this._def.hasEnd) ?
2306                    this._calendar.dateEnv.toDate(this._instance.range.end) :
2307                    null;
2308            },
2309            enumerable: true,
2310            configurable: true
2311        });
2312        Object.defineProperty(EventApi.prototype, "id", {
2313            // computable props that all access the def
2314            // TODO: find a TypeScript-compatible way to do this at scale
2315            get: function () { return this._def.publicId; },
2316            enumerable: true,
2317            configurable: true
2318        });
2319        Object.defineProperty(EventApi.prototype, "groupId", {
2320            get: function () { return this._def.groupId; },
2321            enumerable: true,
2322            configurable: true
2323        });
2324        Object.defineProperty(EventApi.prototype, "allDay", {
2325            get: function () { return this._def.allDay; },
2326            enumerable: true,
2327            configurable: true
2328        });
2329        Object.defineProperty(EventApi.prototype, "title", {
2330            get: function () { return this._def.title; },
2331            enumerable: true,
2332            configurable: true
2333        });
2334        Object.defineProperty(EventApi.prototype, "url", {
2335            get: function () { return this._def.url; },
2336            enumerable: true,
2337            configurable: true
2338        });
2339        Object.defineProperty(EventApi.prototype, "rendering", {
2340            get: function () { return this._def.rendering; },
2341            enumerable: true,
2342            configurable: true
2343        });
2344        Object.defineProperty(EventApi.prototype, "startEditable", {
2345            get: function () { return this._def.ui.startEditable; },
2346            enumerable: true,
2347            configurable: true
2348        });
2349        Object.defineProperty(EventApi.prototype, "durationEditable", {
2350            get: function () { return this._def.ui.durationEditable; },
2351            enumerable: true,
2352            configurable: true
2353        });
2354        Object.defineProperty(EventApi.prototype, "constraint", {
2355            get: function () { return this._def.ui.constraints[0] || null; },
2356            enumerable: true,
2357            configurable: true
2358        });
2359        Object.defineProperty(EventApi.prototype, "overlap", {
2360            get: function () { return this._def.ui.overlap; },
2361            enumerable: true,
2362            configurable: true
2363        });
2364        Object.defineProperty(EventApi.prototype, "allow", {
2365            get: function () { return this._def.ui.allows[0] || null; },
2366            enumerable: true,
2367            configurable: true
2368        });
2369        Object.defineProperty(EventApi.prototype, "backgroundColor", {
2370            get: function () { return this._def.ui.backgroundColor; },
2371            enumerable: true,
2372            configurable: true
2373        });
2374        Object.defineProperty(EventApi.prototype, "borderColor", {
2375            get: function () { return this._def.ui.borderColor; },
2376            enumerable: true,
2377            configurable: true
2378        });
2379        Object.defineProperty(EventApi.prototype, "textColor", {
2380            get: function () { return this._def.ui.textColor; },
2381            enumerable: true,
2382            configurable: true
2383        });
2384        Object.defineProperty(EventApi.prototype, "classNames", {
2385            // NOTE: user can't modify these because Object.freeze was called in event-def parsing
2386            get: function () { return this._def.ui.classNames; },
2387            enumerable: true,
2388            configurable: true
2389        });
2390        Object.defineProperty(EventApi.prototype, "extendedProps", {
2391            get: function () { return this._def.extendedProps; },
2392            enumerable: true,
2393            configurable: true
2394        });
2395        return EventApi;
2396    }());
2397
2398    /*
2399    Specifying nextDayThreshold signals that all-day ranges should be sliced.
2400    */
2401    function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
2402        var inverseBgByGroupId = {};
2403        var inverseBgByDefId = {};
2404        var defByGroupId = {};
2405        var bgRanges = [];
2406        var fgRanges = [];
2407        var eventUis = compileEventUis(eventStore.defs, eventUiBases);
2408        for (var defId in eventStore.defs) {
2409            var def = eventStore.defs[defId];
2410            if (def.rendering === 'inverse-background') {
2411                if (def.groupId) {
2412                    inverseBgByGroupId[def.groupId] = [];
2413                    if (!defByGroupId[def.groupId]) {
2414                        defByGroupId[def.groupId] = def;
2415                    }
2416                }
2417                else {
2418                    inverseBgByDefId[defId] = [];
2419                }
2420            }
2421        }
2422        for (var instanceId in eventStore.instances) {
2423            var instance = eventStore.instances[instanceId];
2424            var def = eventStore.defs[instance.defId];
2425            var ui = eventUis[def.defId];
2426            var origRange = instance.range;
2427            var normalRange = (!def.allDay && nextDayThreshold) ?
2428                computeVisibleDayRange(origRange, nextDayThreshold) :
2429                origRange;
2430            var slicedRange = intersectRanges(normalRange, framingRange);
2431            if (slicedRange) {
2432                if (def.rendering === 'inverse-background') {
2433                    if (def.groupId) {
2434                        inverseBgByGroupId[def.groupId].push(slicedRange);
2435                    }
2436                    else {
2437                        inverseBgByDefId[instance.defId].push(slicedRange);
2438                    }
2439                }
2440                else {
2441                    (def.rendering === 'background' ? bgRanges : fgRanges).push({
2442                        def: def,
2443                        ui: ui,
2444                        instance: instance,
2445                        range: slicedRange,
2446                        isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
2447                        isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf()
2448                    });
2449                }
2450            }
2451        }
2452        for (var groupId in inverseBgByGroupId) { // BY GROUP
2453            var ranges = inverseBgByGroupId[groupId];
2454            var invertedRanges = invertRanges(ranges, framingRange);
2455            for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) {
2456                var invertedRange = invertedRanges_1[_i];
2457                var def = defByGroupId[groupId];
2458                var ui = eventUis[def.defId];
2459                bgRanges.push({
2460                    def: def,
2461                    ui: ui,
2462                    instance: null,
2463                    range: invertedRange,
2464                    isStart: false,
2465                    isEnd: false
2466                });
2467            }
2468        }
2469        for (var defId in inverseBgByDefId) {
2470            var ranges = inverseBgByDefId[defId];
2471            var invertedRanges = invertRanges(ranges, framingRange);
2472            for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) {
2473                var invertedRange = invertedRanges_2[_a];
2474                bgRanges.push({
2475                    def: eventStore.defs[defId],
2476                    ui: eventUis[defId],
2477                    instance: null,
2478                    range: invertedRange,
2479                    isStart: false,
2480                    isEnd: false
2481                });
2482            }
2483        }
2484        return { bg: bgRanges, fg: fgRanges };
2485    }
2486    function hasBgRendering(def) {
2487        return def.rendering === 'background' || def.rendering === 'inverse-background';
2488    }
2489    function filterSegsViaEls(view, segs, isMirror) {
2490        if (view.hasPublicHandlers('eventRender')) {
2491            segs = segs.filter(function (seg) {
2492                var custom = view.publiclyTrigger('eventRender', [
2493                    {
2494                        event: new EventApi(view.calendar, seg.eventRange.def, seg.eventRange.instance),
2495                        isMirror: isMirror,
2496                        isStart: seg.isStart,
2497                        isEnd: seg.isEnd,
2498                        // TODO: include seg.range once all components consistently generate it
2499                        el: seg.el,
2500                        view: view
2501                    }
2502                ]);
2503                if (custom === false) { // means don't render at all
2504                    return false;
2505                }
2506                else if (custom && custom !== true) {
2507                    seg.el = custom;
2508                }
2509                return true;
2510            });
2511        }
2512        for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
2513            var seg = segs_1[_i];
2514            setElSeg(seg.el, seg);
2515        }
2516        return segs;
2517    }
2518    function setElSeg(el, seg) {
2519        el.fcSeg = seg;
2520    }
2521    function getElSeg(el) {
2522        return el.fcSeg || null;
2523    }
2524    // event ui computation
2525    function compileEventUis(eventDefs, eventUiBases) {
2526        return mapHash(eventDefs, function (eventDef) {
2527            return compileEventUi(eventDef, eventUiBases);
2528        });
2529    }
2530    function compileEventUi(eventDef, eventUiBases) {
2531        var uis = [];
2532        if (eventUiBases['']) {
2533            uis.push(eventUiBases['']);
2534        }
2535        if (eventUiBases[eventDef.defId]) {
2536            uis.push(eventUiBases[eventDef.defId]);
2537        }
2538        uis.push(eventDef.ui);
2539        return combineEventUis(uis);
2540    }
2541
2542    // applies the mutation to ALL defs/instances within the event store
2543    function applyMutationToEventStore(eventStore, eventConfigBase, mutation, calendar) {
2544        var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
2545        var dest = createEmptyEventStore();
2546        for (var defId in eventStore.defs) {
2547            var def = eventStore.defs[defId];
2548            dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, calendar.pluginSystem.hooks.eventDefMutationAppliers, calendar);
2549        }
2550        for (var instanceId in eventStore.instances) {
2551            var instance = eventStore.instances[instanceId];
2552            var def = dest.defs[instance.defId]; // important to grab the newly modified def
2553            dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, calendar);
2554        }
2555        return dest;
2556    }
2557    function applyMutationToEventDef(eventDef, eventConfig, mutation, appliers, calendar) {
2558        var standardProps = mutation.standardProps || {};
2559        // if hasEnd has not been specified, guess a good value based on deltas.
2560        // if duration will change, there's no way the default duration will persist,
2561        // and thus, we need to mark the event as having a real end
2562        if (standardProps.hasEnd == null &&
2563            eventConfig.durationEditable &&
2564            (mutation.startDelta || mutation.endDelta)) {
2565            standardProps.hasEnd = true; // TODO: is this mutation okay?
2566        }
2567        var copy = __assign({}, eventDef, standardProps, { ui: __assign({}, eventDef.ui, standardProps.ui) });
2568        if (mutation.extendedProps) {
2569            copy.extendedProps = __assign({}, copy.extendedProps, mutation.extendedProps);
2570        }
2571        for (var _i = 0, appliers_1 = appliers; _i < appliers_1.length; _i++) {
2572            var applier = appliers_1[_i];
2573            applier(copy, mutation, calendar);
2574        }
2575        if (!copy.hasEnd && calendar.opt('forceEventDuration')) {
2576            copy.hasEnd = true;
2577        }
2578        return copy;
2579    }
2580    function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
2581    eventConfig, mutation, calendar) {
2582        var dateEnv = calendar.dateEnv;
2583        var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
2584        var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
2585        var copy = __assign({}, eventInstance);
2586        if (forceAllDay) {
2587            copy.range = computeAlignedDayRange(copy.range);
2588        }
2589        if (mutation.datesDelta && eventConfig.startEditable) {
2590            copy.range = {
2591                start: dateEnv.add(copy.range.start, mutation.datesDelta),
2592                end: dateEnv.add(copy.range.end, mutation.datesDelta)
2593            };
2594        }
2595        if (mutation.startDelta && eventConfig.durationEditable) {
2596            copy.range = {
2597                start: dateEnv.add(copy.range.start, mutation.startDelta),
2598                end: copy.range.end
2599            };
2600        }
2601        if (mutation.endDelta && eventConfig.durationEditable) {
2602            copy.range = {
2603                start: copy.range.start,
2604                end: dateEnv.add(copy.range.end, mutation.endDelta)
2605            };
2606        }
2607        if (clearEnd) {
2608            copy.range = {
2609                start: copy.range.start,
2610                end: calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start)
2611            };
2612        }
2613        // in case event was all-day but the supplied deltas were not
2614        // better util for this?
2615        if (eventDef.allDay) {
2616            copy.range = {
2617                start: startOfDay(copy.range.start),
2618                end: startOfDay(copy.range.end)
2619            };
2620        }
2621        // handle invalid durations
2622        if (copy.range.end < copy.range.start) {
2623            copy.range.end = calendar.getDefaultEventEnd(eventDef.allDay, copy.range.start);
2624        }
2625        return copy;
2626    }
2627
2628    function reduceEventStore (eventStore, action, eventSources, dateProfile, calendar) {
2629        switch (action.type) {
2630            case 'RECEIVE_EVENTS': // raw
2631                return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, calendar);
2632            case 'ADD_EVENTS': // already parsed, but not expanded
2633                return addEvent(eventStore, action.eventStore, // new ones
2634                dateProfile ? dateProfile.activeRange : null, calendar);
2635            case 'MERGE_EVENTS': // already parsed and expanded
2636                return mergeEventStores(eventStore, action.eventStore);
2637            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
2638            case 'NEXT':
2639            case 'SET_DATE':
2640            case 'SET_VIEW_TYPE':
2641                if (dateProfile) {
2642                    return expandRecurring(eventStore, dateProfile.activeRange, calendar);
2643                }
2644                else {
2645                    return eventStore;
2646                }
2647            case 'CHANGE_TIMEZONE':
2648                return rezoneDates(eventStore, action.oldDateEnv, calendar.dateEnv);
2649            case 'MUTATE_EVENTS':
2650                return applyMutationToRelated(eventStore, action.instanceId, action.mutation, action.fromApi, calendar);
2651            case 'REMOVE_EVENT_INSTANCES':
2652                return excludeInstances(eventStore, action.instances);
2653            case 'REMOVE_EVENT_DEF':
2654                return filterEventStoreDefs(eventStore, function (eventDef) {
2655                    return eventDef.defId !== action.defId;
2656                });
2657            case 'REMOVE_EVENT_SOURCE':
2658                return excludeEventsBySourceId(eventStore, action.sourceId);
2659            case 'REMOVE_ALL_EVENT_SOURCES':
2660                return filterEventStoreDefs(eventStore, function (eventDef) {
2661                    return !eventDef.sourceId; // only keep events with no source id
2662                });
2663            case 'REMOVE_ALL_EVENTS':
2664                return createEmptyEventStore();
2665            case 'RESET_EVENTS':
2666                return {
2667                    defs: eventStore.defs,
2668                    instances: eventStore.instances
2669                };
2670            default:
2671                return eventStore;
2672        }
2673    }
2674    function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, calendar) {
2675        if (eventSource && // not already removed
2676            fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
2677        ) {
2678            var subset = parseEvents(transformRawEvents(rawEvents, eventSource, calendar), eventSource.sourceId, calendar);
2679            if (fetchRange) {
2680                subset = expandRecurring(subset, fetchRange, calendar);
2681            }
2682            return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
2683        }
2684        return eventStore;
2685    }
2686    function addEvent(eventStore, subset, expandRange, calendar) {
2687        if (expandRange) {
2688            subset = expandRecurring(subset, expandRange, calendar);
2689        }
2690        return mergeEventStores(eventStore, subset);
2691    }
2692    function rezoneDates(eventStore, oldDateEnv, newDateEnv) {
2693        var defs = eventStore.defs;
2694        var instances = mapHash(eventStore.instances, function (instance) {
2695            var def = defs[instance.defId];
2696            if (def.allDay || def.recurringDef) {
2697                return instance; // isn't dependent on timezone
2698            }
2699            else {
2700                return __assign({}, instance, { range: {
2701                        start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
2702                        end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo))
2703                    }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
2704            }
2705        });
2706        return { defs: defs, instances: instances };
2707    }
2708    function applyMutationToRelated(eventStore, instanceId, mutation, fromApi, calendar) {
2709        var relevant = getRelevantEvents(eventStore, instanceId);
2710        var eventConfigBase = fromApi ?
2711            { '': {
2712                    startEditable: true,
2713                    durationEditable: true,
2714                    constraints: [],
2715                    overlap: null,
2716                    allows: [],
2717                    backgroundColor: '',
2718                    borderColor: '',
2719                    textColor: '',
2720                    classNames: []
2721                } } :
2722            calendar.eventUiBases;
2723        relevant = applyMutationToEventStore(relevant, eventConfigBase, mutation, calendar);
2724        return mergeEventStores(eventStore, relevant);
2725    }
2726    function excludeEventsBySourceId(eventStore, sourceId) {
2727        return filterEventStoreDefs(eventStore, function (eventDef) {
2728            return eventDef.sourceId !== sourceId;
2729        });
2730    }
2731    // QUESTION: why not just return instances? do a general object-property-exclusion util
2732    function excludeInstances(eventStore, removals) {
2733        return {
2734            defs: eventStore.defs,
2735            instances: filterHash(eventStore.instances, function (instance) {
2736                return !removals[instance.instanceId];
2737            })
2738        };
2739    }
2740
2741    // high-level segmenting-aware tester functions
2742    // ------------------------------------------------------------------------------------------------------------------------
2743    function isInteractionValid(interaction, calendar) {
2744        return isNewPropsValid({ eventDrag: interaction }, calendar); // HACK: the eventDrag props is used for ALL interactions
2745    }
2746    function isDateSelectionValid(dateSelection, calendar) {
2747        return isNewPropsValid({ dateSelection: dateSelection }, calendar);
2748    }
2749    function isNewPropsValid(newProps, calendar) {
2750        var view = calendar.view;
2751        var props = __assign({ businessHours: view ? view.props.businessHours : createEmptyEventStore(), dateSelection: '', eventStore: calendar.state.eventStore, eventUiBases: calendar.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
2752        return (calendar.pluginSystem.hooks.isPropsValid || isPropsValid)(props, calendar);
2753    }
2754    function isPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2755        if (dateSpanMeta === void 0) { dateSpanMeta = {}; }
2756        if (state.eventDrag && !isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
2757            return false;
2758        }
2759        if (state.dateSelection && !isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig)) {
2760            return false;
2761        }
2762        return true;
2763    }
2764    // Moving Event Validation
2765    // ------------------------------------------------------------------------------------------------------------------------
2766    function isInteractionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2767        var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
2768        var subjectEventStore = interaction.mutatedEvents;
2769        var subjectDefs = subjectEventStore.defs;
2770        var subjectInstances = subjectEventStore.instances;
2771        var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
2772            state.eventUiBases :
2773            { '': calendar.selectionConfig } // if not a real event, validate as a selection
2774        );
2775        if (filterConfig) {
2776            subjectConfigs = mapHash(subjectConfigs, filterConfig);
2777        }
2778        var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); // exclude the subject events. TODO: exclude defs too?
2779        var otherDefs = otherEventStore.defs;
2780        var otherInstances = otherEventStore.instances;
2781        var otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
2782        for (var subjectInstanceId in subjectInstances) {
2783            var subjectInstance = subjectInstances[subjectInstanceId];
2784            var subjectRange = subjectInstance.range;
2785            var subjectConfig = subjectConfigs[subjectInstance.defId];
2786            var subjectDef = subjectDefs[subjectInstance.defId];
2787            // constraint
2788            if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, calendar)) {
2789                return false;
2790            }
2791            // overlap
2792            var overlapFunc = calendar.opt('eventOverlap');
2793            if (typeof overlapFunc !== 'function') {
2794                overlapFunc = null;
2795            }
2796            for (var otherInstanceId in otherInstances) {
2797                var otherInstance = otherInstances[otherInstanceId];
2798                // intersect! evaluate
2799                if (rangesIntersect(subjectRange, otherInstance.range)) {
2800                    var otherOverlap = otherConfigs[otherInstance.defId].overlap;
2801                    // consider the other event's overlap. only do this if the subject event is a "real" event
2802                    if (otherOverlap === false && interaction.isEvent) {
2803                        return false;
2804                    }
2805                    if (subjectConfig.overlap === false) {
2806                        return false;
2807                    }
2808                    if (overlapFunc && !overlapFunc(new EventApi(calendar, otherDefs[otherInstance.defId], otherInstance), // still event
2809                    new EventApi(calendar, subjectDef, subjectInstance) // moving event
2810                    )) {
2811                        return false;
2812                    }
2813                }
2814            }
2815            // allow (a function)
2816            var calendarEventStore = calendar.state.eventStore; // need global-to-calendar, not local to component (splittable)state
2817            for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) {
2818                var subjectAllow = _a[_i];
2819                var subjectDateSpan = __assign({}, dateSpanMeta, { range: subjectInstance.range, allDay: subjectDef.allDay });
2820                var origDef = calendarEventStore.defs[subjectDef.defId];
2821                var origInstance = calendarEventStore.instances[subjectInstanceId];
2822                var eventApi = void 0;
2823                if (origDef) { // was previously in the calendar
2824                    eventApi = new EventApi(calendar, origDef, origInstance);
2825                }
2826                else { // was an external event
2827                    eventApi = new EventApi(calendar, subjectDef); // no instance, because had no dates
2828                }
2829                if (!subjectAllow(calendar.buildDateSpanApi(subjectDateSpan), eventApi)) {
2830                    return false;
2831                }
2832            }
2833        }
2834        return true;
2835    }
2836    // Date Selection Validation
2837    // ------------------------------------------------------------------------------------------------------------------------
2838    function isDateSelectionPropsValid(state, calendar, dateSpanMeta, filterConfig) {
2839        var relevantEventStore = state.eventStore;
2840        var relevantDefs = relevantEventStore.defs;
2841        var relevantInstances = relevantEventStore.instances;
2842        var selection = state.dateSelection;
2843        var selectionRange = selection.range;
2844        var selectionConfig = calendar.selectionConfig;
2845        if (filterConfig) {
2846            selectionConfig = filterConfig(selectionConfig);
2847        }
2848        // constraint
2849        if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, calendar)) {
2850            return false;
2851        }
2852        // overlap
2853        var overlapFunc = calendar.opt('selectOverlap');
2854        if (typeof overlapFunc !== 'function') {
2855            overlapFunc = null;
2856        }
2857        for (var relevantInstanceId in relevantInstances) {
2858            var relevantInstance = relevantInstances[relevantInstanceId];
2859            // intersect! evaluate
2860            if (rangesIntersect(selectionRange, relevantInstance.range)) {
2861                if (selectionConfig.overlap === false) {
2862                    return false;
2863                }
2864                if (overlapFunc && !overlapFunc(new EventApi(calendar, relevantDefs[relevantInstance.defId], relevantInstance))) {
2865                    return false;
2866                }
2867            }
2868        }
2869        // allow (a function)
2870        for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) {
2871            var selectionAllow = _a[_i];
2872            var fullDateSpan = __assign({}, dateSpanMeta, selection);
2873            if (!selectionAllow(calendar.buildDateSpanApi(fullDateSpan), null)) {
2874                return false;
2875            }
2876        }
2877        return true;
2878    }
2879    // Constraint Utils
2880    // ------------------------------------------------------------------------------------------------------------------------
2881    function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, calendar) {
2882        for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
2883            var constraint = constraints_1[_i];
2884            if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, calendar), subjectRange)) {
2885                return false;
2886            }
2887        }
2888        return true;
2889    }
2890    function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
2891    otherEventStore, // for if constraint is an even group ID
2892    businessHoursUnexpanded, // for if constraint is 'businessHours'
2893    calendar // for expanding businesshours
2894    ) {
2895        if (constraint === 'businessHours') {
2896            return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, calendar));
2897        }
2898        else if (typeof constraint === 'string') { // an group ID
2899            return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) {
2900                return eventDef.groupId === constraint;
2901            }));
2902        }
2903        else if (typeof constraint === 'object' && constraint) { // non-null object
2904            return eventStoreToRanges(expandRecurring(constraint, subjectRange, calendar));
2905        }
2906        return []; // if it's false
2907    }
2908    // TODO: move to event-store file?
2909    function eventStoreToRanges(eventStore) {
2910        var instances = eventStore.instances;
2911        var ranges = [];
2912        for (var instanceId in instances) {
2913            ranges.push(instances[instanceId].range);
2914        }
2915        return ranges;
2916    }
2917    // TODO: move to geom file?
2918    function anyRangesContainRange(outerRanges, innerRange) {
2919        for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) {
2920            var outerRange = outerRanges_1[_i];
2921            if (rangeContainsRange(outerRange, innerRange)) {
2922                return true;
2923            }
2924        }
2925        return false;
2926    }
2927    // Parsing
2928    // ------------------------------------------------------------------------------------------------------------------------
2929    function normalizeConstraint(input, calendar) {
2930        if (Array.isArray(input)) {
2931            return parseEvents(input, '', calendar, true); // allowOpenRange=true
2932        }
2933        else if (typeof input === 'object' && input) { // non-null object
2934            return parseEvents([input], '', calendar, true); // allowOpenRange=true
2935        }
2936        else if (input != null) {
2937            return String(input);
2938        }
2939        else {
2940            return null;
2941        }
2942    }
2943
2944    function htmlEscape(s) {
2945        return (s + '').replace(/&/g, '&amp;')
2946            .replace(/</g, '&lt;')
2947            .replace(/>/g, '&gt;')
2948            .replace(/'/g, '&#039;')
2949            .replace(/"/g, '&quot;')
2950            .replace(/\n/g, '<br />');
2951    }
2952    // Given a hash of CSS properties, returns a string of CSS.
2953    // Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.
2954    function cssToStr(cssProps) {
2955        var statements = [];
2956        for (var name_1 in cssProps) {
2957            var val = cssProps[name_1];
2958            if (val != null && val !== '') {
2959                statements.push(name_1 + ':' + val);
2960            }
2961        }
2962        return statements.join(';');
2963    }
2964    // Given an object hash of HTML attribute names to values,
2965    // generates a string that can be injected between < > in HTML
2966    function attrsToStr(attrs) {
2967        var parts = [];
2968        for (var name_2 in attrs) {
2969            var val = attrs[name_2];
2970            if (val != null) {
2971                parts.push(name_2 + '="' + htmlEscape(val) + '"');
2972            }
2973        }
2974        return parts.join(' ');
2975    }
2976    function parseClassName(raw) {
2977        if (Array.isArray(raw)) {
2978            return raw;
2979        }
2980        else if (typeof raw === 'string') {
2981            return raw.split(/\s+/);
2982        }
2983        else {
2984            return [];
2985        }
2986    }
2987
2988    var UNSCOPED_EVENT_UI_PROPS = {
2989        editable: Boolean,
2990        startEditable: Boolean,
2991        durationEditable: Boolean,
2992        constraint: null,
2993        overlap: null,
2994        allow: null,
2995        className: parseClassName,
2996        classNames: parseClassName,
2997        color: String,
2998        backgroundColor: String,
2999        borderColor: String,
3000        textColor: String
3001    };
3002    function processUnscopedUiProps(rawProps, calendar, leftovers) {
3003        var props = refineProps(rawProps, UNSCOPED_EVENT_UI_PROPS, {}, leftovers);
3004        var constraint = normalizeConstraint(props.constraint, calendar);
3005        return {
3006            startEditable: props.startEditable != null ? props.startEditable : props.editable,
3007            durationEditable: props.durationEditable != null ? props.durationEditable : props.editable,
3008            constraints: constraint != null ? [constraint] : [],
3009            overlap: props.overlap,
3010            allows: props.allow != null ? [props.allow] : [],
3011            backgroundColor: props.backgroundColor || props.color,
3012            borderColor: props.borderColor || props.color,
3013            textColor: props.textColor,
3014            classNames: props.classNames.concat(props.className)
3015        };
3016    }
3017    function processScopedUiProps(prefix, rawScoped, calendar, leftovers) {
3018        var rawUnscoped = {};
3019        var wasFound = {};
3020        for (var key in UNSCOPED_EVENT_UI_PROPS) {
3021            var scopedKey = prefix + capitaliseFirstLetter(key);
3022            rawUnscoped[key] = rawScoped[scopedKey];
3023            wasFound[scopedKey] = true;
3024        }
3025        if (prefix === 'event') {
3026            rawUnscoped.editable = rawScoped.editable; // special case. there is no 'eventEditable', just 'editable'
3027        }
3028        if (leftovers) {
3029            for (var key in rawScoped) {
3030                if (!wasFound[key]) {
3031                    leftovers[key] = rawScoped[key];
3032                }
3033            }
3034        }
3035        return processUnscopedUiProps(rawUnscoped, calendar);
3036    }
3037    var EMPTY_EVENT_UI = {
3038        startEditable: null,
3039        durationEditable: null,
3040        constraints: [],
3041        overlap: null,
3042        allows: [],
3043        backgroundColor: '',
3044        borderColor: '',
3045        textColor: '',
3046        classNames: []
3047    };
3048    // prevent against problems with <2 args!
3049    function combineEventUis(uis) {
3050        return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
3051    }
3052    function combineTwoEventUis(item0, item1) {
3053        return {
3054            startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
3055            durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
3056            constraints: item0.constraints.concat(item1.constraints),
3057            overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
3058            allows: item0.allows.concat(item1.allows),
3059            backgroundColor: item1.backgroundColor || item0.backgroundColor,
3060            borderColor: item1.borderColor || item0.borderColor,
3061            textColor: item1.textColor || item0.textColor,
3062            classNames: item0.classNames.concat(item1.classNames)
3063        };
3064    }
3065
3066    var NON_DATE_PROPS = {
3067        id: String,
3068        groupId: String,
3069        title: String,
3070        url: String,
3071        rendering: String,
3072        extendedProps: null
3073    };
3074    var DATE_PROPS = {
3075        start: null,
3076        date: null,
3077        end: null,
3078        allDay: null
3079    };
3080    var uid = 0;
3081    function parseEvent(raw, sourceId, calendar, allowOpenRange) {
3082        var allDayDefault = computeIsAllDayDefault(sourceId, calendar);
3083        var leftovers0 = {};
3084        var recurringRes = parseRecurring(raw, // raw, but with single-event stuff stripped out
3085        allDayDefault, calendar.dateEnv, calendar.pluginSystem.hooks.recurringTypes, leftovers0 // will populate with non-recurring props
3086        );
3087        if (recurringRes) {
3088            var def = parseEventDef(leftovers0, sourceId, recurringRes.allDay, Boolean(recurringRes.duration), calendar);
3089            def.recurringDef = {
3090                typeId: recurringRes.typeId,
3091                typeData: recurringRes.typeData,
3092                duration: recurringRes.duration
3093            };
3094            return { def: def, instance: null };
3095        }
3096        else {
3097            var leftovers1 = {};
3098            var singleRes = parseSingle(raw, allDayDefault, calendar, leftovers1, allowOpenRange);
3099            if (singleRes) {
3100                var def = parseEventDef(leftovers1, sourceId, singleRes.allDay, singleRes.hasEnd, calendar);
3101                var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
3102                return { def: def, instance: instance };
3103            }
3104        }
3105        return null;
3106    }
3107    /*
3108    Will NOT populate extendedProps with the leftover properties.
3109    Will NOT populate date-related props.
3110    The EventNonDateInput has been normalized (id => publicId, etc).
3111    */
3112    function parseEventDef(raw, sourceId, allDay, hasEnd, calendar) {
3113        var leftovers = {};
3114        var def = pluckNonDateProps(raw, calendar, leftovers);
3115        def.defId = String(uid++);
3116        def.sourceId = sourceId;
3117        def.allDay = allDay;
3118        def.hasEnd = hasEnd;
3119        for (var _i = 0, _a = calendar.pluginSystem.hooks.eventDefParsers; _i < _a.length; _i++) {
3120            var eventDefParser = _a[_i];
3121            var newLeftovers = {};
3122            eventDefParser(def, leftovers, newLeftovers);
3123            leftovers = newLeftovers;
3124        }
3125        def.extendedProps = __assign(leftovers, def.extendedProps || {});
3126        // help out EventApi from having user modify props
3127        Object.freeze(def.ui.classNames);
3128        Object.freeze(def.extendedProps);
3129        return def;
3130    }
3131    function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
3132        return {
3133            instanceId: String(uid++),
3134            defId: defId,
3135            range: range,
3136            forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
3137            forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo
3138        };
3139    }
3140    function parseSingle(raw, allDayDefault, calendar, leftovers, allowOpenRange) {
3141        var props = pluckDateProps(raw, leftovers);
3142        var allDay = props.allDay;
3143        var startMeta;
3144        var startMarker = null;
3145        var hasEnd = false;
3146        var endMeta;
3147        var endMarker = null;
3148        startMeta = calendar.dateEnv.createMarkerMeta(props.start);
3149        if (startMeta) {
3150            startMarker = startMeta.marker;
3151        }
3152        else if (!allowOpenRange) {
3153            return null;
3154        }
3155        if (props.end != null) {
3156            endMeta = calendar.dateEnv.createMarkerMeta(props.end);
3157        }
3158        if (allDay == null) {
3159            if (allDayDefault != null) {
3160                allDay = allDayDefault;
3161            }
3162            else {
3163                // fall back to the date props LAST
3164                allDay = (!startMeta || startMeta.isTimeUnspecified) &&
3165                    (!endMeta || endMeta.isTimeUnspecified);
3166            }
3167        }
3168        if (allDay && startMarker) {
3169            startMarker = startOfDay(startMarker);
3170        }
3171        if (endMeta) {
3172            endMarker = endMeta.marker;
3173            if (allDay) {
3174                endMarker = startOfDay(endMarker);
3175            }
3176            if (startMarker && endMarker <= startMarker) {
3177                endMarker = null;
3178            }
3179        }
3180        if (endMarker) {
3181            hasEnd = true;
3182        }
3183        else if (!allowOpenRange) {
3184            hasEnd = calendar.opt('forceEventDuration') || false;
3185            endMarker = calendar.dateEnv.add(startMarker, allDay ?
3186                calendar.defaultAllDayEventDuration :
3187                calendar.defaultTimedEventDuration);
3188        }
3189        return {
3190            allDay: allDay,
3191            hasEnd: hasEnd,
3192            range: { start: startMarker, end: endMarker },
3193            forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
3194            forcedEndTzo: endMeta ? endMeta.forcedTzo : null
3195        };
3196    }
3197    function pluckDateProps(raw, leftovers) {
3198        var props = refineProps(raw, DATE_PROPS, {}, leftovers);
3199        props.start = (props.start !== null) ? props.start : props.date;
3200        delete props.date;
3201        return props;
3202    }
3203    function pluckNonDateProps(raw, calendar, leftovers) {
3204        var preLeftovers = {};
3205        var props = refineProps(raw, NON_DATE_PROPS, {}, preLeftovers);
3206        var ui = processUnscopedUiProps(preLeftovers, calendar, leftovers);
3207        props.publicId = props.id;
3208        delete props.id;
3209        props.ui = ui;
3210        return props;
3211    }
3212    function computeIsAllDayDefault(sourceId, calendar) {
3213        var res = null;
3214        if (sourceId) {
3215            var source = calendar.state.eventSources[sourceId];
3216            res = source.allDayDefault;
3217        }
3218        if (res == null) {
3219            res = calendar.opt('allDayDefault');
3220        }
3221        return res;
3222    }
3223
3224    var DEF_DEFAULTS = {
3225        startTime: '09:00',
3226        endTime: '17:00',
3227        daysOfWeek: [1, 2, 3, 4, 5],
3228        rendering: 'inverse-background',
3229        classNames: 'fc-nonbusiness',
3230        groupId: '_businessHours' // so multiple defs get grouped
3231    };
3232    /*
3233    TODO: pass around as EventDefHash!!!
3234    */
3235    function parseBusinessHours(input, calendar) {
3236        return parseEvents(refineInputs(input), '', calendar);
3237    }
3238    function refineInputs(input) {
3239        var rawDefs;
3240        if (input === true) {
3241            rawDefs = [{}]; // will get DEF_DEFAULTS verbatim
3242        }
3243        else if (Array.isArray(input)) {
3244            // if specifying an array, every sub-definition NEEDS a day-of-week
3245            rawDefs = input.filter(function (rawDef) {
3246                return rawDef.daysOfWeek;
3247            });
3248        }
3249        else if (typeof input === 'object' && input) { // non-null object
3250            rawDefs = [input];
3251        }
3252        else { // is probably false
3253            rawDefs = [];
3254        }
3255        rawDefs = rawDefs.map(function (rawDef) {
3256            return __assign({}, DEF_DEFAULTS, rawDef);
3257        });
3258        return rawDefs;
3259    }
3260
3261    function memoizeRendering(renderFunc, unrenderFunc, dependencies) {
3262        if (dependencies === void 0) { dependencies = []; }
3263        var dependents = [];
3264        var thisContext;
3265        var prevArgs;
3266        function unrender() {
3267            if (prevArgs) {
3268                for (var _i = 0, dependents_1 = dependents; _i < dependents_1.length; _i++) {
3269                    var dependent = dependents_1[_i];
3270                    dependent.unrender();
3271                }
3272                if (unrenderFunc) {
3273                    unrenderFunc.apply(thisContext, prevArgs);
3274                }
3275                prevArgs = null;
3276            }
3277        }
3278        function res() {
3279            if (!prevArgs || !isArraysEqual(prevArgs, arguments)) {
3280                unrender();
3281                thisContext = this;
3282                prevArgs = arguments;
3283                renderFunc.apply(this, arguments);
3284            }
3285        }
3286        res.dependents = dependents;
3287        res.unrender = unrender;
3288        for (var _i = 0, dependencies_1 = dependencies; _i < dependencies_1.length; _i++) {
3289            var dependency = dependencies_1[_i];
3290            dependency.dependents.push(res);
3291        }
3292        return res;
3293    }
3294
3295    var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
3296    var Splitter = /** @class */ (function () {
3297        function Splitter() {
3298            this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
3299            this.splitDateSelection = memoize(this._splitDateSpan);
3300            this.splitEventStore = memoize(this._splitEventStore);
3301            this.splitIndividualUi = memoize(this._splitIndividualUi);
3302            this.splitEventDrag = memoize(this._splitInteraction);
3303            this.splitEventResize = memoize(this._splitInteraction);
3304            this.eventUiBuilders = {}; // TODO: typescript protection
3305        }
3306        Splitter.prototype.splitProps = function (props) {
3307            var _this = this;
3308            var keyInfos = this.getKeyInfo(props);
3309            var defKeys = this.getKeysForEventDefs(props.eventStore);
3310            var dateSelections = this.splitDateSelection(props.dateSelection);
3311            var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
3312            var eventStores = this.splitEventStore(props.eventStore, defKeys);
3313            var eventDrags = this.splitEventDrag(props.eventDrag);
3314            var eventResizes = this.splitEventResize(props.eventResize);
3315            var splitProps = {};
3316            this.eventUiBuilders = mapHash(keyInfos, function (info, key) {
3317                return _this.eventUiBuilders[key] || memoize(buildEventUiForKey);
3318            });
3319            for (var key in keyInfos) {
3320                var keyInfo = keyInfos[key];
3321                var eventStore = eventStores[key] || EMPTY_EVENT_STORE;
3322                var buildEventUi = this.eventUiBuilders[key];
3323                splitProps[key] = {
3324                    businessHours: keyInfo.businessHours || props.businessHours,
3325                    dateSelection: dateSelections[key] || null,
3326                    eventStore: eventStore,
3327                    eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
3328                    eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
3329                    eventDrag: eventDrags[key] || null,
3330                    eventResize: eventResizes[key] || null
3331                };
3332            }
3333            return splitProps;
3334        };
3335        Splitter.prototype._splitDateSpan = function (dateSpan) {
3336            var dateSpans = {};
3337            if (dateSpan) {
3338                var keys = this.getKeysForDateSpan(dateSpan);
3339                for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
3340                    var key = keys_1[_i];
3341                    dateSpans[key] = dateSpan;
3342                }
3343            }
3344            return dateSpans;
3345        };
3346        Splitter.prototype._getKeysForEventDefs = function (eventStore) {
3347            var _this = this;
3348            return mapHash(eventStore.defs, function (eventDef) {
3349                return _this.getKeysForEventDef(eventDef);
3350            });
3351        };
3352        Splitter.prototype._splitEventStore = function (eventStore, defKeys) {
3353            var defs = eventStore.defs, instances = eventStore.instances;
3354            var splitStores = {};
3355            for (var defId in defs) {
3356                for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
3357                    var key = _a[_i];
3358                    if (!splitStores[key]) {
3359                        splitStores[key] = createEmptyEventStore();
3360                    }
3361                    splitStores[key].defs[defId] = defs[defId];
3362                }
3363            }
3364            for (var instanceId in instances) {
3365                var instance = instances[instanceId];
3366                for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) {
3367                    var key = _c[_b];
3368                    if (splitStores[key]) { // must have already been created
3369                        splitStores[key].instances[instanceId] = instance;
3370                    }
3371                }
3372            }
3373            return splitStores;
3374        };
3375        Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) {
3376            var splitHashes = {};
3377            for (var defId in eventUiBases) {
3378                if (defId) { // not the '' key
3379                    for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) {
3380                        var key = _a[_i];
3381                        if (!splitHashes[key]) {
3382                            splitHashes[key] = {};
3383                        }
3384                        splitHashes[key][defId] = eventUiBases[defId];
3385                    }
3386                }
3387            }
3388            return splitHashes;
3389        };
3390        Splitter.prototype._splitInteraction = function (interaction) {
3391            var splitStates = {};
3392            if (interaction) {
3393                var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents) // can't use cached. might be events from other calendar
3394                );
3395                // can't rely on defKeys because event data is mutated
3396                var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
3397                var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
3398                var populate = function (key) {
3399                    if (!splitStates[key]) {
3400                        splitStates[key] = {
3401                            affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE,
3402                            mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE,
3403                            isEvent: interaction.isEvent,
3404                            origSeg: interaction.origSeg
3405                        };
3406                    }
3407                };
3408                for (var key in affectedStores_1) {
3409                    populate(key);
3410                }
3411                for (var key in mutatedStores_1) {
3412                    populate(key);
3413                }
3414            }
3415            return splitStates;
3416        };
3417        return Splitter;
3418    }());
3419    function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
3420        var baseParts = [];
3421        if (allUi) {
3422            baseParts.push(allUi);
3423        }
3424        if (eventUiForKey) {
3425            baseParts.push(eventUiForKey);
3426        }
3427        var stuff = {
3428            '': combineEventUis(baseParts)
3429        };
3430        if (individualUi) {
3431            __assign(stuff, individualUi);
3432        }
3433        return stuff;
3434    }
3435
3436    // Generates HTML for an anchor to another view into the calendar.
3437    // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings.
3438    // `gotoOptions` can either be a DateMarker, or an object with the form:
3439    // { date, type, forceOff }
3440    // `type` is a view-type like "day" or "week". default value is "day".
3441    // `attrs` and `innerHtml` are use to generate the rest of the HTML tag.
3442    function buildGotoAnchorHtml(component, gotoOptions, attrs, innerHtml) {
3443        var dateEnv = component.dateEnv;
3444        var date;
3445        var type;
3446        var forceOff;
3447        var finalOptions;
3448        if (gotoOptions instanceof Date) {
3449            date = gotoOptions; // a single date-like input
3450        }
3451        else {
3452            date = gotoOptions.date;
3453            type = gotoOptions.type;
3454            forceOff = gotoOptions.forceOff;
3455        }
3456        finalOptions = {
3457            date: dateEnv.formatIso(date, { omitTime: true }),
3458            type: type || 'day'
3459        };
3460        if (typeof attrs === 'string') {
3461            innerHtml = attrs;
3462            attrs = null;
3463        }
3464        attrs = attrs ? ' ' + attrsToStr(attrs) : ''; // will have a leading space
3465        innerHtml = innerHtml || '';
3466        if (!forceOff && component.opt('navLinks')) {
3467            return '<a' + attrs +
3468                ' data-goto="' + htmlEscape(JSON.stringify(finalOptions)) + '">' +
3469                innerHtml +
3470                '</a>';
3471        }
3472        else {
3473            return '<span' + attrs + '>' +
3474                innerHtml +
3475                '</span>';
3476        }
3477    }
3478    function getAllDayHtml(component) {
3479        return component.opt('allDayHtml') || htmlEscape(component.opt('allDayText'));
3480    }
3481    // Computes HTML classNames for a single-day element
3482    function getDayClasses(date, dateProfile, context, noThemeHighlight) {
3483        var calendar = context.calendar, view = context.view, theme = context.theme, dateEnv = context.dateEnv;
3484        var classes = [];
3485        var todayStart;
3486        var todayEnd;
3487        if (!rangeContainsMarker(dateProfile.activeRange, date)) {
3488            classes.push('fc-disabled-day');
3489        }
3490        else {
3491            classes.push('fc-' + DAY_IDS[date.getUTCDay()]);
3492            if (view.opt('monthMode') &&
3493                dateEnv.getMonth(date) !== dateEnv.getMonth(dateProfile.currentRange.start)) {
3494                classes.push('fc-other-month');
3495            }
3496            todayStart = startOfDay(calendar.getNow());
3497            todayEnd = addDays(todayStart, 1);
3498            if (date < todayStart) {
3499                classes.push('fc-past');
3500            }
3501            else if (date >= todayEnd) {
3502                classes.push('fc-future');
3503            }
3504            else {
3505                classes.push('fc-today');
3506                if (noThemeHighlight !== true) {
3507                    classes.push(theme.getClass('today'));
3508                }
3509            }
3510        }
3511        return classes;
3512    }
3513
3514    // given a function that resolves a result asynchronously.
3515    // the function can either call passed-in success and failure callbacks,
3516    // or it can return a promise.
3517    // if you need to pass additional params to func, bind them first.
3518    function unpromisify(func, success, failure) {
3519        // guard against success/failure callbacks being called more than once
3520        // and guard against a promise AND callback being used together.
3521        var isResolved = false;
3522        var wrappedSuccess = function () {
3523            if (!isResolved) {
3524                isResolved = true;
3525                success.apply(this, arguments);
3526            }
3527        };
3528        var wrappedFailure = function () {
3529            if (!isResolved) {
3530                isResolved = true;
3531                if (failure) {
3532                    failure.apply(this, arguments);
3533                }
3534            }
3535        };
3536        var res = func(wrappedSuccess, wrappedFailure);
3537        if (res && typeof res.then === 'function') {
3538            res.then(wrappedSuccess, wrappedFailure);
3539        }
3540    }
3541
3542    var Mixin = /** @class */ (function () {
3543        function Mixin() {
3544        }
3545        // mix into a CLASS
3546        Mixin.mixInto = function (destClass) {
3547            this.mixIntoObj(destClass.prototype);
3548        };
3549        // mix into ANY object
3550        Mixin.mixIntoObj = function (destObj) {
3551            var _this = this;
3552            Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
3553                if (!destObj[name]) { // if destination doesn't already define it
3554                    destObj[name] = _this.prototype[name];
3555                }
3556            });
3557        };
3558        /*
3559        will override existing methods
3560        TODO: remove! not used anymore
3561        */
3562        Mixin.mixOver = function (destClass) {
3563            var _this = this;
3564            Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
3565                destClass.prototype[name] = _this.prototype[name];
3566            });
3567        };
3568        return Mixin;
3569    }());
3570
3571    /*
3572    USAGE:
3573      import { default as EmitterMixin, EmitterInterface } from './EmitterMixin'
3574    in class:
3575      on: EmitterInterface['on']
3576      one: EmitterInterface['one']
3577      off: EmitterInterface['off']
3578      trigger: EmitterInterface['trigger']
3579      triggerWith: EmitterInterface['triggerWith']
3580      hasHandlers: EmitterInterface['hasHandlers']
3581    after class:
3582      EmitterMixin.mixInto(TheClass)
3583    */
3584    var EmitterMixin = /** @class */ (function (_super) {
3585        __extends(EmitterMixin, _super);
3586        function EmitterMixin() {
3587            return _super !== null && _super.apply(this, arguments) || this;
3588        }
3589        EmitterMixin.prototype.on = function (type, handler) {
3590            addToHash(this._handlers || (this._handlers = {}), type, handler);
3591            return this; // for chaining
3592        };
3593        // todo: add comments
3594        EmitterMixin.prototype.one = function (type, handler) {
3595            addToHash(this._oneHandlers || (this._oneHandlers = {}), type, handler);
3596            return this; // for chaining
3597        };
3598        EmitterMixin.prototype.off = function (type, handler) {
3599            if (this._handlers) {
3600                removeFromHash(this._handlers, type, handler);
3601            }
3602            if (this._oneHandlers) {
3603                removeFromHash(this._oneHandlers, type, handler);
3604            }
3605            return this; // for chaining
3606        };
3607        EmitterMixin.prototype.trigger = function (type) {
3608            var args = [];
3609            for (var _i = 1; _i < arguments.length; _i++) {
3610                args[_i - 1] = arguments[_i];
3611            }
3612            this.triggerWith(type, this, args);
3613            return this; // for chaining
3614        };
3615        EmitterMixin.prototype.triggerWith = function (type, context, args) {
3616            if (this._handlers) {
3617                applyAll(this._handlers[type], context, args);
3618            }
3619            if (this._oneHandlers) {
3620                applyAll(this._oneHandlers[type], context, args);
3621                delete this._oneHandlers[type]; // will never fire again
3622            }
3623            return this; // for chaining
3624        };
3625        EmitterMixin.prototype.hasHandlers = function (type) {
3626            return (this._handlers && this._handlers[type] && this._handlers[type].length) ||
3627                (this._oneHandlers && this._oneHandlers[type] && this._oneHandlers[type].length);
3628        };
3629        return EmitterMixin;
3630    }(Mixin));
3631    function addToHash(hash, type, handler) {
3632        (hash[type] || (hash[type] = []))
3633            .push(handler);
3634    }
3635    function removeFromHash(hash, type, handler) {
3636        if (handler) {
3637            if (hash[type]) {
3638                hash[type] = hash[type].filter(function (func) {
3639                    return func !== handler;
3640                });
3641            }
3642        }
3643        else {
3644            delete hash[type]; // remove all handler funcs for this type
3645        }
3646    }
3647
3648    /*
3649    Records offset information for a set of elements, relative to an origin element.
3650    Can record the left/right OR the top/bottom OR both.
3651    Provides methods for querying the cache by position.
3652    */
3653    var PositionCache = /** @class */ (function () {
3654        function PositionCache(originEl, els, isHorizontal, isVertical) {
3655            this.originEl = originEl;
3656            this.els = els;
3657            this.isHorizontal = isHorizontal;
3658            this.isVertical = isVertical;
3659        }
3660        // Queries the els for coordinates and stores them.
3661        // Call this method before using and of the get* methods below.
3662        PositionCache.prototype.build = function () {
3663            var originEl = this.originEl;
3664            var originClientRect = this.originClientRect =
3665                originEl.getBoundingClientRect(); // relative to viewport top-left
3666            if (this.isHorizontal) {
3667                this.buildElHorizontals(originClientRect.left);
3668            }
3669            if (this.isVertical) {
3670                this.buildElVerticals(originClientRect.top);
3671            }
3672        };
3673        // Populates the left/right internal coordinate arrays
3674        PositionCache.prototype.buildElHorizontals = function (originClientLeft) {
3675            var lefts = [];
3676            var rights = [];
3677            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
3678                var el = _a[_i];
3679                var rect = el.getBoundingClientRect();
3680                lefts.push(rect.left - originClientLeft);
3681                rights.push(rect.right - originClientLeft);
3682            }
3683            this.lefts = lefts;
3684            this.rights = rights;
3685        };
3686        // Populates the top/bottom internal coordinate arrays
3687        PositionCache.prototype.buildElVerticals = function (originClientTop) {
3688            var tops = [];
3689            var bottoms = [];
3690            for (var _i = 0, _a = this.els; _i < _a.length; _i++) {
3691                var el = _a[_i];
3692                var rect = el.getBoundingClientRect();
3693                tops.push(rect.top - originClientTop);
3694                bottoms.push(rect.bottom - originClientTop);
3695            }
3696            this.tops = tops;
3697            this.bottoms = bottoms;
3698        };
3699        // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
3700        // If no intersection is made, returns undefined.
3701        PositionCache.prototype.leftToIndex = function (leftPosition) {
3702            var lefts = this.lefts;
3703            var rights = this.rights;
3704            var len = lefts.length;
3705            var i;
3706            for (i = 0; i < len; i++) {
3707                if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
3708                    return i;
3709                }
3710            }
3711        };
3712        // Given a top offset (from document top), returns the index of the el that it vertically intersects.
3713        // If no intersection is made, returns undefined.
3714        PositionCache.prototype.topToIndex = function (topPosition) {
3715            var tops = this.tops;
3716            var bottoms = this.bottoms;
3717            var len = tops.length;
3718            var i;
3719            for (i = 0; i < len; i++) {
3720                if (topPosition >= tops[i] && topPosition < bottoms[i]) {
3721                    return i;
3722                }
3723            }
3724        };
3725        // Gets the width of the element at the given index
3726        PositionCache.prototype.getWidth = function (leftIndex) {
3727            return this.rights[leftIndex] - this.lefts[leftIndex];
3728        };
3729        // Gets the height of the element at the given index
3730        PositionCache.prototype.getHeight = function (topIndex) {
3731            return this.bottoms[topIndex] - this.tops[topIndex];
3732        };
3733        return PositionCache;
3734    }());
3735
3736    /*
3737    An object for getting/setting scroll-related information for an element.
3738    Internally, this is done very differently for window versus DOM element,
3739    so this object serves as a common interface.
3740    */
3741    var ScrollController = /** @class */ (function () {
3742        function ScrollController() {
3743        }
3744        ScrollController.prototype.getMaxScrollTop = function () {
3745            return this.getScrollHeight() - this.getClientHeight();
3746        };
3747        ScrollController.prototype.getMaxScrollLeft = function () {
3748            return this.getScrollWidth() - this.getClientWidth();
3749        };
3750        ScrollController.prototype.canScrollVertically = function () {
3751            return this.getMaxScrollTop() > 0;
3752        };
3753        ScrollController.prototype.canScrollHorizontally = function () {
3754            return this.getMaxScrollLeft() > 0;
3755        };
3756        ScrollController.prototype.canScrollUp = function () {
3757            return this.getScrollTop() > 0;
3758        };
3759        ScrollController.prototype.canScrollDown = function () {
3760            return this.getScrollTop() < this.getMaxScrollTop();
3761        };
3762        ScrollController.prototype.canScrollLeft = function () {
3763            return this.getScrollLeft() > 0;
3764        };
3765        ScrollController.prototype.canScrollRight = function () {
3766            return this.getScrollLeft() < this.getMaxScrollLeft();
3767        };
3768        return ScrollController;
3769    }());
3770    var ElementScrollController = /** @class */ (function (_super) {
3771        __extends(ElementScrollController, _super);
3772        function ElementScrollController(el) {
3773            var _this = _super.call(this) || this;
3774            _this.el = el;
3775            return _this;
3776        }
3777        ElementScrollController.prototype.getScrollTop = function () {
3778            return this.el.scrollTop;
3779        };
3780        ElementScrollController.prototype.getScrollLeft = function () {
3781            return this.el.scrollLeft;
3782        };
3783        ElementScrollController.prototype.setScrollTop = function (top) {
3784            this.el.scrollTop = top;
3785        };
3786        ElementScrollController.prototype.setScrollLeft = function (left) {
3787            this.el.scrollLeft = left;
3788        };
3789        ElementScrollController.prototype.getScrollWidth = function () {
3790            return this.el.scrollWidth;
3791        };
3792        ElementScrollController.prototype.getScrollHeight = function () {
3793            return this.el.scrollHeight;
3794        };
3795        ElementScrollController.prototype.getClientHeight = function () {
3796            return this.el.clientHeight;
3797        };
3798        ElementScrollController.prototype.getClientWidth = function () {
3799            return this.el.clientWidth;
3800        };
3801        return ElementScrollController;
3802    }(ScrollController));
3803    var WindowScrollController = /** @class */ (function (_super) {
3804        __extends(WindowScrollController, _super);
3805        function WindowScrollController() {
3806            return _super !== null && _super.apply(this, arguments) || this;
3807        }
3808        WindowScrollController.prototype.getScrollTop = function () {
3809            return window.pageYOffset;
3810        };
3811        WindowScrollController.prototype.getScrollLeft = function () {
3812            return window.pageXOffset;
3813        };
3814        WindowScrollController.prototype.setScrollTop = function (n) {
3815            window.scroll(window.pageXOffset, n);
3816        };
3817        WindowScrollController.prototype.setScrollLeft = function (n) {
3818            window.scroll(n, window.pageYOffset);
3819        };
3820        WindowScrollController.prototype.getScrollWidth = function () {
3821            return document.documentElement.scrollWidth;
3822        };
3823        WindowScrollController.prototype.getScrollHeight = function () {
3824            return document.documentElement.scrollHeight;
3825        };
3826        WindowScrollController.prototype.getClientHeight = function () {
3827            return document.documentElement.clientHeight;
3828        };
3829        WindowScrollController.prototype.getClientWidth = function () {
3830            return document.documentElement.clientWidth;
3831        };
3832        return WindowScrollController;
3833    }(ScrollController));
3834
3835    /*
3836    Embodies a div that has potential scrollbars
3837    */
3838    var ScrollComponent = /** @class */ (function (_super) {
3839        __extends(ScrollComponent, _super);
3840        function ScrollComponent(overflowX, overflowY) {
3841            var _this = _super.call(this, createElement('div', {
3842                className: 'fc-scroller'
3843            })) || this;
3844            _this.overflowX = overflowX;
3845            _this.overflowY = overflowY;
3846            _this.applyOverflow();
3847            return _this;
3848        }
3849        // sets to natural height, unlocks overflow
3850        ScrollComponent.prototype.clear = function () {
3851            this.setHeight('auto');
3852            this.applyOverflow();
3853        };
3854        ScrollComponent.prototype.destroy = function () {
3855            removeElement(this.el);
3856        };
3857        // Overflow
3858        // -----------------------------------------------------------------------------------------------------------------
3859        ScrollComponent.prototype.applyOverflow = function () {
3860            applyStyle(this.el, {
3861                overflowX: this.overflowX,
3862                overflowY: this.overflowY
3863            });
3864        };
3865        // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
3866        // Useful for preserving scrollbar widths regardless of future resizes.
3867        // Can pass in scrollbarWidths for optimization.
3868        ScrollComponent.prototype.lockOverflow = function (scrollbarWidths) {
3869            var overflowX = this.overflowX;
3870            var overflowY = this.overflowY;
3871            scrollbarWidths = scrollbarWidths || this.getScrollbarWidths();
3872            if (overflowX === 'auto') {
3873                overflowX = (scrollbarWidths.bottom || // horizontal scrollbars?
3874                    this.canScrollHorizontally() // OR scrolling pane with massless scrollbars?
3875                ) ? 'scroll' : 'hidden';
3876            }
3877            if (overflowY === 'auto') {
3878                overflowY = (scrollbarWidths.left || scrollbarWidths.right || // horizontal scrollbars?
3879                    this.canScrollVertically() // OR scrolling pane with massless scrollbars?
3880                ) ? 'scroll' : 'hidden';
3881            }
3882            applyStyle(this.el, { overflowX: overflowX, overflowY: overflowY });
3883        };
3884        ScrollComponent.prototype.setHeight = function (height) {
3885            applyStyleProp(this.el, 'height', height);
3886        };
3887        ScrollComponent.prototype.getScrollbarWidths = function () {
3888            var edges = computeEdges(this.el);
3889            return {
3890                left: edges.scrollbarLeft,
3891                right: edges.scrollbarRight,
3892                bottom: edges.scrollbarBottom
3893            };
3894        };
3895        return ScrollComponent;
3896    }(ElementScrollController));
3897
3898    var Theme = /** @class */ (function () {
3899        function Theme(calendarOptions) {
3900            this.calendarOptions = calendarOptions;
3901            this.processIconOverride();
3902        }
3903        Theme.prototype.processIconOverride = function () {
3904            if (this.iconOverrideOption) {
3905                this.setIconOverride(this.calendarOptions[this.iconOverrideOption]);
3906            }
3907        };
3908        Theme.prototype.setIconOverride = function (iconOverrideHash) {
3909            var iconClassesCopy;
3910            var buttonName;
3911            if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object
3912                iconClassesCopy = __assign({}, this.iconClasses);
3913                for (buttonName in iconOverrideHash) {
3914                    iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
3915                }
3916                this.iconClasses = iconClassesCopy;
3917            }
3918            else if (iconOverrideHash === false) {
3919                this.iconClasses = {};
3920            }
3921        };
3922        Theme.prototype.applyIconOverridePrefix = function (className) {
3923            var prefix = this.iconOverridePrefix;
3924            if (prefix && className.indexOf(prefix) !== 0) { // if not already present
3925                className = prefix + className;
3926            }
3927            return className;
3928        };
3929        Theme.prototype.getClass = function (key) {
3930            return this.classes[key] || '';
3931        };
3932        Theme.prototype.getIconClass = function (buttonName) {
3933            var className = this.iconClasses[buttonName];
3934            if (className) {
3935                return this.baseIconClass + ' ' + className;
3936            }
3937            return '';
3938        };
3939        Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
3940            var className;
3941            if (this.iconOverrideCustomButtonOption) {
3942                className = customButtonProps[this.iconOverrideCustomButtonOption];
3943                if (className) {
3944                    return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className);
3945                }
3946            }
3947            return '';
3948        };
3949        return Theme;
3950    }());
3951    Theme.prototype.classes = {};
3952    Theme.prototype.iconClasses = {};
3953    Theme.prototype.baseIconClass = '';
3954    Theme.prototype.iconOverridePrefix = '';
3955
3956    var guid = 0;
3957    var Component = /** @class */ (function () {
3958        function Component(context, isView) {
3959            // HACK to populate view at top of component instantiation call chain
3960            if (isView) {
3961                context.view = this;
3962            }
3963            this.uid = String(guid++);
3964            this.context = context;
3965            this.dateEnv = context.dateEnv;
3966            this.theme = context.theme;
3967            this.view = context.view;
3968            this.calendar = context.calendar;
3969            this.isRtl = this.opt('dir') === 'rtl';
3970        }
3971        Component.addEqualityFuncs = function (newFuncs) {
3972            this.prototype.equalityFuncs = __assign({}, this.prototype.equalityFuncs, newFuncs);
3973        };
3974        Component.prototype.opt = function (name) {
3975            return this.context.options[name];
3976        };
3977        Component.prototype.receiveProps = function (props) {
3978            var _a = recycleProps(this.props || {}, props, this.equalityFuncs), anyChanges = _a.anyChanges, comboProps = _a.comboProps;
3979            this.props = comboProps;
3980            if (anyChanges) {
3981                this.render(comboProps);
3982            }
3983        };
3984        Component.prototype.render = function (props) {
3985        };
3986        // after destroy is called, this component won't ever be used again
3987        Component.prototype.destroy = function () {
3988        };
3989        return Component;
3990    }());
3991    Component.prototype.equalityFuncs = {};
3992    /*
3993    Reuses old values when equal. If anything is unequal, returns newProps as-is.
3994    Great for PureComponent, but won't be feasible with React, so just eliminate and use React's DOM diffing.
3995    */
3996    function recycleProps(oldProps, newProps, equalityFuncs) {
3997        var comboProps = {}; // some old, some new
3998        var anyChanges = false;
3999        for (var key in newProps) {
4000            if (key in oldProps && (oldProps[key] === newProps[key] ||
4001                (equalityFuncs[key] && equalityFuncs[key](oldProps[key], newProps[key])))) {
4002                // equal to old? use old prop
4003                comboProps[key] = oldProps[key];
4004            }
4005            else {
4006                comboProps[key] = newProps[key];
4007                anyChanges = true;
4008            }
4009        }
4010        for (var key in oldProps) {
4011            if (!(key in newProps)) {
4012                anyChanges = true;
4013                break;
4014            }
4015        }
4016        return { anyChanges: anyChanges, comboProps: comboProps };
4017    }
4018
4019    /*
4020    PURPOSES:
4021    - hook up to fg, fill, and mirror renderers
4022    - interface for dragging and hits
4023    */
4024    var DateComponent = /** @class */ (function (_super) {
4025        __extends(DateComponent, _super);
4026        function DateComponent(context, el, isView) {
4027            var _this = _super.call(this, context, isView) || this;
4028            _this.el = el;
4029            return _this;
4030        }
4031        DateComponent.prototype.destroy = function () {
4032            _super.prototype.destroy.call(this);
4033            removeElement(this.el);
4034        };
4035        // TODO: WHAT ABOUT (sourceSeg && sourceSeg.component.doesDragMirror)
4036        //
4037        // Event Drag-n-Drop Rendering (for both events and external elements)
4038        // ---------------------------------------------------------------------------------------------------------------
4039        /*
4040        renderEventDragSegs(state: EventSegUiInteractionState) {
4041          if (state) {
4042            let { isEvent, segs, sourceSeg } = state
4043      
4044            if (this.eventRenderer) {
4045              this.eventRenderer.hideByHash(state.affectedInstances)
4046            }
4047      
4048            // if the user is dragging something that is considered an event with real event data,
4049            // and this component likes to do drag mirrors OR the component where the seg came from
4050            // likes to do drag mirrors, then render a drag mirror.
4051            if (isEvent && (this.doesDragMirror || sourceSeg && sourceSeg.component.doesDragMirror)) {
4052              if (this.mirrorRenderer) {
4053                this.mirrorRenderer.renderSegs(segs, { isDragging: true, sourceSeg })
4054              }
4055            }
4056      
4057            // if it would be impossible to render a drag mirror OR this component likes to render
4058            // highlights, then render a highlight.
4059            if (!isEvent || this.doesDragHighlight) {
4060              if (this.fillRenderer) {
4061                this.fillRenderer.renderSegs('highlight', segs)
4062              }
4063            }
4064          }
4065        }
4066        */
4067        // Hit System
4068        // -----------------------------------------------------------------------------------------------------------------
4069        DateComponent.prototype.buildPositionCaches = function () {
4070        };
4071        DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
4072            return null; // this should be abstract
4073        };
4074        // Validation
4075        // -----------------------------------------------------------------------------------------------------------------
4076        DateComponent.prototype.isInteractionValid = function (interaction) {
4077            var calendar = this.calendar;
4078            var dateProfile = this.props.dateProfile; // HACK
4079            var instances = interaction.mutatedEvents.instances;
4080            if (dateProfile) { // HACK for DayTile
4081                for (var instanceId in instances) {
4082                    if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
4083                        return false;
4084                    }
4085                }
4086            }
4087            return isInteractionValid(interaction, calendar);
4088        };
4089        DateComponent.prototype.isDateSelectionValid = function (selection) {
4090            var dateProfile = this.props.dateProfile; // HACK
4091            if (dateProfile && // HACK for DayTile
4092                !rangeContainsRange(dateProfile.validRange, selection.range)) {
4093                return false;
4094            }
4095            return isDateSelectionValid(selection, this.calendar);
4096        };
4097        // Triggering
4098        // -----------------------------------------------------------------------------------------------------------------
4099        // TODO: move to Calendar
4100        DateComponent.prototype.publiclyTrigger = function (name, args) {
4101            var calendar = this.calendar;
4102            return calendar.publiclyTrigger(name, args);
4103        };
4104        DateComponent.prototype.publiclyTriggerAfterSizing = function (name, args) {
4105            var calendar = this.calendar;
4106            return calendar.publiclyTriggerAfterSizing(name, args);
4107        };
4108        DateComponent.prototype.hasPublicHandlers = function (name) {
4109            var calendar = this.calendar;
4110            return calendar.hasPublicHandlers(name);
4111        };
4112        DateComponent.prototype.triggerRenderedSegs = function (segs, isMirrors) {
4113            var calendar = this.calendar;
4114            if (this.hasPublicHandlers('eventPositioned')) {
4115                for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
4116                    var seg = segs_1[_i];
4117                    this.publiclyTriggerAfterSizing('eventPositioned', [
4118                        {
4119                            event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
4120                            isMirror: isMirrors,
4121                            isStart: seg.isStart,
4122                            isEnd: seg.isEnd,
4123                            el: seg.el,
4124                            view: this // safe to cast because this method is only called on context.view
4125                        }
4126                    ]);
4127                }
4128            }
4129            if (!calendar.state.loadingLevel) { // avoid initial empty state while pending
4130                calendar.afterSizingTriggers._eventsPositioned = [null]; // fire once
4131            }
4132        };
4133        DateComponent.prototype.triggerWillRemoveSegs = function (segs, isMirrors) {
4134            var calendar = this.calendar;
4135            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
4136                var seg = segs_2[_i];
4137                calendar.trigger('eventElRemove', seg.el);
4138            }
4139            if (this.hasPublicHandlers('eventDestroy')) {
4140                for (var _a = 0, segs_3 = segs; _a < segs_3.length; _a++) {
4141                    var seg = segs_3[_a];
4142                    this.publiclyTrigger('eventDestroy', [
4143                        {
4144                            event: new EventApi(calendar, seg.eventRange.def, seg.eventRange.instance),
4145                            isMirror: isMirrors,
4146                            el: seg.el,
4147                            view: this // safe to cast because this method is only called on context.view
4148                        }
4149                    ]);
4150                }
4151            }
4152        };
4153        // Pointer Interaction Utils
4154        // -----------------------------------------------------------------------------------------------------------------
4155        DateComponent.prototype.isValidSegDownEl = function (el) {
4156            return !this.props.eventDrag && // HACK
4157                !this.props.eventResize && // HACK
4158                !elementClosest(el, '.fc-mirror') &&
4159                (this.isPopover() || !this.isInPopover(el));
4160            // ^above line ensures we don't detect a seg interaction within a nested component.
4161            // it's a HACK because it only supports a popover as the nested component.
4162        };
4163        DateComponent.prototype.isValidDateDownEl = function (el) {
4164            var segEl = elementClosest(el, this.fgSegSelector);
4165            return (!segEl || segEl.classList.contains('fc-mirror')) &&
4166                !elementClosest(el, '.fc-more') && // a "more.." link
4167                !elementClosest(el, 'a[data-goto]') && // a clickable nav link
4168                !this.isInPopover(el);
4169        };
4170        DateComponent.prototype.isPopover = function () {
4171            return this.el.classList.contains('fc-popover');
4172        };
4173        DateComponent.prototype.isInPopover = function (el) {
4174            return Boolean(elementClosest(el, '.fc-popover'));
4175        };
4176        return DateComponent;
4177    }(Component));
4178    DateComponent.prototype.fgSegSelector = '.fc-event-container > *';
4179    DateComponent.prototype.bgSegSelector = '.fc-bgevent:not(.fc-nonbusiness)';
4180
4181    var uid$1 = 0;
4182    function createPlugin(input) {
4183        return {
4184            id: String(uid$1++),
4185            deps: input.deps || [],
4186            reducers: input.reducers || [],
4187            eventDefParsers: input.eventDefParsers || [],
4188            isDraggableTransformers: input.isDraggableTransformers || [],
4189            eventDragMutationMassagers: input.eventDragMutationMassagers || [],
4190            eventDefMutationAppliers: input.eventDefMutationAppliers || [],
4191            dateSelectionTransformers: input.dateSelectionTransformers || [],
4192            datePointTransforms: input.datePointTransforms || [],
4193            dateSpanTransforms: input.dateSpanTransforms || [],
4194            views: input.views || {},
4195            viewPropsTransformers: input.viewPropsTransformers || [],
4196            isPropsValid: input.isPropsValid || null,
4197            externalDefTransforms: input.externalDefTransforms || [],
4198            eventResizeJoinTransforms: input.eventResizeJoinTransforms || [],
4199            viewContainerModifiers: input.viewContainerModifiers || [],
4200            eventDropTransformers: input.eventDropTransformers || [],
4201            componentInteractions: input.componentInteractions || [],
4202            calendarInteractions: input.calendarInteractions || [],
4203            themeClasses: input.themeClasses || {},
4204            eventSourceDefs: input.eventSourceDefs || [],
4205            cmdFormatter: input.cmdFormatter,
4206            recurringTypes: input.recurringTypes || [],
4207            namedTimeZonedImpl: input.namedTimeZonedImpl,
4208            defaultView: input.defaultView || '',
4209            elementDraggingImpl: input.elementDraggingImpl,
4210            optionChangeHandlers: input.optionChangeHandlers || {}
4211        };
4212    }
4213    var PluginSystem = /** @class */ (function () {
4214        function PluginSystem() {
4215            this.hooks = {
4216                reducers: [],
4217                eventDefParsers: [],
4218                isDraggableTransformers: [],
4219                eventDragMutationMassagers: [],
4220                eventDefMutationAppliers: [],
4221                dateSelectionTransformers: [],
4222                datePointTransforms: [],
4223                dateSpanTransforms: [],
4224                views: {},
4225                viewPropsTransformers: [],
4226                isPropsValid: null,
4227                externalDefTransforms: [],
4228                eventResizeJoinTransforms: [],
4229                viewContainerModifiers: [],
4230                eventDropTransformers: [],
4231                componentInteractions: [],
4232                calendarInteractions: [],
4233                themeClasses: {},
4234                eventSourceDefs: [],
4235                cmdFormatter: null,
4236                recurringTypes: [],
4237                namedTimeZonedImpl: null,
4238                defaultView: '',
4239                elementDraggingImpl: null,
4240                optionChangeHandlers: {}
4241            };
4242            this.addedHash = {};
4243        }
4244        PluginSystem.prototype.add = function (plugin) {
4245            if (!this.addedHash[plugin.id]) {
4246                this.addedHash[plugin.id] = true;
4247                for (var _i = 0, _a = plugin.deps; _i < _a.length; _i++) {
4248                    var dep = _a[_i];
4249                    this.add(dep);
4250                }
4251                this.hooks = combineHooks(this.hooks, plugin);
4252            }
4253        };
4254        return PluginSystem;
4255    }());
4256    function combineHooks(hooks0, hooks1) {
4257        return {
4258            reducers: hooks0.reducers.concat(hooks1.reducers),
4259            eventDefParsers: hooks0.eventDefParsers.concat(hooks1.eventDefParsers),
4260            isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),
4261            eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
4262            eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
4263            dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
4264            datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
4265            dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
4266            views: __assign({}, hooks0.views, hooks1.views),
4267            viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
4268            isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
4269            externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
4270            eventResizeJoinTransforms: hooks0.eventResizeJoinTransforms.concat(hooks1.eventResizeJoinTransforms),
4271            viewContainerModifiers: hooks0.viewContainerModifiers.concat(hooks1.viewContainerModifiers),
4272            eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
4273            calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
4274            componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
4275            themeClasses: __assign({}, hooks0.themeClasses, hooks1.themeClasses),
4276            eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
4277            cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
4278            recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
4279            namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
4280            defaultView: hooks0.defaultView || hooks1.defaultView,
4281            elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
4282            optionChangeHandlers: __assign({}, hooks0.optionChangeHandlers, hooks1.optionChangeHandlers)
4283        };
4284    }
4285
4286    var eventSourceDef = {
4287        ignoreRange: true,
4288        parseMeta: function (raw) {
4289            if (Array.isArray(raw)) { // short form
4290                return raw;
4291            }
4292            else if (Array.isArray(raw.events)) {
4293                return raw.events;
4294            }
4295            return null;
4296        },
4297        fetch: function (arg, success) {
4298            success({
4299                rawEvents: arg.eventSource.meta
4300            });
4301        }
4302    };
4303    var ArrayEventSourcePlugin = createPlugin({
4304        eventSourceDefs: [eventSourceDef]
4305    });
4306
4307    var eventSourceDef$1 = {
4308        parseMeta: function (raw) {
4309            if (typeof raw === 'function') { // short form
4310                return raw;
4311            }
4312            else if (typeof raw.events === 'function') {
4313                return raw.events;
4314            }
4315            return null;
4316        },
4317        fetch: function (arg, success, failure) {
4318            var dateEnv = arg.calendar.dateEnv;
4319            var func = arg.eventSource.meta;
4320            unpromisify(func.bind(null, {
4321                start: dateEnv.toDate(arg.range.start),
4322                end: dateEnv.toDate(arg.range.end),
4323                startStr: dateEnv.formatIso(arg.range.start),
4324                endStr: dateEnv.formatIso(arg.range.end),
4325                timeZone: dateEnv.timeZone
4326            }), function (rawEvents) {
4327                success({ rawEvents: rawEvents }); // needs an object response
4328            }, failure // send errorObj directly to failure callback
4329            );
4330        }
4331    };
4332    var FuncEventSourcePlugin = createPlugin({
4333        eventSourceDefs: [eventSourceDef$1]
4334    });
4335
4336    function requestJson(method, url, params, successCallback, failureCallback) {
4337        method = method.toUpperCase();
4338        var body = null;
4339        if (method === 'GET') {
4340            url = injectQueryStringParams(url, params);
4341        }
4342        else {
4343            body = encodeParams(params);
4344        }
4345        var xhr = new XMLHttpRequest();
4346        xhr.open(method, url, true);
4347        if (method !== 'GET') {
4348            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
4349        }
4350        xhr.onload = function () {
4351            if (xhr.status >= 200 && xhr.status < 400) {
4352                try {
4353                    var res = JSON.parse(xhr.responseText);
4354                    successCallback(res, xhr);
4355                }
4356                catch (err) {
4357                    failureCallback('Failure parsing JSON', xhr);
4358                }
4359            }
4360            else {
4361                failureCallback('Request failed', xhr);
4362            }
4363        };
4364        xhr.onerror = function () {
4365            failureCallback('Request failed', xhr);
4366        };
4367        xhr.send(body);
4368    }
4369    function injectQueryStringParams(url, params) {
4370        return url +
4371            (url.indexOf('?') === -1 ? '?' : '&') +
4372            encodeParams(params);
4373    }
4374    function encodeParams(params) {
4375        var parts = [];
4376        for (var key in params) {
4377            parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
4378        }
4379        return parts.join('&');
4380    }
4381
4382    var eventSourceDef$2 = {
4383        parseMeta: function (raw) {
4384            if (typeof raw === 'string') { // short form
4385                raw = { url: raw };
4386            }
4387            else if (!raw || typeof raw !== 'object' || !raw.url) {
4388                return null;
4389            }
4390            return {
4391                url: raw.url,
4392                method: (raw.method || 'GET').toUpperCase(),
4393                extraParams: raw.extraParams,
4394                startParam: raw.startParam,
4395                endParam: raw.endParam,
4396                timeZoneParam: raw.timeZoneParam
4397            };
4398        },
4399        fetch: function (arg, success, failure) {
4400            var meta = arg.eventSource.meta;
4401            var requestParams = buildRequestParams(meta, arg.range, arg.calendar);
4402            requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) {
4403                success({ rawEvents: rawEvents, xhr: xhr });
4404            }, function (errorMessage, xhr) {
4405                failure({ message: errorMessage, xhr: xhr });
4406            });
4407        }
4408    };
4409    var JsonFeedEventSourcePlugin = createPlugin({
4410        eventSourceDefs: [eventSourceDef$2]
4411    });
4412    function buildRequestParams(meta, range, calendar) {
4413        var dateEnv = calendar.dateEnv;
4414        var startParam;
4415        var endParam;
4416        var timeZoneParam;
4417        var customRequestParams;
4418        var params = {};
4419        startParam = meta.startParam;
4420        if (startParam == null) {
4421            startParam = calendar.opt('startParam');
4422        }
4423        endParam = meta.endParam;
4424        if (endParam == null) {
4425            endParam = calendar.opt('endParam');
4426        }
4427        timeZoneParam = meta.timeZoneParam;
4428        if (timeZoneParam == null) {
4429            timeZoneParam = calendar.opt('timeZoneParam');
4430        }
4431        // retrieve any outbound GET/POST data from the options
4432        if (typeof meta.extraParams === 'function') {
4433            // supplied as a function that returns a key/value object
4434            customRequestParams = meta.extraParams();
4435        }
4436        else {
4437            // probably supplied as a straight key/value object
4438            customRequestParams = meta.extraParams || {};
4439        }
4440        __assign(params, customRequestParams);
4441        params[startParam] = dateEnv.formatIso(range.start);
4442        params[endParam] = dateEnv.formatIso(range.end);
4443        if (dateEnv.timeZone !== 'local') {
4444            params[timeZoneParam] = dateEnv.timeZone;
4445        }
4446        return params;
4447    }
4448
4449    var recurring = {
4450        parse: function (rawEvent, leftoverProps, dateEnv) {
4451            var createMarker = dateEnv.createMarker.bind(dateEnv);
4452            var processors = {
4453                daysOfWeek: null,
4454                startTime: createDuration,
4455                endTime: createDuration,
4456                startRecur: createMarker,
4457                endRecur: createMarker
4458            };
4459            var props = refineProps(rawEvent, processors, {}, leftoverProps);
4460            var anyValid = false;
4461            for (var propName in props) {
4462                if (props[propName] != null) {
4463                    anyValid = true;
4464                    break;
4465                }
4466            }
4467            if (anyValid) {
4468                var duration = null;
4469                if ('duration' in leftoverProps) {
4470                    duration = createDuration(leftoverProps.duration);
4471                    delete leftoverProps.duration;
4472                }
4473                if (!duration && props.startTime && props.endTime) {
4474                    duration = subtractDurations(props.endTime, props.startTime);
4475                }
4476                return {
4477                    allDayGuess: Boolean(!props.startTime && !props.endTime),
4478                    duration: duration,
4479                    typeData: props // doesn't need endTime anymore but oh well
4480                };
4481            }
4482            return null;
4483        },
4484        expand: function (typeData, framingRange, dateEnv) {
4485            var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur });
4486            if (clippedFramingRange) {
4487                return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);
4488            }
4489            else {
4490                return [];
4491            }
4492        }
4493    };
4494    var SimpleRecurrencePlugin = createPlugin({
4495        recurringTypes: [recurring]
4496    });
4497    function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {
4498        var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null;
4499        var dayMarker = startOfDay(framingRange.start);
4500        var endMarker = framingRange.end;
4501        var instanceStarts = [];
4502        while (dayMarker < endMarker) {
4503            var instanceStart 
4504            // if everyday, or this particular day-of-week
4505            = void 0;
4506            // if everyday, or this particular day-of-week
4507            if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
4508                if (startTime) {
4509                    instanceStart = dateEnv.add(dayMarker, startTime);
4510                }
4511                else {
4512                    instanceStart = dayMarker;
4513                }
4514                instanceStarts.push(instanceStart);
4515            }
4516            dayMarker = addDays(dayMarker, 1);
4517        }
4518        return instanceStarts;
4519    }
4520
4521    var DefaultOptionChangeHandlers = createPlugin({
4522        optionChangeHandlers: {
4523            events: function (events, calendar, deepEqual) {
4524                handleEventSources([events], calendar, deepEqual);
4525            },
4526            eventSources: handleEventSources,
4527            plugins: handlePlugins
4528        }
4529    });
4530    function handleEventSources(inputs, calendar, deepEqual) {
4531        var unfoundSources = hashValuesToArray(calendar.state.eventSources);
4532        var newInputs = [];
4533        for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) {
4534            var input = inputs_1[_i];
4535            var inputFound = false;
4536            for (var i = 0; i < unfoundSources.length; i++) {
4537                if (deepEqual(unfoundSources[i]._raw, input)) {
4538                    unfoundSources.splice(i, 1); // delete
4539                    inputFound = true;
4540                    break;
4541                }
4542            }
4543            if (!inputFound) {
4544                newInputs.push(input);
4545            }
4546        }
4547        for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) {
4548            var unfoundSource = unfoundSources_1[_a];
4549            calendar.dispatch({
4550                type: 'REMOVE_EVENT_SOURCE',
4551                sourceId: unfoundSource.sourceId
4552            });
4553        }
4554        for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) {
4555            var newInput = newInputs_1[_b];
4556            calendar.addEventSource(newInput);
4557        }
4558    }
4559    // shortcoming: won't remove plugins
4560    function handlePlugins(inputs, calendar) {
4561        calendar.addPluginInputs(inputs); // will gracefully handle duplicates
4562    }
4563
4564    var config = {}; // TODO: make these options
4565    var globalDefaults = {
4566        defaultRangeSeparator: ' - ',
4567        titleRangeSeparator: ' \u2013 ',
4568        defaultTimedEventDuration: '01:00:00',
4569        defaultAllDayEventDuration: { day: 1 },
4570        forceEventDuration: false,
4571        nextDayThreshold: '00:00:00',
4572        // display
4573        columnHeader: true,
4574        defaultView: '',
4575        aspectRatio: 1.35,
4576        header: {
4577            left: 'title',
4578            center: '',
4579            right: 'today prev,next'
4580        },
4581        weekends: true,
4582        weekNumbers: false,
4583        weekNumberCalculation: 'local',
4584        editable: false,
4585        // nowIndicator: false,
4586        scrollTime: '06:00:00',
4587        minTime: '00:00:00',
4588        maxTime: '24:00:00',
4589        showNonCurrentDates: true,
4590        // event ajax
4591        lazyFetching: true,
4592        startParam: 'start',
4593        endParam: 'end',
4594        timeZoneParam: 'timeZone',
4595        timeZone: 'local',
4596        // allDayDefault: undefined,
4597        // locale
4598        locales: [],
4599        locale: '',
4600        // dir: will get this from the default locale
4601        // buttonIcons: null,
4602        // allows setting a min-height to the event segment to prevent short events overlapping each other
4603        timeGridEventMinHeight: 0,
4604        themeSystem: 'standard',
4605        // eventResizableFromStart: false,
4606        dragRevertDuration: 500,
4607        dragScroll: true,
4608        allDayMaintainDuration: false,
4609        // selectable: false,
4610        unselectAuto: true,
4611        // selectMinDistance: 0,
4612        dropAccept: '*',
4613        eventOrder: 'start,-duration,allDay,title',
4614        // ^ if start tie, longer events go before shorter. final tie-breaker is title text
4615        // rerenderDelay: null,
4616        eventLimit: false,
4617        eventLimitClick: 'popover',
4618        dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
4619        handleWindowResize: true,
4620        windowResizeDelay: 100,
4621        longPressDelay: 1000,
4622        eventDragMinDistance: 5 // only applies to mouse
4623    };
4624    var rtlDefaults = {
4625        header: {
4626            left: 'next,prev today',
4627            center: '',
4628            right: 'title'
4629        },
4630        buttonIcons: {
4631            // TODO: make RTL support the responibility of the theme
4632            prev: 'fc-icon-chevron-right',
4633            next: 'fc-icon-chevron-left',
4634            prevYear: 'fc-icon-chevrons-right',
4635            nextYear: 'fc-icon-chevrons-left'
4636        }
4637    };
4638    var complexOptions = [
4639        'header',
4640        'footer',
4641        'buttonText',
4642        'buttonIcons'
4643    ];
4644    // Merges an array of option objects into a single object
4645    function mergeOptions(optionObjs) {
4646        return mergeProps(optionObjs, complexOptions);
4647    }
4648    // TODO: move this stuff to a "plugin"-related file...
4649    var INTERNAL_PLUGINS = [
4650        ArrayEventSourcePlugin,
4651        FuncEventSourcePlugin,
4652        JsonFeedEventSourcePlugin,
4653        SimpleRecurrencePlugin,
4654        DefaultOptionChangeHandlers
4655    ];
4656    function refinePluginDefs(pluginInputs) {
4657        var plugins = [];
4658        for (var _i = 0, pluginInputs_1 = pluginInputs; _i < pluginInputs_1.length; _i++) {
4659            var pluginInput = pluginInputs_1[_i];
4660            if (typeof pluginInput === 'string') {
4661                var globalName = 'FullCalendar' + capitaliseFirstLetter(pluginInput);
4662                if (!window[globalName]) {
4663                    console.warn('Plugin file not loaded for ' + pluginInput);
4664                }
4665                else {
4666                    plugins.push(window[globalName].default); // is an ES6 module
4667                }
4668            }
4669            else {
4670                plugins.push(pluginInput);
4671            }
4672        }
4673        return INTERNAL_PLUGINS.concat(plugins);
4674    }
4675
4676    var RAW_EN_LOCALE = {
4677        code: 'en',
4678        week: {
4679            dow: 0,
4680            doy: 4 // 4 days need to be within the year to be considered the first week
4681        },
4682        dir: 'ltr',
4683        buttonText: {
4684            prev: 'prev',
4685            next: 'next',
4686            prevYear: 'prev year',
4687            nextYear: 'next year',
4688            year: 'year',
4689            today: 'today',
4690            month: 'month',
4691            week: 'week',
4692            day: 'day',
4693            list: 'list'
4694        },
4695        weekLabel: 'W',
4696        allDayText: 'all-day',
4697        eventLimitText: 'more',
4698        noEventsMessage: 'No events to display'
4699    };
4700    function parseRawLocales(explicitRawLocales) {
4701        var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
4702        var globalArray = window['FullCalendarLocalesAll'] || []; // from locales-all.js
4703        var globalObject = window['FullCalendarLocales'] || {}; // from locales/*.js. keys are meaningless
4704        var allRawLocales = globalArray.concat(// globalArray is low prio
4705        hashValuesToArray(globalObject), // medium prio
4706        explicitRawLocales // highest prio
4707        );
4708        var rawLocaleMap = {
4709            en: RAW_EN_LOCALE // necessary?
4710        };
4711        for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) {
4712            var rawLocale = allRawLocales_1[_i];
4713            rawLocaleMap[rawLocale.code] = rawLocale;
4714        }
4715        return {
4716            map: rawLocaleMap,
4717            defaultCode: defaultCode
4718        };
4719    }
4720    function buildLocale(inputSingular, available) {
4721        if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
4722            return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
4723        }
4724        else {
4725            return queryLocale(inputSingular, available);
4726        }
4727    }
4728    function queryLocale(codeArg, available) {
4729        var codes = [].concat(codeArg || []); // will convert to array
4730        var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
4731        return parseLocale(codeArg, codes, raw);
4732    }
4733    function queryRawLocale(codes, available) {
4734        for (var i = 0; i < codes.length; i++) {
4735            var parts = codes[i].toLocaleLowerCase().split('-');
4736            for (var j = parts.length; j > 0; j--) {
4737                var simpleId = parts.slice(0, j).join('-');
4738                if (available[simpleId]) {
4739                    return available[simpleId];
4740                }
4741            }
4742        }
4743        return null;
4744    }
4745    function parseLocale(codeArg, codes, raw) {
4746        var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']);
4747        delete merged.code; // don't want this part of the options
4748        var week = merged.week;
4749        delete merged.week;
4750        return {
4751            codeArg: codeArg,
4752            codes: codes,
4753            week: week,
4754            simpleNumberFormat: new Intl.NumberFormat(codeArg),
4755            options: merged
4756        };
4757    }
4758
4759    var OptionsManager = /** @class */ (function () {
4760        function OptionsManager(overrides) {
4761            this.overrides = __assign({}, overrides); // make a copy
4762            this.dynamicOverrides = {};
4763            this.compute();
4764        }
4765        OptionsManager.prototype.mutate = function (updates, removals, isDynamic) {
4766            var overrideHash = isDynamic ? this.dynamicOverrides : this.overrides;
4767            __assign(overrideHash, updates);
4768            for (var _i = 0, removals_1 = removals; _i < removals_1.length; _i++) {
4769                var propName = removals_1[_i];
4770                delete overrideHash[propName];
4771            }
4772            this.compute();
4773        };
4774        // Computes the flattened options hash for the calendar and assigns to `this.options`.
4775        // Assumes this.overrides and this.dynamicOverrides have already been initialized.
4776        OptionsManager.prototype.compute = function () {
4777            // TODO: not a very efficient system
4778            var locales = firstDefined(// explicit locale option given?
4779            this.dynamicOverrides.locales, this.overrides.locales, globalDefaults.locales);
4780            var locale = firstDefined(// explicit locales option given?
4781            this.dynamicOverrides.locale, this.overrides.locale, globalDefaults.locale);
4782            var available = parseRawLocales(locales);
4783            var localeDefaults = buildLocale(locale || available.defaultCode, available.map).options;
4784            var dir = firstDefined(// based on options computed so far, is direction RTL?
4785            this.dynamicOverrides.dir, this.overrides.dir, localeDefaults.dir);
4786            var dirDefaults = dir === 'rtl' ? rtlDefaults : {};
4787            this.dirDefaults = dirDefaults;
4788            this.localeDefaults = localeDefaults;
4789            this.computed = mergeOptions([
4790                globalDefaults,
4791                dirDefaults,
4792                localeDefaults,
4793                this.overrides,
4794                this.dynamicOverrides
4795            ]);
4796        };
4797        return OptionsManager;
4798    }());
4799
4800    var calendarSystemClassMap = {};
4801    function registerCalendarSystem(name, theClass) {
4802        calendarSystemClassMap[name] = theClass;
4803    }
4804    function createCalendarSystem(name) {
4805        return new calendarSystemClassMap[name]();
4806    }
4807    var GregorianCalendarSystem = /** @class */ (function () {
4808        function GregorianCalendarSystem() {
4809        }
4810        GregorianCalendarSystem.prototype.getMarkerYear = function (d) {
4811            return d.getUTCFullYear();
4812        };
4813        GregorianCalendarSystem.prototype.getMarkerMonth = function (d) {
4814            return d.getUTCMonth();
4815        };
4816        GregorianCalendarSystem.prototype.getMarkerDay = function (d) {
4817            return d.getUTCDate();
4818        };
4819        GregorianCalendarSystem.prototype.arrayToMarker = function (arr) {
4820            return arrayToUtcDate(arr);
4821        };
4822        GregorianCalendarSystem.prototype.markerToArray = function (marker) {
4823            return dateToUtcArray(marker);
4824        };
4825        return GregorianCalendarSystem;
4826    }());
4827    registerCalendarSystem('gregory', GregorianCalendarSystem);
4828
4829    var ISO_RE = /^\s*(\d{4})(-(\d{2})(-(\d{2})([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
4830    function parse(str) {
4831        var m = ISO_RE.exec(str);
4832        if (m) {
4833            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));
4834            if (isValidDate(marker)) {
4835                var timeZoneOffset = null;
4836                if (m[13]) {
4837                    timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
4838                        Number(m[18] || 0));
4839                }
4840                return {
4841                    marker: marker,
4842                    isTimeUnspecified: !m[6],
4843                    timeZoneOffset: timeZoneOffset
4844                };
4845            }
4846        }
4847        return null;
4848    }
4849
4850    var DateEnv = /** @class */ (function () {
4851        function DateEnv(settings) {
4852            var timeZone = this.timeZone = settings.timeZone;
4853            var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
4854            if (settings.namedTimeZoneImpl && isNamedTimeZone) {
4855                this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
4856            }
4857            this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
4858            this.calendarSystem = createCalendarSystem(settings.calendarSystem);
4859            this.locale = settings.locale;
4860            this.weekDow = settings.locale.week.dow;
4861            this.weekDoy = settings.locale.week.doy;
4862            if (settings.weekNumberCalculation === 'ISO') {
4863                this.weekDow = 1;
4864                this.weekDoy = 4;
4865            }
4866            if (typeof settings.firstDay === 'number') {
4867                this.weekDow = settings.firstDay;
4868            }
4869            if (typeof settings.weekNumberCalculation === 'function') {
4870                this.weekNumberFunc = settings.weekNumberCalculation;
4871            }
4872            this.weekLabel = settings.weekLabel != null ? settings.weekLabel : settings.locale.options.weekLabel;
4873            this.cmdFormatter = settings.cmdFormatter;
4874        }
4875        // Creating / Parsing
4876        DateEnv.prototype.createMarker = function (input) {
4877            var meta = this.createMarkerMeta(input);
4878            if (meta === null) {
4879                return null;
4880            }
4881            return meta.marker;
4882        };
4883        DateEnv.prototype.createNowMarker = function () {
4884            if (this.canComputeOffset) {
4885                return this.timestampToMarker(new Date().valueOf());
4886            }
4887            else {
4888                // if we can't compute the current date val for a timezone,
4889                // better to give the current local date vals than UTC
4890                return arrayToUtcDate(dateToLocalArray(new Date()));
4891            }
4892        };
4893        DateEnv.prototype.createMarkerMeta = function (input) {
4894            if (typeof input === 'string') {
4895                return this.parse(input);
4896            }
4897            var marker = null;
4898            if (typeof input === 'number') {
4899                marker = this.timestampToMarker(input);
4900            }
4901            else if (input instanceof Date) {
4902                input = input.valueOf();
4903                if (!isNaN(input)) {
4904                    marker = this.timestampToMarker(input);
4905                }
4906            }
4907            else if (Array.isArray(input)) {
4908                marker = arrayToUtcDate(input);
4909            }
4910            if (marker === null || !isValidDate(marker)) {
4911                return null;
4912            }
4913            return { marker: marker, isTimeUnspecified: false, forcedTzo: null };
4914        };
4915        DateEnv.prototype.parse = function (s) {
4916            var parts = parse(s);
4917            if (parts === null) {
4918                return null;
4919            }
4920            var marker = parts.marker;
4921            var forcedTzo = null;
4922            if (parts.timeZoneOffset !== null) {
4923                if (this.canComputeOffset) {
4924                    marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
4925                }
4926                else {
4927                    forcedTzo = parts.timeZoneOffset;
4928                }
4929            }
4930            return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo };
4931        };
4932        // Accessors
4933        DateEnv.prototype.getYear = function (marker) {
4934            return this.calendarSystem.getMarkerYear(marker);
4935        };
4936        DateEnv.prototype.getMonth = function (marker) {
4937            return this.calendarSystem.getMarkerMonth(marker);
4938        };
4939        // Adding / Subtracting
4940        DateEnv.prototype.add = function (marker, dur) {
4941            var a = this.calendarSystem.markerToArray(marker);
4942            a[0] += dur.years;
4943            a[1] += dur.months;
4944            a[2] += dur.days;
4945            a[6] += dur.milliseconds;
4946            return this.calendarSystem.arrayToMarker(a);
4947        };
4948        DateEnv.prototype.subtract = function (marker, dur) {
4949            var a = this.calendarSystem.markerToArray(marker);
4950            a[0] -= dur.years;
4951            a[1] -= dur.months;
4952            a[2] -= dur.days;
4953            a[6] -= dur.milliseconds;
4954            return this.calendarSystem.arrayToMarker(a);
4955        };
4956        DateEnv.prototype.addYears = function (marker, n) {
4957            var a = this.calendarSystem.markerToArray(marker);
4958            a[0] += n;
4959            return this.calendarSystem.arrayToMarker(a);
4960        };
4961        DateEnv.prototype.addMonths = function (marker, n) {
4962            var a = this.calendarSystem.markerToArray(marker);
4963            a[1] += n;
4964            return this.calendarSystem.arrayToMarker(a);
4965        };
4966        // Diffing Whole Units
4967        DateEnv.prototype.diffWholeYears = function (m0, m1) {
4968            var calendarSystem = this.calendarSystem;
4969            if (timeAsMs(m0) === timeAsMs(m1) &&
4970                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
4971                calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
4972                return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
4973            }
4974            return null;
4975        };
4976        DateEnv.prototype.diffWholeMonths = function (m0, m1) {
4977            var calendarSystem = this.calendarSystem;
4978            if (timeAsMs(m0) === timeAsMs(m1) &&
4979                calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
4980                return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
4981                    (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
4982            }
4983            return null;
4984        };
4985        // Range / Duration
4986        DateEnv.prototype.greatestWholeUnit = function (m0, m1) {
4987            var n = this.diffWholeYears(m0, m1);
4988            if (n !== null) {
4989                return { unit: 'year', value: n };
4990            }
4991            n = this.diffWholeMonths(m0, m1);
4992            if (n !== null) {
4993                return { unit: 'month', value: n };
4994            }
4995            n = diffWholeWeeks(m0, m1);
4996            if (n !== null) {
4997                return { unit: 'week', value: n };
4998            }
4999            n = diffWholeDays(m0, m1);
5000            if (n !== null) {
5001                return { unit: 'day', value: n };
5002            }
5003            n = diffHours(m0, m1);
5004            if (isInt(n)) {
5005                return { unit: 'hour', value: n };
5006            }
5007            n = diffMinutes(m0, m1);
5008            if (isInt(n)) {
5009                return { unit: 'minute', value: n };
5010            }
5011            n = diffSeconds(m0, m1);
5012            if (isInt(n)) {
5013                return { unit: 'second', value: n };
5014            }
5015            return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
5016        };
5017        DateEnv.prototype.countDurationsBetween = function (m0, m1, d) {
5018            // TODO: can use greatestWholeUnit
5019            var diff;
5020            if (d.years) {
5021                diff = this.diffWholeYears(m0, m1);
5022                if (diff !== null) {
5023                    return diff / asRoughYears(d);
5024                }
5025            }
5026            if (d.months) {
5027                diff = this.diffWholeMonths(m0, m1);
5028                if (diff !== null) {
5029                    return diff / asRoughMonths(d);
5030                }
5031            }
5032            if (d.days) {
5033                diff = diffWholeDays(m0, m1);
5034                if (diff !== null) {
5035                    return diff / asRoughDays(d);
5036                }
5037            }
5038            return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
5039        };
5040        // Start-Of
5041        DateEnv.prototype.startOf = function (m, unit) {
5042            if (unit === 'year') {
5043                return this.startOfYear(m);
5044            }
5045            else if (unit === 'month') {
5046                return this.startOfMonth(m);
5047            }
5048            else if (unit === 'week') {
5049                return this.startOfWeek(m);
5050            }
5051            else if (unit === 'day') {
5052                return startOfDay(m);
5053            }
5054            else if (unit === 'hour') {
5055                return startOfHour(m);
5056            }
5057            else if (unit === 'minute') {
5058                return startOfMinute(m);
5059            }
5060            else if (unit === 'second') {
5061                return startOfSecond(m);
5062            }
5063        };
5064        DateEnv.prototype.startOfYear = function (m) {
5065            return this.calendarSystem.arrayToMarker([
5066                this.calendarSystem.getMarkerYear(m)
5067            ]);
5068        };
5069        DateEnv.prototype.startOfMonth = function (m) {
5070            return this.calendarSystem.arrayToMarker([
5071                this.calendarSystem.getMarkerYear(m),
5072                this.calendarSystem.getMarkerMonth(m)
5073            ]);
5074        };
5075        DateEnv.prototype.startOfWeek = function (m) {
5076            return this.calendarSystem.arrayToMarker([
5077                this.calendarSystem.getMarkerYear(m),
5078                this.calendarSystem.getMarkerMonth(m),
5079                m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7)
5080            ]);
5081        };
5082        // Week Number
5083        DateEnv.prototype.computeWeekNumber = function (marker) {
5084            if (this.weekNumberFunc) {
5085                return this.weekNumberFunc(this.toDate(marker));
5086            }
5087            else {
5088                return weekOfYear(marker, this.weekDow, this.weekDoy);
5089            }
5090        };
5091        // TODO: choke on timeZoneName: long
5092        DateEnv.prototype.format = function (marker, formatter, dateOptions) {
5093            if (dateOptions === void 0) { dateOptions = {}; }
5094            return formatter.format({
5095                marker: marker,
5096                timeZoneOffset: dateOptions.forcedTzo != null ?
5097                    dateOptions.forcedTzo :
5098                    this.offsetForMarker(marker)
5099            }, this);
5100        };
5101        DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) {
5102            if (dateOptions === void 0) { dateOptions = {}; }
5103            if (dateOptions.isEndExclusive) {
5104                end = addMs(end, -1);
5105            }
5106            return formatter.formatRange({
5107                marker: start,
5108                timeZoneOffset: dateOptions.forcedStartTzo != null ?
5109                    dateOptions.forcedStartTzo :
5110                    this.offsetForMarker(start)
5111            }, {
5112                marker: end,
5113                timeZoneOffset: dateOptions.forcedEndTzo != null ?
5114                    dateOptions.forcedEndTzo :
5115                    this.offsetForMarker(end)
5116            }, this);
5117        };
5118        DateEnv.prototype.formatIso = function (marker, extraOptions) {
5119            if (extraOptions === void 0) { extraOptions = {}; }
5120            var timeZoneOffset = null;
5121            if (!extraOptions.omitTimeZoneOffset) {
5122                if (extraOptions.forcedTzo != null) {
5123                    timeZoneOffset = extraOptions.forcedTzo;
5124                }
5125                else {
5126                    timeZoneOffset = this.offsetForMarker(marker);
5127                }
5128            }
5129            return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
5130        };
5131        // TimeZone
5132        DateEnv.prototype.timestampToMarker = function (ms) {
5133            if (this.timeZone === 'local') {
5134                return arrayToUtcDate(dateToLocalArray(new Date(ms)));
5135            }
5136            else if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
5137                return new Date(ms);
5138            }
5139            else {
5140                return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
5141            }
5142        };
5143        DateEnv.prototype.offsetForMarker = function (m) {
5144            if (this.timeZone === 'local') {
5145                return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
5146            }
5147            else if (this.timeZone === 'UTC') {
5148                return 0;
5149            }
5150            else if (this.namedTimeZoneImpl) {
5151                return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
5152            }
5153            return null;
5154        };
5155        // Conversion
5156        DateEnv.prototype.toDate = function (m, forcedTzo) {
5157            if (this.timeZone === 'local') {
5158                return arrayToLocalDate(dateToUtcArray(m));
5159            }
5160            else if (this.timeZone === 'UTC') {
5161                return new Date(m.valueOf()); // make sure it's a copy
5162            }
5163            else if (!this.namedTimeZoneImpl) {
5164                return new Date(m.valueOf() - (forcedTzo || 0));
5165            }
5166            else {
5167                return new Date(m.valueOf() -
5168                    this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60 // convert minutes -> ms
5169                );
5170            }
5171        };
5172        return DateEnv;
5173    }());
5174
5175    var SIMPLE_SOURCE_PROPS = {
5176        id: String,
5177        allDayDefault: Boolean,
5178        eventDataTransform: Function,
5179        success: Function,
5180        failure: Function
5181    };
5182    var uid$2 = 0;
5183    function doesSourceNeedRange(eventSource, calendar) {
5184        var defs = calendar.pluginSystem.hooks.eventSourceDefs;
5185        return !defs[eventSource.sourceDefId].ignoreRange;
5186    }
5187    function parseEventSource(raw, calendar) {
5188        var defs = calendar.pluginSystem.hooks.eventSourceDefs;
5189        for (var i = defs.length - 1; i >= 0; i--) { // later-added plugins take precedence
5190            var def = defs[i];
5191            var meta = def.parseMeta(raw);
5192            if (meta) {
5193                var res = parseEventSourceProps(typeof raw === 'object' ? raw : {}, meta, i, calendar);
5194                res._raw = raw;
5195                return res;
5196            }
5197        }
5198        return null;
5199    }
5200    function parseEventSourceProps(raw, meta, sourceDefId, calendar) {
5201        var leftovers0 = {};
5202        var props = refineProps(raw, SIMPLE_SOURCE_PROPS, {}, leftovers0);
5203        var leftovers1 = {};
5204        var ui = processUnscopedUiProps(leftovers0, calendar, leftovers1);
5205        props.isFetching = false;
5206        props.latestFetchId = '';
5207        props.fetchRange = null;
5208        props.publicId = String(raw.id || '');
5209        props.sourceId = String(uid$2++);
5210        props.sourceDefId = sourceDefId;
5211        props.meta = meta;
5212        props.ui = ui;
5213        props.extendedProps = leftovers1;
5214        return props;
5215    }
5216
5217    function reduceEventSources (eventSources, action, dateProfile, calendar) {
5218        switch (action.type) {
5219            case 'ADD_EVENT_SOURCES': // already parsed
5220                return addSources(eventSources, action.sources, dateProfile ? dateProfile.activeRange : null, calendar);
5221            case 'REMOVE_EVENT_SOURCE':
5222                return removeSource(eventSources, action.sourceId);
5223            case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
5224            case 'NEXT':
5225            case 'SET_DATE':
5226            case 'SET_VIEW_TYPE':
5227                if (dateProfile) {
5228                    return fetchDirtySources(eventSources, dateProfile.activeRange, calendar);
5229                }
5230                else {
5231                    return eventSources;
5232                }
5233            case 'FETCH_EVENT_SOURCES':
5234            case 'CHANGE_TIMEZONE':
5235                return fetchSourcesByIds(eventSources, action.sourceIds ?
5236                    arrayToHash(action.sourceIds) :
5237                    excludeStaticSources(eventSources, calendar), dateProfile ? dateProfile.activeRange : null, calendar);
5238            case 'RECEIVE_EVENTS':
5239            case 'RECEIVE_EVENT_ERROR':
5240                return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
5241            case 'REMOVE_ALL_EVENT_SOURCES':
5242                return {};
5243            default:
5244                return eventSources;
5245        }
5246    }
5247    var uid$3 = 0;
5248    function addSources(eventSourceHash, sources, fetchRange, calendar) {
5249        var hash = {};
5250        for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) {
5251            var source = sources_1[_i];
5252            hash[source.sourceId] = source;
5253        }
5254        if (fetchRange) {
5255            hash = fetchDirtySources(hash, fetchRange, calendar);
5256        }
5257        return __assign({}, eventSourceHash, hash);
5258    }
5259    function removeSource(eventSourceHash, sourceId) {
5260        return filterHash(eventSourceHash, function (eventSource) {
5261            return eventSource.sourceId !== sourceId;
5262        });
5263    }
5264    function fetchDirtySources(sourceHash, fetchRange, calendar) {
5265        return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) {
5266            return isSourceDirty(eventSource, fetchRange, calendar);
5267        }), fetchRange, calendar);
5268    }
5269    function isSourceDirty(eventSource, fetchRange, calendar) {
5270        if (!doesSourceNeedRange(eventSource, calendar)) {
5271            return !eventSource.latestFetchId;
5272        }
5273        else {
5274            return !calendar.opt('lazyFetching') ||
5275                !eventSource.fetchRange ||
5276                fetchRange.start < eventSource.fetchRange.start ||
5277                fetchRange.end > eventSource.fetchRange.end;
5278        }
5279    }
5280    function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, calendar) {
5281        var nextSources = {};
5282        for (var sourceId in prevSources) {
5283            var source = prevSources[sourceId];
5284            if (sourceIdHash[sourceId]) {
5285                nextSources[sourceId] = fetchSource(source, fetchRange, calendar);
5286            }
5287            else {
5288                nextSources[sourceId] = source;
5289            }
5290        }
5291        return nextSources;
5292    }
5293    function fetchSource(eventSource, fetchRange, calendar) {
5294        var sourceDef = calendar.pluginSystem.hooks.eventSourceDefs[eventSource.sourceDefId];
5295        var fetchId = String(uid$3++);
5296        sourceDef.fetch({
5297            eventSource: eventSource,
5298            calendar: calendar,
5299            range: fetchRange
5300        }, function (res) {
5301            var rawEvents = res.rawEvents;
5302            var calSuccess = calendar.opt('eventSourceSuccess');
5303            var calSuccessRes;
5304            var sourceSuccessRes;
5305            if (eventSource.success) {
5306                sourceSuccessRes = eventSource.success(rawEvents, res.xhr);
5307            }
5308            if (calSuccess) {
5309                calSuccessRes = calSuccess(rawEvents, res.xhr);
5310            }
5311            rawEvents = sourceSuccessRes || calSuccessRes || rawEvents;
5312            calendar.dispatch({
5313                type: 'RECEIVE_EVENTS',
5314                sourceId: eventSource.sourceId,
5315                fetchId: fetchId,
5316                fetchRange: fetchRange,
5317                rawEvents: rawEvents
5318            });
5319        }, function (error) {
5320            var callFailure = calendar.opt('eventSourceFailure');
5321            console.warn(error.message, error);
5322            if (eventSource.failure) {
5323                eventSource.failure(error);
5324            }
5325            if (callFailure) {
5326                callFailure(error);
5327            }
5328            calendar.dispatch({
5329                type: 'RECEIVE_EVENT_ERROR',
5330                sourceId: eventSource.sourceId,
5331                fetchId: fetchId,
5332                fetchRange: fetchRange,
5333                error: error
5334            });
5335        });
5336        return __assign({}, eventSource, { isFetching: true, latestFetchId: fetchId });
5337    }
5338    function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
5339        var _a;
5340        var eventSource = sourceHash[sourceId];
5341        if (eventSource && // not already removed
5342            fetchId === eventSource.latestFetchId) {
5343            return __assign({}, sourceHash, (_a = {}, _a[sourceId] = __assign({}, eventSource, { isFetching: false, fetchRange: fetchRange }), _a));
5344        }
5345        return sourceHash;
5346    }
5347    function excludeStaticSources(eventSources, calendar) {
5348        return filterHash(eventSources, function (eventSource) {
5349            return doesSourceNeedRange(eventSource, calendar);
5350        });
5351    }
5352
5353    var DateProfileGenerator = /** @class */ (function () {
5354        function DateProfileGenerator(viewSpec, calendar) {
5355            this.viewSpec = viewSpec;
5356            this.options = viewSpec.options;
5357            this.dateEnv = calendar.dateEnv;
5358            this.calendar = calendar;
5359            this.initHiddenDays();
5360        }
5361        /* Date Range Computation
5362        ------------------------------------------------------------------------------------------------------------------*/
5363        // Builds a structure with info about what the dates/ranges will be for the "prev" view.
5364        DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate) {
5365            var dateEnv = this.dateEnv;
5366            var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5367            currentDateProfile.dateIncrement);
5368            return this.build(prevDate, -1);
5369        };
5370        // Builds a structure with info about what the dates/ranges will be for the "next" view.
5371        DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate) {
5372            var dateEnv = this.dateEnv;
5373            var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month
5374            currentDateProfile.dateIncrement);
5375            return this.build(nextDate, 1);
5376        };
5377        // Builds a structure holding dates/ranges for rendering around the given date.
5378        // Optional direction param indicates whether the date is being incremented/decremented
5379        // from its previous value. decremented = -1, incremented = 1 (default).
5380        DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) {
5381            if (forceToValid === void 0) { forceToValid = false; }
5382            var validRange;
5383            var minTime = null;
5384            var maxTime = null;
5385            var currentInfo;
5386            var isRangeAllDay;
5387            var renderRange;
5388            var activeRange;
5389            var isValid;
5390            validRange = this.buildValidRange();
5391            validRange = this.trimHiddenDays(validRange);
5392            if (forceToValid) {
5393                currentDate = constrainMarkerToRange(currentDate, validRange);
5394            }
5395            currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
5396            isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
5397            renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
5398            renderRange = this.trimHiddenDays(renderRange);
5399            activeRange = renderRange;
5400            if (!this.options.showNonCurrentDates) {
5401                activeRange = intersectRanges(activeRange, currentInfo.range);
5402            }
5403            minTime = createDuration(this.options.minTime);
5404            maxTime = createDuration(this.options.maxTime);
5405            activeRange = this.adjustActiveRange(activeRange, minTime, maxTime);
5406            activeRange = intersectRanges(activeRange, validRange); // might return null
5407            // it's invalid if the originally requested date is not contained,
5408            // or if the range is completely outside of the valid range.
5409            isValid = rangesIntersect(currentInfo.range, validRange);
5410            return {
5411                // constraint for where prev/next operations can go and where events can be dragged/resized to.
5412                // an object with optional start and end properties.
5413                validRange: validRange,
5414                // range the view is formally responsible for.
5415                // for example, a month view might have 1st-31st, excluding padded dates
5416                currentRange: currentInfo.range,
5417                // name of largest unit being displayed, like "month" or "week"
5418                currentRangeUnit: currentInfo.unit,
5419                isRangeAllDay: isRangeAllDay,
5420                // dates that display events and accept drag-n-drop
5421                // will be `null` if no dates accept events
5422                activeRange: activeRange,
5423                // date range with a rendered skeleton
5424                // includes not-active days that need some sort of DOM
5425                renderRange: renderRange,
5426                // Duration object that denotes the first visible time of any given day
5427                minTime: minTime,
5428                // Duration object that denotes the exclusive visible end time of any given day
5429                maxTime: maxTime,
5430                isValid: isValid,
5431                // how far the current date will move for a prev/next operation
5432                dateIncrement: this.buildDateIncrement(currentInfo.duration)
5433                // pass a fallback (might be null) ^
5434            };
5435        };
5436        // Builds an object with optional start/end properties.
5437        // Indicates the minimum/maximum dates to display.
5438        // not responsible for trimming hidden days.
5439        DateProfileGenerator.prototype.buildValidRange = function () {
5440            return this.getRangeOption('validRange', this.calendar.getNow()) ||
5441                { start: null, end: null }; // completely open-ended
5442        };
5443        // Builds a structure with info about the "current" range, the range that is
5444        // highlighted as being the current month for example.
5445        // See build() for a description of `direction`.
5446        // Guaranteed to have `range` and `unit` properties. `duration` is optional.
5447        DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
5448            var _a = this, viewSpec = _a.viewSpec, dateEnv = _a.dateEnv;
5449            var duration = null;
5450            var unit = null;
5451            var range = null;
5452            var dayCount;
5453            if (viewSpec.duration) {
5454                duration = viewSpec.duration;
5455                unit = viewSpec.durationUnit;
5456                range = this.buildRangeFromDuration(date, direction, duration, unit);
5457            }
5458            else if ((dayCount = this.options.dayCount)) {
5459                unit = 'day';
5460                range = this.buildRangeFromDayCount(date, direction, dayCount);
5461            }
5462            else if ((range = this.buildCustomVisibleRange(date))) {
5463                unit = dateEnv.greatestWholeUnit(range.start, range.end).unit;
5464            }
5465            else {
5466                duration = this.getFallbackDuration();
5467                unit = greatestDurationDenominator(duration).unit;
5468                range = this.buildRangeFromDuration(date, direction, duration, unit);
5469            }
5470            return { duration: duration, unit: unit, range: range };
5471        };
5472        DateProfileGenerator.prototype.getFallbackDuration = function () {
5473            return createDuration({ day: 1 });
5474        };
5475        // Returns a new activeRange to have time values (un-ambiguate)
5476        // minTime or maxTime causes the range to expand.
5477        DateProfileGenerator.prototype.adjustActiveRange = function (range, minTime, maxTime) {
5478            var dateEnv = this.dateEnv;
5479            var start = range.start;
5480            var end = range.end;
5481            if (this.viewSpec.class.prototype.usesMinMaxTime) {
5482                // expand active range if minTime is negative (why not when positive?)
5483                if (asRoughDays(minTime) < 0) {
5484                    start = startOfDay(start); // necessary?
5485                    start = dateEnv.add(start, minTime);
5486                }
5487                // expand active range if maxTime is beyond one day (why not when positive?)
5488                if (asRoughDays(maxTime) > 1) {
5489                    end = startOfDay(end); // necessary?
5490                    end = addDays(end, -1);
5491                    end = dateEnv.add(end, maxTime);
5492                }
5493            }
5494            return { start: start, end: end };
5495        };
5496        // Builds the "current" range when it is specified as an explicit duration.
5497        // `unit` is the already-computed greatestDurationDenominator unit of duration.
5498        DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
5499            var dateEnv = this.dateEnv;
5500            var alignment = this.options.dateAlignment;
5501            var dateIncrementInput;
5502            var dateIncrementDuration;
5503            var start;
5504            var end;
5505            var res;
5506            // compute what the alignment should be
5507            if (!alignment) {
5508                dateIncrementInput = this.options.dateIncrement;
5509                if (dateIncrementInput) {
5510                    dateIncrementDuration = createDuration(dateIncrementInput);
5511                    // use the smaller of the two units
5512                    if (asRoughMs(dateIncrementDuration) < asRoughMs(duration)) {
5513                        alignment = greatestDurationDenominator(dateIncrementDuration, !getWeeksFromInput(dateIncrementInput)).unit;
5514                    }
5515                    else {
5516                        alignment = unit;
5517                    }
5518                }
5519                else {
5520                    alignment = unit;
5521                }
5522            }
5523            // if the view displays a single day or smaller
5524            if (asRoughDays(duration) <= 1) {
5525                if (this.isHiddenDay(start)) {
5526                    start = this.skipHiddenDays(start, direction);
5527                    start = startOfDay(start);
5528                }
5529            }
5530            function computeRes() {
5531                start = dateEnv.startOf(date, alignment);
5532                end = dateEnv.add(start, duration);
5533                res = { start: start, end: end };
5534            }
5535            computeRes();
5536            // if range is completely enveloped by hidden days, go past the hidden days
5537            if (!this.trimHiddenDays(res)) {
5538                date = this.skipHiddenDays(date, direction);
5539                computeRes();
5540            }
5541            return res;
5542        };
5543        // Builds the "current" range when a dayCount is specified.
5544        DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
5545            var dateEnv = this.dateEnv;
5546            var customAlignment = this.options.dateAlignment;
5547            var runningCount = 0;
5548            var start = date;
5549            var end;
5550            if (customAlignment) {
5551                start = dateEnv.startOf(start, customAlignment);
5552            }
5553            start = startOfDay(start);
5554            start = this.skipHiddenDays(start, direction);
5555            end = start;
5556            do {
5557                end = addDays(end, 1);
5558                if (!this.isHiddenDay(end)) {
5559                    runningCount++;
5560                }
5561            } while (runningCount < dayCount);
5562            return { start: start, end: end };
5563        };
5564        // Builds a normalized range object for the "visible" range,
5565        // which is a way to define the currentRange and activeRange at the same time.
5566        DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
5567            var dateEnv = this.dateEnv;
5568            var visibleRange = this.getRangeOption('visibleRange', dateEnv.toDate(date));
5569            if (visibleRange && (visibleRange.start == null || visibleRange.end == null)) {
5570                return null;
5571            }
5572            return visibleRange;
5573        };
5574        // Computes the range that will represent the element/cells for *rendering*,
5575        // but which may have voided days/times.
5576        // not responsible for trimming hidden days.
5577        DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
5578            return currentRange;
5579        };
5580        // Compute the duration value that should be added/substracted to the current date
5581        // when a prev/next operation happens.
5582        DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
5583            var dateIncrementInput = this.options.dateIncrement;
5584            var customAlignment;
5585            if (dateIncrementInput) {
5586                return createDuration(dateIncrementInput);
5587            }
5588            else if ((customAlignment = this.options.dateAlignment)) {
5589                return createDuration(1, customAlignment);
5590            }
5591            else if (fallback) {
5592                return fallback;
5593            }
5594            else {
5595                return createDuration({ days: 1 });
5596            }
5597        };
5598        // Arguments after name will be forwarded to a hypothetical function value
5599        // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects.
5600        // Always clone your objects if you fear mutation.
5601        DateProfileGenerator.prototype.getRangeOption = function (name) {
5602            var otherArgs = [];
5603            for (var _i = 1; _i < arguments.length; _i++) {
5604                otherArgs[_i - 1] = arguments[_i];
5605            }
5606            var val = this.options[name];
5607            if (typeof val === 'function') {
5608                val = val.apply(null, otherArgs);
5609            }
5610            if (val) {
5611                val = parseRange(val, this.dateEnv);
5612            }
5613            if (val) {
5614                val = computeVisibleDayRange(val);
5615            }
5616            return val;
5617        };
5618        /* Hidden Days
5619        ------------------------------------------------------------------------------------------------------------------*/
5620        // Initializes internal variables related to calculating hidden days-of-week
5621        DateProfileGenerator.prototype.initHiddenDays = function () {
5622            var hiddenDays = this.options.hiddenDays || []; // array of day-of-week indices that are hidden
5623            var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
5624            var dayCnt = 0;
5625            var i;
5626            if (this.options.weekends === false) {
5627                hiddenDays.push(0, 6); // 0=sunday, 6=saturday
5628            }
5629            for (i = 0; i < 7; i++) {
5630                if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
5631                    dayCnt++;
5632                }
5633            }
5634            if (!dayCnt) {
5635                throw new Error('invalid hiddenDays'); // all days were hidden? bad.
5636            }
5637            this.isHiddenDayHash = isHiddenDayHash;
5638        };
5639        // Remove days from the beginning and end of the range that are computed as hidden.
5640        // If the whole range is trimmed off, returns null
5641        DateProfileGenerator.prototype.trimHiddenDays = function (range) {
5642            var start = range.start;
5643            var end = range.end;
5644            if (start) {
5645                start = this.skipHiddenDays(start);
5646            }
5647            if (end) {
5648                end = this.skipHiddenDays(end, -1, true);
5649            }
5650            if (start == null || end == null || start < end) {
5651                return { start: start, end: end };
5652            }
5653            return null;
5654        };
5655        // Is the current day hidden?
5656        // `day` is a day-of-week index (0-6), or a Date (used for UTC)
5657        DateProfileGenerator.prototype.isHiddenDay = function (day) {
5658            if (day instanceof Date) {
5659                day = day.getUTCDay();
5660            }
5661            return this.isHiddenDayHash[day];
5662        };
5663        // Incrementing the current day until it is no longer a hidden day, returning a copy.
5664        // DOES NOT CONSIDER validRange!
5665        // If the initial value of `date` is not a hidden day, don't do anything.
5666        // Pass `isExclusive` as `true` if you are dealing with an end date.
5667        // `inc` defaults to `1` (increment one day forward each time)
5668        DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) {
5669            if (inc === void 0) { inc = 1; }
5670            if (isExclusive === void 0) { isExclusive = false; }
5671            while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
5672                date = addDays(date, inc);
5673            }
5674            return date;
5675        };
5676        return DateProfileGenerator;
5677    }());
5678    // TODO: find a way to avoid comparing DateProfiles. it's tedious
5679    function isDateProfilesEqual(p0, p1) {
5680        return rangesEqual(p0.validRange, p1.validRange) &&
5681            rangesEqual(p0.activeRange, p1.activeRange) &&
5682            rangesEqual(p0.renderRange, p1.renderRange) &&
5683            durationsEqual(p0.minTime, p1.minTime) &&
5684            durationsEqual(p0.maxTime, p1.maxTime);
5685        /*
5686        TODO: compare more?
5687          currentRange: DateRange
5688          currentRangeUnit: string
5689          isRangeAllDay: boolean
5690          isValid: boolean
5691          dateIncrement: Duration
5692        */
5693    }
5694
5695    function reduce (state, action, calendar) {
5696        var viewType = reduceViewType(state.viewType, action);
5697        var dateProfile = reduceDateProfile(state.dateProfile, action, state.currentDate, viewType, calendar);
5698        var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendar);
5699        var nextState = __assign({}, state, { viewType: viewType,
5700            dateProfile: dateProfile, currentDate: reduceCurrentDate(state.currentDate, action, dateProfile), eventSources: eventSources, eventStore: reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendar), dateSelection: reduceDateSelection(state.dateSelection, action, calendar), eventSelection: reduceSelectedEvent(state.eventSelection, action), eventDrag: reduceEventDrag(state.eventDrag, action, eventSources, calendar), eventResize: reduceEventResize(state.eventResize, action, eventSources, calendar), eventSourceLoadingLevel: computeLoadingLevel(eventSources), loadingLevel: computeLoadingLevel(eventSources) });
5701        for (var _i = 0, _a = calendar.pluginSystem.hooks.reducers; _i < _a.length; _i++) {
5702            var reducerFunc = _a[_i];
5703            nextState = reducerFunc(nextState, action, calendar);
5704        }
5705        // console.log(action.type, nextState)
5706        return nextState;
5707    }
5708    function reduceViewType(currentViewType, action) {
5709        switch (action.type) {
5710            case 'SET_VIEW_TYPE':
5711                return action.viewType;
5712            default:
5713                return currentViewType;
5714        }
5715    }
5716    function reduceDateProfile(currentDateProfile, action, currentDate, viewType, calendar) {
5717        var newDateProfile;
5718        switch (action.type) {
5719            case 'PREV':
5720                newDateProfile = calendar.dateProfileGenerators[viewType].buildPrev(currentDateProfile, currentDate);
5721                break;
5722            case 'NEXT':
5723                newDateProfile = calendar.dateProfileGenerators[viewType].buildNext(currentDateProfile, currentDate);
5724                break;
5725            case 'SET_DATE':
5726                if (!currentDateProfile.activeRange ||
5727                    !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker)) {
5728                    newDateProfile = calendar.dateProfileGenerators[viewType].build(action.dateMarker, undefined, true // forceToValid
5729                    );
5730                }
5731                break;
5732            case 'SET_VIEW_TYPE':
5733                var generator = calendar.dateProfileGenerators[viewType];
5734                if (!generator) {
5735                    throw new Error(viewType ?
5736                        'The FullCalendar view "' + viewType + '" does not exist. Make sure your plugins are loaded correctly.' :
5737                        'No available FullCalendar view plugins.');
5738                }
5739                newDateProfile = generator.build(action.dateMarker || currentDate, undefined, true // forceToValid
5740                );
5741                break;
5742        }
5743        if (newDateProfile &&
5744            newDateProfile.isValid &&
5745            !(currentDateProfile && isDateProfilesEqual(currentDateProfile, newDateProfile))) {
5746            return newDateProfile;
5747        }
5748        else {
5749            return currentDateProfile;
5750        }
5751    }
5752    function reduceCurrentDate(currentDate, action, dateProfile) {
5753        switch (action.type) {
5754            case 'PREV':
5755            case 'NEXT':
5756                if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) {
5757                    return dateProfile.currentRange.start;
5758                }
5759                else {
5760                    return currentDate;
5761                }
5762            case 'SET_DATE':
5763            case 'SET_VIEW_TYPE':
5764                var newDate = action.dateMarker || currentDate;
5765                if (dateProfile.activeRange && !rangeContainsMarker(dateProfile.activeRange, newD
5765ate)) {
5766                    return dateProfile.currentRange.start;
5767                }
5768                else {
5769                    return newDate;
5770                }
5771            default:
5772                return currentDate;
5773        }
5774    }
5775    function reduceDateSelection(currentSelection, action, calendar) {
5776        switch (action.type) {
5777            case 'SELECT_DATES':
5778                return action.selection;
5779            case 'UNSELECT_DATES':
5780                return null;
5781            default:
5782                return currentSelection;
5783        }
5784    }
5785    function reduceSelectedEvent(currentInstanceId, action) {
5786        switch (action.type) {
5787            case 'SELECT_EVENT':
5788                return action.eventInstanceId;
5789            case 'UNSELECT_EVENT':
5790                return '';
5791            default:
5792                return currentInstanceId;
5793        }
5794    }
5795    function reduceEventDrag(currentDrag, action, sources, calendar) {
5796        switch (action.type) {
5797            case 'SET_EVENT_DRAG':
5798                var newDrag = action.state;
5799                return {
5800                    affectedEvents: newDrag.affectedEvents,
5801                    mutatedEvents: newDrag.mutatedEvents,
5802                    isEvent: newDrag.isEvent,
5803                    origSeg: newDrag.origSeg
5804                };
5805            case 'UNSET_EVENT_DRAG':
5806                return null;
5807            default:
5808                return currentDrag;
5809        }
5810    }
5811    function reduceEventResize(currentResize, action, sources, calendar) {
5812        switch (action.type) {
5813            case 'SET_EVENT_RESIZE':
5814                var newResize = action.state;
5815                return {
5816                    affectedEvents: newResize.affectedEvents,
5817                    mutatedEvents: newResize.mutatedEvents,
5818                    isEvent: newResize.isEvent,
5819                    origSeg: newResize.origSeg
5820                };
5821            case 'UNSET_EVENT_RESIZE':
5822                return null;
5823            default:
5824                return currentResize;
5825        }
5826    }
5827    function computeLoadingLevel(eventSources) {
5828        var cnt = 0;
5829        for (var sourceId in eventSources) {
5830            if (eventSources[sourceId].isFetching) {
5831                cnt++;
5832            }
5833        }
5834        return cnt;
5835    }
5836
5837    var STANDARD_PROPS = {
5838        start: null,
5839        end: null,
5840        allDay: Boolean
5841    };
5842    function parseDateSpan(raw, dateEnv, defaultDuration) {
5843        var span = parseOpenDateSpan(raw, dateEnv);
5844        var range = span.range;
5845        if (!range.start) {
5846            return null;
5847        }
5848        if (!range.end) {
5849            if (defaultDuration == null) {
5850                return null;
5851            }
5852            else {
5853                range.end = dateEnv.add(range.start, defaultDuration);
5854            }
5855        }
5856        return span;
5857    }
5858    /*
5859    TODO: somehow combine with parseRange?
5860    Will return null if the start/end props were present but parsed invalidly.
5861    */
5862    function parseOpenDateSpan(raw, dateEnv) {
5863        var leftovers = {};
5864        var standardProps = refineProps(raw, STANDARD_PROPS, {}, leftovers);
5865        var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
5866        var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
5867        var allDay = standardProps.allDay;
5868        if (allDay == null) {
5869            allDay = (startMeta && startMeta.isTimeUnspecified) &&
5870                (!endMeta || endMeta.isTimeUnspecified);
5871        }
5872        // use this leftover object as the selection object
5873        leftovers.range = {
5874            start: startMeta ? startMeta.marker : null,
5875            end: endMeta ? endMeta.marker : null
5876        };
5877        leftovers.allDay = allDay;
5878        return leftovers;
5879    }
5880    function isDateSpansEqual(span0, span1) {
5881        return rangesEqual(span0.range, span1.range) &&
5882            span0.allDay === span1.allDay &&
5883            isSpanPropsEqual(span0, span1);
5884    }
5885    // the NON-DATE-RELATED props
5886    function isSpanPropsEqual(span0, span1) {
5887        for (var propName in span1) {
5888            if (propName !== 'range' && propName !== 'allDay') {
5889                if (span0[propName] !== span1[propName]) {
5890                    return false;
5891                }
5892            }
5893        }
5894        // are there any props that span0 has that span1 DOESN'T have?
5895        // both have range/allDay, so no need to special-case.
5896        for (var propName in span0) {
5897            if (!(propName in span1)) {
5898                return false;
5899            }
5900        }
5901        return true;
5902    }
5903    function buildDateSpanApi(span, dateEnv) {
5904        return {
5905            start: dateEnv.toDate(span.range.start),
5906            end: dateEnv.toDate(span.range.end),
5907            startStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
5908            endStr: dateEnv.formatIso(span.range.end, { omitTime: span.allDay }),
5909            allDay: span.allDay
5910        };
5911    }
5912    function buildDatePointApi(span, dateEnv) {
5913        return {
5914            date: dateEnv.toDate(span.range.start),
5915            dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
5916            allDay: span.allDay
5917        };
5918    }
5919    function fabricateEventRange(dateSpan, eventUiBases, calendar) {
5920        var def = parseEventDef({ editable: false }, '', // sourceId
5921        dateSpan.allDay, true, // hasEnd
5922        calendar);
5923        return {
5924            def: def,
5925            ui: compileEventUi(def, eventUiBases),
5926            instance: createEventInstance(def.defId, dateSpan.range),
5927            range: dateSpan.range,
5928            isStart: true,
5929            isEnd: true
5930        };
5931    }
5932
5933    function compileViewDefs(defaultConfigs, overrideConfigs) {
5934        var hash = {};
5935        var viewType;
5936        for (viewType in defaultConfigs) {
5937            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5938        }
5939        for (viewType in overrideConfigs) {
5940            ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5941        }
5942        return hash;
5943    }
5944    function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5945        if (hash[viewType]) {
5946            return hash[viewType];
5947        }
5948        var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
5949        if (viewDef) {
5950            hash[viewType] = viewDef;
5951        }
5952        return viewDef;
5953    }
5954    function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
5955        var defaultConfig = defaultConfigs[viewType];
5956        var overrideConfig = overrideConfigs[viewType];
5957        var queryProp = function (name) {
5958            return (defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :
5959                ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null);
5960        };
5961        var theClass = queryProp('class');
5962        var superType = queryProp('superType');
5963        if (!superType && theClass) {
5964            superType =
5965                findViewNameBySubclass(theClass, overrideConfigs) ||
5966                    findViewNameBySubclass(theClass, defaultConfigs);
5967        }
5968        var superDef = null;
5969        if (superType) {
5970            if (superType === viewType) {
5971                throw new Error('Can\'t have a custom view type that references itself');
5972            }
5973            superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);
5974        }
5975        if (!theClass && superDef) {
5976            theClass = superDef.class;
5977        }
5978        if (!theClass) {
5979            return null; // don't throw a warning, might be settings for a single-unit view
5980        }
5981        return {
5982            type: viewType,
5983            class: theClass,
5984            defaults: __assign({}, (superDef ? superDef.defaults : {}), (defaultConfig ? defaultConfig.options : {})),
5985            overrides: __assign({}, (superDef ? superDef.overrides : {}), (overrideConfig ? overrideConfig.options : {}))
5986        };
5987    }
5988    function findViewNameBySubclass(viewSubclass, configs) {
5989        var superProto = Object.getPrototypeOf(viewSubclass.prototype);
5990        for (var viewType in configs) {
5991            var parsed = configs[viewType];
5992            // need DIRECT subclass, so instanceof won't do it
5993            if (parsed.class && parsed.class.prototype === superProto) {
5994                return viewType;
5995            }
5996        }
5997        return '';
5998    }
5999
6000    function parseViewConfigs(inputs) {
6001        return mapHash(inputs, parseViewConfig);
6002    }
6003    var VIEW_DEF_PROPS = {
6004        type: String,
6005        class: null
6006    };
6007    function parseViewConfig(input) {
6008        if (typeof input === 'function') {
6009            input = { class: input };
6010        }
6011        var options = {};
6012        var props = refineProps(input, VIEW_DEF_PROPS, {}, options);
6013        return {
6014            superType: props.type,
6015            class: props.class,
6016            options: options
6017        };
6018    }
6019
6020    function buildViewSpecs(defaultInputs, optionsManager) {
6021        var defaultConfigs = parseViewConfigs(defaultInputs);
6022        var overrideConfigs = parseViewConfigs(optionsManager.overrides.views);
6023        var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
6024        return mapHash(viewDefs, function (viewDef) {
6025            return buildViewSpec(viewDef, overrideConfigs, optionsManager);
6026        });
6027    }
6028    function buildViewSpec(viewDef, overrideConfigs, optionsManager) {
6029        var durationInput = viewDef.overrides.duration ||
6030            viewDef.defaults.duration ||
6031            optionsManager.dynamicOverrides.duration ||
6032            optionsManager.overrides.duration;
6033        var duration = null;
6034        var durationUnit = '';
6035        var singleUnit = '';
6036        var singleUnitOverrides = {};
6037        if (durationInput) {
6038            duration = createDuration(durationInput);
6039            if (duration) { // valid?
6040                var denom = greatestDurationDenominator(duration, !getWeeksFromInput(durationInput));
6041                durationUnit = denom.unit;
6042                if (denom.value === 1) {
6043                    singleUnit = durationUnit;
6044                    singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].options : {};
6045                }
6046            }
6047        }
6048        var queryButtonText = function (options) {
6049            var buttonTextMap = options.buttonText || {};
6050            var buttonTextKey = viewDef.defaults.buttonTextKey;
6051            if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
6052                return buttonTextMap[buttonTextKey];
6053            }
6054            if (buttonTextMap[viewDef.type] != null) {
6055                return buttonTextMap[viewDef.type];
6056            }
6057            if (buttonTextMap[singleUnit] != null) {
6058                return buttonTextMap[singleUnit];
6059            }
6060        };
6061        return {
6062            type: viewDef.type,
6063            class: viewDef.class,
6064            duration: duration,
6065            durationUnit: durationUnit,
6066            singleUnit: singleUnit,
6067            options: __assign({}, globalDefaults, viewDef.defaults, optionsManager.dirDefaults, optionsManager.localeDefaults, optionsManager.overrides, singleUnitOverrides, viewDef.overrides, optionsManager.dynamicOverrides),
6068            buttonTextOverride: queryButtonText(optionsManager.dynamicOverrides) ||
6069                queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence
6070                viewDef.overrides.buttonText,
6071            buttonTextDefault: queryButtonText(optionsManager.localeDefaults) ||
6072                queryButtonText(optionsManager.dirDefaults) ||
6073                viewDef.defaults.buttonText ||
6074                queryButtonText(globalDefaults) ||
6075                viewDef.type // fall back to given view name
6076        };
6077    }
6078
6079    var Toolbar = /** @class */ (function (_super) {
6080        __extends(Toolbar, _super);
6081        function Toolbar(context, extraClassName) {
6082            var _this = _super.call(this, context) || this;
6083            _this._renderLayout = memoizeRendering(_this.renderLayout, _this.unrenderLayout);
6084            _this._updateTitle = memoizeRendering(_this.updateTitle, null, [_this._renderLayout]);
6085            _this._updateActiveButton = memoizeRendering(_this.updateActiveButton, null, [_this._renderLayout]);
6086            _this._updateToday = memoizeRendering(_this.updateToday, null, [_this._renderLayout]);
6087            _this._updatePrev = memoizeRendering(_this.updatePrev, null, [_this._renderLayout]);
6088            _this._updateNext = memoizeRendering(_this.updateNext, null, [_this._renderLayout]);
6089            _this.el = createElement('div', { className: 'fc-toolbar ' + extraClassName });
6090            return _this;
6091        }
6092        Toolbar.prototype.destroy = function () {
6093            _super.prototype.destroy.call(this);
6094            this._renderLayout.unrender(); // should unrender everything else
6095            removeElement(this.el);
6096        };
6097        Toolbar.prototype.render = function (props) {
6098            this._renderLayout(props.layout);
6099            this._updateTitle(props.title);
6100            this._updateActiveButton(props.activeButton);
6101            this._updateToday(props.isTodayEnabled);
6102            this._updatePrev(props.isPrevEnabled);
6103            this._updateNext(props.isNextEnabled);
6104        };
6105        Toolbar.prototype.renderLayout = function (layout) {
6106            var el = this.el;
6107            this.viewsWithButtons = [];
6108            appendToElement(el, this.renderSection('left', layout.left));
6109            appendToElement(el, this.renderSection('center', layout.center));
6110            appendToElement(el, this.renderSection('right', layout.right));
6111        };
6112        Toolbar.prototype.unrenderLayout = function () {
6113            this.el.innerHTML = '';
6114        };
6115        Toolbar.prototype.renderSection = function (position, buttonStr) {
6116            var _this = this;
6117            var _a = this, theme = _a.theme, calendar = _a.calendar;
6118            var optionsManager = calendar.optionsManager;
6119            var viewSpecs = calendar.viewSpecs;
6120            var sectionEl = createElement('div', { className: 'fc-' + position });
6121            var calendarCustomButtons = optionsManager.computed.customButtons || {};
6122            var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {};
6123            var calendarButtonText = optionsManager.computed.buttonText || {};
6124            if (buttonStr) {
6125                buttonStr.split(' ').forEach(function (buttonGroupStr, i) {
6126                    var groupChildren = [];
6127                    var isOnlyButtons = true;
6128                    var groupEl;
6129                    buttonGroupStr.split(',').forEach(function (buttonName, j) {
6130                        var customButtonProps;
6131                        var viewSpec;
6132                        var buttonClick;
6133                        var buttonIcon; // only one of these will be set
6134                        var buttonText; // "
6135                        var buttonInnerHtml;
6136                        var buttonClasses;
6137                        var buttonEl;
6138                        var buttonAriaAttr;
6139                        if (buttonName === 'title') {
6140                            groupChildren.push(htmlToElement('<h2>&nbsp;</h2>')); // we always want it to take up height
6141                            isOnlyButtons = false;
6142                        }
6143                        else {
6144                            if ((customButtonProps = calendarCustomButtons[buttonName])) {
6145                                buttonClick = function (ev) {
6146                                    if (customButtonProps.click) {
6147                                        customButtonProps.click.call(buttonEl, ev);
6148                                    }
6149                                };
6150                                (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
6151                                    (buttonIcon = theme.getIconClass(buttonName)) ||
6152                                    (buttonText = customButtonProps.text);
6153                            }
6154                            else if ((viewSpec = viewSpecs[buttonName])) {
6155                                _this.viewsWithButtons.push(buttonName);
6156                                buttonClick = function () {
6157                                    calendar.changeView(buttonName);
6158                                };
6159                                (buttonText = viewSpec.buttonTextOverride) ||
6160                                    (buttonIcon = theme.getIconClass(buttonName)) ||
6161                                    (buttonText = viewSpec.buttonTextDefault);
6162                            }
6163                            else if (calendar[buttonName]) { // a calendar method
6164                                buttonClick = function () {
6165                                    calendar[buttonName]();
6166                                };
6167                                (buttonText = calendarButtonTextOverrides[buttonName]) ||
6168                                    (buttonIcon = theme.getIconClass(buttonName)) ||
6169                                    (buttonText = calendarButtonText[buttonName]);
6170                                //            ^ everything else is considered default
6171                            }
6172                            if (buttonClick) {
6173                                buttonClasses = [
6174                                    'fc-' + buttonName + '-button',
6175                                    theme.getClass('button')
6176                                ];
6177                                if (buttonText) {
6178                                    buttonInnerHtml = htmlEscape(buttonText);
6179                                    buttonAriaAttr = '';
6180                                }
6181                                else if (buttonIcon) {
6182                                    buttonInnerHtml = "<span class='" + buttonIcon + "'></span>";
6183                                    buttonAriaAttr = ' aria-label="' + buttonName + '"';
6184                                }
6185                                buttonEl = htmlToElement(// type="button" so that it doesn't submit a form
6186                                '<button type="button" class="' + buttonClasses.join(' ') + '"' +
6187                                    buttonAriaAttr +
6188                                    '>' + buttonInnerHtml + '</button>');
6189                                buttonEl.addEventListener('click', buttonClick);
6190                                groupChildren.push(buttonEl);
6191                            }
6192                        }
6193                    });
6194                    if (groupChildren.length > 1) {
6195                        groupEl = document.createElement('div');
6196                        var buttonGroupClassName = theme.getClass('buttonGroup');
6197                        if (isOnlyButtons && buttonGroupClassName) {
6198                            groupEl.classList.add(buttonGroupClassName);
6199                        }
6200                        appendToElement(groupEl, groupChildren);
6201                        sectionEl.appendChild(groupEl);
6202                    }
6203                    else {
6204                        appendToElement(sectionEl, groupChildren); // 1 or 0 children
6205                    }
6206                });
6207            }
6208            return sectionEl;
6209        };
6210        Toolbar.prototype.updateToday = function (isTodayEnabled) {
6211            this.toggleButtonEnabled('today', isTodayEnabled);
6212        };
6213        Toolbar.prototype.updatePrev = function (isPrevEnabled) {
6214            this.toggleButtonEnabled('prev', isPrevEnabled);
6215        };
6216        Toolbar.prototype.updateNext = function (isNextEnabled) {
6217            this.toggleButtonEnabled('next', isNextEnabled);
6218        };
6219        Toolbar.prototype.updateTitle = function (text) {
6220            findElements(this.el, 'h2').forEach(function (titleEl) {
6221                titleEl.innerText = text;
6222            });
6223        };
6224        Toolbar.prototype.updateActiveButton = function (buttonName) {
6225            var className = this.theme.getClass('buttonActive');
6226            findElements(this.el, 'button').forEach(function (buttonEl) {
6227                if (buttonName && buttonEl.classList.contains('fc-' 
6227+ buttonName + '-button')) {
6228                    buttonEl.classList.add(className);
6229                }
6230                else {
6231                    buttonEl.classList.remove(className);
6232                }
6233            });
6234        };
6235        Toolbar.prototype.toggleButtonEnabled = function (buttonName, bool) {
6236            findElements(this.el, '.fc-' + buttonName + '-button').forEach(function (buttonEl) {
6237                buttonEl.disabled = !bool;
6238            });
6239        };
6240        return Toolbar;
6241    }(Component));
6242
6243    var CalendarComponent = /** @class */ (function (_super) {
6244        __extends(CalendarComponent, _super);
6245        function CalendarComponent(context, el) {
6246            var _this = _super.call(this, context) || this;
6247            _this._renderToolbars = memoizeRendering(_this.renderToolbars);
6248            _this.buildViewPropTransformers = memoize(buildViewPropTransformers);
6249            _this.el = el;
6250            prependToElement(el, _this.contentEl = createElement('div', { className: 'fc-view-container' }));
6251            var calendar = _this.calendar;
6252            for (var _i = 0, _a = calendar.pluginSystem.hooks.viewContainerModifiers; _i < _a.length; _i++) {
6253                var modifyViewContainer = _a[_i];
6254                modifyViewContainer(_this.contentEl, calendar);
6255            }
6256            _this.toggleElClassNames(true);
6257            _this.computeTitle = memoize(computeTitle);
6258            _this.parseBusinessHours = memoize(function (input) {
6259                return parseBusinessHours(input, _this.calendar);
6260            });
6261            return _this;
6262        }
6263        CalendarComponent.prototype.destroy = function () {
6264            if (this.header) {
6265                this.header.destroy();
6266            }
6267            if (this.footer) {
6268                this.footer.destroy();
6269            }
6270            if (this.view) {
6271                this.view.destroy();
6272            }
6273            removeElement(this.contentEl);
6274            this.toggleElClassNames(false);
6275            _super.prototype.destroy.call(this);
6276        };
6277        CalendarComponent.prototype.toggleElClassNames = function (bool) {
6278            var classList = this.el.classList;
6279            var dirClassName = 'fc-' + this.opt('dir');
6280            var themeClassName = this.theme.getClass('widget');
6281            if (bool) {
6282                classList.add('fc');
6283                classList.add(dirClassName);
6284                classList.add(themeClassName);
6285            }
6286            else {
6287                classList.remove('fc');
6288                classList.remove(dirClassName);
6289                classList.remove(themeClassName);
6290            }
6291        };
6292        CalendarComponent.prototype.render = function (props) {
6293            this.freezeHeight();
6294            var title = this.computeTitle(props.dateProfile, props.viewSpec.options);
6295            this._renderToolbars(props.viewSpec, props.dateProfile, props.currentDate, props.dateProfileGenerator, title);
6296            this.renderView(props, title);
6297            this.updateSize();
6298            this.thawHeight();
6299        };
6300        CalendarComponent.prototype.renderToolbars = function (viewSpec, dateProfile, currentDate, dateProfileGenerator, title) {
6301            var headerLayout = this.opt('header');
6302            var footerLayout = this.opt('footer');
6303            var now = this.calendar.getNow();
6304            var todayInfo = dateProfileGenerator.build(now);
6305            var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate);
6306            var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate);
6307            var toolbarProps = {
6308                title: title,
6309                activeButton: viewSpec.type,
6310                isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now),
6311                isPrevEnabled: prevInfo.isValid,
6312                isNextEnabled: nextInfo.isValid
6313            };
6314            if (headerLayout) {
6315                if (!this.header) {
6316                    this.header = new Toolbar(this.context, 'fc-header-toolbar');
6317                    prependToElement(this.el, this.header.el);
6318                }
6319                this.header.receiveProps(__assign({ layout: headerLayout }, toolbarProps));
6320            }
6321            else if (this.header) {
6322                this.header.destroy();
6323                this.header = null;
6324            }
6325            if (footerLayout) {
6326                if (!this.footer) {
6327                    this.footer = new Toolbar(this.context, 'fc-footer-toolbar');
6328                    appendToElement(this.el, this.footer.el);
6329                }
6330                this.footer.receiveProps(__assign({ layout: footerLayout }, toolbarProps));
6331            }
6332            else if (this.footer) {
6333                this.footer.destroy();
6334                this.footer = null;
6335            }
6336        };
6337        CalendarComponent.prototype.renderView = function (props, title) {
6338            var view = this.view;
6339            var viewSpec = props.viewSpec, dateProfileGenerator = props.dateProfileGenerator;
6340            if (!view || view.viewSpec !== viewSpec) {
6341                if (view) {
6342                    view.destroy();
6343                }
6344                view = this.view = new viewSpec['class']({
6345                    calendar: this.calendar,
6346                    view: null,
6347                    dateEnv: this.dateEnv,
6348                    theme: this.theme,
6349                    options: viewSpec.options
6350                }, viewSpec, dateProfileGenerator, this.contentEl);
6351            }
6352            else {
6353                view.addScroll(view.queryScroll());
6354            }
6355            view.title = title; // for the API
6356            var viewProps = {
6357                dateProfile: props.dateProfile,
6358                businessHours: this.parseBusinessHours(viewSpec.options.businessHours),
6359                eventStore: props.eventStore,
6360                eventUiBases: props.eventUiBases,
6361                dateSelection: props.dateSelection,
6362                eventSelection: props.eventSelection,
6363                eventDrag: props.eventDrag,
6364                eventResize: props.eventResize
6365            };
6366            var transformers = this.buildViewPropTransformers(this.calendar.pluginSystem.hooks.viewPropsTransformers);
6367            for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
6368                var transformer = transformers_1[_i];
6369                __assign(viewProps, transformer.transform(viewProps, viewSpec, props, view));
6370            }
6371            view.receiveProps(viewProps);
6372        };
6373        // Sizing
6374        // -----------------------------------------------------------------------------------------------------------------
6375        CalendarComponent.prototype.updateSize = function (isResize) {
6376            if (isResize === void 0) { isResize = false; }
6377            var view = this.view;
6378            if (isResize) {
6379                view.addScroll(view.queryScroll());
6380            }
6381            if (isResize || this.isHeightAuto == null) {
6382                this.computeHeightVars();
6383            }
6384            view.updateSize(isResize, this.viewHeight, this.isHeightAuto);
6385            view.updateNowIndicator(); // we need to guarantee this will run after updateSize
6386            view.popScroll(isResize);
6387        };
6388        CalendarComponent.prototype.computeHeightVars = function () {
6389            var calendar = this.calendar; // yuck. need to handle dynamic options
6390            var heightInput = calendar.opt('height');
6391            var contentHeightInput = calendar.opt('contentHeight');
6392            this.isHeightAuto = heightInput === 'auto' || contentHeightInput === 'auto';
6393            if (typeof contentHeightInput === 'number') { // exists and not 'auto'
6394                this.viewHeight = contentHeightInput;
6395            }
6396            else if (typeof contentHeightInput === 'function') { // exists and is a function
6397                this.viewHeight = contentHeightInput();
6398            }
6399            else if (typeof heightInput === 'number') { // exists and not 'auto'
6400                this.viewHeight = heightInput - this.queryToolbarsHeight();
6401            }
6402            else if (typeof heightInput === 'function') { // exists and is a function
6403                this.viewHeight = heightInput() - this.queryToolbarsHeight();
6404            }
6405            else if (heightInput === 'parent') { // set to height of parent element
6406                var parentEl = this.el.parentNode;
6407                this.viewHeight = parentEl.getBoundingClientRect().height - this.queryToolbarsHeight();
6408            }
6409            else {
6410                this.viewHeight = Math.round(this.contentEl.getBoundingClientRect().width /
6411                    Math.max(calendar.opt('aspectRatio'), .5));
6412            }
6413        };
6414        CalendarComponent.prototype.queryToolbarsHeight = function () {
6415            var height = 0;
6416            if (this.header) {
6417                height += computeHeightAndMargins(this.header.el);
6418            }
6419            if (this.footer) {
6420                height += computeHeightAndMargins(this.footer.el);
6421            }
6422            return height;
6423        };
6424        // Height "Freezing"
6425        // -----------------------------------------------------------------------------------------------------------------
6426        CalendarComponent.prototype.freezeHeight = function () {
6427            applyStyle(this.el, {
6428                height: this.el.getBoundingClientRect().height,
6429                overflow: 'hidden'
6430            });
6431        };
6432        CalendarComponent.prototype.thawHeight = function () {
6433            applyStyle(this.el, {
6434                height: '',
6435                overflow: ''
6436            });
6437        };
6438        return CalendarComponent;
6439    }(Component));
6440    // Title and Date Formatting
6441    // -----------------------------------------------------------------------------------------------------------------
6442    // Computes what the title at the top of the calendar should be for this view
6443    function computeTitle(dateProfile, viewOptions) {
6444        var range;
6445        // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
6446        if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
6447            range = dateProfile.currentRange;
6448        }
6449        else { // for day units or smaller, use the actual day range
6450            range = dateProfile.activeRange;
6451        }
6452        return this.dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || computeTitleFormat(dateProfile), viewOptions.titleRangeSeparator), { isEndExclusive: dateProfile.isRangeAllDay });
6453    }
6454    // Generates the format string that should be used to generate the title for the current date range.
6455    // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
6456    function computeTitleFormat(dateProfile) {
6457        var currentRangeUnit = dateProfile.currentRangeUnit;
6458        if (currentRangeUnit === 'year') {
6459            return { year: 'numeric' };
6460        }
6461        else if (currentRangeUnit === 'month') {
6462            return { year: 'numeric', month: 'long' }; // like "September 2014"
6463        }
6464        else {
6465            var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end);
6466            if (days !== null && days > 1) {
6467                // multi-day range. shorter, like "Sep 9 - 10 2014"
6468                return { year: 'numeric', month: 'short', day: 'numeric' };
6469            }
6470            else {
6471                // one day. longer, like "September 9 2014"
6472                return { year: 'numeric', month: 'long', day: 'numeric' };
6473            }
6474        }
6475    }
6476    // Plugin
6477    // -----------------------------------------------------------------------------------------------------------------
6478    function buildViewPropTransformers(theClasses) {
6479        return theClasses.map(function (theClass) {
6480            return new theClass();
6481        });
6482    }
6483
6484    var Interaction = /** @class */ (function () {
6485        function Interaction(settings) {
6486            this.component = settings.component;
6487        }
6488        Interaction.prototype.destroy = function () {
6489        };
6490        return Interaction;
6491    }());
6492    function parseInteractionSettings(component, input) {
6493        return {
6494            component: component,
6495            el: input.el,
6496            useEventCenter: input.useEventCenter != null ? input.useEventCenter : true
6497        };
6498    }
6499    function interactionSettingsToStore(settings) {
6500        var _a;
6501        return _a = {},
6502            _a[settings.component.uid] = settings,
6503            _a;
6504    }
6505    // global state
6506    var interactionSettingsStore = {};
6507
6508    /*
6509    Detects when the user clicks on an event within a DateComponent
6510    */
6511    var EventClicking = /** @class */ (function (_super) {
6512        __extends(EventClicking, _super);
6513        function EventClicking(settings) {
6514            var _this = _super.call(this, settings) || this;
6515            _this.handleSegClick = function (ev, segEl) {
6516                var component = _this.component;
6517                var seg = getElSeg(segEl);
6518                if (seg && // might be the <div> surrounding the more link
6519                    component.isValidSegDownEl(ev.target)) {
6520                    // our way to simulate a link click for elements that can't be <a> tags
6521                    // grab before trigger fired in case trigger trashes DOM thru rerendering
6522                    var hasUrlContainer = elementClosest(ev.target, '.fc-has-url');
6523                    var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
6524                    component.publiclyTrigger('eventClick', [
6525                        {
6526                            el: segEl,
6527                            event: new EventApi(component.calendar, seg.eventRange.def, seg.eventRange.instance),
6528                            jsEvent: ev,
6529                            view: component.view
6530                        }
6531                    ]);
6532                    if (url && !ev.defaultPrevented) {
6533                        window.location.href = url;
6534                    }
6535                }
6536            };
6537            var component = settings.component;
6538            _this.destroy = listenBySelector(component.el, 'click', component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegClick);
6539            return _this;
6540        }
6541        return EventClicking;
6542    }(Interaction));
6543
6544    /*
6545    Triggers events and adds/removes core classNames when the user's pointer
6546    enters/leaves event-elements of a component.
6547    */
6548    var EventHovering = /** @class */ (function (_super) {
6549        __extends(EventHovering, _super);
6550        function EventHovering(settings) {
6551            var _this = _super.call(this, settings) || this;
6552            // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
6553            _this.handleEventElRemove = function (el) {
6554                if (el === _this.currentSegEl) {
6555                    _this.handleSegLeave(null, _this.currentSegEl);
6556                }
6557            };
6558            _this.handleSegEnter = function (ev, segEl) {
6559                if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper
6560                    segEl.classList.add('fc-allow-mouse-resize');
6561                    _this.currentSegEl = segEl;
6562                    _this.triggerEvent('eventMouseEnter', ev, segEl);
6563                }
6564            };
6565            _this.handleSegLeave = function (ev, segEl) {
6566                if (_this.currentSegEl) {
6567                    segEl.classList.remove('fc-allow-mouse-resize');
6568                    _this.currentSegEl = null;
6569                    _this.triggerEvent('eventMouseLeave', ev, segEl);
6570                }
6571            };
6572            var component = settings.component;
6573            _this.removeHoverListeners = listenToHoverBySelector(component.el, component.fgSegSelector + ',' + component.bgSegSelector, _this.handleSegEnter, _this.handleSegLeave);
6574            component.calendar.on('eventElRemove', _this.handleEventElRemove);
6575            return _this;
6576        }
6577        EventHovering.prototype.destroy = function () {
6578            this.removeHoverListeners();
6579            this.component.calendar.off('eventElRemove', this.handleEventElRemove);
6580        };
6581        EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) {
6582            var component = this.component;
6583            var seg = getElSeg(segEl);
6584            if (!ev || component.isValidSegDownEl(ev.target)) {
6585                component.publiclyTrigger(publicEvName, [
6586                    {
6587                        el: segEl,
6588                        event: new EventApi(this.component.calendar, seg.eventRange.def, seg.eventRange.instance),
6589                        jsEvent: ev,
6590                        view: component.view
6591                    }
6592                ]);
6593            }
6594        };
6595        return EventHovering;
6596    }(Interaction));
6597
6598    var StandardTheme = /** @class */ (function (_super) {
6599        __extends(StandardTheme, _super);
6600        function StandardTheme() {
6601            return _super !== null && _super.apply(this, arguments) || this;
6602        }
6603        return StandardTheme;
6604    }(Theme));
6605    StandardTheme.prototype.classes = {
6606        widget: 'fc-unthemed',
6607        widgetHeader: 'fc-widget-header',
6608        widgetContent: 'fc-widget-content',
6609        buttonGroup: 'fc-button-group',
6610        button: 'fc-button fc-button-primary',
6611        buttonActive: 'fc-button-active',
6612        popoverHeader: 'fc-widget-header',
6613        popoverContent: 'fc-widget-content',
6614        // day grid
6615        headerRow: 'fc-widget-header',
6616        dayRow: 'fc-widget-content',
6617        // list view
6618        listView: 'fc-widget-content'
6619    };
6620    StandardTheme.prototype.baseIconClass = 'fc-icon';
6621    StandardTheme.prototype.iconClasses = {
6622        close: 'fc-icon-x',
6623        prev: 'fc-icon-chevron-left',
6624        next: 'fc-icon-chevron-right',
6625        prevYear: 'fc-icon-chevrons-left',
6626        nextYear: 'fc-icon-chevrons-right'
6627    };
6628    StandardTheme.prototype.iconOverrideOption = 'buttonIcons';
6629    StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
6630    StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
6631
6632    var Calendar = /** @class */ (function () {
6633        function Calendar(el, overrides) {
6634            var _this = this;
6635            this.parseRawLocales = memoize(parseRawLocales);
6636            this.buildLocale = memoize(buildLocale);
6637            this.buildDateEnv = memoize(buildDateEnv);
6638            this.buildTheme = memoize(buildTheme);
6639            this.buildEventUiSingleBase = memoize(this._buildEventUiSingleBase);
6640            this.buildSelectionConfig = memoize(this._buildSelectionConfig);
6641            this.buildEventUiBySource = memoizeOutput(buildEventUiBySource, isPropsEqual);
6642            this.buildEventUiBases = memoize(buildEventUiBases);
6643            this.interactionsStore = {};
6644            this.actionQueue = [];
6645            this.isReducing = false;
6646            // isDisplaying: boolean = false // installed in DOM? accepting renders?
6647            this.needsRerender = false; // needs a render?
6648            this.needsFullRerender = false;
6649            this.isRendering = false; // currently in the executeRender function?
6650            this.renderingPauseDepth = 0;
6651            this.buildDelayedRerender = memoize(buildDelayedRerender);
6652            this.afterSizingTriggers = {};
6653            this.isViewUpdated = false;
6654            this.isDatesUpdated = false;
6655            this.isEventsUpdated = false;
6656            this.el = el;
6657            this.optionsManager = new OptionsManager(overrides || {});
6658            this.pluginSystem = new PluginSystem();
6659            // only do once. don't do in handleOptions. because can't remove plugins
6660            this.addPluginInputs(this.optionsManager.computed.plugins || []);
6661            this.handleOptions(this.optionsManager.computed);
6662            this.publiclyTrigger('_init'); // for tests
6663            this.hydrate();
6664            this.calendarInteractions = this.pluginSystem.hooks.calendarInteractions
6665                .map(function (calendarInteractionClass) {
6666                return new calendarInteractionClass(_this);
6667            });
6668        }
6669        Calendar.prototype.addPluginInputs = function (pluginInputs) {
6670            var pluginDefs = refinePluginDefs(pluginInputs);
6671            for (var _i = 0, pluginDefs_1 = pluginDefs; _i < pluginDefs_1.length; _i++) {
6672                var pluginDef = pluginDefs_1[_i];
6673                this.pluginSystem.add(pluginDef);
6674            }
6675        };
6676        Object.defineProperty(Calendar.prototype, "view", {
6677            // public API
6678            get: function () {
6679                return this.component ? this.component.view : null;
6680            },
6681            enumerable: true,
6682            configurable: true
6683        });
6684        // Public API for rendering
6685        // -----------------------------------------------------------------------------------------------------------------
6686        Calendar.prototype.render = function () {
6687            if (!this.component) {
6688                this.renderableEventStore = createEmptyEventStore();
6689                this.bindHandlers();
6690                this.executeRender();
6691            }
6692            else {
6693                this.requestRerender(true);
6694            }
6695        };
6696        Calendar.prototype.destroy = function () {
6697            if (this.component) {
6698                this.unbindHandlers();
6699                this.component.destroy(); // don't null-out. in case API needs access
6700                this.component = null; // umm ???
6701                for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) {
6702                    var interaction = _a[_i];
6703                    interaction.destroy();
6704                }
6705                this.publiclyTrigger('_destroyed');
6706            }
6707        };
6708        // Handlers
6709        // -----------------------------------------------------------------------------------------------------------------
6710        Calendar.prototype.bindHandlers = function () {
6711            var _this = this;
6712            // event delegation for nav links
6713            this.removeNavLinkListener = listenBySelector(this.el, 'click', 'a[data-goto]', function (ev, anchorEl) {
6714                var gotoOptions = anchorEl.getAttribute('data-goto');
6715                gotoOptions = gotoOptions ? JSON.parse(gotoOptions) : {};
6716                var dateEnv = _this.dateEnv;
6717                var dateMarker = dateEnv.createMarker(gotoOptions.date);
6718                var viewType = gotoOptions.type;
6719                // property like "navLinkDayClick". might be a string or a function
6720                var customAction = _this.viewOpt('navLink' + capitaliseFirstLetter(viewType) + 'Click');
6721                if (typeof customAction === 'function') {
6722                    customAction(dateEnv.toDate(dateMarker), ev);
6723                }
6724                else {
6725                    if (typeof customAction === 'string') {
6726                        viewType = customAction;
6727                    }
6728                    _this.zoomTo(dateMarker, viewType);
6729                }
6730            });
6731            if (this.opt('handleWindowResize')) {
6732                window.addEventListener('resize', this.windowResizeProxy = debounce(// prevents rapid calls
6733                this.windowResize.bind(this), this.opt('windowResizeDelay')));
6734            }
6735        };
6736        Calendar.prototype.unbindHandlers = function () {
6737            this.removeNavLinkListener();
6738            if (this.windowResizeProxy) {
6739                window.removeEventListener('resize', this.windowResizeProxy);
6740                this.windowResizeProxy = null;
6741            }
6742        };
6743        // Dispatcher
6744        // -----------------------------------------------------------------------------------------------------------------
6745        Calendar.prototype.hydrate = function () {
6746            var _this = this;
6747            this.state = this.buildInitialState();
6748            var rawSources = this.opt('eventSources') || [];
6749            var singleRawSource = this.opt('events');
6750            var sources = []; // parsed
6751            if (singleRawSource) {
6752                rawSources.unshift(singleRawSource);
6753            }
6754            for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) {
6755                var rawSource = rawSources_1[_i];
6756                var source = parseEventSource(rawSource, this);
6757                if (source) {
6758                    sources.push(source);
6759                }
6760            }
6761            this.batchRendering(function () {
6762                _this.dispatch({ type: 'INIT' }); // pass in sources here?
6763                _this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: sources });
6764                _this.dispatch({
6765                    type: 'SET_VIEW_TYPE',
6766                    viewType: _this.opt('defaultView') || _this.pluginSystem.hooks.defaultView
6767                });
6768            });
6769        };
6770        Calendar.prototype.buildInitialState = function () {
6771            return {
6772                viewType: null,
6773                loadingLevel: 0,
6774                eventSourceLoadingLevel: 0,
6775                currentDate: this.getInitialDate(),
6776                dateProfile: null,
6777                eventSources: {},
6778                eventStore: createEmptyEventStore(),
6779                dateSelection: null,
6780                eventSelection: '',
6781                eventDrag: null,
6782                eventResize: null
6783            };
6784        };
6785        Calendar.prototype.dispatch = function (action) {
6786            this.actionQueue.push(action);
6787            if (!this.isReducing) {
6788                this.isReducing = true;
6789                var oldState = this.state;
6790                while (this.actionQueue.length) {
6791                    this.state = this.reduce(this.state, this.actionQueue.shift(), this);
6792                }
6793                var newState = this.state;
6794                this.isReducing = false;
6795                if (!oldState.loadingLevel && newState.loadingLevel) {
6796                    this.publiclyTrigger('loading', [true]);
6797                }
6798                else if (oldState.loadingLevel && !newState.loadingLevel) {
6799                    this.publiclyTrigger('loading', [false]);
6800                }
6801                var view = this.component && this.component.view;
6802                if (oldState.eventStore !== newState.eventStore || this.needsFullRerender) {
6803                    if (oldState.eventStore) {
6804                        this.isEventsUpdated = true;
6805                    }
6806                }
6807                if (oldState.dateProfile !== newState.dateProfile || this.needsFullRerender) {
6808                    if (oldState.dateProfile && view) { // why would view be null!?
6809                        this.publiclyTrigger('datesDestroy', [
6810                            {
6811                                view: view,
6812                                el: view.el
6813                            }
6814                        ]);
6815                    }
6816                    this.isDatesUpdated = true;
6817                }
6818                if (oldState.viewType !== newState.viewType || this.needsFullRerender) {
6819                    if (oldState.viewType && view) { // why would view be null!?
6820                        this.publiclyTrigger('viewSkeletonDestroy', [
6821                            {
6822                                view: view,
6823                                el: view.el
6824                            }
6825                        ]);
6826                    }
6827                    this.isViewUpdated = true;
6828                }
6829                this.requestRerender();
6830            }
6831        };
6832        Calendar.prototype.reduce = function (state, action, calendar) {
6833            return reduce(state, action, calendar);
6834        };
6835        // Render Queue
6836        // -----------------------------------------------------------------------------------------------------------------
6837        Calendar.prototype.requestRerender = function (needsFull) {
6838            if (needsFull === void 0) { needsFull = false; }
6839            this.needsRerender = true;
6840            this.needsFullRerender = this.needsFullRerender || needsFull;
6841            this.delayedRerender(); // will call a debounced-version of tryRerender
6842        };
6843        Calendar.prototype.tryRerender = function () {
6844            if (this.component && // must be accepting renders
6845                this.needsRerender && // indicates that a rerender was requested
6846                !this.renderingPauseDepth && // not paused
6847                !this.isRendering // not currently in the render loop
6848            ) {
6849                this.executeRender();
6850            }
6851        };
6852        Calendar.prototype.batchRendering = function (func) {
6853            this.renderingPauseDepth++;
6854            func();
6855            this.renderingPauseDepth--;
6856            if (this.needsRerender) {
6857                this.requestRerender();
6858            }
6859        };
6860        // Rendering
6861        // -----------------------------------------------------------------------------------------------------------------
6862        Calendar.prototype.executeRender = function () {
6863            var needsFullRerender = this.needsFullRerender; // save before clearing
6864            // clear these BEFORE the render so that new values will accumulate during render
6865            this.needsRerender = false;
6866            this.needsFullRerender = false;
6867            this.isRendering = true;
6868            this.renderComponent(needsFullRerender);
6869            this.isRendering = false;
6870            // received a rerender request while rendering
6871            if (this.needsRerender) {
6872                this.delayedRerender();
6873            }
6874        };
6875        /*
6876        don't call this directly. use executeRender instead
6877        */
6878        Calendar.prototype.renderComponent = function (needsFull) {
6879            var _a = this, state = _a.state, component = _a.component;
6880            var viewType = state.viewType;
6881            var viewSpec = this.viewSpecs[viewType];
6882            var savedScroll = (needsFull && component) ? component.view.queryScroll() : null;
6883            if (!viewSpec) {
6884                throw new Error("View type \"" + viewType + "\" is not valid");
6885            }
6886            // if event sources are still loading and progressive rendering hasn't been enabled,
6887            // keep rendering the last fully loaded set of events
6888            var renderableEventStore = this.renderableEventStore =
6889                (state.eventSourceLoadingLevel && !this.opt('progressiveEventRendering')) ?
6890                    this.renderableEventStore :
6891                    state.eventStore;
6892            var eventUiSingleBase = this.buildEventUiSingleBase(viewSpec.options);
6893            var eventUiBySource = this.buildEventUiBySource(state.eventSources);
6894            var eventUiBases = this.eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
6895            if (needsFull || !component) {
6896                if (component) {
6897                    component.freezeHeight(); // next component will unfreeze it
6898                    component.destroy();
6899                }
6900                component = this.component = new CalendarComponent({
6901                    calendar: this,
6902                    view: null,
6903                    dateEnv: this.dateEnv,
6904                    theme: this.theme,
6905                    options: this.optionsManager.computed
6906                }, this.el);
6907                this.isViewUpdated = true;
6908                this.isDatesUpdated = true;
6909                this.isEventsUpdated = true;
6910            }
6911            component.receiveProps(__assign({}, state, { viewSpec: viewSpec, dateProfile: state.dateProfile, dateProfileGenerator: this.dateProfileGenerators[viewType], eventStore: renderableEventStore, eventUiBases: eventUiBases, dateSelection: state.dateSelection, eventSelection: state.eventSelection, eventDrag: state.eventDrag, eventResize: state.eventResize }));
6912            if (savedScroll) {
6913                component.view.applyScroll(savedScroll, false);
6914            }
6915            if (this.isViewUpdated) {
6916                this.isViewUpdated = false;
6917                this.publiclyTrigger('viewSkeletonRender', [
6918                    {
6919                        view: component.view,
6920                        el: component.view.el
6921                    }
6922                ]);
6923            }
6924            if (this.isDatesUpdated) {
6925                this.isDatesUpdated = false;
6926                this.publiclyTrigger('datesRender', [
6927                    {
6928                        view: component.view,
6929                        el: component.view.el
6930                    }
6931                ]);
6932            }
6933            if (this.isEventsUpdated) {
6934                this.isEventsUpdated = false;
6935            }
6936            this.releaseAfterSizingTriggers();
6937        };
6938        // Options
6939        // -----------------------------------------------------------------------------------------------------------------
6940        Calendar.prototype.setOption = function (name, val) {
6941            var _a;
6942            this.mutateOptions((_a = {}, _a[name] = val, _a), [], true);
6943        };
6944        Calendar.prototype.getOption = function (name) {
6945            return this.optionsManager.computed[name];
6946        };
6947        Calendar.prototype.opt = function (name) {
6948            return this.optionsManager.computed[name];
6949        };
6950        Calendar.prototype.viewOpt = function (name) {
6951            return this.viewOpts()[name];
6952        };
6953        Calendar.prototype.viewOpts = function () {
6954            return this.viewSpecs[this.state.viewType].options;
6955        };
6956        /*
6957        handles option changes (like a diff)
6958        */
6959        Calendar.prototype.mutateOptions = function (updates, removals, isDynamic, deepEqual) {
6960            var _this = this;
6961            var changeHandlers = this.pluginSystem.hooks.optionChangeHandlers;
6962            var normalUpdates = {};
6963            var specialUpdates = {};
6964            var oldDateEnv = this.dateEnv; // do this before handleOptions
6965            var isTimeZoneDirty = false;
6966            var isSizeDirty = false;
6967            var anyDifficultOptions = Boolean(removals.length);
6968            for (var name_1 in updates) {
6969                if (changeHandlers[name_1]) {
6970                    specialUpdates[name_1] = updates[name_1];
6971                }
6972                else {
6973                    normalUpdates[name_1] = updates[name_1];
6974                }
6975            }
6976            for (var name_2 in normalUpdates) {
6977                if (/^(height|contentHeight|aspectRatio)$/.test(name_2)) {
6978                    isSizeDirty = true;
6979                }
6980                else if (/^(defaultDate|defaultView)$/.test(name_2)) ;
6981                else {
6982                    anyDifficultOptions = true;
6983                    if (name_2 === 'timeZone') {
6984                        isTimeZoneDirty = true;
6985                    }
6986                }
6987            }
6988            this.optionsManager.mutate(normalUpdates, removals, isDynamic);
6989            if (anyDifficultOptions) {
6990                this.handleOptions(this.optionsManager.computed);
6991                this.needsFullRerender = true;
6992            }
6993            this.batchRendering(function () {
6994                if (anyDifficultOptions) {
6995                    if (isTimeZoneDirty) {
6996                        _this.dispatch({
6997                            type: 'CHANGE_TIMEZONE',
6998                            oldDateEnv: oldDateEnv
6999                        });
7000                    }
7001                    /* HACK
7002                    has the same effect as calling this.requestRerender(true)
7003                    but recomputes the state's dateProfile
7004                    */
7005                    _this.dispatch({
7006                        type: 'SET_VIEW_TYPE',
7007                        viewType: _this.state.viewType
7008                    });
7009                }
7010                else if (isSizeDirty) {
7011                    _this.updateSize();
7012                }
7013                // special updates
7014                if (deepEqual) {
7015                    for (var name_3 in specialUpdates) {
7016                        changeHandlers[name_3](specialUpdates[name_3], _this, deepEqual);
7017                    }
7018                }
7019            });
7020        };
7021        /*
7022        rebuilds things based off of a complete set of refined options
7023        */
7024        Calendar.prototype.handleOptions = function (options) {
7025            var _this = this;
7026            var pluginHooks = this.pluginSystem.hooks;
7027            this.defaultAllDayEventDuration = createDuration(options.defaultAllDayEventDuration);
7028            this.defaultTimedEventDuration = createDuration(options.defaultTimedEventDuration);
7029            this.delayedRerender = this.buildDelayedRerender(options.rerenderDelay);
7030            this.theme = this.buildTheme(options);
7031            var available = this.parseRawLocales(options.locales);
7032            this.availableRawLocales = available.map;
7033            var locale = this.buildLocale(options.locale || available.defaultCode, available.map);
7034            this.dateEnv = this.buildDateEnv(locale, options.timeZone, pluginHooks.namedTimeZonedImpl, options.firstDay, options.weekNumberCalculation, options.weekLabel, pluginHooks.cmdFormatter);
7035            this.selectionConfig = this.buildSelectionConfig(options); // needs dateEnv. do after :(
7036            // ineffecient to do every time?
7037            this.viewSpecs = buildViewSpecs(pluginHooks.views, this.optionsManager);
7038            // ineffecient to do every time?
7039            this.dateProfileGenerators = mapHash(this.viewSpecs, function (viewSpec) {
7040                return new viewSpec.class.prototype.dateProfileGeneratorClass(viewSpec, _this);
7041            });
7042        };
7043        Calendar.prototype.getAvailableLocaleCodes = function () {
7044            return Object.keys(this.availableRawLocales);
7045        };
7046        Calendar.prototype._buildSelectionConfig = function (rawOpts) {
7047            return processScopedUiProps('select', rawOpts, this);
7048        };
7049        Calendar.prototype._buildEventUiSingleBase = function (rawOpts) {
7050            if (rawOpts.editable) { // so 'editable' affected events
7051                rawOpts = __assign({}, rawOpts, { eventEditable: true });
7052            }
7053            return processScopedUiProps('event', rawOpts, this);
7054        };
7055        // Trigger
7056        // -----------------------------------------------------------------------------------------------------------------
7057        Calendar.prototype.hasPublicHandlers = function (name) {
7058            return this.hasHandlers(name) ||
7059                this.opt(name); // handler specified in options
7060        };
7061        Calendar.prototype.publiclyTrigger = function (name, args) {
7062            var optHandler = this.opt(name);
7063            this.triggerWith(name, this, args);
7064            if (optHandler) {
7065                return optHandler.apply(this, args);
7066            }
7067        };
7068        Calendar.prototype.publiclyTriggerAfterSizing = function (name, args) {
7069            var afterSizingTriggers = this.afterSizingTriggers;
7070            (afterSizingTriggers[name] || (afterSizingTriggers[name] = [])).push(args);
7071        };
7072        Calendar.prototype.releaseAfterSizingTriggers = function () {
7073            var afterSizingTriggers = this.afterSizingTriggers;
7074            for (var name_4 in afterSizingTriggers) {
7075                for (var _i = 0, _a = afterSizingTriggers[name_4]; _i < _a.length; _i++) {
7076                    var args = _a[_i];
7077                    this.publiclyTrigger(name_4, args);
7078                }
7079            }
7080            this.afterSizingTriggers = {};
7081        };
7082        // View
7083        // -----------------------------------------------------------------------------------------------------------------
7084        // Returns a boolean about whether the view is okay to instantiate at some point
7085        Calendar.prototype.isValidViewType = function (viewType) {
7086            return Boolean(this.viewSpecs[viewType]);
7087        };
7088        Calendar.prototype.changeView = function (viewType, dateOrRange) {
7089            var dateMarker = null;
7090            if (dateOrRange) {
7091                if (dateOrRange.start && dateOrRange.end) { // a range
7092                    this.optionsManager.mutate({ visibleRange: dateOrRange }, []); // will not rerender
7093                    this.handleOptions(this.optionsManager.computed); // ...but yuck
7094                }
7095                else { // a date
7096                    dateMarker = this.dateEnv.createMarker(dateOrRange); // just like gotoDate
7097                }
7098            }
7099            this.unselect();
7100            this.dispatch({
7101                type: 'SET_VIEW_TYPE',
7102                viewType: viewType,
7103                dateMarker: dateMarker
7104            });
7105        };
7106        // Forces navigation to a view for the given date.
7107        // `viewType` can be a specific view name or a generic one like "week" or "day".
7108        // needs to change
7109        Calendar.prototype.zoomTo = function (dateMarker, viewType) {
7110            var spec;
7111            viewType = viewType || 'day'; // day is default zoom
7112            spec = this.viewSpecs[viewType] ||
7113                this.getUnitViewSpec(viewType);
7114            this.unselect();
7115            if (spec) {
7116                this.dispatch({
7117                    type: 'SET_VIEW_TYPE',
7118                    viewType: spec.type,
7119                    dateMarker: dateMarker
7120                });
7121            }
7122            else {
7123                this.dispatch({
7124                    type: 'SET_DATE',
7125                    dateMarker: dateMarker
7126                });
7127            }
7128        };
7129        // Given a duration singular unit, like "week" or "day", finds a matching view spec.
7130        // Preference is given to views that have corresponding buttons.
7131        Calendar.prototype.getUnitViewSpec = function (unit) {
7132            var component = this.component;
7133            var viewTypes = [];
7134            var i;
7135            var spec;
7136            // put views that have buttons first. there will be duplicates, but oh
7137            if (component.header) {
7138                viewTypes.push.apply(viewTypes, component.header.viewsWithButtons);
7139            }
7140            if (component.footer) {
7141                viewTypes.push.apply(viewTypes, component.footer.viewsWithButtons);
7142            }
7143            for (var viewType in this.viewSpecs) {
7144                viewTypes.push(viewType);
7145            }
7146            for (i = 0; i < viewTypes.length; i++) {
7147                spec = this.viewSpecs[viewTypes[i]];
7148                if (spec) {
7149                    if (spec.singleUnit === unit) {
7150                        return spec;
7151                    }
7152                }
7153            }
7154        };
7155        // Current Date
7156        // -----------------------------------------------------------------------------------------------------------------
7157        Calendar.prototype.getInitialDate = function () {
7158            var defaultDateInput = this.opt('defaultDate');
7159            // compute the initial ambig-timezone date
7160            if (defaultDateInput != null) {
7161                return this.dateEnv.createMarker(defaultDateInput);
7162            }
7163            else {
7164                return this.getNow(); // getNow already returns unzoned
7165            }
7166        };
7167        Calendar.prototype.prev = function () {
7168            this.unselect();
7169            this.dispatch({ type: 'PREV' });
7170        };
7171        Calendar.prototype.next = function () {
7172            this.unselect();
7173            this.dispatch({ type: 'NEXT' });
7174        };
7175        Calendar.prototype.prevYear = function () {
7176            this.unselect();
7177            this.dispatch({
7178                type: 'SET_DATE',
7179                dateMarker: this.dateEnv.addYears(this.state.currentDate, -1)
7180            });
7181        };
7182        Calendar.prototype.nextYear = function () {
7183            this.unselect();
7184            this.dispatch({
7185                type: 'SET_DATE',
7186                dateMarker: this.dateEnv.addYears(this.state.currentDate, 1)
7187            });
7188        };
7189        Calendar.prototype.today = function () {
7190            this.unselect();
7191            this.dispatch({
7192                type: 'SET_DATE',
7193                dateMarker: this.getNow()
7194            });
7195        };
7196        Calendar.prototype.gotoDate = function (zonedDateInput) {
7197            this.unselect();
7198            this.dispatch({
7199                type: 'SET_DATE',
7200                dateMarker: this.dateEnv.createMarker(zonedDateInput)
7201            });
7202        };
7203        Calendar.prototype.incrementDate = function (deltaInput) {
7204            var delta = createDuration(deltaInput);
7205            if (delta) { // else, warn about invalid input?
7206                this.unselect();
7207                this.dispatch({
7208                    type: 'SET_DATE',
7209                    dateMarker: this.dateEnv.add(this.state.currentDate, delta)
7210                });
7211            }
7212        };
7213        // for external API
7214        Calendar.prototype.getDate = function () {
7215            return this.dateEnv.toDate(this.state.currentDate);
7216        };
7217        // Date Formatting Utils
7218        // -----------------------------------------------------------------------------------------------------------------
7219        Calendar.prototype.formatDate = function (d, formatter) {
7220            var dateEnv = this.dateEnv;
7221            return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
7222        };
7223        // `settings` is for formatter AND isEndExclusive
7224        Calendar.prototype.formatRange = function (d0, d1, settings) {
7225            var dateEnv = this.dateEnv;
7226            return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings, this.opt('defaultRangeSeparator')), settings);
7227        };
7228        Calendar.prototype.formatIso = function (d, omitTime) {
7229            var dateEnv = this.dateEnv;
7230            return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime });
7231        };
7232        // Sizing
7233        // -----------------------------------------------------------------------------------------------------------------
7234        Calendar.prototype.windowResize = function (ev) {
7235            if (!this.isHandlingWindowResize &&
7236                this.component && // why?
7237                ev.target === window // not a jqui resize event
7238            ) {
7239                this.isHandlingWindowResize = true;
7240                this.updateSize();
7241                this.publiclyTrigger('windowResize', [this.view]);
7242                this.isHandlingWindowResize = false;
7243            }
7244        };
7245        Calendar.prototype.updateSize = function () {
7246            if (this.component) { // when?
7247                this.component.updateSize(true);
7248            }
7249        };
7250        // Component Registration
7251        // -----------------------------------------------------------------------------------------------------------------
7252        Calendar.prototype.registerInteractiveComponent = function (component, settingsInput) {
7253            var settings = parseInteractionSettings(component, settingsInput);
7254            var DEFAULT_INTERACTIONS = [
7255                EventClicking,
7256                EventHovering
7257            ];
7258            var interactionClasses = DEFAULT_INTERACTIONS.concat(this.pluginSystem.hooks.componentInteractions);
7259            var interactions = interactionClasses.map(function (interactionClass) {
7260                return new interactionClass(settings);
7261            });
7262            this.interactionsStore[component.uid] = interactions;
7263            interactionSettingsStore[component.uid] = settings;
7264        };
7265        Calendar.prototype.unregisterInteractiveComponent = function (component) {
7266            for (var _i = 0, _a = this.interactionsStore[component.uid]; _i < _a.length; _i++) {
7267                var listener = _a[_i];
7268                listener.destroy();
7269            }
7270            delete this.interactionsStore[component.uid];
7271            delete interactionSettingsStore[component.uid];
7272        };
7273        // Date Selection / Event Selection / DayClick
7274        // -----------------------------------------------------------------------------------------------------------------
7275        // this public method receives start/end dates in any format, with any timezone
7276        // NOTE: args were changed from v3
7277        Calendar.prototype.select = function (dateOrObj, endDate) {
7278            var selectionInput;
7279            if (endDate == null) {
7280                if (dateOrObj.start != null) {
7281                    selectionInput = dateOrObj;
7282                }
7283                else {
7284                    selectionInput = {
7285                        start: dateOrObj,
7286                        end: null
7287                    };
7288                }
7289            }
7290            else {
7291                selectionInput = {
7292                    start: dateOrObj,
7293                    end: endDate
7294                };
7295            }
7296            var selection = parseDateSpan(selectionInput, this.dateEnv, createDuration({ days: 1 }) // TODO: cache this?
7297            );
7298            if (selection) { // throw parse error otherwise?
7299                this.dispatch({ type: 'SELECT_DATES', selection: selection });
7300                this.triggerDateSelect(selection);
7301            }
7302        };
7303        // public method
7304        Calendar.prototype.unselect = function (pev) {
7305            if (this.state.dateSelection) {
7306                this.dispatch({ type: 'UNSELECT_DATES' });
7307                this.triggerDateUnselect(pev);
7308            }
7309        };
7310        Calendar.prototype.triggerDateSelect = function (selection, pev) {
7311            var arg = __assign({}, this.buildDateSpanApi(selection), { jsEvent: pev ? pev.origEvent : null, view: this.view });
7312            this.publiclyTrigger('select', [arg]);
7313        };
7314        Calendar.prototype.triggerDateUnselect = function (pev) {
7315            this.publiclyTrigger('unselect', [
7316                {
7317                    jsEvent: pev ? pev.origEvent : null,
7318                    view: this.view
7319                }
7320            ]);
7321        };
7322        // TODO: receive pev?
7323        Calendar.prototype.triggerDateClick = function (dateSpan, dayEl, view, ev) {
7324            var arg = __assign({}, this.buildDatePointApi(dateSpan), { dayEl: dayEl, jsEvent: ev, // Is this always a mouse event? See #4655
7325                view: view });
7326            this.publiclyTrigger('dateClick', [arg]);
7327        };
7328        Calendar.prototype.buildDatePointApi = function (dateSpan) {
7329            var props = {};
7330            for (var _i = 0, _a = this.pluginSystem.hooks.datePointTransforms; _i < _a.length; _i++) {
7331                var transform = _a[_i];
7332                __assign(props, transform(dateSpan, this));
7333            }
7334            __assign(props, buildDatePointApi(dateSpan, this.dateEnv));
7335            return props;
7336        };
7337        Calendar.prototype.buildDateSpanApi = function (dateSpan) {
7338            var props = {};
7339            for (var _i = 0, _a = this.pluginSystem.hooks.dateSpanTransforms; _i < _a.length; _i++) {
7340                var transform = _a[_i];
7341                __assign(props, transform(dateSpan, this));
7342            }
7343            __assign(props, buildDateSpanApi(dateSpan, this.dateEnv));
7344            return props;
7345        };
7346        // Date Utils
7347        // -----------------------------------------------------------------------------------------------------------------
7348        // Returns a DateMarker for the current date, as defined by the client's computer or from the `now` option
7349        Calendar.prototype.getNow = function () {
7350            var now = this.opt('now');
7351            if (typeof now === 'function') {
7352                now = now();
7353            }
7354            if (now == null) {
7355                return this.dateEnv.createNowMarker();
7356            }
7357            return this.dateEnv.createMarker(now);
7358        };
7359        // Event-Date Utilities
7360        // -----------------------------------------------------------------------------------------------------------------
7361        // Given an event's allDay status and start date, return what its fallback end date should be.
7362        // TODO: rename to computeDefaultEventEnd
7363        Calendar.prototype.getDefaultEventEnd = function (allDay, marker) {
7364            var end = marker;
7365            if (allDay) {
7366                end = startOfDay(end);
7367                end = this.dateEnv.add(end, this.defaultAllDayEventDuration);
7368            }
7369            else {
7370                end = this.dateEnv.add(end, this.defaultTimedEventDuration);
7371            }
7372            return end;
7373        };
7374        // Public Events API
7375        // -----------------------------------------------------------------------------------------------------------------
7376        Calendar.prototype.addEvent = function (eventInput, sourceIn
7376put) {
7377            if (eventInput instanceof EventApi) {
7378                var def = eventInput._def;
7379                var instance = eventInput._instance;
7380                // not already present? don't want to add an old snapshot
7381                if (!this.state.eventStore.defs[def.defId]) {
7382                    this.dispatch({
7383                        type: 'ADD_EVENTS',
7384                        eventStore: eventTupleToStore({ def: def, instance: instance }) // TODO: better util for two args?
7385                    });
7386                }
7387                return eventInput;
7388            }
7389            var sourceId;
7390            if (sourceInput instanceof EventSourceApi) {
7391                sourceId = sourceInput.internalEventSource.sourceId;
7392            }
7393            else if (sourceInput != null) {
7394                var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
7395                if (!sourceApi) {
7396                    console.warn('Could not find an event source with ID "' + sourceInput + '"'); // TODO: test
7397                    return null;
7398                }
7399                else {
7400                    sourceId = sourceApi.internalEventSource.sourceId;
7401                }
7402            }
7403            var tuple = parseEvent(eventInput, sourceId, this);
7404            if (tuple) {
7405                this.dispatch({
7406                    type: 'ADD_EVENTS',
7407                    eventStore: eventTupleToStore(tuple)
7408                });
7409                return new EventApi(this, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
7410            }
7411            return null;
7412        };
7413        // TODO: optimize
7414        Calendar.prototype.getEventById = function (id) {
7415            var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
7416            id = String(id);
7417            for (var defId in defs) {
7418                var def = defs[defId];
7419                if (def.publicId === id) {
7420                    if (def.recurringDef) {
7421                        return new EventApi(this, def, null);
7422                    }
7423                    else {
7424                        for (var instanceId in instances) {
7425                            var instance = instances[instanceId];
7426                            if (instance.defId === def.defId) {
7427                                return new EventApi(this, def, instance);
7428                            }
7429                        }
7430                    }
7431                }
7432            }
7433            return null;
7434        };
7435        Calendar.prototype.getEvents = function () {
7436            var _a = this.state.eventStore, defs = _a.defs, instances = _a.instances;
7437            var eventApis = [];
7438            for (var id in instances) {
7439                var instance = instances[id];
7440                var def = defs[instance.defId];
7441                eventApis.push(new EventApi(this, def, instance));
7442            }
7443            return eventApis;
7444        };
7445        Calendar.prototype.removeAllEvents = function () {
7446            this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
7447        };
7448        Calendar.prototype.rerenderEvents = function () {
7449            this.dispatch({ type: 'RESET_EVENTS' });
7450        };
7451        // Public Event Sources API
7452        // -----------------------------------------------------------------------------------------------------------------
7453        Calendar.prototype.getEventSources = function () {
7454            var sourceHash = this.state.eventSources;
7455            var sourceApis = [];
7456            for (var internalId in sourceHash) {
7457                sourceApis.push(new EventSourceApi(this, sourceHash[internalId]));
7458            }
7459            return sourceApis;
7460        };
7461        Calendar.prototype.getEventSourceById = function (id) {
7462            var sourceHash = this.state.eventSources;
7463            id = String(id);
7464            for (var sourceId in sourceHash) {
7465                if (sourceHash[sourceId].publicId === id) {
7466                    return new EventSourceApi(this, sourceHash[sourceId]);
7467                }
7468            }
7469            return null;
7470        };
7471        Calendar.prototype.addEventSource = function (sourceInput) {
7472            if (sourceInput instanceof EventSourceApi) {
7473                // not already present? don't want to add an old snapshot
7474                if (!this.state.eventSources[sourceInput.internalEventSource.sourceId]) {
7475                    this.dispatch({
7476                        type: 'ADD_EVENT_SOURCES',
7477                        sources: [sourceInput.internalEventSource]
7478                    });
7479                }
7480                return sourceInput;
7481            }
7482            var eventSource = parseEventSource(sourceInput, this);
7483            if (eventSource) { // TODO: error otherwise?
7484                this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
7485                return new EventSourceApi(this, eventSource);
7486            }
7487            return null;
7488        };
7489        Calendar.prototype.removeAllEventSources = function () {
7490            this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
7491        };
7492        Calendar.prototype.refetchEvents = function () {
7493            this.dispatch({ type: 'FETCH_EVENT_SOURCES' });
7494        };
7495        // Scroll
7496        // -----------------------------------------------------------------------------------------------------------------
7497        Calendar.prototype.scrollToTime = function (timeInput) {
7498            var duration = createDuration(timeInput);
7499            if (duration) {
7500                this.component.view.scrollToDuration(duration);
7501            }
7502        };
7503        return Calendar;
7504    }());
7505    EmitterMixin.mixInto(Calendar);
7506    // for memoizers
7507    // -----------------------------------------------------------------------------------------------------------------
7508    function buildDateEnv(locale, timeZone, namedTimeZoneImpl, firstDay, weekNumberCalculation, weekLabel, cmdFormatter) {
7509        return new DateEnv({
7510            calendarSystem: 'gregory',
7511            timeZone: timeZone,
7512            namedTimeZoneImpl: namedTimeZoneImpl,
7513            locale: locale,
7514            weekNumberCalculation: weekNumberCalculation,
7515            firstDay: firstDay,
7516            weekLabel: weekLabel,
7517            cmdFormatter: cmdFormatter
7518        });
7519    }
7520    function buildTheme(calendarOptions) {
7521        var themeClass = this.pluginSystem.hooks.themeClasses[calendarOptions.themeSystem] || StandardTheme;
7522        return new themeClass(calendarOptions);
7523    }
7524    function buildDelayedRerender(wait) {
7525        var func = this.tryRerender.bind(this);
7526        if (wait != null) {
7527            func = debounce(func, wait);
7528        }
7529        return func;
7530    }
7531    function buildEventUiBySource(eventSources) {
7532        return mapHash(eventSources, function (eventSource) {
7533            return eventSource.ui;
7534        });
7535    }
7536    function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
7537        var eventUiBases = { '': eventUiSingleBase };
7538        for (var defId in eventDefs) {
7539            var def = eventDefs[defId];
7540            if (def.sourceId && eventUiBySource[def.sourceId]) {
7541                eventUiBases[defId] = eventUiBySource[def.sourceId];
7542            }
7543        }
7544        return eventUiBases;
7545    }
7546
7547    var View = /** @class */ (function (_super) {
7548        __extends(View, _super);
7549        function View(context, viewSpec, dateProfileGenerator, parentEl) {
7550            var _this = _super.call(this, context, createElement('div', { className: 'fc-view fc-' + viewSpec.type + '-view' }), true // isView (HACK)
7551            ) || this;
7552            _this.renderDatesMem = memoizeRendering(_this.renderDatesWrap, _this.unrenderDatesWrap);
7553            _this.renderBusinessHoursMem = memoizeRendering(_this.renderBusinessHours, _this.unrenderBusinessHours, [_this.renderDatesMem]);
7554            _this.renderDateSelectionMem = memoizeRendering(_this.renderDateSelectionWrap, _this.unrenderDateSelectionWrap, [_this.renderDatesMem]);
7555            _this.renderEventsMem = memoizeRendering(_this.renderEvents, _this.unrenderEvents, [_this.renderDatesMem]);
7556            _this.renderEventSelectionMem = memoizeRendering(_this.renderEventSelectionWrap, _this.unrenderEventSelectionWrap, [_this.renderEventsMem]);
7557            _this.renderEventDragMem = memoizeRendering(_this.renderEventDragWrap, _this.unrenderEventDragWrap, [_this.renderDatesMem]);
7558            _this.renderEventResizeMem = memoizeRendering(_this.renderEventResizeWrap, _this.unrenderEventResizeWrap, [_this.renderDatesMem]);
7559            _this.viewSpec = viewSpec;
7560            _this.dateProfileGenerator = dateProfileGenerator;
7561            _this.type = viewSpec.type;
7562            _this.eventOrderSpecs = parseFieldSpecs(_this.opt('eventOrder'));
7563            _this.nextDayThreshold = createDuration(_this.opt('nextDayThreshold'));
7564            parentEl.appendChild(_this.el);
7565            _this.initialize();
7566            return _this;
7567        }
7568        View.prototype.initialize = function () {
7569        };
7570        Object.defineProperty(View.prototype, "activeStart", {
7571            // Date Setting/Unsetting
7572            // -----------------------------------------------------------------------------------------------------------------
7573            get: function () {
7574                return this.dateEnv.toDate(this.props.dateProfile.activeRange.start);
7575            },
7576            enumerable: true,
7577            configurable: true
7578        });
7579        Object.defineProperty(View.prototype, "activeEnd", {
7580            get: function () {
7581                return this.dateEnv.toDate(this.props.dateProfile.activeRange.end);
7582            },
7583            enumerable: true,
7584            configurable: true
7585        });
7586        Object.defineProperty(View.prototype, "currentStart", {
7587            get: function () {
7588                return this.dateEnv.toDate(this.props.dateProfile.currentRange.start);
7589            },
7590            enumerable: true,
7591            configurable: true
7592        });
7593        Object.defineProperty(View.prototype, "currentEnd", {
7594            get: function () {
7595                return this.dateEnv.toDate(this.props.dateProfile.currentRange.end);
7596            },
7597            enumerable: true,
7598            configurable: true
7599        });
7600        // General Rendering
7601        // -----------------------------------------------------------------------------------------------------------------
7602        View.prototype.render = function (props) {
7603            this.renderDatesMem(props.dateProfile);
7604            this.renderBusinessHoursMem(props.businessHours);
7605            this.renderDateSelectionMem(props.dateSelection);
7606            this.renderEventsMem(props.eventStore);
7607            this.renderEventSelectionMem(props.eventSelection);
7608            this.renderEventDragMem(props.eventDrag);
7609            this.renderEventResizeMem(props.eventResize);
7610        };
7611        View.prototype.destroy = function () {
7612            _super.prototype.destroy.call(this);
7613            this.renderDatesMem.unrender(); // should unrender everything else
7614        };
7615        // Sizing
7616        // -----------------------------------------------------------------------------------------------------------------
7617        View.prototype.updateSize = function (isResize, viewHeight, isAuto) {
7618            var calendar = this.calendar;
7619            if (isResize || // HACKS...
7620                calendar.isViewUpdated ||
7621                calendar.isDatesUpdated ||
7622                calendar.isEventsUpdated) {
7623                // sort of the catch-all sizing
7624                // anything that might cause dimension changes
7625                this.updateBaseSize(isResize, viewHeight, isAuto);
7626            }
7627        };
7628        View.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
7629        };
7630        // Date Rendering
7631        // -----------------------------------------------------------------------------------------------------------------
7632        View.prototype.renderDatesWrap = function (dateProfile) {
7633            this.renderDates(dateProfile);
7634            this.addScroll({
7635                duration: createDuration(this.opt('scrollTime'))
7636            });
7637            this.startNowIndicator(dateProfile); // shouldn't render yet because updateSize will be called soon
7638        };
7639        View.prototype.unrenderDatesWrap = function () {
7640            this.stopNowIndicator();
7641            this.unrenderDates();
7642        };
7643        View.prototype.renderDates = function (dateProfile) { };
7644        View.prototype.unrenderDates = function () { };
7645        // Business Hours
7646        // -----------------------------------------------------------------------------------------------------------------
7647        View.prototype.renderBusinessHours = function (businessHours) { };
7648        View.prototype.unrenderBusinessHours = function () { };
7649        // Date Selection
7650        // -----------------------------------------------------------------------------------------------------------------
7651        View.prototype.renderDateSelectionWrap = function (selection) {
7652            if (selection) {
7653                this.renderDateSelection(selection);
7654            }
7655        };
7656        View.prototype.unrenderDateSelectionWrap = function (selection) {
7657            if (selection) {
7658                this.unrenderDateSelection(selection);
7659            }
7660        };
7661        View.prototype.renderDateSelection = function (selection) { };
7662        View.prototype.unrenderDateSelection = function (selection) { };
7663        // Event Rendering
7664        // -----------------------------------------------------------------------------------------------------------------
7665        View.prototype.renderEvents = function (eventStore) { };
7666        View.prototype.unrenderEvents = function () { };
7667        // util for subclasses
7668        View.prototype.sliceEvents = function (eventStore, allDay) {
7669            var props = this.props;
7670            return sliceEventStore(eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? this.nextDayThreshold : null).fg;
7671        };
7672        View.prototype.computeEventDraggable = function (eventDef, eventUi) {
7673            var transformers = this.calendar.pluginSystem.hooks.isDraggableTransformers;
7674            var val = eventUi.startEditable;
7675            for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) {
7676                var transformer = transformers_1[_i];
7677                val = transformer(val, eventDef, eventUi, this);
7678            }
7679            return val;
7680        };
7681        View.prototype.computeEventStartResizable = function (eventDef, eventUi) {
7682            return eventUi.durationEditable && this.opt('eventResizableFromStart');
7683        };
7684        View.prototype.computeEventEndResizable = function (eventDef, eventUi) {
7685            return eventUi.durationEditable;
7686        };
7687        // Event Selection
7688        // -----------------------------------------------------------------------------------------------------------------
7689        View.prototype.renderEventSelectionWrap = function (instanceId) {
7690            if (instanceId) {
7691                this.renderEventSelection(instanceId);
7692            }
7693        };
7694        View.prototype.unrenderEventSelectionWrap = function (instanceId) {
7695            if (instanceId) {
7696                this.unrenderEventSelection(instanceId);
7697            }
7698        };
7699        View.prototype.renderEventSelection = function (instanceId) { };
7700        View.prototype.unrenderEventSelection = function (instanceId) { };
7701        // Event Drag
7702        // -----------------------------------------------------------------------------------------------------------------
7703        View.prototype.renderEventDragWrap = function (state) {
7704            if (state) {
7705                this.renderEventDrag(state);
7706            }
7707        };
7708        View.prototype.unrenderEventDragWrap = function (state) {
7709            if (state) {
7710                this.unrenderEventDrag(state);
7711            }
7712        };
7713        View.prototype.renderEventDrag = function (state) { };
7714        View.prototype.unrenderEventDrag = function (state) { };
7715        // Event Resize
7716        // -----------------------------------------------------------------------------------------------------------------
7717        View.prototype.renderEventResizeWrap = function (state) {
7718            if (state) {
7719                this.renderEventResize(state);
7720            }
7721        };
7722        View.prototype.unrenderEventResizeWrap = function (state) {
7723            if (state) {
7724                this.unrenderEventResize(state);
7725            }
7726        };
7727        View.prototype.renderEventResize = function (state) { };
7728        View.prototype.unrenderEventResize = function (state) { };
7729        /* Now Indicator
7730        ------------------------------------------------------------------------------------------------------------------*/
7731        // Immediately render the current time indicator and begins re-rendering it at an interval,
7732        // which is defined by this.getNowIndicatorUnit().
7733        // TODO: somehow do this for the current whole day's background too
7734        View.prototype.startNowIndicator = function (dateProfile) {
7735            var _this = this;
7736            var dateEnv = this.dateEnv;
7737            var unit;
7738            var update;
7739            var delay; // ms wait value
7740            if (this.opt('nowIndicator')) {
7741                unit = this.getNowIndicatorUnit(dateProfile);
7742                if (unit) {
7743                    update = this.updateNowIndicator.bind(this);
7744                    this.initialNowDate = this.calendar.getNow();
7745                    this.initialNowQueriedMs = new Date().valueOf();
7746                    // wait until the beginning of the next interval
7747                    delay = dateEnv.add(dateEnv.startOf(this.initialNowDate, unit), createDuration(1, unit)).valueOf() - this.initialNowDate.valueOf();
7748                    // TODO: maybe always use setTimeout, waiting until start of next unit
7749                    this.nowIndicatorTimeoutID = setTimeout(function () {
7750                        _this.nowIndicatorTimeoutID = null;
7751                        update();
7752                        if (unit === 'second') {
7753                            delay = 1000; // every second
7754                        }
7755                        else {
7756                            delay = 1000 * 60; // otherwise, every minute
7757                        }
7758                        _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval
7759                    }, delay);
7760                }
7761                // rendering will be initiated in updateSize
7762            }
7763        };
7764        // rerenders the now indicator, computing the new current time from the amount of time that has passed
7765        // since the initial getNow call.
7766        View.prototype.updateNowIndicator = function () {
7767            if (this.props.dateProfile && // a way to determine if dates were rendered yet
7768                this.initialNowDate // activated before?
7769            ) {
7770                this.unrenderNowIndicator(); // won't unrender if unnecessary
7771                this.renderNowIndicator(addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs));
7772                this.isNowIndicatorRendered = true;
7773            }
7774        };
7775        // Immediately unrenders the view's current time indicator and stops any re-rendering timers.
7776        // Won't cause side effects if indicator isn't rendered.
7777        View.prototype.stopNowIndicator = function () {
7778            if (this.isNowIndicatorRendered) {
7779                if (this.nowIndicatorTimeoutID) {
7780                    clearTimeout(this.nowIndicatorTimeoutID);
7781                    this.nowIndicatorTimeoutID = null;
7782                }
7783                if (this.nowIndicatorIntervalID) {
7784                    clearInterval(this.nowIndicatorIntervalID);
7785                    this.nowIndicatorIntervalID = null;
7786                }
7787                this.unrenderNowIndicator();
7788                this.isNowIndicatorRendered = false;
7789            }
7790        };
7791        View.prototype.getNowIndicatorUnit = function (dateProfile) {
7792            // subclasses should implement
7793        };
7794        // Renders a current time indicator at the given datetime
7795        View.prototype.renderNowIndicator = function (date) {
7796            // SUBCLASSES MUST PASS TO CHILDREN!
7797        };
7798        // Undoes the rendering actions from renderNowIndicator
7799        View.prototype.unrenderNowIndicator = function () {
7800            // SUBCLASSES MUST PASS TO CHILDREN!
7801        };
7802        /* Scroller
7803        ------------------------------------------------------------------------------------------------------------------*/
7804        View.prototype.addScroll = function (scroll) {
7805            var queuedScroll = this.queuedScroll || (this.queuedScroll = {});
7806            __assign(queuedScroll, scroll);
7807        };
7808        View.prototype.popScroll = function (isResize) {
7809            this.applyQueuedScroll(isResize);
7810            this.queuedScroll = null;
7811        };
7812        View.prototype.applyQueuedScroll = function (isResize) {
7813            this.applyScroll(this.queuedScroll || {}, isResize);
7814        };
7815        View.prototype.queryScroll = function () {
7816            var scroll = {};
7817            if (this.props.dateProfile) { // dates rendered yet?
7818                __assign(scroll, this.queryDateScroll());
7819            }
7820            return scroll;
7821        };
7822        View.prototype.applyScroll = function (scroll, isResize) {
7823            var duration = scroll.duration;
7824            if (duration != null) {
7825                delete scroll.duration;
7826                if (this.props.dateProfile) { // dates rendered yet?
7827                    __assign(scroll, this.computeDateScroll(duration));
7828                }
7829            }
7830            if (this.props.dateProfile) { // dates rendered yet?
7831                this.applyDateScroll(scroll);
7832            }
7833        };
7834        View.prototype.computeDateScroll = function (duration) {
7835            return {}; // subclasses must implement
7836        };
7837        View.prototype.queryDateScroll = function () {
7838            return {}; // subclasses must implement
7839        };
7840        View.prototype.applyDateScroll = function (scroll) {
7841            // subclasses must implement
7842        };
7843        // for API
7844        View.prototype.scrollToDuration = function (duration) {
7845            this.applyScroll({ duration: duration }, false);
7846        };
7847        return View;
7848    }(DateComponent));
7849    EmitterMixin.mixInto(View);
7850    View.prototype.usesMinMaxTime = false;
7851    View.prototype.dateProfileGeneratorClass = DateProfileGenerator;
7852
7853    var FgEventRenderer = /** @class */ (function () {
7854        function FgEventRenderer(context) {
7855            this.segs = [];
7856            this.isSizeDirty = false;
7857            this.context = context;
7858        }
7859        FgEventRenderer.prototype.renderSegs = function (segs, mirrorInfo) {
7860            this.rangeUpdated(); // called too frequently :(
7861            // render an `.el` on each seg
7862            // returns a subset of the segs. segs that were actually rendered
7863            segs = this.renderSegEls(segs, mirrorInfo);
7864            this.segs = segs;
7865            this.attachSegs(segs, mirrorInfo);
7866            this.isSizeDirty = true;
7867            this.context.view.triggerRenderedSegs(this.segs, Boolean(mirrorInfo));
7868        };
7869        FgEventRenderer.prototype.unrender = function (_segs, mirrorInfo) {
7870            this.context.view.triggerWillRemoveSegs(this.segs, Boolean(mirrorInfo));
7871            this.detachSegs(this.segs);
7872            this.segs = [];
7873        };
7874        // Updates values that rely on options and also relate to range
7875        FgEventRenderer.prototype.rangeUpdated = function () {
7876            var options = this.context.options;
7877            var displayEventTime;
7878            var displayEventEnd;
7879            this.eventTimeFormat = createFormatter(options.eventTimeFormat || this.computeEventTimeFormat(), options.defaultRangeSeparator);
7880            displayEventTime = options.displayEventTime;
7881            if (displayEventTime == null) {
7882                displayEventTime = this.computeDisplayEventTime(); // might be based off of range
7883            }
7884            displayEventEnd = options.displayEventEnd;
7885            if (displayEventEnd == null) {
7886                displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range
7887            }
7888            this.displayEventTime = displayEventTime;
7889            this.displayEventEnd = displayEventEnd;
7890        };
7891        // Renders and assigns an `el` property for each foreground event segment.
7892        // Only returns segments that successfully rendered.
7893        FgEventRenderer.prototype.renderSegEls = function (segs, mirrorInfo) {
7894            var html = '';
7895            var i;
7896            if (segs.length) { // don't build an empty html string
7897                // build a large concatenation of event segment HTML
7898                for (i = 0; i < segs.length; i++) {
7899                    html += this.renderSegHtml(segs[i], mirrorInfo);
7900                }
7901                // Grab individual elements from the combined HTML string. Use each as the default rendering.
7902                // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
7903                htmlToElements(html).forEach(function (el, i) {
7904                    var seg = segs[i];
7905                    if (el) {
7906                        seg.el = el;
7907                    }
7908                });
7909                segs = filterSegsViaEls(this.context.view, segs, Boolean(mirrorInfo));
7910            }
7911            return segs;
7912        };
7913        // Generic utility for generating the HTML classNames for an event segment's element
7914        FgEventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable, mirrorInfo) {
7915            var classes = [
7916                'fc-event',
7917                seg.isStart ? 'fc-start' : 'fc-not-start',
7918                seg.isEnd ? 'fc-end' : 'fc-not-end'
7919            ].concat(seg.eventRange.ui.classNames);
7920            if (isDraggable) {
7921                classes.push('fc-draggable');
7922            }
7923            if (isResizable) {
7924                classes.push('fc-resizable');
7925            }
7926            if (mirrorInfo) {
7927                classes.push('fc-mirror');
7928                if (mirrorInfo.isDragging) {
7929                    classes.push('fc-dragging');
7930                }
7931                if (mirrorInfo.isResizing) {
7932                    classes.push('fc-resizing');
7933                }
7934            }
7935            return classes;
7936        };
7937        // Compute the text that should be displayed on an event's element.
7938        // `range` can be the Event object itself, or something range-like, with at least a `start`.
7939        // If event times are disabled, or the event has no time, will return a blank string.
7940        // If not specified, formatter will default to the eventTimeFormat setting,
7941        // and displayEnd will default to the displayEventEnd setting.
7942        FgEventRenderer.prototype.getTimeText = function (eventRange, formatter, displayEnd) {
7943            var def = eventRange.def, instance = eventRange.instance;
7944            return this._getTimeText(instance.range.start, def.hasEnd ? instance.range.end : null, def.allDay, formatter, displayEnd, instance.forcedStartTzo, instance.forcedEndTzo);
7945        };
7946        FgEventRenderer.prototype._getTimeText = function (start, end, allDay, formatter, displayEnd, forcedStartTzo, forcedEndTzo) {
7947            var dateEnv = this.context.dateEnv;
7948            if (formatter == null) {
7949                formatter = this.eventTimeFormat;
7950            }
7951            if (displayEnd == null) {
7952                displayEnd = this.displayEventEnd;
7953            }
7954            if (this.displayEventTime && !allDay) {
7955                if (displayEnd && end) {
7956                    return dateEnv.formatRange(start, end, formatter, {
7957                        forcedStartTzo: forcedStartTzo,
7958                        forcedEndTzo: forcedEndTzo
7959                    });
7960                }
7961                else {
7962                    return dateEnv.format(start, formatter, {
7963                        forcedTzo: forcedStartTzo
7964                    });
7965                }
7966            }
7967            return '';
7968        };
7969        FgEventRenderer.prototype.computeEventTimeFormat = function () {
7970            return {
7971                hour: 'numeric',
7972                minute: '2-digit',
7973                omitZeroMinute: true
7974            };
7975        };
7976        FgEventRenderer.prototype.computeDisplayEventTime = function () {
7977            return true;
7978        };
7979        FgEventRenderer.prototype.computeDisplayEventEnd = function () {
7980            return true;
7981        };
7982        // Utility for generating event skin-related CSS properties
7983        FgEventRenderer.prototype.getSkinCss = function (ui) {
7984            return {
7985                'background-color': ui.backgroundColor,
7986                'border-color': ui.borderColor,
7987                color: ui.textColor
7988            };
7989        };
7990        FgEventRenderer.prototype.sortEventSegs = function (segs) {
7991            var specs = this.context.view.eventOrderSpecs;
7992            var objs = segs.map(buildSegCompareObj);
7993            objs.sort(function (obj0, obj1) {
7994                return compareByFieldSpecs(obj0, obj1, specs);
7995            });
7996            return objs.map(function (c) {
7997                return c._seg;
7998            });
7999        };
8000        FgEventRenderer.prototype.computeSizes = function (force) {
8001            if (force || this.isSizeDirty) {
8002                this.computeSegSizes(this.segs);
8003            }
8004        };
8005        FgEventRenderer.prototype.assignSizes = function (force) {
8006            if (force || this.isSizeDirty) {
8007                this.assignSegSizes(this.segs);
8008                this.isSizeDirty = false;
8009            }
8010        };
8011        FgEventRenderer.prototype.computeSegSizes = function (segs) {
8012        };
8013        FgEventRenderer.prototype.assignSegSizes = function (segs) {
8014        };
8015        // Manipulation on rendered segs
8016        FgEventRenderer.prototype.hideByHash = function (hash) {
8017            if (hash) {
8018                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
8019                    var seg = _a[_i];
8020                    if (hash[seg.eventRange.instance.instanceId]) {
8021                        seg.el.style.visibility = 'hidden';
8022                    }
8023                }
8024            }
8025        };
8026        FgEventRenderer.prototype.showByHash = function (hash) {
8027            if (hash) {
8028                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
8029                    var seg = _a[_i];
8030                    if (hash[seg.eventRange.instance.instanceId]) {
8031                        seg.el.style.visibility = '';
8032                    }
8033                }
8034            }
8035        };
8036        FgEventRenderer.prototype.selectByInstanceId = function (instanceId) {
8037            if (instanceId) {
8038                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
8039                    var seg = _a[_i];
8040                    var eventInstance = seg.eventRange.instance;
8041                    if (eventInstance && eventInstance.instanceId === instanceId &&
8042                        seg.el // necessary?
8043                    ) {
8044                        seg.el.classList.add('fc-selected');
8045                    }
8046                }
8047            }
8048        };
8049        FgEventRenderer.prototype.unselectByInstanceId = function (instanceId) {
8050            if (instanceId) {
8051                for (var _i = 0, _a = this.segs; _i < _a.length; _i++) {
8052                    var seg = _a[_i];
8053                    if (seg.el) { // necessary?
8054                        seg.el.classList.remove('fc-selected');
8055                    }
8056                }
8057            }
8058        };
8059        return FgEventRenderer;
8060    }());
8061    // returns a object with all primitive props that can be compared
8062    function buildSegCompareObj(seg) {
8063        var eventDef = seg.eventRange.def;
8064        var range = seg.eventRange.instance.range;
8065        var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
8066        var end = range.end ? range.end.valueOf() : 0; // "
8067        return __assign({}, eventDef.extendedProps, eventDef, { id: eventDef.publicId, start: start,
8068            end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg // for later retrieval
8069         });
8070    }
8071
8072    var FillRenderer = /** @class */ (function () {
8073        function FillRenderer(context) {
8074            this.fillSegTag = 'div';
8075            this.dirtySizeFlags = {};
8076            this.context = context;
8077            this.containerElsByType = {};
8078            this.segsByType = {};
8079        }
8080        FillRenderer.prototype.getSegsByType = function (type) {
8081            return this.segsByType[type] || [];
8082        };
8083        FillRenderer.prototype.renderSegs = function (type, segs) {
8084            var _a;
8085            var renderedSegs = this.renderSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs
8086            var containerEls = this.attachSegs(type, renderedSegs);
8087            if (containerEls) {
8088                (_a = (this.containerElsByType[type] || (this.containerElsByType[type] = []))).push.apply(_a, containerEls);
8089            }
8090            this.segsByType[type] = renderedSegs;
8091            if (type === 'bgEvent') {
8092                this.context.view.triggerRenderedSegs(renderedSegs, false); // isMirror=false
8093            }
8094            this.dirtySizeFlags[type] = true;
8095        };
8096        // Unrenders a specific type of fill that is currently rendered on the grid
8097        FillRenderer.prototype.unrender = function (type) {
8098            var segs = this.segsByType[type];
8099            if (segs) {
8100                if (type === 'bgEvent') {
8101                    this.context.view.triggerWillRemoveSegs(segs, false); // isMirror=false
8102                }
8103                this.detachSegs(type, segs);
8104            }
8105        };
8106        // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
8107        // Only returns segments that successfully rendered.
8108        FillRenderer.prototype.renderSegEls = function (type, segs) {
8109            var _this = this;
8110            var html = '';
8111            var i;
8112            if (segs.length) {
8113                // build a large concatenation of segment HTML
8114                for (i = 0; i < segs.length; i++) {
8115                    html += this.renderSegHtml(type, segs[i]);
8116                }
8117                // Grab individual elements from the combined HTML string. Use each as the default rendering.
8118                // Then, compute the 'el' for each segment.
8119                htmlToElements(html).forEach(function (el, i) {
8120                    var seg = segs[i];
8121                    if (el) {
8122                        seg.el = el;
8123                    }
8124                });
8125                if (type === 'bgEvent') {
8126                    segs = filterSegsViaEls(this.context.view, segs, false // isMirror. background events can never be mirror elements
8127                    );
8128                }
8129                // correct element type? (would be bad if a non-TD were inserted into a table for example)
8130                segs = segs.filter(function (seg) {
8131                    return elementMatches(seg.el, _this.fillSegTag);
8132                });
8133            }
8134            return segs;
8135        };
8136        // Builds the HTML needed for one fill segment. Generic enough to work with different types.
8137        FillRenderer.prototype.renderSegHtml = function (type, seg) {
8138            var css = null;
8139            var classNames = [];
8140            if (type !== 'highlight' && type !== 'businessHours') {
8141                css = {
8142                    'background-color': seg.eventRange.ui.backgroundColor
8143                };
8144            }
8145            if (type !== 'highlight') {
8146                classNames = classNames.concat(seg.eventRange.ui.classNames);
8147            }
8148            if (type === 'businessHours') {
8149                classNames.push('fc-bgevent');
8150            }
8151            else {
8152                classNames.push('fc-' + type.toLowerCase());
8153            }
8154            return '<' + this.fillSegTag +
8155                (classNames.length ? ' class="' + classNames.join(' ') + '"' : '') +
8156                (css ? ' style="' + cssToStr(css) + '"' : '') +
8157                '></' + this.fillSegTag + '>';
8158        };
8159        FillRenderer.prototype.detachSegs = function (type, segs) {
8160            var containerEls = this.containerElsByType[type];
8161            if (containerEls) {
8162                containerEls.forEach(removeElement);
8163                delete this.containerElsByType[type];
8164            }
8165        };
8166        FillRenderer.prototype.computeSizes = function (force) {
8167            for (var type in this.segsByType) {
8168                if (force || this.dirtySizeFlags[type]) {
8169                    this.computeSegSizes(this.segsByType[type]);
8170                }
8171            }
8172        };
8173        FillRenderer.prototype.assignSizes = function (force) {
8174            for (var type in this.segsByType) {
8175                if (force || this.dirtySizeFlags[type]) {
8176                    this.assignSegSizes(this.segsByType[type]);
8177                }
8178            }
8179            this.dirtySizeFlags = {};
8180        };
8181        FillRenderer.prototype.computeSegSizes = function (segs) {
8182        };
8183        FillRenderer.prototype.assignSegSizes = function (segs) {
8184        };
8185        return FillRenderer;
8186    }());
8187
8188    var NamedTimeZoneImpl = /** @class */ (function () {
8189        function NamedTimeZoneImpl(timeZoneName) {
8190            this.timeZoneName = timeZoneName;
8191        }
8192        return NamedTimeZoneImpl;
8193    }());
8194
8195    /*
8196    An abstraction for a dragging interaction originating on an event.
8197    Does higher-level things than PointerDragger, such as possibly:
8198    - a "mirror" that moves with the pointer
8199    - a minimum number of pixels or other criteria for a true drag to begin
8200
8201    subclasses must emit:
8202    - pointerdown
8203    - dragstart
8204    - dragmove
8205    - pointerup
8206    - dragend
8207    */
8208    var ElementDragging = /** @class */ (function () {
8209        function ElementDragging(el) {
8210            this.emitter = new EmitterMixin();
8211        }
8212        ElementDragging.prototype.destroy = function () {
8213        };
8214        ElementDragging.prototype.setMirrorIsVisible = function (bool) {
8215            // optional if subclass doesn't want to support a mirror
8216        };
8217        ElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
8218            // optional if subclass doesn't want to support a mirror
8219        };
8220        ElementDragging.prototype.setAutoScrollEnabled = function (bool) {
8221            // optional
8222        };
8223        return ElementDragging;
8224    }());
8225
8226    function formatDate(dateInput, settings) {
8227        if (settings === void 0) { settings = {}; }
8228        var dateEnv = buildDateEnv$1(settings);
8229        var formatter = createFormatter(settings);
8230        var dateMeta = dateEnv.createMarkerMeta(dateInput);
8231        if (!dateMeta) { // TODO: warning?
8232            return '';
8233        }
8234        return dateEnv.format(dateMeta.marker, formatter, {
8235            forcedTzo: dateMeta.forcedTzo
8236        });
8237    }
8238    function formatRange(startInput, endInput, settings // mixture of env and formatter settings
8239    ) {
8240        var dateEnv = buildDateEnv$1(typeof settings === 'object' && settings ? settings : {}); // pass in if non-null object
8241        var formatter = createFormatter(settings, globalDefaults.defaultRangeSeparator);
8242        var startMeta = dateEnv.createMarkerMeta(startInput);
8243        var endMeta = dateEnv.createMarkerMeta(endInput);
8244        if (!startMeta || !endMeta) { // TODO: warning?
8245            return '';
8246        }
8247        return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
8248            forcedStartTzo: startMeta.forcedTzo,
8249            forcedEndTzo: endMeta.forcedTzo,
8250            isEndExclusive: settings.isEndExclusive
8251        });
8252    }
8253    // TODO: more DRY and optimized
8254    function buildDateEnv$1(settings) {
8255        var locale = buildLocale(settings.locale || 'en', parseRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
8256        // ensure required settings
8257        settings = __assign({ timeZone: globalDefaults.timeZone, calendarSystem: 'gregory' }, settings, { locale: locale });
8258        return new DateEnv(settings);
8259    }
8260
8261    var DRAG_META_PROPS = {
8262        startTime: createDuration,
8263        duration: createDuration,
8264        create: Boolean,
8265        sourceId: String
8266    };
8267    var DRAG_META_DEFAULTS = {
8268        create: true
8269    };
8270    function parseDragMeta(raw) {
8271        var leftoverProps = {};
8272        var refined = refineProps(raw, DRAG_META_PROPS, DRAG_META_DEFAULTS, leftoverProps);
8273        refined.leftoverProps = leftoverProps;
8274        return refined;
8275    }
8276
8277    // Computes a default column header formatting string if `colFormat` is not explicitly defined
8278    function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
8279        // if more than one week row, or if there are a lot of columns with not much space,
8280        // put just the day numbers will be in each cell
8281        if (!datesRepDistinctDays || dayCnt > 10) {
8282            return { weekday: 'short' }; // "Sat"
8283        }
8284        else if (dayCnt > 1) {
8285            return { weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }; // "Sat 11/12"
8286        }
8287        else {
8288            return { weekday: 'long' }; // "Saturday"
8289        }
8290    }
8291    function renderDateCell(dateMarker, dateProfile, datesRepDistinctDays, colCnt, colHeadFormat, context, colspan, otherAttrs) {
8292        var view = context.view, dateEnv = context.dateEnv, theme = context.theme, options = context.options;
8293        var isDateValid = rangeContainsMarker(dateProfile.activeRange, dateMarker); // TODO: called too frequently. cache somehow.
8294        var classNames = [
8295            'fc-day-header',
8296            theme.getClass('widgetHeader')
8297        ];
8298        var innerHtml;
8299        if (typeof options.columnHeaderHtml === 'function') {
8300            innerHtml = options.columnHeaderHtml(dateEnv.toDate(dateMarker));
8301        }
8302        else if (typeof options.columnHeaderText === 'function') {
8303            innerHtml = htmlEscape(options.columnHeaderText(dateEnv.toDate(dateMarker)));
8304        }
8305        else {
8306            innerHtml = htmlEscape(dateEnv.format(dateMarker, colHeadFormat));
8307        }
8308        // if only one row of days, the classNames on the header can represent the specific days beneath
8309        if (datesRepDistinctDays) {
8310            classNames = classNames.concat(
8311            // includes the day-of-week class
8312            // noThemeHighlight=true (don't highlight the header)
8313            getDayClasses(dateMarker, dateProfile, context, true));
8314        }
8315        else {
8316            classNames.push('fc-' + DAY_IDS[dateMarker.getUTCDay()]); // only add the day-of-week class
8317        }
8318        return '' +
8319            '<th class="' + classNames.join(' ') + '"' +
8320            ((isDateValid && datesRepDistinctDays) ?
8321                ' data-date="' + dateEnv.formatIso(dateMarker, { omitTime: true }) + '"' :
8322                '') +
8323            (colspan > 1 ?
8324                ' colspan="' + colspan + '"' :
8325                '') +
8326            (otherAttrs ?
8327                ' ' + otherAttrs :
8328                '') +
8329            '>' +
8330            (isDateValid ?
8331                // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff)
8332                buildGotoAnchorHtml(view, { date: dateMarker, forceOff: !datesRepDistinctDays || colCnt === 1 }, innerHtml) :
8333                // if not valid, display text, but no link
8334                innerHtml) +
8335            '</th>';
8336    }
8337
8338    var DayHeader = /** @class */ (function (_super) {
8339        __extends(DayHeader, _super);
8340        function DayHeader(context, parentEl) {
8341            var _this = _super.call(this, context) || this;
8342            parentEl.innerHTML = ''; // because might be nbsp
8343            parentEl.appendChild(_this.el = htmlToElement('<div class="fc-row ' + _this.theme.getClass('headerRow') + '">' +
8344                '<table class="' + _this.theme.getClass('tableGrid') + '">' +
8345                '<thead></thead>' +
8346                '</table>' +
8347                '</div>'));
8348            _this.thead = _this.el.querySelector('thead');
8349            return _this;
8350        }
8351        DayHeader.prototype.destroy = function () {
8352            removeElement(this.el);
8353        };
8354        DayHeader.prototype.render = function (props) {
8355            var dates = props.dates, datesRepDistinctDays = props.datesRepDistinctDays;
8356            var parts = [];
8357            if (props.renderIntroHtml) {
8358                parts.push(props.renderIntroHtml());
8359            }
8360            var colHeadFormat = createFormatter(this.opt('columnHeaderFormat') ||
8361                computeFallbackHeaderFormat(datesRepDistinctDays, dates.length));
8362            for (var _i = 0, dates_1 = dates; _i < dates_1.length; _i++) {
8363                var date = dates_1[_i];
8364                parts.push(renderDateCell(date, props.dateProfile, datesRepDistinctDays, dates.length, colHeadFormat, this.context));
8365            }
8366            if (this.isRtl) {
8367                parts.reverse();
8368            }
8369            this.thead.innerHTML = '<tr>' + parts.join('') + '</tr>';
8370        };
8371        return DayHeader;
8372    }(Component));
8373
8374    var DaySeries = /** @class */ (function () {
8375        function DaySeries(range, dateProfileGenerator) {
8376            var date = range.start;
8377            var end = range.end;
8378            var indices = [];
8379            var dates = [];
8380            var dayIndex = -1;
8381            while (date < end) { // loop each day from start to end
8382                if (dateProfileGenerator.isHiddenDay(date)) {
8383                    indices.push(dayIndex + 0.5); // mark that it's between indices
8384                }
8385                else {
8386                    dayIndex++;
8387                    indices.push(dayIndex);
8388                    dates.push(date);
8389                }
8390                date = addDays(date, 1);
8391            }
8392            this.dates = dates;
8393            this.indices = indices;
8394            this.cnt = dates.length;
8395        }
8396        DaySeries.prototype.sliceRange = function (range) {
8397            var firstIndex = this.getDateDayIndex(range.start); // inclusive first index
8398            var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
8399            var clippedFirstIndex = Math.max(0, firstIndex);
8400            var clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
8401            // deal with in-between indices
8402            clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
8403            clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
8404            if (clippedFirstIndex <= clippedLastIndex) {
8405                return {
8406                    firstIndex: clippedFirstIndex,
8407                    lastIndex: clippedLastIndex,
8408                    isStart: firstIndex === clippedFirstIndex,
8409                    isEnd: lastIndex === clippedLastIndex
8410                };
8411            }
8412            else {
8413                return null;
8414            }
8415        };
8416        // Given a date, returns its chronolocial cell-index from the first cell of the grid.
8417        // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
8418        // If before the first offset, returns a negative number.
8419        // If after the last offset, returns an offset past the last cell offset.
8420        // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
8421        DaySeries.prototype.getDateDayIndex = function (date) {
8422            var indices = this.indices;
8423            var dayOffset = Math.floor(diffDays(this.dates[0], date));
8424            if (dayOffset < 0) {
8425                return indices[0] - 1;
8426            }
8427            else if (dayOffset >= indices.length) {
8428                return indices[indices.length - 1] + 1;
8429            }
8430            else {
8431                return indices[dayOffset];
8432            }
8433        };
8434        return DaySeries;
8435    }());
8436
8437    var DayTable = /** @class */ (function () {
8438        function DayTable(daySeries, breakOnWeeks) {
8439            var dates = daySeries.dates;
8440            var daysPerRow;
8441            var firstDay;
8442            var rowCnt;
8443            if (breakOnWeeks) {
8444                // count columns until the day-of-week repeats
8445                firstDay = dates[0].getUTCDay();
8446                for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow++) {
8447                    if (dates[daysPerRow].getUTCDay() === firstDay) {
8448                        break;
8449                    }
8450                }
8451                rowCnt = Math.ceil(dates.length / daysPerRow);
8452            }
8453            else {
8454                rowCnt = 1;
8455                daysPerRow = dates.length;
8456            }
8457            this.rowCnt = rowCnt;
8458            this.colCnt = daysPerRow;
8459            this.daySeries = daySeries;
8460            this.cells = this.buildCells();
8461            this.headerDates = this.buildHeaderDates();
8462        }
8463        DayTable.prototype.buildCells = function () {
8464            var rows = [];
8465            for (var row = 0; row < this.rowCnt; row++) {
8466                var cells = [];
8467                for (var col = 0; col < this.colCnt; col++) {
8468                    cells.push(this.buildCell(row, col));
8469                }
8470                rows.push(cells);
8471            }
8472            return rows;
8473        };
8474        DayTable.prototype.buildCell = function (row, col) {
8475            return {
8476                date: this.daySeries.dates[row * this.colCnt + col]
8477            };
8478        };
8479        DayTable.prototype.buildHeaderDates = function () {
8480            var dates = [];
8481            for (var col = 0; col < this.colCnt; col++) {
8482                dates.push(this.cells[0][col].date);
8483            }
8484            return dates;
8485        };
8486        DayTable.prototype.sliceRange = function (range) {
8487            var colCnt = this.colCnt;
8488            var seriesSeg = this.daySeries.sliceRange(range);
8489            var segs = [];
8490            if (seriesSeg) {
8491                var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex;
8492                var index = firstIndex;
8493                while (index <= lastIndex) {
8494                    var row = Math.floor(index / colCnt);
8495                    var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
8496                    segs.push({
8497                        row: row,
8498                        firstCol: index % colCnt,
8499                        lastCol: (nextIndex - 1) % colCnt,
8500                        isStart: seriesSeg.isStart && index === firstIndex,
8501                        isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex
8502                    });
8503                    index = nextIndex;
8504                }
8505            }
8506            return segs;
8507        };
8508        return DayTable;
8509    }());
8510
8511    var Slicer = /** @class */ (function () {
8512        function Slicer() {
8513            this.sliceBusinessHours = memoize(this._sliceBusinessHours);
8514            this.sliceDateSelection = memoize(this._sliceDateSpan);
8515            this.sliceEventStore = memoize(this._sliceEventStore);
8516            this.sliceEventDrag = memoize(this._sliceInteraction);
8517            this.sliceEventResize = memoize(this._sliceInteraction);
8518        }
8519        Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, component) {
8520            var extraArgs = [];
8521            for (var _i = 4; _i < arguments.length; _i++) {
8522                extraArgs[_i - 4] = arguments[_i];
8523            }
8524            var eventUiBases = props.eventUiBases;
8525            var eventSegs = this.sliceEventStore.apply(this, [props.eventStore, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs));
8526            return {
8527                dateSelectionSegs: this.sliceDateSelection.apply(this, [props.dateSelection, eventUiBases, component].concat(extraArgs)),
8528                businessHourSegs: this.sliceBusinessHours.apply(this, [props.businessHours, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8529                fgEventSegs: eventSegs.fg,
8530                bgEventSegs: eventSegs.bg,
8531                eventDrag: this.sliceEventDrag.apply(this, [props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8532                eventResize: this.sliceEventResize.apply(this, [props.eventResize, eventUiBases, dateProfile, nextDayThreshold, component].concat(extraArgs)),
8533                eventSelection: props.eventSelection
8534            }; // TODO: give interactionSegs?
8535        };
8536        Slicer.prototype.sliceNowDate = function (// does not memoize
8537        date, component) {
8538            var extraArgs = [];
8539            for (var _i = 2; _i < arguments.length; _i++) {
8540                extraArgs[_i - 2] = arguments[_i];
8541            }
8542            return this._sliceDateSpan.apply(this, [{ range: { start: date, end: addMs(date, 1) }, allDay: false },
8543                {},
8544                component].concat(extraArgs));
8545        };
8546        Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, component) {
8547            var extraArgs = [];
8548            for (var _i = 4; _i < arguments.length; _i++) {
8549                extraArgs[_i - 4] = arguments[_i];
8550            }
8551            if (!businessHours) {
8552                return [];
8553            }
8554            return this._sliceEventStore.apply(this, [expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), component.calendar),
8555                {},
8556                dateProfile,
8557                nextDayThreshold,
8558                component].concat(extraArgs)).bg;
8559        };
8560        Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold, component) {
8561            var extraArgs = [];
8562            for (var _i = 5; _i < arguments.length; _i++) {
8563                extraArgs[_i - 5] = arguments[_i];
8564            }
8565            if (eventStore) {
8566                var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8567                return {
8568                    bg: this.sliceEventRanges(rangeRes.bg, component, extraArgs),
8569                    fg: this.sliceEventRanges(rangeRes.fg, component, extraArgs)
8570                };
8571            }
8572            else {
8573                return { bg: [], fg: [] };
8574            }
8575        };
8576        Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold, component) {
8577            var extraArgs = [];
8578            for (var _i = 5; _i < arguments.length; _i++) {
8579                extraArgs[_i - 5] = arguments[_i];
8580            }
8581            if (!interaction) {
8582                return null;
8583            }
8584            var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
8585            return {
8586                segs: this.sliceEventRanges(rangeRes.fg, component, extraArgs),
8587                affectedInstances: interaction.affectedEvents.instances,
8588                isEvent: interaction.isEvent,
8589                sourceSeg: interaction.origSeg
8590            };
8591        };
8592        Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, component) {
8593            var extraArgs = [];
8594            for (var _i = 3; _i < arguments.length; _i++) {
8595                extraArgs[_i - 3] = arguments[_i];
8596            }
8597            if (!dateSpan) {
8598                return [];
8599            }
8600            var eventRange = fabricateEventRange(dateSpan, eventUiBases, component.calendar);
8601            var segs = this.sliceRange.apply(this, [dateSpan.range].concat(extraArgs));
8602            for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) {
8603                var seg = segs_1[_a];
8604                seg.component = component;
8605                seg.eventRange = eventRange;
8606            }
8607            return segs;
8608        };
8609        /*
8610        "complete" seg means it has component and eventRange
8611        */
8612        Slicer.prototype.sliceEventRanges = function (eventRanges, component, // TODO: kill
8613        extraArgs) {
8614            var segs = [];
8615            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
8616                var eventRange = eventRanges_1[_i];
8617                segs.push.apply(segs, this.sliceEventRange(eventRange, component, extraArgs));
8618            }
8619            return segs;
8620        };
8621        /*
8622        "complete" seg means it has component and eventRange
8623        */
8624        Slicer.prototype.sliceEventRange = function (eventRange, component, // TODO: kill
8625        extraArgs) {
8626            var segs = this.sliceRange.apply(this, [eventRange.range].concat(extraArgs));
8627            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
8628                var seg = segs_2[_i];
8629                seg.component = component;
8630                seg.eventRange = eventRange;
8631                seg.isStart = eventRange.isStart && seg.isStart;
8632                seg.isEnd = eventRange.isEnd && seg.isEnd;
8633            }
8634            return segs;
8635        };
8636        return Slicer;
8637    }());
8638    /*
8639    for incorporating minTime/maxTime if appropriate
8640    TODO: should be part of DateProfile!
8641    TimelineDateProfile already does this btw
8642    */
8643    function computeActiveRange(dateProfile, isComponentAllDay) {
8644        var range = dateProfile.activeRange;
8645        if (isComponentAllDay) {
8646            return range;
8647        }
8648        return {
8649            start: addMs(range.start, dateProfile.minTime.milliseconds),
8650            end: addMs(range.end, dateProfile.maxTime.milliseconds - 864e5) // 864e5 = ms in a day
8651        };
8652    }
8653
8654    // exports
8655    // --------------------------------------------------------------------------------------------------
8656    var version = '4.3.1';
8657
8658    exports.Calendar = Calendar;
8659    exports.Component = Component;
8660    exports.DateComponent = DateComponent;
8661    exports.DateEnv = DateEnv;
8662    exports.DateProfileGenerator = DateProfileGenerator;
8663    exports.DayHeader = DayHeader;
8664    exports.DaySeries = DaySeries;
8665    exports.DayTable = DayTable;
8666    exports.ElementDragging = ElementDragging;
8667    exports.ElementScrollController = ElementScrollController;
8668    exports.EmitterMixin = EmitterMixin;
8669    exports.EventApi = EventApi;
8670    exports.FgEventRenderer = FgEventRenderer;
8671    exports.FillRenderer = FillRenderer;
8672    exports.Interaction = Interaction;
8673    exports.Mixin = Mixin;
8674    exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
8675    exports.PositionCache = PositionCache;
8676    exports.ScrollComponent = ScrollComponent;
8677    exports.ScrollController = ScrollController;
8678    exports.Slicer = Slicer;
8679    exports.Splitter = Splitter;
8680    exports.Theme = Theme;
8681    exports.View = View;
8682    exports.WindowScrollController = WindowScrollController;
8683    exports.addDays = addDays;
8684    exports.addDurations = addDurations;
8685    exports.addMs = addMs;
8686    exports.addWeeks = addWeeks;
8687    exports.allowContextMenu = allowContextMenu;
8688    exports.allowSelection = allowSelection;
8689    exports.appendToElement = appendToElement;
8690    exports.applyAll = applyAll;
8691    exports.applyMutationToEventStore = applyMutationToEventStore;
8692    exports.applyStyle = applyStyle;
8693    exports.applyStyleProp = applyStyleProp;
8694    exports.asRoughMinutes = asRoughMinutes;
8695    exports.asRoughMs = asRoughMs;
8696    exports.asRoughSeconds = asRoughSeconds;
8697    exports.buildGotoAnchorHtml = buildGotoAnchorHtml;
8698    exports.buildSegCompareObj = buildSegCompareObj;
8699    exports.capitaliseFirstLetter = capitaliseFirstLetter;
8700    exports.combineEventUis = combineEventUis;
8701    exports.compareByFieldSpec = compareByFieldSpec;
8702    exports.compareByFieldSpecs = compareByFieldSpecs;
8703    exports.compareNumbers = compareNumbers;
8704    exports.compensateScroll = compensateScroll;
8705    exports.computeClippingRect = computeClippingRect;
8706    exports.computeEdges = computeEdges;
8707    exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat;
8708    exports.computeHeightAndMargins = computeHeightAndMargins;
8709    exports.computeInnerRect = computeInnerRect;
8710    exports.computeRect = computeRect;
8711    exports.computeVisibleDayRange = computeVisibleDayRange;
8712    exports.config = config;
8713    exports.constrainPoint = constrainPoint;
8714    exports.createDuration = createDuration;
8715    exports.createElement = createElement;
8716    exports.createEmptyEventStore = createEmptyEventStore;
8717    exports.createEventInstance = createEventInstance;
8718    exports.createFormatter = createFormatter;
8719    exports.createPlugin = createPlugin;
8720    exports.cssToStr = cssToStr;
8721    exports.debounce = debounce;
8722    exports.diffDates = diffDates;
8723    exports.diffDayAndTime = diffDayAndTime;
8724    exports.diffDays = diffDays;
8725    exports.diffPoints = diffPoints;
8726    exports.diffWeeks = diffWeeks;
8727    exports.diffWholeDays = diffWholeDays;
8728    exports.diffWholeWeeks = diffWholeWeeks;
8729    exports.disableCursor = disableCursor;
8730    exports.distributeHeight = distributeHeight;
8731    exports.elementClosest = elementClosest;
8732    exports.elementMatches = elementMatches;
8733    exports.enableCursor = enableCursor;
8734    exports.eventTupleToStore = eventTupleToStore;
8735    exports.filterEventStoreDefs = filterEventStoreDefs;
8736    exports.filterHash = filterHash;
8737    exports.findChildren = findChildren;
8738    exports.findElements = findElements;
8739    exports.flexibleCompare = flexibleCompare;
8740    exports.forceClassName = forceClassName;
8741    exports.formatDate = formatDate;
8742    exports.formatIsoTimeString = formatIsoTimeString;
8743    exports.formatRange = formatRange;
8744    exports.getAllDayHtml = getAllDayHtml;
8745    exports.getClippingParents = getClippingParents;
8746    exports.getDayClasses = getDayClasses;
8747    exports.getElSeg = getElSeg;
8748    exports.getRectCenter = getRectCenter;
8749    exports.getRelevantEvents = getRelevantEvents;
8750    exports.globalDefaults = globalDefaults;
8751    exports.greatestDurationDenominator = greatestDurationDenominator;
8752    exports.hasBgRendering = hasBgRendering;
8753    exports.htmlEscape = htmlEscape;
8754    exports.htmlToElement = htmlToElement;
8755    exports.insertAfterElement = insertAfterElement;
8756    exports.interactionSettingsStore = interactionSettingsStore;
8757    exports.interactionSettingsToStore = interactionSettingsToStore;
8758    exports.intersectRanges = intersectRanges;
8759    exports.intersectRects = intersectRects;
8760    exports.isArraysEqual = isArraysEqual;
8761    exports.isDateSpansEqual = isDateSpansEqual;
8762    exports.isInt = isInt;
8763    exports.isInteractionValid = isInteractionValid;
8764    exports.isMultiDayRange = isMultiDayRange;
8765    exports.isPropsEqual = isPropsEqual;
8766    exports.isPropsValid = isPropsValid;
8767    exports.isSingleDay = isSingleDay;
8768    exports.isValidDate = isValidDate;
8769    exports.listenBySelector = listenBySelector;
8770    exports.mapHash = mapHash;
8771    exports.matchCellWidths = matchCellWidths;
8772    exports.memoize = memoize;
8773    exports.memoizeOutput = memoizeOutput;
8774    exports.memoizeRendering = memoizeRendering;
8775    exports.mergeEventStores = mergeEventStores;
8776    exports.multiplyDuration = multiplyDuration;
8777    exports.padStart = padStart;
8778    exports.parseBusinessHours = parseBusinessHours;
8779    exports.parseDragMeta = parseDragMeta;
8780    exports.parseEventDef = parseEventDef;
8781    exports.parseFieldSpecs = parseFieldSpecs;
8782    exports.parseMarker = parse;
8783    exports.pointInsideRect = pointInsideRect;
8784    exports.prependToElement = prependToElement;
8785    exports.preventContextMenu = preventContextMenu;
8786    exports.preventDefault = preventDefault;
8787    exports.preventSelection = preventSelection;
8788    exports.processScopedUiProps = processScopedUiProps;
8789    exports.rangeContainsMarker = rangeContainsMarker;
8790    exports.rangeContainsRange = rangeContainsRange;
8791    exports.rangesEqual = rangesEqual;
8792    exports.rangesIntersect = rangesIntersect;
8793    exports.refineProps = refineProps;
8794    exports.removeElement = removeElement;
8795    exports.removeExact = removeExact;
8796    exports.renderDateCell = renderDateCell;
8797    exports.requestJson = requestJson;
8798    exports.sliceEventStore = sliceEventStore;
8799    exports.startOfDay = startOfDay;
8800    exports.subtractInnerElHeight = subtractInnerElHeight;
8801    exports.translateRect = translateRect;
8802    exports.uncompensateScroll = uncompensateScroll;
8803    exports.undistributeHeight = undistributeHeight;
8804    exports.unpromisify = unpromisify;
8805    exports.version = version;
8806    exports.whenTransitionDone = whenTransitionDone;
8807    exports.wholeDivideDurations = wholeDivideDurations;
8808
8809    Object.defineProperty(exports, '__esModule', { value: true });
8810
8811}));
8812
8813},{}],3:[function(require,module,exports){
8814/*!
8815FullCalendar Day Grid Plugin v4.3.0
8816Docs & License: https://fullcalendar.io/
8817(c) 2019 Adam Shaw
8818*/
8819
8820(function (global, factory) {
8821    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
8822    typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
8823    (global = global || self, factory(global.FullCalendarDayGrid = {}, global.FullCalendar));
8824}(this, function (exports, core) { 'use strict';
8825
8826    /*! *****************************************************************************
8827    Copyright (c) Microsoft Corporation. All rights reserved.
8828    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
8829    this file except in compliance with the License. You may obtain a copy of the
8830    License at http://www.apache.org/licenses/LICENSE-2.0
8831
8832    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8833    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
8834    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
8835    MERCHANTABLITY OR NON-INFRINGEMENT.
8836
8837    See the Apache Version 2.0 License for specific language governing permissions
8838    and limitations under the License.
8839    ***************************************************************************** */
8840    /* global Reflect, Promise */
8841
8842    var extendStatics = function(d, b) {
8843        extendStatics = Object.setPrototypeOf ||
8844            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
8845            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
8846        return extendStatics(d, b);
8847    };
8848
8849    function __extends(d, b) {
8850        extendStatics(d, b);
8851        function __() { this.constructor = d; }
8852        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
8853    }
8854
8855    var __assign = function() {
8856        __assign = Object.assign || function __assign(t) {
8857            for (var s, i = 1, n = arguments.length; i < n; i++) {
8858                s = arguments[i];
8859                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
8860            }
8861            return t;
8862        };
8863        return __assign.apply(this, arguments);
8864    };
8865
8866    var DayGridDateProfileGenerator = /** @class */ (function (_super) {
8867        __extends(DayGridDateProfileGenerator, _super);
8868        function DayGridDateProfileGenerator() {
8869            return _super !== null && _super.apply(this, arguments) || this;
8870        }
8871        // Computes the date range that will be rendered.
8872        DayGridDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
8873            var dateEnv = this.dateEnv;
8874            var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay);
8875            var start = renderRange.start;
8876            var end = renderRange.end;
8877            var endOfWeek;
8878            // year and month views should be aligned with weeks. this is already done for week
8879            if (/^(year|month)$/.test(currentRangeUnit)) {
8880                start = dateEnv.startOfWeek(start);
8881                // make end-of-week if not already
8882                endOfWeek = dateEnv.startOfWeek(end);
8883                if (endOfWeek.valueOf() !== end.valueOf()) {
8884                    end = core.addWeeks(endOfWeek, 1);
8885                }
8886            }
8887            // ensure 6 weeks
8888            if (this.options.monthMode &&
8889                this.options.fixedWeekCount) {
8890                var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
8891                core.diffWeeks(start, end));
8892                end = core.addWeeks(end, 6 - rowCnt);
8893            }
8894            return { start: start, end: end };
8895        };
8896        return DayGridDateProfileGenerator;
8897    }(core.DateProfileGenerator));
8898
8899    /* A rectangular panel that is absolutely positioned over other content
8900    ------------------------------------------------------------------------------------------------------------------------
8901    Options:
8902      - className (string)
8903      - content (HTML string, element, or element array)
8904      - parentEl
8905      - top
8906      - left
8907      - right (the x coord of where the right edge should be. not a "CSS" right)
8908      - autoHide (boolean)
8909      - show (callback)
8910      - hide (callback)
8911    */
8912    var Popover = /** @class */ (function () {
8913        function Popover(options) {
8914            var _this = this;
8915            this.isHidden = true;
8916            this.margin = 10; // the space required between the popover and the edges of the scroll container
8917            // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
8918            this.documentMousedown = function (ev) {
8919                // only hide the popover if the click happened outside the popover
8920                if (_this.el && !_this.el.contains(ev.target)) {
8921                    _this.hide();
8922                }
8923            };
8924            this.options = options;
8925        }
8926        // Shows the popover on the specified position. Renders it if not already
8927        Popover.prototype.show = function () {
8928            if (this.isHidden) {
8929                if (!this.el) {
8930                    this.render();
8931                }
8932                this.el.style.display = '';
8933                this.position();
8934                this.isHidden = false;
8935                this.trigger('show');
8936            }
8937        };
8938        // Hides the popover, through CSS, but does not remove it from the DOM
8939        Popover.prototype.hide = function () {
8940            if (!this.isHidden) {
8941                this.el.style.display = 'none';
8942                this.isHidden = true;
8943                this.trigger('hide');
8944            }
8945        };
8946        // Creates `this.el` and renders content inside of it
8947        Popover.prototype.render = function () {
8948            var _this = this;
8949            var options = this.options;
8950            var el = this.el = core.createElement('div', {
8951                className: 'fc-popover ' + (options.className || ''),
8952                style: {
8953                    top: '0',
8954                    left: '0'
8955                }
8956            });
8957            if (typeof options.content === 'function') {
8958                options.content(el);
8959            }
8960            options.parentEl.appendChild(el);
8961            // when a click happens on anything inside with a 'fc-close' className, hide the popover
8962            core.listenBySelector(el, 'click', '.fc-close', function (ev) {
8963                _this.hide();
8964            });
8965            if (options.autoHide) {
8966                document.addEventListener('mousedown', this.documentMousedown);
8967            }
8968        };
8969        // Hides and unregisters any handlers
8970        Popover.prototype.destroy = function () {
8971            this.hide();
8972            if (this.el) {
8973                core.removeElement(this.el);
8974                this.el = null;
8975            }
8976            document.removeEventListener('mousedown', this.documentMousedown);
8977        };
8978        // Positions the popover optimally, using the top/left/right options
8979        Popover.prototype.position = function () {
8980            var options = this.options;
8981            var el = this.el;
8982            var elDims = el.getBoundingClientRect(); // only used for width,height
8983            var origin = core.computeRect(el.offsetParent);
8984            var clippingRect = core.computeClippingRect(options.parentEl);
8985            var top; // the "position" (not "offset") values for the popover
8986            var left; //
8987            // compute top and left
8988            top = options.top || 0;
8989            if (options.left !== undefined) {
8990                left = options.left;
8991            }
8992            else if (options.right !== undefined) {
8993                left = options.right - elDims.width; // derive the left value from the right value
8994            }
8995            else {
8996                left = 0;
8997            }
8998            // constrain to the view port. if constrained by two edges, give precedence to top/left
8999            top = Math.min(top, clippingRect.bottom - elDims.height - this.margin);
9000            top = Math.max(top, clippingRect.top + this.margin);
9001            left = Math.min(left, clippingRect.right - elDims.width - this.margin);
9002            left = Math.max(left, clippingRect.left + this.margin);
9003            core.applyStyle(el, {
9004                top: top - origin.top,
9005                left: left - origin.left
9006            });
9007        };
9008        // Triggers a callback. Calls a function in the option hash of the same name.
9009        // Arguments beyond the first `name` are forwarded on.
9010        // TODO: better code reuse for this. Repeat code
9011        // can kill this???
9012        Popover.prototype.trigger = function (name) {
9013            if (this.options[name]) {
9014                this.options[name].apply(this, Array.prototype.slice.call(arguments, 1));
9015            }
9016        };
9017        return Popover;
9018    }());
9019
9020    /* Event-rendering methods for the DayGrid class
9021    ----------------------------------------------------------------------------------------------------------------------*/
9022    // "Simple" is bad a name. has nothing to do with SimpleDayGrid
9023    var SimpleDayGridEventRenderer = /** @class */ (function (_super) {
9024        __extends(SimpleDayGridEventRenderer, _super);
9025        function SimpleDayGridEventRenderer() {
9026            return _super !== null && _super.apply(this, arguments) || this;
9027        }
9028        // Builds the HTML to be used for the default element for an individual segment
9029        SimpleDayGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) {
9030            var _a = this.context, view = _a.view, options = _a.options;
9031            var eventRange = seg.eventRange;
9032            var eventDef = eventRange.def;
9033            var eventUi = eventRange.ui;
9034            var allDay = eventDef.allDay;
9035            var isDraggable = view.computeEventDraggable(eventDef, eventUi);
9036            var isResizableFromStart = allDay && seg.isStart && view.computeEventStartResizable(eventDef, eventUi);
9037            var isResizableFromEnd = allDay && seg.isEnd && view.computeEventEndResizable(eventDef, eventUi);
9038            var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo);
9039            var skinCss = core.cssToStr(this.getSkinCss(eventUi));
9040            var timeHtml = '';
9041            var timeText;
9042            var titleHtml;
9043            classes.unshift('fc-day-grid-event', 'fc-h-event');
9044            // Only display a timed events time if it is the starting segment
9045            if (seg.isStart) {
9046                timeText = this.getTimeText(eventRange);
9047                if (timeText) {
9048                    timeHtml = '<span class="fc-time">' + core.htmlEscape(timeText) + '</span>';
9049                }
9050            }
9051            titleHtml =
9052                '<span class="fc-title">' +
9053                    (core.htmlEscape(eventDef.title || '') || '&nbsp;') + // we always want one line of height
9054                    '</span>';
9055            return '<a class="' + classes.join(' ') + '"' +
9056                (eventDef.url ?
9057                    ' href="' + core.htmlEscape(eventDef.url) + '"' :
9058                    '') +
9059                (skinCss ?
9060                    ' style="' + skinCss + '"' :
9061                    '') +
9062                '>' +
9063                '<div class="fc-content">' +
9064                (options.dir === 'rtl' ?
9065                    titleHtml + ' ' + timeHtml : // put a natural space in between
9066                    timeHtml + ' ' + titleHtml //
9067                ) +
9068                '</div>' +
9069                (isResizableFromStart ?
9070                    '<div class="fc-resizer fc-start-resizer"></div>' :
9071                    '') +
9072                (isResizableFromEnd ?
9073                    '<div class="fc-resizer fc-end-resizer"></div>' :
9074                    '') +
9075                '</a>';
9076        };
9077        // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined
9078        SimpleDayGridEventRenderer.prototype.computeEventTimeFormat = function () {
9079            return {
9080                hour: 'numeric',
9081                minute: '2-digit',
9082                omitZeroMinute: true,
9083                meridiem: 'narrow'
9084            };
9085        };
9086        SimpleDayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
9087            return false; // TODO: somehow consider the originating DayGrid's column count
9088        };
9089        return SimpleDayGridEventRenderer;
9090    }(core.FgEventRenderer));
9091
9092    /* Event-rendering methods for the DayGrid class
9093    ----------------------------------------------------------------------------------------------------------------------*/
9094    var DayGridEventRenderer = /** @class */ (function (_super) {
9095        __extends(DayGridEventRenderer, _super);
9096        function DayGridEventRenderer(dayGrid) {
9097            var _this = _super.call(this, dayGrid.context) || this;
9098            _this.dayGrid = dayGrid;
9099            return _this;
9100        }
9101        // Renders the given foreground event segments onto the grid
9102        DayGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
9103            var rowStructs = this.rowStructs = this.renderSegRows(segs);
9104            // append to each row's content skeleton
9105            this.dayGrid.rowEls.forEach(function (rowNode, i) {
9106                rowNode.querySelector('.fc-content-skeleton > table').appendChild(rowStructs[i].tbodyEl);
9107            });
9108            // removes the "more.." events popover
9109            if (!mirrorInfo) {
9110                this.dayGrid.removeSegPopover();
9111            }
9112        };
9113        // Unrenders all currently rendered foreground event segments
9114        DayGridEventRenderer.prototype.detachSegs = function () {
9115            var rowStructs = this.rowStructs || [];
9116            var rowStruct;
9117            while ((rowStruct = rowStructs.pop())) {
9118                core.removeElement(rowStruct.tbodyEl);
9119            }
9120            this.rowStructs = null;
9121        };
9122        // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.
9123        // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
9124        // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
9125        DayGridEventRenderer.prototype.renderSegRows = function (segs) {
9126            var rowStructs = [];
9127            var segRows;
9128            var row;
9129            segRows = this.groupSegRows(segs); // group into nested arrays
9130            // iterate each row of segment groupings
9131            for (row = 0; row < segRows.length; row++) {
9132                rowStructs.push(this.renderSegRow(row, segRows[row]));
9133            }
9134            return rowStructs;
9135        };
9136        // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains
9137        // the segments. Returns object with a bunch of internal data about how the render was calculated.
9138        // NOTE: modifies rowSegs
9139        DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) {
9140            var dayGrid = this.dayGrid;
9141            var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl;
9142            var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels
9143            var levelCnt = Math.max(1, segLevels.length); // ensure at least one level
9144            var tbody = document.createElement('tbody');
9145            var segMatrix = []; // lookup for which segments are rendered into which level+col cells
9146            var cellMatrix = []; // lookup for all <td> elements of the level+col matrix
9147            var loneCellMatrix = []; // lookup for <td> elements that only take up a single column
9148            var i;
9149            var levelSegs;
9150            var col;
9151            var tr;
9152            var j;
9153            var seg;
9154            var td;
9155            // populates empty cells from the current column (`col`) to `endCol`
9156            function emptyCellsUntil(endCol) {
9157                while (col < endCol) {
9158                    // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell
9159                    td = (loneCellMatrix[i - 1] || [])[col];
9160                    if (td) {
9161                        td.rowSpan = (td.rowSpan || 1) + 1;
9162                    }
9163                    else {
9164                        td = document.createElement('td');
9165                        tr.appendChild(td);
9166                    }
9167                    cellMatrix[i][col] = td;
9168                    loneCellMatrix[i][col] = td;
9169                    col++;
9170                }
9171            }
9172            for (i = 0; i < levelCnt; i++) { // iterate through all levels
9173                levelSegs = segLevels[i];
9174                col = 0;
9175                tr = document.createElement('tr');
9176                segMatrix.push([]);
9177                cellMatrix.push([]);
9178                loneCellMatrix.push([]);
9179                // levelCnt might be 1 even though there are no actual levels. protect against this.
9180                // this single empty row is useful for styling.
9181                if (levelSegs) {
9182                    for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level
9183                        seg = levelSegs[j];
9184                        var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
9185                        var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
9186                        emptyCellsUntil(leftCol);
9187                        // create a container that occupies or more columns. append the event element.
9188                        td = core.createElement('td', { className: 'fc-event-container' }, seg.el);
9189                        if (leftCol !== rightCol) {
9190                            td.colSpan = rightCol - leftCol + 1;
9191                        }
9192                        else { // a single-column segment
9193                            loneCellMatrix[i][col] = td;
9194                        }
9195                        while (col <= rightCol) {
9196                            cellMatrix[i][col] = td;
9197                            segMatrix[i][col] = seg;
9198                            col++;
9199                        }
9200                        tr.appendChild(td);
9201                    }
9202                }
9203                emptyCellsUntil(colCnt); // finish off the row
9204                var introHtml = dayGrid.renderProps.renderIntroHtml();
9205                if (introHtml) {
9206                    if (dayGrid.isRtl) {
9207                        core.appendToElement(tr, introHtml);
9208                    }
9209                    else {
9210                        core.prependToElement(tr, introHtml);
9211                    }
9212                }
9213                tbody.appendChild(tr);
9214            }
9215            return {
9216                row: row,
9217                tbodyEl: tbody,
9218                cellMatrix: cellMatrix,
9219                segMatrix: segMatrix,
9220                segLevels: segLevels,
9221                segs: rowSegs
9222            };
9223        };
9224        // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
9225        // NOTE: modifies segs
9226        DayGridEventRenderer.prototype.buildSegLevels = function (segs) {
9227            var _a = this.dayGrid, isRtl = _a.isRtl, colCnt = _a.colCnt;
9228            var levels = [];
9229            var i;
9230            var seg;
9231            var j;
9232            // Give preference to elements with certain criteria, so they have
9233            // a chance to be closer to the top.
9234            segs = this.sortEventSegs(segs);
9235            for (i = 0; i < segs.length; i++) {
9236                seg = segs[i];
9237                // loop through levels, starting with the topmost, until the segment doesn't collide with other segments
9238                for (j = 0; j < levels.length; j++) {
9239                    if (!isDaySegCollision(seg, levels[j])) {
9240                        break;
9241                    }
9242                }
9243                // `j` now holds the desired subrow index
9244                seg.level = j;
9245                seg.leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol; // for sorting only
9246                seg.rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol // for sorting only
9247                ;
9248                (levels[j] || (levels[j] = [])).push(seg);
9249            }
9250            // order segments left-to-right. very important if calendar is RTL
9251            for (j = 0; j < levels.length; j++) {
9252                levels[j].sort(compareDaySegCols);
9253            }
9254            return levels;
9255        };
9256        // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
9257        DayGridEventRenderer.prototype.groupSegRows = function (segs) {
9258            var segRows = [];
9259            var i;
9260            for (i = 0; i < this.dayGrid.rowCnt; i++) {
9261                segRows.push([]);
9262            }
9263            for (i = 0; i < segs.length; i++) {
9264                segRows[segs[i].row].push(segs[i]);
9265            }
9266            return segRows;
9267        };
9268        // Computes a default `displayEventEnd` value if one is not expliclty defined
9269        DayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
9270            return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day
9271        };
9272        return DayGridEventRenderer;
9273    }(SimpleDayGridEventRenderer));
9274    // Computes whether two segments' columns collide. They are assumed to be in the same row.
9275    function isDaySegCollision(seg, otherSegs) {
9276        var i;
9277        var otherSeg;
9278        for (i = 0; i < otherSegs.length; i++) {
9279            otherSeg = otherSegs[i];
9280            if (otherSeg.firstCol <= seg.lastCol &&
9281                otherSeg.lastCol >= seg.firstCol) {
9282                return true;
9283            }
9284        }
9285        return false;
9286    }
9287    // A cmp function for determining the leftmost event
9288    function compareDaySegCols(a, b) {
9289        return a.leftCol - b.leftCol;
9290    }
9291
9292    var DayGridMirrorRenderer = /** @class */ (function (_super) {
9293        __extends(DayGridMirrorRenderer, _super);
9294        function DayGridMirrorRenderer() {
9295            return _super !== null && _super.apply(this, arguments) || this;
9296        }
9297        DayGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
9298            var sourceSeg = mirrorInfo.sourceSeg;
9299            var rowStructs = this.rowStructs = this.renderSegRows(segs);
9300            // inject each new event skeleton into each associated row
9301            this.dayGrid.rowEls.forEach(function (rowNode, row) {
9302                var skeletonEl = core.htmlToElement('<div class="fc-mirror-skeleton"><table></table></div>'); // will be absolutely positioned
9303                var skeletonTopEl;
9304                var skeletonTop;
9305                // If there is an original segment, match the top position. Otherwise, put it at the row's top level
9306                if (sourceSeg && sourceSeg.row === row) {
9307                    skeletonTopEl = sourceSeg.el;
9308                }
9309                else {
9310                    skeletonTopEl = rowNode.querySelector('.fc-content-skeleton tbody');
9311                    if (!skeletonTopEl) { // when no events
9312                        skeletonTopEl = rowNode.querySelector('.fc-content-skeleton table');
9313                    }
9314                }
9315                skeletonTop = skeletonTopEl.getBoundingClientRect().top -
9316                    rowNode.getBoundingClientRect().top; // the offsetParent origin
9317                skeletonEl.style.top = skeletonTop + 'px';
9318                skeletonEl.querySelector('table').appendChild(rowStructs[row].tbodyEl);
9319                rowNode.appendChild(skeletonEl);
9320            });
9321        };
9322        return DayGridMirrorRenderer;
9323    }(DayGridEventRenderer));
9324
9325    var EMPTY_CELL_HTML = '<td style="pointer-events:none"></td>';
9326    var DayGridFillRenderer = /** @class */ (function (_super) {
9327        __extends(DayGridFillRenderer, _super);
9328        function DayGridFillRenderer(dayGrid) {
9329            var _this = _super.call(this, dayGrid.context) || this;
9330            _this.fillSegTag = 'td'; // override the default tag name
9331            _this.dayGrid = dayGrid;
9332            return _this;
9333        }
9334        DayGridFillRenderer.prototype.renderSegs = function (type, segs) {
9335            // don't render timed background events
9336            if (type === 'bgEvent') {
9337                segs = segs.filter(function (seg) {
9338                    return seg.eventRange.def.allDay;
9339                });
9340            }
9341            _super.prototype.renderSegs.call(this, type, segs);
9342        };
9343        DayGridFillRenderer.prototype.attachSegs = function (type, segs) {
9344            var els = [];
9345            var i;
9346            var seg;
9347            var skeletonEl;
9348            for (i = 0; i < segs.length; i++) {
9349                seg = segs[i];
9350                skeletonEl = this.renderFillRow(type, seg);
9351                this.dayGrid.rowEls[seg.row].appendChild(skeletonEl);
9352                els.push(skeletonEl);
9353            }
9354            return els;
9355        };
9356        // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
9357        DayGridFillRenderer.prototype.renderFillRow = function (type, seg) {
9358            var dayGrid = this.dayGrid;
9359            var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl;
9360            var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
9361            var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
9362            var startCol = leftCol;
9363            var endCol = rightCol + 1;
9364            var className;
9365            var skeletonEl;
9366            var trEl;
9367            if (type === 'businessHours') {
9368                className = 'bgevent';
9369            }
9370            else {
9371                className = type.toLowerCase();
9372            }
9373            skeletonEl = core.htmlToElement('<div class="fc-' + className + '-skeleton">' +
9374                '<table><tr></tr></table>' +
9375                '</div>');
9376            trEl = skeletonEl.getElementsByTagName('tr')[0];
9377            if (startCol > 0) {
9378                core.appendToElement(trEl, 
9379                // will create (startCol + 1) td's
9380                new Array(startCol + 1).join(EMPTY_CELL_HTML));
9381            }
9382            seg.el.colSpan = endCol - startCol;
9383            trEl.appendChild(seg.el);
9384            if (endCol < colCnt) {
9385                core.appendToElement(trEl, 
9386                // will create (colCnt - endCol) td's
9387                new Array(colCnt - endCol + 1).join(EMPTY_CELL_HTML));
9388            }
9389            var introHtml = dayGrid.renderProps.renderIntroHtml();
9390            if (introHtml) {
9391                if (dayGrid.isRtl) {
9392                    core.appendToElement(trEl, introHtml);
9393                }
9394                else {
9395                    core.prependToElement(trEl, introHtml);
9396                }
9397            }
9398            return skeletonEl;
9399        };
9400        return DayGridFillRenderer;
9401    }(core.FillRenderer));
9402
9403    var DayTile = /** @class */ (function (_super) {
9404        __extends(DayTile, _super);
9405        function DayTile(context, el) {
9406            var _this = _super.call(this, context, el) || this;
9407            var eventRenderer = _this.eventRenderer = new DayTileEventRenderer(_this);
9408            var renderFrame = _this.renderFrame = core.memoizeRendering(_this._renderFrame);
9409            _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderFrame]);
9410            _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
9411            _this.renderEventDrag = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]);
9412            _this.renderEventResize = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]);
9413            context.calendar.registerInteractiveComponent(_this, {
9414                el: _this.el,
9415                useEventCenter: false
9416            });
9417            return _this;
9418        }
9419        DayTile.prototype.render = function (props) {
9420            this.renderFrame(props.date);
9421            this.renderFgEvents(props.fgSegs);
9422            this.renderEventSelection(props.eventSelection);
9423            this.renderEventDrag(props.eventDragInstances);
9424            this.renderEventResize(props.eventResizeInstances);
9425        };
9426        DayTile.prototype.destroy = function () {
9427            _super.prototype.destroy.call(this);
9428            this.renderFrame.unrender(); // should unrender everything else
9429            this.calendar.unregisterInteractiveComponent(this);
9430        };
9431        DayTile.prototype._renderFrame = function (date) {
9432            var _a = this, theme = _a.theme, dateEnv = _a.dateEnv;
9433            var title = dateEnv.format(date, core.createFormatter(this.opt('dayPopoverFormat')) // TODO: cache
9434            );
9435            this.el.innerHTML =
9436                '<div class="fc-header ' + theme.getClass('popoverHeader') + '">' +
9437                    '<span class="fc-title">' +
9438                    core.htmlEscape(title) +
9439                    '</span>' +
9440                    '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' +
9441                    '</div>' +
9442                    '<div class="fc-body ' + theme.getClass('popoverContent') + '">' +
9443                    '<div class="fc-event-container"></div>' +
9444                    '</div>';
9445            this.segContainerEl = this.el.querySelector('.fc-event-container');
9446        };
9447        DayTile.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
9448            var date = this.props.date; // HACK
9449            if (positionLeft < elWidth && positionTop < elHeight) {
9450                return {
9451                    component: this,
9452                    dateSpan: {
9453                        allDay: true,
9454                        range: { start: date, end: core.addDays(date, 1) }
9455                    },
9456                    dayEl: this.el,
9457                    rect: {
9458                        left: 0,
9459                        top: 0,
9460                        right: elWidth,
9461                        bottom: elHeight
9462                    },
9463                    layer: 1
9464                };
9465            }
9466        };
9467        return DayTile;
9468    }(core.DateComponent));
9469    var DayTileEventRenderer = /** @class */ (function (_super) {
9470        __extends(DayTileEventRenderer, _super);
9471        function DayTileEventRenderer(dayTile) {
9472            var _this = _super.call(this, dayTile.context) || this;
9473            _this.dayTile = dayTile;
9474            return _this;
9475        }
9476        DayTileEventRenderer.prototype.attachSegs = function (segs) {
9477            for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
9478                var seg = segs_1[_i];
9479                this.dayTile.segContainerEl.appendChild(seg.el);
9480            }
9481        };
9482        DayTileEventRenderer.prototype.detachSegs = function (segs) {
9483            for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
9484                var seg = segs_2[_i];
9485                core.removeElement(seg.el);
9486            }
9487        };
9488        return DayTileEventRenderer;
9489    }(SimpleDayGridEventRenderer));
9490
9491    var DayBgRow = /** @class */ (function () {
9492        function DayBgRow(context) {
9493            this.context = context;
9494        }
9495        DayBgRow.prototype.renderHtml = function (props) {
9496            var parts = [];
9497            if (props.renderIntroHtml) {
9498                parts.push(props.renderIntroHtml());
9499            }
9500            for (var _i = 0, _a = props.cells; _i < _a.length; _i++) {
9501                var cell = _a[_i];
9502                parts.push(renderCellHtml(cell.date, props.dateProfile, this.context, cell.htmlAttrs));
9503            }
9504            if (!props.cells.length) {
9505                parts.push('<td class="fc-day ' + this.context.theme.getClass('widgetContent') + '"></td>');
9506            }
9507            if (this.context.options.dir === 'rtl') {
9508                parts.reverse();
9509            }
9510            return '<tr>' + parts.join('') + '</tr>';
9511        };
9512        return DayBgRow;
9513    }());
9514    function renderCellHtml(date, dateProfile, context, otherAttrs) {
9515        var dateEnv = context.dateEnv, theme = context.theme;
9516        var isDateValid = core.rangeContainsMarker(dateProfile.activeRange, date); // TODO: called too frequently. cache somehow.
9517        var classes = core.getDayClasses(date, dateProfile, context);
9518        classes.unshift('fc-day', theme.getClass('widgetContent'));
9519        return '<td class="' + classes.join(' ') + '"' +
9520            (isDateValid ?
9521                ' data-date="' + dateEnv.formatIso(date, { omitTime: true }) + '"' :
9522                '') +
9523            (otherAttrs ?
9524                ' ' + otherAttrs :
9525                '') +
9526            '></td>';
9527    }
9528
9529    var DAY_NUM_FORMAT = core.createFormatter({ day: 'numeric' });
9530    var WEEK_NUM_FORMAT = core.createFormatter({ week: 'numeric' });
9531    var DayGrid = /** @class */ (function (_super) {
9532        __extends(DayGrid, _super);
9533        function DayGrid(context, el, renderProps) {
9534            var _this = _super.call(this, context, el) || this;
9535            _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid
9536            _this.isCellSizesDirty = false;
9537            var eventRenderer = _this.eventRenderer = new DayGridEventRenderer(_this);
9538            var fillRenderer = _this.fillRenderer = new DayGridFillRenderer(_this);
9539            _this.mirrorRenderer = new DayGridMirrorRenderer(_this);
9540            var renderCells = _this.renderCells = core.memoizeRendering(_this._renderCells, _this._unrenderCells);
9541            _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderCells]);
9542            _this.renderDateSelection = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'highlight'), fillRenderer.unrender.bind(fillRenderer, 'highlight'), [renderCells]);
9543            _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderCells]);
9544            _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderCells]);
9545            _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
9546            _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderCells]);
9547            _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderCells]);
9548            _this.renderProps = renderProps;
9549            return _this;
9550        }
9551        DayGrid.prototype.render = function (props) {
9552            var cells = props.cells;
9553            this.rowCnt = cells.length;
9554            this.colCnt = cells[0].length;
9555            this.renderCells(cells, props.isRigid);
9556            this.renderBusinessHours(props.businessHourSegs);
9557            this.renderDateSelection(props.dateSelectionSegs);
9558            this.renderBgEvents(props.bgEventSegs);
9559            this.renderFgEvents(props.fgEventSegs);
9560            this.renderEventSelection(props.eventSelection);
9561            this.renderEventDrag(props.eventDrag);
9562            this.renderEventResize(props.eventResize);
9563            if (this.segPopoverTile) {
9564                this.updateSegPopoverTile();
9565            }
9566        };
9567        DayGrid.prototype.destroy = function () {
9568            _super.prototype.destroy.call(this);
9569            this.renderCells.unrender(); // will unrender everything else
9570        };
9571        DayGrid.prototype.getCellRange = function (row, col) {
9572            var start = this.props.cells[row][col].date;
9573            var end = core.addDays(start, 1);
9574            return { start: start, end: end };
9575        };
9576        DayGrid.prototype.updateSegPopoverTile = function (date, segs) {
9577            var ownProps = this.props;
9578            this.segPopoverTile.receiveProps({
9579                date: date || this.segPopoverTile.props.date,
9580                fgSegs: segs || this.segPopoverTile.props.fgSegs,
9581                eventSelection: ownProps.eventSelection,
9582                eventDragInstances: ownProps.eventDrag ? ownProps.eventDrag.affectedInstances : null,
9583                eventResizeInstances: ownProps.eventResize ? ownProps.eventResize.affectedInstances : null
9584            });
9585        };
9586        /* Date Rendering
9587        ------------------------------------------------------------------------------------------------------------------*/
9588        DayGrid.prototype._renderCells = function (cells, isRigid) {
9589            var _a = this, view = _a.view, dateEnv = _a.dateEnv;
9590            var _b = this, rowCnt = _b.rowCnt, colCnt = _b.colCnt;
9591            var html = '';
9592            var row;
9593            var col;
9594            for (row = 0; row < rowCnt; row++) {
9595                html += this.renderDayRowHtml(row, isRigid);
9596            }
9597            this.el.innerHTML = html;
9598            this.rowEls = core.findElements(this.el, '.fc-row');
9599            this.cellEls = core.findElements(this.el, '.fc-day, .fc-disabled-day');
9600            if (this.isRtl) {
9601                this.cellEls.reverse();
9602            }
9603            this.rowPositions = new core.PositionCache(this.el, this.rowEls, false, true // vertical
9604            );
9605            this.colPositions = new core.PositionCache(this.el, this.cellEls.slice(0, colCnt), // only the first row
9606            true, false // horizontal
9607            );
9608            // trigger dayRender with each cell's element
9609            for (row = 0; row < rowCnt; row++) {
9610                for (col = 0; col < colCnt; col++) {
9611                    this.publiclyTrigger('dayRender', [
9612                        {
9613                            date: dateEnv.toDate(cells[row][col].date),
9614                            el: this.getCellEl(row, col),
9615                            view: view
9616                        }
9617                    ]);
9618                }
9619            }
9620            this.isCellSizesDirty = true;
9621        };
9622        DayGrid.prototype._unrenderCells = function () {
9623            this.removeSegPopover();
9624        };
9625        // Generates the HTML for a single row, which is a div that wraps a table.
9626        // `row` is the row number.
9627        DayGrid.prototype.renderDayRowHtml = function (row, isRigid) {
9628            var theme = this.theme;
9629            var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')];
9630            if (isRigid) {
9631                classes.push('fc-rigid');
9632            }
9633            var bgRow = new DayBgRow(this.context);
9634            return '' +
9635                '<div class="' + classes.join(' ') + '">' +
9636                '<div class="fc-bg">' +
9637                '<table class="' + theme.getClass('tableGrid') + '">' +
9638                bgRow.renderHtml({
9639                    cells: this.props.cells[row],
9640                    dateProfile: this.props.dateProfile,
9641                    renderIntroHtml: this.renderProps.renderBgIntroHtml
9642                }) +
9643                '</table>' +
9644                '</div>' +
9645                '<div class="fc-content-skeleton">' +
9646                '<table>' +
9647                (this.getIsNumbersVisible() ?
9648                    '<thead>' +
9649                        this.renderNumberTrHtml(row) +
9650                        '</thead>' :
9651                    '') +
9652                '</table>' +
9653                '</div>' +
9654                '</div>';
9655        };
9656        DayGrid.prototype.getIsNumbersVisible = function () {
9657            return this.getIsDayNumbersVisible() ||
9658                this.renderProps.cellWeekNumbersVisible ||
9659                this.renderProps.colWeekNumbersVisible;
9660        };
9661        DayGrid.prototype.getIsDayNumbersVisible = function () {
9662            return this.rowCnt > 1;
9663        };
9664        /* Grid Number Rendering
9665        ------------------------------------------------------------------------------------------------------------------*/
9666        DayGrid.prototype.renderNumberTrHtml = function (row) {
9667            var intro = this.renderProps.renderNumberIntroHtml(row, this);
9668            return '' +
9669                '<tr>' +
9670                (this.isRtl ? '' : intro) +
9671                this.renderNumberCellsHtml(row) +
9672                (this.isRtl ? intro : '') +
9673                '</tr>';
9674        };
9675        DayGrid.prototype.renderNumberCellsHtml = function (row) {
9676            var htmls = [];
9677            var col;
9678            var date;
9679            for (col = 0; col < this.colCnt; col++) {
9680                date = this.props.cells[row][col].date;
9681                htmls.push(this.renderNumberCellHtml(date));
9682            }
9683            if (this.isRtl) {
9684                htmls.reverse();
9685            }
9686            return htmls.join('');
9687        };
9688        // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
9689        // The number row will only exist if either day numbers or week numbers are turned on.
9690        DayGrid.prototype.renderNumberCellHtml = function (date) {
9691            var _a = this, view = _a.view, dateEnv = _a.dateEnv;
9692            var html = '';
9693            var isDateValid = core.rangeContainsMarker(this.props.dateProfile.activeRange, date); // TODO: called too frequently. cache somehow.
9694            var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid;
9695            var classes;
9696            var weekCalcFirstDow;
9697            if (!isDayNumberVisible && !this.renderProps.cellWeekNumbersVisible) {
9698                // no numbers in day cell (week number must be along the side)
9699                return '<td></td>'; //  will create an empty space above events :(
9700            }
9701            classes = core.getDayClasses(date, this.props.dateProfile, this.context);
9702            classes.unshift('fc-day-top');
9703            if (this.renderProps.cellWeekNumbersVisible) {
9704                weekCalcFirstDow = dateEnv.weekDow;
9705            }
9706            html += '<td class="' + classes.join(' ') + '"' +
9707                (isDateValid ?
9708                    ' data-date="' + dateEnv.formatIso(date, { omitTime: true }) + '"' :
9709                    '') +
9710                '>';
9711            if (this.renderProps.cellWeekNumbersVisible && (date.getUTCDay() === weekCalcFirstDow)) {
9712                html += core.buildGotoAnchorHtml(view, { date: date, type: 'week' }, { 'class': 'fc-week-number' }, dateEnv.format(date, WEEK_NUM_FORMAT) // inner HTML
9713                );
9714            }
9715            if (isDayNumberVisible) {
9716                html += core.buildGotoAnchorHtml(view, date, { 'class': 'fc-day-number' }, dateEnv.format(date, DAY_NUM_FORMAT) // inner HTML
9717                );
9718            }
9719            html += '</td>';
9720            return html;
9721        };
9722        /* Sizing
9723        ------------------------------------------------------------------------------------------------------------------*/
9724        DayGrid.prototype.updateSize = function (isResize) {
9725            var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer;
9726            if (isResize ||
9727                this.isCellSizesDirty ||
9728                this.view.calendar.isEventsUpdated // hack
9729            ) {
9730                this.buildPositionCaches();
9731                this.isCellSizesDirty = false;
9732            }
9733            fillRenderer.computeSizes(isResize);
9734            eventRenderer.computeSizes(isResize);
9735            mirrorRenderer.computeSizes(isResize);
9736            fillRenderer.assignSizes(isResize);
9737            eventRenderer.assignSizes(isResize);
9738            mirrorRenderer.assignSizes(isResize);
9739        };
9740        DayGrid.prototype.buildPositionCaches = function () {
9741            this.buildColPositions();
9742            this.buildRowPositions();
9743        };
9744        DayGrid.prototype.buildColPositions = function () {
9745            this.colPositions.build();
9746        };
9747        DayGrid.prototype.buildRowPositions = function () {
9748            this.rowPositions.build();
9749            this.rowPositions.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack
9750        };
9751        /* Hit System
9752        ------------------------------------------------------------------------------------------------------------------*/
9753        DayGrid.prototype.positionToHit = function (leftPosition, topPosition) {
9754            var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions;
9755            var col = colPositions.leftToIndex(leftPosition);
9756            var row = rowPositions.topToIndex(topPosition);
9757            if (row != null && col != null) {
9758                return {
9759                    row: row,
9760                    col: col,
9761                    dateSpan: {
9762                        range: this.getCellRange(row, col),
9763                        allDay: true
9764                    },
9765                    dayEl: this.getCellEl(row, col),
9766                    relativeRect: {
9767                        left: colPositions.lefts[col],
9768                        right: colPositions.rights[col],
9769                        top: rowPositions.tops[row],
9770                        bottom: rowPositions.bottoms[row]
9771                    }
9772                };
9773            }
9774        };
9775        /* Cell System
9776        ------------------------------------------------------------------------------------------------------------------*/
9777        // FYI: the first column is the leftmost column, regardless of date
9778        DayGrid.prototype.getCellEl = function (row, col) {
9779            return this.cellEls[row * this.colCnt + col];
9780        };
9781        /* Event Drag Visualization
9782        ------------------------------------------------------------------------------------------------------------------*/
9783        DayGrid.prototype._renderEventDrag = function (state) {
9784            if (state) {
9785                this.eventRenderer.hideByHash(state.affectedInstances);
9786                this.fillRenderer.renderSegs('highlight', state.segs);
9787            }
9788        };
9789        DayGrid.prototype._unrenderEventDrag = function (state) {
9790            if (state) {
9791                this.eventRenderer.showByHash(state.affectedInstances);
9792                this.fillRenderer.unrender('highlight');
9793            }
9794        };
9795        /* Event Resize Visualization
9796        ------------------------------------------------------------------------------------------------------------------*/
9797        DayGrid.prototype._renderEventResize = function (state) {
9798            if (state) {
9799                this.eventRenderer.hideByHash(state.affectedInstances);
9800                this.fillRenderer.renderSegs('highlight', state.segs);
9801                this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
9802            }
9803        };
9804        DayGrid.prototype._unrenderEventResize = function (state) {
9805            if (state) {
9806                this.eventRenderer.showByHash(state.affectedInstances);
9807                this.fillRenderer.unrender('highlight');
9808                this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
9809            }
9810        };
9811        /* More+ Link Popover
9812        ------------------------------------------------------------------------------------------------------------------*/
9813        DayGrid.prototype.removeSegPopover = function () {
9814            if (this.segPopover) {
9815                this.segPopover.hide(); // in handler, will call segPopover's removeElement
9816            }
9817        };
9818        // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid.
9819        // `levelLimit` can be false (don't limit), a number, or true (should be computed).
9820        DayGrid.prototype.limitRows = function (levelLimit) {
9821            var rowStructs = this.eventRenderer.rowStructs || [];
9822            var row; // row #
9823            var rowLevelLimit;
9824            for (row = 0; row < rowStructs.length; row++) {
9825                this.unlimitRow(row);
9826                if (!levelLimit) {
9827                    rowLevelLimit = false;
9828                }
9829                else if (typeof levelLimit === 'number') {
9830                    rowLevelLimit = levelLimit;
9831                }
9832                else {
9833                    rowLevelLimit = this.computeRowLevelLimit(row);
9834                }
9835                if (rowLevelLimit !== false) {
9836                    this.limitRow(row, rowLevelLimit);
9837                }
9838            }
9839        };
9840        // Computes the number of levels a row will accomodate without going outside its bounds.
9841        // Assumes the row is "rigid" (maintains a constant height regardless of what is inside).
9842        // `row` is the row number.
9843        DayGrid.prototype.computeRowLevelLimit = function (row) {
9844            var rowEl = this.rowEls[row]; // the containing "fake" row div
9845            var rowBottom = rowEl.getBoundingClientRect().bottom; // relative to viewport!
9846            var trEls = core.findChildren(this.eventRenderer.rowStructs[row].tbodyEl);
9847            var i;
9848            var trEl;
9849            // Reveal one level <tr> at a time and stop when we find one out of bounds
9850            for (i = 0; i < trEls.length; i++) {
9851                trEl = trEls[i];
9852                trEl.classList.remove('fc-limited'); // reset to original state (reveal)
9853                if (trEl.getBoundingClientRect().bottom > rowBottom) {
9854                    return i;
9855                }
9856            }
9857            return false; // should not limit at all
9858        };
9859        // Limits the given grid row to the maximum number of levels and injects "more" links if necessary.
9860        // `row` is the row number.
9861        // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
9862        DayGrid.prototype.limitRow = function (row, levelLimit) {
9863            var _this = this;
9864            var _a = this, colCnt = _a.colCnt, isRtl = _a.isRtl;
9865            var rowStruct = this.eventRenderer.rowStructs[row];
9866            var moreNodes = []; // array of "more" <a> links and <td> DOM nodes
9867            var col = 0; // col #, left-to-right (not chronologically)
9868            var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right
9869            var cellMatrix; // a matrix (by level, then column) of all <td> elements in the row
9870            var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes
9871            var i;
9872            var seg;
9873            var segsBelow; // array of segment objects below `seg` in the current `col`
9874            var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies
9875            var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)
9876            var td;
9877            var rowSpan;
9878            var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell
9879            var j;
9880            var moreTd;
9881            var moreWrap;
9882            var moreLink;
9883            // Iterates through empty level cells and places "more" links inside if need be
9884            var emptyCellsUntil = function (endCol) {
9885                while (col < endCol) {
9886                    segsBelow = _this.getCellSegs(row, col, levelLimit);
9887                    if (segsBelow.length) {
9888                        td = cellMatrix[levelLimit - 1][col];
9889                        moreLink = _this.renderMoreLink(row, col, segsBelow);
9890                        moreWrap = core.createElement('div', null, moreLink);
9891                        td.appendChild(moreWrap);
9892                        moreNodes.push(moreWrap);
9893                    }
9894                    col++;
9895                }
9896            };
9897            if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?
9898                levelSegs = rowStruct.segLevels[levelLimit - 1];
9899                cellMatrix = rowStruct.cellMatrix;
9900                limitedNodes = core.findChildren(rowStruct.tbodyEl).slice(levelLimit); // get level <tr> elements past the limit
9901                limitedNodes.forEach(function (node) {
9902                    node.classList.add('fc-limited'); // hide elements and get a simple DOM-nodes array
9903                });
9904                // iterate though segments in the last allowable level
9905                for (i = 0; i < levelSegs.length; i++) {
9906                    seg = levelSegs[i];
9907                    var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
9908                    var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
9909                    emptyCellsUntil(leftCol); // process empty cells before the segment
9910                    // determine *all* segments below `seg` that occupy the same columns
9911                    colSegsBelow = [];
9912                    totalSegsBelow = 0;
9913                    while (col <= rightCol) {
9914                        segsBelow = this.getCellSegs(row, col, levelLimit);
9915                        colSegsBelow.push(segsBelow);
9916                        totalSegsBelow += segsBelow.length;
9917                        col++;
9918                    }
9919                    if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links?
9920                        td = cellMatrix[levelLimit - 1][leftCol]; // the segment's parent cell
9921                        rowSpan = td.rowSpan || 1;
9922                        segMoreNodes = [];
9923                        // make a replacement <td> for each column the segment occupies. will be one for each colspan
9924                        for (j = 0; j < colSegsBelow.length; j++) {
9925                            moreTd = core.createElement('td', { className: 'fc-more-cell', rowSpan: rowSpan });
9926                            segsBelow = colSegsBelow[j];
9927                            moreLink = this.renderMoreLink(row, leftCol + j, [seg].concat(segsBelow) // count seg as hidden too
9928                            );
9929                            moreWrap = core.createElement('div', null, moreLink);
9930                            moreTd.appendChild(moreWrap);
9931                            segMoreNodes.push(moreTd);
9932                            moreNodes.push(moreTd);
9933                        }
9934                        td.classList.add('fc-limited');
9935                        core.insertAfterElement(td, segMoreNodes);
9936                        limitedNodes.push(td);
9937                    }
9938                }
9939                emptyCellsUntil(this.colCnt); // finish off the level
9940                rowStruct.moreEls = moreNodes; // for easy undoing later
9941                rowStruct.limitedEls = limitedNodes; // for easy undoing later
9942            }
9943        };
9944        // Reveals all levels and removes all "more"-related elements for a grid's row.
9945        // `row` is a row number.
9946        DayGrid.prototype.unlimitRow = function (row) {
9947            var rowStruct = this.eventRenderer.rowStructs[row];
9948            if (rowStruct.moreEls) {
9949                rowStruct.moreEls.forEach(core.removeElement);
9950                rowStruct.moreEls = null;
9951            }
9952            if (rowStruct.limitedEls) {
9953                rowStruct.limitedEls.forEach(function (limitedEl) {
9954                    limitedEl.classList.remove('fc-limited');
9955                });
9956                rowStruct.limitedEls = null;
9957            }
9958        };
9959        // Renders an <a> element that represents hidden event element for a cell.
9960        // Responsible for attaching click handler as well.
9961        DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) {
9962            var _this = this;
9963            var _a = this, view = _a.view, dateEnv = _a.dateEnv;
9964            var a = core.createElement('a', { className: 'fc-more' });
9965            a.innerText = this.getMoreLinkText(hiddenSegs.length);
9966            a.addEventListener('click', function (ev) {
9967                var clickOption = _this.opt('eventLimitClick');
9968                var _col = _this.isRtl ? _this.colCnt - col - 1 : col; // HACK: props.cells has different dir system?
9969                var date = _this.props.cells[row][_col].date;
9970                var moreEl = ev.currentTarget;
9971                var dayEl = _this.getCellEl(row, col);
9972                var allSegs = _this.getCellSegs(row, col);
9973                // rescope the segments to be within the cell's date
9974                var reslicedAllSegs = _this.resliceDaySegs(allSegs, date);
9975                var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);
9976                if (typeof clickOption === 'function') {
9977                    // the returned value can be an atomic option
9978                    clickOption = _this.publiclyTrigger('eventLimitClick', [
9979                        {
9980                            date: dateEnv.toDate(date),
9981                            allDay: true,
9982                            dayEl: dayEl,
9983                            moreEl: moreEl,
9984                            segs: reslicedAllSegs,
9985                            hiddenSegs: reslicedHiddenSegs,
9986                            jsEvent: ev,
9987                            view: view
9988                        }
9989                    ]);
9990                }
9991                if (clickOption === 'popover') {
9992                    _this.showSegPopover(row, col, moreEl, reslicedAllSegs);
9993                }
9994                else if (typeof clickOption === 'string') { // a view name
9995                    view.calendar.zoomTo(date, clickOption);
9996                }
9997            });
9998            return a;
9999        };
10000        // Reveals the popover that displays all events within a cell
10001        DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) {
10002            var _this = this;
10003            var _a = this, calendar = _a.calendar, view = _a.view, theme = _a.theme;
10004            var _col = this.isRtl ? this.colCnt - col - 1 : col; // HACK: props.cells has different dir system?
10005            var moreWrap = moreLink.parentNode; // the <div> wrapper around the <a>
10006            var topEl; // the element we want to match the top coordinate of
10007            var options;
10008            if (this.rowCnt === 1) {
10009                topEl = view.el; // will cause the popover to cover any sort of header
10010            }
10011            else {
10012                topEl = this.rowEls[row]; // will align with top of row
10013            }
10014            options = {
10015                className: 'fc-more-popover ' + theme.getClass('popover'),
10016                parentEl: view.el,
10017                top: core.computeRect(topEl).top,
10018                autoHide: true,
10019                content: function (el) {
10020                    _this.segPopoverTile = new DayTile(_this.context, el);
10021                    _this.updateSegPopoverTile(_this.props.cells[row][_col].date, segs);
10022                },
10023                hide: function () {
10024                    _this.segPopoverTile.destroy();
10025                    _this.segPopoverTile = null;
10026                    _this.segPopover.destroy();
10027                    _this.segPopover = null;
10028                }
10029            };
10030            // Determine horizontal coordinate.
10031            // We use the moreWrap instead of the <td> to avoid border confusion.
10032            if (this.isRtl) {
10033                options.right = core.computeRect(moreWrap).right + 1; // +1 to be over cell border
10034            }
10035            else {
10036                options.left = core.computeRect(moreWrap).left - 1; // -1 to be over cell border
10037            }
10038            this.segPopover = new Popover(options);
10039            this.segPopover.show();
10040            calendar.releaseAfterSizingTriggers(); // hack for eventPositioned
10041        };
10042        // Given the events within an array of segment objects, reslice them to be in a single day
10043        DayGrid.prototype.resliceDaySegs = function (segs, dayDate) {
10044            var dayStart = dayDate;
10045            var dayEnd = core.addDays(dayStart, 1);
10046            var dayRange = { start: dayStart, end: dayEnd };
10047            var newSegs = [];
10048            for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
10049                var seg = segs_1[_i];
10050                var eventRange = seg.eventRange;
10051                var origRange = eventRange.range;
10052                var slicedRange = core.intersectRanges(origRange, dayRange);
10053                if (slicedRange) {
10054                    newSegs.push(__assign({}, seg, { eventRange: {
10055                            def: eventRange.def,
10056                            ui: __assign({}, eventRange.ui, { durationEditable: false }),
10057                            instance: eventRange.instance,
10058                            range: slicedRange
10059                        }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }));
10060                }
10061            }
10062            return newSegs;
10063        };
10064        // Generates the text that should be inside a "more" link, given the number of events it represents
10065        DayGrid.prototype.getMoreLinkText = function (num) {
10066            var opt = this.opt('eventLimitText');
10067            if (typeof opt === 'function') {
10068                return opt(num);
10069            }
10070            else {
10071                return '+' + num + ' ' + opt;
10072            }
10073        };
10074        // Returns segments within a given cell.
10075        // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.
10076        DayGrid.prototype.getCellSegs = function (row, col, startLevel) {
10077            var segMatrix = this.eventRenderer.rowStructs[row].segMatrix;
10078            var level = startLevel || 0;
10079            var segs = [];
10080            var seg;
10081            while (level < segMatrix.length) {
10082                seg = segMatrix[level][col];
10083                if (seg) {
10084                    segs.push(seg);
10085                }
10086                level++;
10087            }
10088            return segs;
10089        };
10090        return DayGrid;
10091    }(core.DateComponent));
10092
10093    var WEEK_NUM_FORMAT$1 = core.createFormatter({ week: 'numeric' });
10094    /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
10095    ----------------------------------------------------------------------------------------------------------------------*/
10096    // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
10097    // It is responsible for managing width/height.
10098    var DayGridView = /** @class */ (function (_super) {
10099        __extends(DayGridView, _super);
10100        function DayGridView(context, viewSpec, dateProfileGenerator, parentEl) {
10101            var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
10102            /* Header Rendering
10103            ------------------------------------------------------------------------------------------------------------------*/
10104            // Generates the HTML that will go before the day-of week header cells
10105            _this.renderHeadIntroHtml = function () {
10106                var theme = _this.theme;
10107                if (_this.colWeekNumbersVisible) {
10108                    return '' +
10109                        '<th class="fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.weekNumberStyleAttr() + '>' +
10110                        '<span>' + // needed for matchCellWidths
10111                        core.htmlEscape(_this.opt('weekLabel')) +
10112                        '</span>' +
10113                        '</th>';
10114                }
10115                return '';
10116            };
10117            /* Day Grid Rendering
10118            ------------------------------------------------------------------------------------------------------------------*/
10119            // Generates the HTML that will go before content-skeleton cells that display the day/week numbers
10120            _this.renderDayGridNumberIntroHtml = function (row, dayGrid) {
10121                var dateEnv = _this.dateEnv;
10122                var weekStart = dayGrid.props.cells[row][0].date;
10123                if (_this.colWeekNumbersVisible) {
10124                    return '' +
10125                        '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '>' +
10126                        core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
10127                        _this, { date: weekStart, type: 'week', forceOff: dayGrid.colCnt === 1 }, dateEnv.format(weekStart, WEEK_NUM_FORMAT$1) // inner HTML
10128                        ) +
10129                        '</td>';
10130                }
10131                return '';
10132            };
10133            // Generates the HTML that goes before the day bg cells for each day-row
10134            _this.renderDayGridBgIntroHtml = function () {
10135                var theme = _this.theme;
10136                if (_this.colWeekNumbersVisible) {
10137                    return '<td class="fc-week-number ' + theme.getClass('widgetContent') + '" ' + _this.weekNumberStyleAttr() + '></td>';
10138                }
10139                return '';
10140            };
10141            // Generates the HTML that goes before every other type of row generated by DayGrid.
10142            // Affects mirror-skeleton and highlight-skeleton rows.
10143            _this.renderDayGridIntroHtml = function () {
10144                if (_this.colWeekNumbersVisible) {
10145                    return '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '></td>';
10146                }
10147                return '';
10148            };
10149            _this.el.classList.add('fc-dayGrid-view');
10150            _this.el.innerHTML = _this.renderSkeletonHtml();
10151            _this.scroller = new core.ScrollComponent('hidden', // overflow x
10152            'auto' // overflow y
10153            );
10154            var dayGridContainerEl = _this.scroller.el;
10155            _this.el.querySelector('.fc-body > tr > td').appendChild(dayGridContainerEl);
10156            dayGridContainerEl.classList.add('fc-day-grid-container');
10157            var dayGridEl = core.createElement('div', { className: 'fc-day-grid' });
10158            dayGridContainerEl.appendChild(dayGridEl);
10159            var cellWeekNumbersVisible;
10160            if (_this.opt('weekNumbers')) {
10161                if (_this.opt('weekNumbersWithinDays')) {
10162                    cellWeekNumbersVisible = true;
10163                    _this.colWeekNumbersVisible = false;
10164                }
10165                else {
10166                    cellWeekNumbersVisible = false;
10167                    _this.colWeekNumbersVisible = true;
10168                }
10169            }
10170            else {
10171                _this.colWeekNumbersVisible = false;
10172                cellWeekNumbersVisible = false;
10173            }
10174            _this.dayGrid = new DayGrid(_this.context, dayGridEl, {
10175                renderNumberIntroHtml: _this.renderDayGridNumberIntroHtml,
10176                renderBgIntroHtml: _this.renderDayGridBgIntroHtml,
10177                renderIntroHtml: _this.renderDayGridIntroHtml,
10178                colWeekNumbersVisible: _this.colWeekNumbersVisible,
10179                cellWeekNumbersVisible: cellWeekNumbersVisible
10180            });
10181            return _this;
10182        }
10183        DayGridView.prototype.destroy = function () {
10184            _super.prototype.destroy.call(this);
10185            this.dayGrid.destroy();
10186            this.scroller.destroy();
10187        };
10188        // Builds the HTML skeleton for the view.
10189        // The day-grid component will render inside of a container defined by this HTML.
10190        DayGridView.prototype.renderSkeletonHtml = function () {
10191            var theme = this.theme;
10192            return '' +
10193                '<table class="' + theme.getClass('tableGrid') + '">' +
10194                (this.opt('columnHeader') ?
10195                    '<thead class="fc-head">' +
10196                        '<tr>' +
10197                        '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
10198                        '</tr>' +
10199                        '</thead>' :
10200                    '') +
10201                '<tbody class="fc-body">' +
10202                '<tr>' +
10203                '<td class="' + theme.getClass('widgetContent') + '"></td>' +
10204                '</tr>' +
10205                '</tbody>' +
10206                '</table>';
10207        };
10208        // Generates an HTML attribute string for setting the width of the week number column, if it is known
10209        DayGridView.prototype.weekNumberStyleAttr = function () {
10210            if (this.weekNumberWidth != null) {
10211                return 'style="width:' + this.weekNumberWidth + 'px"';
10212            }
10213            return '';
10214        };
10215        // Determines whether each row should have a constant height
10216        DayGridView.prototype.hasRigidRows = function () {
10217            var eventLimit = this.opt('eventLimit');
10218            return eventLimit && typeof eventLimit !== 'number';
10219        };
10220        /* Dimensions
10221        ------------------------------------------------------------------------------------------------------------------*/
10222        DayGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
10223            _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first
10224            this.dayGrid.updateSize(isResize);
10225        };
10226        // Refreshes the horizontal dimensions of the view
10227        DayGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
10228            var dayGrid = this.dayGrid;
10229            var eventLimit = this.opt('eventLimit');
10230            var headRowEl = this.header ? this.header.el : null; // HACK
10231            var scrollerHeight;
10232            var scrollbarWidths;
10233            // hack to give the view some height prior to dayGrid's columns being rendered
10234            // TODO: separate setting height from scroller VS dayGrid.
10235            if (!dayGrid.rowEls) {
10236                if (!isAuto) {
10237                    scrollerHeight = this.computeScrollerHeight(viewHeight);
10238                    this.scroller.setHeight(scrollerHeight);
10239                }
10240                return;
10241            }
10242            if (this.colWeekNumbersVisible) {
10243                // Make sure all week number cells running down the side have the same width.
10244                this.weekNumberWidth = core.matchCellWidths(core.findElements(this.el, '.fc-week-number'));
10245            }
10246            // reset all heights to be natural
10247            this.scroller.clear();
10248            if (headRowEl) {
10249                core.uncompensateScroll(headRowEl);
10250            }
10251            dayGrid.removeSegPopover(); // kill the "more" popover if displayed
10252            // is the event limit a constant level number?
10253            if (eventLimit && typeof eventLimit === 'number') {
10254                dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after
10255            }
10256            // distribute the height to the rows
10257            // (viewHeight is a "recommended" value if isAuto)
10258            scrollerHeight = this.computeScrollerHeight(viewHeight);
10259            this.setGridHeight(scrollerHeight, isAuto);
10260            // is the event limit dynamically calculated?
10261            if (eventLimit && typeof eventLimit !== 'number') {
10262                dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set
10263            }
10264            if (!isAuto) { // should we force dimensions of the scroll container?
10265                this.scroller.setHeight(scrollerHeight);
10266                scrollbarWidths = this.scroller.getScrollbarWidths();
10267                if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
10268                    if (headRowEl) {
10269                        core.compensateScroll(headRowEl, scrollbarWidths);
10270                    }
10271                    // doing the scrollbar compensation might have created text overflow which created more height. redo
10272                    scrollerHeight = this.computeScrollerHeight(viewHeight);
10273                    this.scroller.setHeight(scrollerHeight);
10274                }
10275                // guarantees the same scrollbar widths
10276                this.scroller.lockOverflow(scrollbarWidths);
10277            }
10278        };
10279        // given a desired total height of the view, returns what the height of the scroller should be
10280        DayGridView.prototype.computeScrollerHeight = function (viewHeight) {
10281            return viewHeight -
10282                core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
10283        };
10284        // Sets the height of just the DayGrid component in this view
10285        DayGridView.prototype.setGridHeight = function (height, isAuto) {
10286            if (this.opt('monthMode')) {
10287                // if auto, make the height of each row the height that it would be if there were 6 weeks
10288                if (isAuto) {
10289                    height *= this.dayGrid.rowCnt / 6;
10290                }
10291                core.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows
10292            }
10293            else {
10294                if (isAuto) {
10295                    core.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding
10296                }
10297                else {
10298                    core.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows
10299                }
10300            }
10301        };
10302        /* Scroll
10303        ------------------------------------------------------------------------------------------------------------------*/
10304        DayGridView.prototype.computeDateScroll = function (duration) {
10305            return { top: 0 };
10306        };
10307        DayGridView.prototype.queryDateScroll = function () {
10308            return { top: this.scroller.getScrollTop() };
10309        };
10310        DayGridView.prototype.applyDateScroll = function (scroll) {
10311            if (scroll.top !== undefined) {
10312                this.scroller.setScrollTop(scroll.top);
10313            }
10314        };
10315        return DayGridView;
10316    }(core.View));
10317    DayGridView.prototype.dateProfileGeneratorClass = DayGridDateProfileGenerator;
10318
10319    var SimpleDayGrid = /** @class */ (function (_super) {
10320        __extends(SimpleDayGrid, _super);
10321        function SimpleDayGrid(context, dayGrid) {
10322            var _this = _super.call(this, context, dayGrid.el) || this;
10323            _this.slicer = new DayGridSlicer();
10324            _this.dayGrid = dayGrid;
10325            context.calendar.registerInteractiveComponent(_this, { el: _this.dayGrid.el });
10326            return _this;
10327        }
10328        SimpleDayGrid.prototype.destroy = function () {
10329            _super.prototype.destroy.call(this);
10330            this.calendar.unregisterInteractiveComponent(this);
10331        };
10332        SimpleDayGrid.prototype.render = function (props) {
10333            var dayGrid = this.dayGrid;
10334            var dateProfile = props.dateProfile, dayTable = props.dayTable;
10335            dayGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, props.nextDayThreshold, dayGrid, dayTable), { dateProfile: dateProfile, cells: dayTable.cells, isRigid: props.isRigid }));
10336        };
10337        SimpleDayGrid.prototype.buildPositionCaches = function () {
10338            this.dayGrid.buildPositionCaches();
10339        };
10340        SimpleDayGrid.prototype.queryHit = function (positionLeft, positionTop) {
10341            var rawHit = this.dayGrid.positionToHit(positionLeft, positionTop);
10342            if (rawHit) {
10343                return {
10344                    component: this.dayGrid,
10345                    dateSpan: rawHit.dateSpan,
10346                    dayEl: rawHit.dayEl,
10347                    rect: {
10348                        left: rawHit.relativeRect.left,
10349                        right: rawHit.relativeRect.right,
10350                        top: rawHit.relativeRect.top,
10351                        bottom: rawHit.relativeRect.bottom
10352                    },
10353                    layer: 0
10354                };
10355            }
10356        };
10357        return SimpleDayGrid;
10358    }(core.DateComponent));
10359    var DayGridSlicer = /** @class */ (function (_super) {
10360        __extends(DayGridSlicer, _super);
10361        function DayGridSlicer() {
10362            return _super !== null && _super.apply(this, arguments) || this;
10363        }
10364        DayGridSlicer.prototype.sliceRange = function (dateRange, dayTable) {
10365            return dayTable.sliceRange(dateRange);
10366        };
10367        return DayGridSlicer;
10368    }(core.Slicer));
10369
10370    var DayGridView$1 = /** @class */ (function (_super) {
10371        __extends(DayGridView, _super);
10372        function DayGridView(_context, viewSpec, dateProfileGenerator, parentEl) {
10373            var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this;
10374            _this.buildDayTable = core.memoize(buildDayTable);
10375            if (_this.opt('columnHeader')) {
10376                _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container'));
10377            }
10378            _this.simpleDayGrid = new SimpleDayGrid(_this.context, _this.dayGrid);
10379            return _this;
10380        }
10381        DayGridView.prototype.destroy = function () {
10382            _super.prototype.destroy.call(this);
10383            if (this.header) {
10384                this.header.destroy();
10385            }
10386            this.simpleDayGrid.destroy();
10387        };
10388        DayGridView.prototype.render = function (props) {
10389            _super.prototype.render.call(this, props);
10390            var dateProfile = this.props.dateProfile;
10391            var dayTable = this.dayTable =
10392                this.buildDayTable(dateProfile, this.dateProfileGenerator);
10393            if (this.header) {
10394                this.header.receiveProps({
10395                    dateProfile: dateProfile,
10396                    dates: dayTable.headerDates,
10397                    datesRepDistinctDays: dayTable.rowCnt === 1,
10398                    renderIntroHtml: this.renderHeadIntroHtml
10399                });
10400            }
10401            this.simpleDayGrid.receiveProps({
10402                dateProfile: dateProfile,
10403                dayTable: dayTable,
10404                businessHours: props.businessHours,
10405                dateSelection: props.dateSelection,
10406                eventStore: props.eventStore,
10407                eventUiBases: props.eventUiBases,
10408                eventSelection: props.eventSelection,
10409                eventDrag: props.eventDrag,
10410                eventResize: props.eventResize,
10411                isRigid: this.hasRigidRows(),
10412                nextDayThreshold: this.nextDayThreshold
10413            });
10414        };
10415        return DayGridView;
10416    }(DayGridView));
10417    function buildDayTable(dateProfile, dateProfileGenerator) {
10418        var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator);
10419        return new core.DayTable(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
10420    }
10421
10422    var main = core.createPlugin({
10423        defaultView: 'dayGridMonth',
10424        views: {
10425            dayGrid: DayGridView$1,
10426            dayGridDay: {
10427                type: 'dayGrid',
10428                duration: { days: 1 }
10429            },
10430            dayGridWeek: {
10431                type: 'dayGrid',
10432                duration: { weeks: 1 }
10433            },
10434            dayGridMonth: {
10435                type: 'dayGrid',
10436                duration: { months: 1 },
10437                monthMode: true,
10438                fixedWeekCount: true
10439            }
10440        }
10441    });
10442
10443    exports.AbstractDayGridView = DayGridView;
10444    exports.DayBgRow = DayBgRow;
10445    exports.DayGrid = DayGrid;
10446    exports.DayGridSlicer = DayGridSlicer;
10447    exports.DayGridView = DayGridView$1;
10448    exports.SimpleDayGrid = SimpleDayGrid;
10449    exports.buildBasicDayTable = buildDayTable;
10450    exports.default = main;
10451
10452    Object.defineProperty(exports, '__esModule', { value: true });
10453
10454}));
10455
10456},{"@fullcalendar/core":2}],4:[function(require,module,exports){
10457/*!
10458FullCalendar Google Calendar Plugin v4.3.0
10459Docs & License: https://fullcalendar.io/
10460(c) 2019 Adam Shaw
10461*/
10462
10463(function (global, factory) {
10464    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
10465    typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
10466    (global = global || self, factory(global.FullCalendarGoogleCalendar = {}, global.FullCalendar));
10467}(this, function (exports, core) { 'use strict';
10468
10469    /*! *****************************************************************************
10470    Copyright (c) Microsoft Corporation. All rights reserved.
10471    Licensed under the Apache License, Version 2.0 (the "License");
10471 you may not use
10472    this file except in compliance with the License. You may obtain a copy of the
10473    License at http://www.apache.org/licenses/LICENSE-2.0
10474
10475    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
10476    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
10477    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
10478    MERCHANTABLITY OR NON-INFRINGEMENT.
10479
10480    See the Apache Version 2.0 License for specific language governing permissions
10481    and limitations under the License.
10482    ***************************************************************************** */
10483
10484    var __assign = function() {
10485        __assign = Object.assign || function __assign(t) {
10486            for (var s, i = 1, n = arguments.length; i < n; i++) {
10487                s = arguments[i];
10488                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
10489            }
10490            return t;
10491        };
10492        return __assign.apply(this, arguments);
10493    };
10494
10495    // TODO: expose somehow
10496    var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars';
10497    var STANDARD_PROPS = {
10498        url: String,
10499        googleCalendarApiKey: String,
10500        googleCalendarId: String,
10501        data: null
10502    };
10503    var eventSourceDef = {
10504        parseMeta: function (raw) {
10505            if (typeof raw === 'string') {
10506                raw = { url: raw };
10507            }
10508            if (typeof raw === 'object') {
10509                var standardProps = core.refineProps(raw, STANDARD_PROPS);
10510                if (!standardProps.googleCalendarId && standardProps.url) {
10511                    standardProps.googleCalendarId = parseGoogleCalendarId(standardProps.url);
10512                }
10513                delete standardProps.url;
10514                if (standardProps.googleCalendarId) {
10515                    return standardProps;
10516                }
10517            }
10518            return null;
10519        },
10520        fetch: function (arg, onSuccess, onFailure) {
10521            var calendar = arg.calendar;
10522            var meta = arg.eventSource.meta;
10523            var apiKey = meta.googleCalendarApiKey || calendar.opt('googleCalendarApiKey');
10524            if (!apiKey) {
10525                onFailure({
10526                    message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/'
10527                });
10528            }
10529            else {
10530                var url = buildUrl(meta);
10531                var requestParams_1 = buildRequestParams(arg.range, apiKey, meta.data, calendar.dateEnv);
10532                core.requestJson('GET', url, requestParams_1, function (body, xhr) {
10533                    if (body.error) {
10534                        onFailure({
10535                            message: 'Google Calendar API: ' + body.error.message,
10536                            errors: body.error.errors,
10537                            xhr: xhr
10538                        });
10539                    }
10540                    else {
10541                        onSuccess({
10542                            rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone),
10543                            xhr: xhr
10544                        });
10545                    }
10546                }, function (message, xhr) {
10547                    onFailure({ message: message, xhr: xhr });
10548                });
10549            }
10550        }
10551    };
10552    function parseGoogleCalendarId(url) {
10553        var match;
10554        // detect if the ID was specified as a single string.
10555        // will match calendars like "[email protected]" in addition to person email calendars.
10556        if (/^[^\/]+@([^\/\.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) {
10557            return url;
10558        }
10559        else if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^\/]*)/.exec(url)) ||
10560            (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^\/]*)/.exec(url))) {
10561            return decodeURIComponent(match[1]);
10562        }
10563    }
10564    function buildUrl(meta) {
10565        return API_BASE + '/' + encodeURIComponent(meta.googleCalendarId) + '/events';
10566    }
10567    function buildRequestParams(range, apiKey, extraParams, dateEnv) {
10568        var params;
10569        var startStr;
10570        var endStr;
10571        if (dateEnv.canComputeOffset) {
10572            // strings will naturally have offsets, which GCal needs
10573            startStr = dateEnv.formatIso(range.start);
10574            endStr = dateEnv.formatIso(range.end);
10575        }
10576        else {
10577            // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day
10578            // from the UTC day-start to guarantee we're getting all the events
10579            // (start/end will be UTC-coerced dates, so toISOString is okay)
10580            startStr = core.addDays(range.start, -1).toISOString();
10581            endStr = core.addDays(range.end, 1).toISOString();
10582        }
10583        params = __assign({}, (extraParams || {}), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 });
10584        if (dateEnv.timeZone !== 'local') {
10585            params.timeZone = dateEnv.timeZone;
10586        }
10587        return params;
10588    }
10589    function gcalItemsToRawEventDefs(items, gcalTimezone) {
10590        return items.map(function (item) {
10591            return gcalItemToRawEventDef(item, gcalTimezone);
10592        });
10593    }
10594    function gcalItemToRawEventDef(item, gcalTimezone) {
10595        var url = item.htmlLink || null;
10596        // make the URLs for each event show times in the correct timezone
10597        if (url && gcalTimezone) {
10598            url = injectQsComponent(url, 'ctz=' + gcalTimezone);
10599        }
10600        return {
10601            id: item.id,
10602            title: item.summary,
10603            start: item.start.dateTime || item.start.date,
10604            end: item.end.dateTime || item.end.date,
10605            url: url,
10606            location: item.location,
10607            description: item.description
10608        };
10609    }
10610    // Injects a string like "arg=value" into the querystring of a URL
10611    // TODO: move to a general util file?
10612    function injectQsComponent(url, component) {
10613        // inject it after the querystring but before the fragment
10614        return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) {
10615            return (qs ? qs + '&' : '?') + component + hash;
10616        });
10617    }
10618    var main = core.createPlugin({
10619        eventSourceDefs: [eventSourceDef]
10620    });
10621
10622    exports.default = main;
10623
10624    Object.defineProperty(exports, '__esModule', { value: true });
10625
10626}));
10627
10628},{"@fullcalendar/core":2}],5:[function(require,module,exports){
10629/*!
10630FullCalendar Interaction Plugin v4.3.0
10631Docs & License: https://fullcalendar.io/
10632(c) 2019 Adam Shaw
10633*/
10634
10635(function (global, factory) {
10636    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
10637    typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
10638    (global = global || self, factory(global.FullCalendarInteraction = {}, global.FullCalendar));
10639}(this, function (exports, core) { 'use strict';
10640
10641    /*! *****************************************************************************
10642    Copyright (c) Microsoft Corporation. All rights reserved.
10643    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
10644    this file except in compliance with the License. You may obtain a copy of the
10645    License at http://www.apache.org/licenses/LICENSE-2.0
10646
10647    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
10648    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
10649    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
10650    MERCHANTABLITY OR NON-INFRINGEMENT.
10651
10652    See the Apache Version 2.0 License for specific language governing permissions
10653    and limitations under the License.
10654    ***************************************************************************** */
10655    /* global Reflect, Promise */
10656
10657    var extendStatics = function(d, b) {
10658        extendStatics = Object.setPrototypeOf ||
10659            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
10660            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
10661        return extendStatics(d, b);
10662    };
10663
10664    function __extends(d, b) {
10665        extendStatics(d, b);
10666        function __() { this.constructor = d; }
10667        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
10668    }
10669
10670    var __assign = function() {
10671        __assign = Object.assign || function __assign(t) {
10672            for (var s, i = 1, n = arguments.length; i < n; i++) {
10673                s = arguments[i];
10674                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
10675            }
10676            return t;
10677        };
10678        return __assign.apply(this, arguments);
10679    };
10680
10681    core.config.touchMouseIgnoreWait = 500;
10682    var ignoreMouseDepth = 0;
10683    var listenerCnt = 0;
10684    var isWindowTouchMoveCancelled = false;
10685    /*
10686    Uses a "pointer" abstraction, which monitors UI events for both mouse and touch.
10687    Tracks when the pointer "drags" on a certain element, meaning down+move+up.
10688
10689    Also, tracks if there was touch-scrolling.
10690    Also, can prevent touch-scrolling from happening.
10691    Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.
10692
10693    emits:
10694    - pointerdown
10695    - pointermove
10696    - pointerup
10697    */
10698    var PointerDragging = /** @class */ (function () {
10699        function PointerDragging(containerEl) {
10700            var _this = this;
10701            this.subjectEl = null;
10702            this.downEl = null;
10703            // options that can be directly assigned by caller
10704            this.selector = ''; // will cause subjectEl in all emitted events to be this element
10705            this.handleSelector = '';
10706            this.shouldIgnoreMove = false;
10707            this.shouldWatchScroll = true; // for simulating pointermove on scroll
10708            // internal states
10709            this.isDragging = false;
10710            this.isTouchDragging = false;
10711            this.wasTouchScroll = false;
10712            // Mouse
10713            // ----------------------------------------------------------------------------------------------------
10714            this.handleMouseDown = function (ev) {
10715                if (!_this.shouldIgnoreMouse() &&
10716                    isPrimaryMouseButton(ev) &&
10717                    _this.tryStart(ev)) {
10718                    var pev = _this.createEventFromMouse(ev, true);
10719                    _this.emitter.trigger('pointerdown', pev);
10720                    _this.initScrollWatch(pev);
10721                    if (!_this.shouldIgnoreMove) {
10722                        document.addEventListener('mousemove', _this.handleMouseMove);
10723                    }
10724                    document.addEventListener('mouseup', _this.handleMouseUp);
10725                }
10726            };
10727            this.handleMouseMove = function (ev) {
10728                var pev = _this.createEventFromMouse(ev);
10729                _this.recordCoords(pev);
10730                _this.emitter.trigger('pointermove', pev);
10731            };
10732            this.handleMouseUp = function (ev) {
10733                document.removeEventListener('mousemove', _this.handleMouseMove);
10734                document.removeEventListener('mouseup', _this.handleMouseUp);
10735                _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev));
10736                _this.cleanup(); // call last so that pointerup has access to props
10737            };
10738            // Touch
10739            // ----------------------------------------------------------------------------------------------------
10740            this.handleTouchStart = function (ev) {
10741                if (_this.tryStart(ev)) {
10742                    _this.isTouchDragging = true;
10743                    var pev = _this.createEventFromTouch(ev, true);
10744                    _this.emitter.trigger('pointerdown', pev);
10745                    _this.initScrollWatch(pev);
10746                    // unlike mouse, need to attach to target, not document
10747                    // https://stackoverflow.com/a/45760014
10748                    var target = ev.target;
10749                    if (!_this.shouldIgnoreMove) {
10750                        target.addEventListener('touchmove', _this.handleTouchMove);
10751                    }
10752                    target.addEventListener('touchend', _this.handleTouchEnd);
10753                    target.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end
10754                    // attach a handler to get called when ANY scroll action happens on the page.
10755                    // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
10756                    // http://stackoverflow.com/a/32954565/96342
10757                    window.addEventListener('scroll', _this.handleTouchScroll, true // useCapture
10758                    );
10759                }
10760            };
10761            this.handleTouchMove = function (ev) {
10762                var pev = _this.createEventFromTouch(ev);
10763                _this.recordCoords(pev);
10764                _this.emitter.trigger('pointermove', pev);
10765            };
10766            this.handleTouchEnd = function (ev) {
10767                if (_this.isDragging) { // done to guard against touchend followed by touchcancel
10768                    var target = ev.target;
10769                    target.removeEventListener('touchmove', _this.handleTouchMove);
10770                    target.removeEventListener('touchend', _this.handleTouchEnd);
10771                    target.removeEventListener('touchcancel', _this.handleTouchEnd);
10772                    window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true
10773                    _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev));
10774                    _this.cleanup(); // call last so that pointerup has access to props
10775                    _this.isTouchDragging = false;
10776                    startIgnoringMouse();
10777                }
10778            };
10779            this.handleTouchScroll = function () {
10780                _this.wasTouchScroll = true;
10781            };
10782            this.handleScroll = function (ev) {
10783                if (!_this.shouldIgnoreMove) {
10784                    var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX;
10785                    var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY;
10786                    _this.emitter.trigger('pointermove', {
10787                        origEvent: ev,
10788                        isTouch: _this.isTouchDragging,
10789                        subjectEl: _this.subjectEl,
10790                        pageX: pageX,
10791                        pageY: pageY,
10792                        deltaX: pageX - _this.origPageX,
10793                        deltaY: pageY - _this.origPageY
10794                    });
10795                }
10796            };
10797            this.containerEl = containerEl;
10798            this.emitter = new core.EmitterMixin();
10799            containerEl.addEventListener('mousedown', this.handleMouseDown);
10800            containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true });
10801            listenerCreated();
10802        }
10803        PointerDragging.prototype.destroy = function () {
10804            this.containerEl.removeEventListener('mousedown', this.handleMouseDown);
10805            this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
10806            listenerDestroyed();
10807        };
10808        PointerDragging.prototype.tryStart = function (ev) {
10809            var subjectEl = this.querySubjectEl(ev);
10810            var downEl = ev.target;
10811            if (subjectEl &&
10812                (!this.handleSelector || core.elementClosest(downEl, this.handleSelector))) {
10813                this.subjectEl = subjectEl;
10814                this.downEl = downEl;
10815                this.isDragging = true; // do this first so cancelTouchScroll will work
10816                this.wasTouchScroll = false;
10817                return true;
10818            }
10819            return false;
10820        };
10821        PointerDragging.prototype.cleanup = function () {
10822            isWindowTouchMoveCancelled = false;
10823            this.isDragging = false;
10824            this.subjectEl = null;
10825            this.downEl = null;
10826            // keep wasTouchScroll around for later access
10827            this.destroyScrollWatch();
10828        };
10829        PointerDragging.prototype.querySubjectEl = function (ev) {
10830            if (this.selector) {
10831                return core.elementClosest(ev.target, this.selector);
10832            }
10833            else {
10834                return this.containerEl;
10835            }
10836        };
10837        PointerDragging.prototype.shouldIgnoreMouse = function () {
10838            return ignoreMouseDepth || this.isTouchDragging;
10839        };
10840        // can be called by user of this class, to cancel touch-based scrolling for the current drag
10841        PointerDragging.prototype.cancelTouchScroll = function () {
10842            if (this.isDragging) {
10843                isWindowTouchMoveCancelled = true;
10844            }
10845        };
10846        // Scrolling that simulates pointermoves
10847        // ----------------------------------------------------------------------------------------------------
10848        PointerDragging.prototype.initScrollWatch = function (ev) {
10849            if (this.shouldWatchScroll) {
10850                this.recordCoords(ev);
10851                window.addEventListener('scroll', this.handleScroll, true); // useCapture=true
10852            }
10853        };
10854        PointerDragging.prototype.recordCoords = function (ev) {
10855            if (this.shouldWatchScroll) {
10856                this.prevPageX = ev.pageX;
10857                this.prevPageY = ev.pageY;
10858                this.prevScrollX = window.pageXOffset;
10859                this.prevScrollY = window.pageYOffset;
10860            }
10861        };
10862        PointerDragging.prototype.destroyScrollWatch = function () {
10863            if (this.shouldWatchScroll) {
10864                window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true
10865            }
10866        };
10867        // Event Normalization
10868        // ----------------------------------------------------------------------------------------------------
10869        PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) {
10870            var deltaX = 0;
10871            var deltaY = 0;
10872            // TODO: repeat code
10873            if (isFirst) {
10874                this.origPageX = ev.pageX;
10875                this.origPageY = ev.pageY;
10876            }
10877            else {
10878                deltaX = ev.pageX - this.origPageX;
10879                deltaY = ev.pageY - this.origPageY;
10880            }
10881            return {
10882                origEvent: ev,
10883                isTouch: false,
10884                subjectEl: this.subjectEl,
10885                pageX: ev.pageX,
10886                pageY: ev.pageY,
10887                deltaX: deltaX,
10888                deltaY: deltaY
10889            };
10890        };
10891        PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) {
10892            var touches = ev.touches;
10893            var pageX;
10894            var pageY;
10895            var deltaX = 0;
10896            var deltaY = 0;
10897            // if touch coords available, prefer,
10898            // because FF would give bad ev.pageX ev.pageY
10899            if (touches && touches.length) {
10900                pageX = touches[0].pageX;
10901                pageY = touches[0].pageY;
10902            }
10903            else {
10904                pageX = ev.pageX;
10905                pageY = ev.pageY;
10906            }
10907            // TODO: repeat code
10908            if (isFirst) {
10909                this.origPageX = pageX;
10910                this.origPageY = pageY;
10911            }
10912            else {
10913                deltaX = pageX - this.origPageX;
10914                deltaY = pageY - this.origPageY;
10915            }
10916            return {
10917                origEvent: ev,
10918                isTouch: true,
10919                subjectEl: this.subjectEl,
10920                pageX: pageX,
10921                pageY: pageY,
10922                deltaX: deltaX,
10923                deltaY: deltaY
10924            };
10925        };
10926        return PointerDragging;
10927    }());
10928    // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
10929    function isPrimaryMouseButton(ev) {
10930        return ev.button === 0 && !ev.ctrlKey;
10931    }
10932    // Ignoring fake mouse events generated by touch
10933    // ----------------------------------------------------------------------------------------------------
10934    function startIgnoringMouse() {
10935        ignoreMouseDepth++;
10936        setTimeout(function () {
10937            ignoreMouseDepth--;
10938        }, core.config.touchMouseIgnoreWait);
10939    }
10940    // We want to attach touchmove as early as possible for Safari
10941    // ----------------------------------------------------------------------------------------------------
10942    function listenerCreated() {
10943        if (!(listenerCnt++)) {
10944            window.addEventListener('touchmove', onWindowTouchMove, { passive: false });
10945        }
10946    }
10947    function listenerDestroyed() {
10948        if (!(--listenerCnt)) {
10949            window.removeEventListener('touchmove', onWindowTouchMove, { passive: false });
10950        }
10951    }
10952    function onWindowTouchMove(ev) {
10953        if (isWindowTouchMoveCancelled) {
10954            ev.preventDefault();
10955        }
10956    }
10957
10958    /*
10959    An effect in which an element follows the movement of a pointer across the screen.
10960    The moving element is a clone of some other element.
10961    Must call start + handleMove + stop.
10962    */
10963    var ElementMirror = /** @class */ (function () {
10964        function ElementMirror() {
10965            this.isVisible = false; // must be explicitly enabled
10966            this.sourceEl = null;
10967            this.mirrorEl = null;
10968            this.sourceElRect = null; // screen coords relative to viewport
10969            // options that can be set directly by caller
10970            this.parentNode = document.body;
10971            this.zIndex = 9999;
10972            this.revertDuration = 0;
10973        }
10974        ElementMirror.prototype.start = function (sourceEl, pageX, pageY) {
10975            this.sourceEl = sourceEl;
10976            this.sourceElRect = this.sourceEl.getBoundingClientRect();
10977            this.origScreenX = pageX - window.pageXOffset;
10978            this.origScreenY = pageY - window.pageYOffset;
10979            this.deltaX = 0;
10980            this.deltaY = 0;
10981            this.updateElPosition();
10982        };
10983        ElementMirror.prototype.handleMove = function (pageX, pageY) {
10984            this.deltaX = (pageX - window.pageXOffset) - this.origScreenX;
10985            this.deltaY = (pageY - window.pageYOffset) - this.origScreenY;
10986            this.updateElPosition();
10987        };
10988        // can be called before start
10989        ElementMirror.prototype.setIsVisible = function (bool) {
10990            if (bool) {
10991                if (!this.isVisible) {
10992                    if (this.mirrorEl) {
10993                        this.mirrorEl.style.display = '';
10994                    }
10995                    this.isVisible = bool; // needs to happen before updateElPosition
10996                    this.updateElPosition(); // because was not updating the position while invisible
10997                }
10998            }
10999            else {
11000                if (this.isVisible) {
11001                    if (this.mirrorEl) {
11002                        this.mirrorEl.style.display = 'none';
11003                    }
11004                    this.isVisible = bool;
11005                }
11006            }
11007        };
11008        // always async
11009        ElementMirror.prototype.stop = function (needsRevertAnimation, callback) {
11010            var _this = this;
11011            var done = function () {
11012                _this.cleanup();
11013                callback();
11014            };
11015            if (needsRevertAnimation &&
11016                this.mirrorEl &&
11017                this.isVisible &&
11018                this.revertDuration && // if 0, transition won't work
11019                (this.deltaX || this.deltaY) // if same coords, transition won't work
11020            ) {
11021                this.doRevertAnimation(done, this.revertDuration);
11022            }
11023            else {
11024                setTimeout(done, 0);
11025            }
11026        };
11027        ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) {
11028            var mirrorEl = this.mirrorEl;
11029            var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened
11030            mirrorEl.style.transition =
11031                'top ' + revertDuration + 'ms,' +
11032                    'left ' + revertDuration + 'ms';
11033            core.applyStyle(mirrorEl, {
11034                left: finalSourceElRect.left,
11035                top: finalSourceElRect.top
11036            });
11037            core.whenTransitionDone(mirrorEl, function () {
11038                mirrorEl.style.transition = '';
11039                callback();
11040            });
11041        };
11042        ElementMirror.prototype.cleanup = function () {
11043            if (this.mirrorEl) {
11044                core.removeElement(this.mirrorEl);
11045                this.mirrorEl = null;
11046            }
11047            this.sourceEl = null;
11048        };
11049        ElementMirror.prototype.updateElPosition = function () {
11050            if (this.sourceEl && this.isVisible) {
11051                core.applyStyle(this.getMirrorEl(), {
11052                    left: this.sourceElRect.left + this.deltaX,
11053                    top: this.sourceElRect.top + this.deltaY
11054                });
11055            }
11056        };
11057        ElementMirror.prototype.getMirrorEl = function () {
11058            var sourceElRect = this.sourceElRect;
11059            var mirrorEl = this.mirrorEl;
11060            if (!mirrorEl) {
11061                mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
11062                // we don't want long taps or any mouse interaction causing selection/menus.
11063                // would use preventSelection(), but that prevents selectstart, causing problems.
11064                mirrorEl.classList.add('fc-unselectable');
11065                mirrorEl.classList.add('fc-dragging');
11066                core.applyStyle(mirrorEl, {
11067                    position: 'fixed',
11068                    zIndex: this.zIndex,
11069                    visibility: '',
11070                    boxSizing: 'border-box',
11071                    width: sourceElRect.right - sourceElRect.left,
11072                    height: sourceElRect.bottom - sourceElRect.top,
11073                    right: 'auto',
11074                    bottom: 'auto',
11075                    margin: 0
11076                });
11077                this.parentNode.appendChild(mirrorEl);
11078            }
11079            return mirrorEl;
11080        };
11081        return ElementMirror;
11082    }());
11083
11084    /*
11085    Is a cache for a given element's scroll information (all the info that ScrollController stores)
11086    in addition the "client rectangle" of the element.. the area within the scrollbars.
11087
11088    The cache can be in one of two modes:
11089    - doesListening:false - ignores when the container is scrolled by someone else
11090    - doesListening:true - watch for scrolling and update the cache
11091    */
11092    var ScrollGeomCache = /** @class */ (function (_super) {
11093        __extends(ScrollGeomCache, _super);
11094        function ScrollGeomCache(scrollController, doesListening) {
11095            var _this = _super.call(this) || this;
11096            _this.handleScroll = function () {
11097                _this.scrollTop = _this.scrollController.getScrollTop();
11098                _this.scrollLeft = _this.scrollController.getScrollLeft();
11099                _this.handleScrollChange();
11100            };
11101            _this.scrollController = scrollController;
11102            _this.doesListening = doesListening;
11103            _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop();
11104            _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
11105            _this.scrollWidth = scrollController.getScrollWidth();
11106            _this.scrollHeight = scrollController.getScrollHeight();
11107            _this.clientWidth = scrollController.getClientWidth();
11108            _this.clientHeight = scrollController.getClientHeight();
11109            _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values
11110            if (_this.doesListening) {
11111                _this.getEventTarget().addEventListener('scroll', _this.handleScroll);
11112            }
11113            return _this;
11114        }
11115        ScrollGeomCache.prototype.destroy = function () {
11116            if (this.doesListening) {
11117                this.getEventTarget().removeEventListener('scroll', this.handleScroll);
11118            }
11119        };
11120        ScrollGeomCache.prototype.getScrollTop = function () {
11121            return this.scrollTop;
11122        };
11123        ScrollGeomCache.prototype.getScrollLeft = function () {
11124            return this.scrollLeft;
11125        };
11126        ScrollGeomCache.prototype.setScrollTop = function (top) {
11127            this.scrollController.setScrollTop(top);
11128            if (!this.doesListening) {
11129                // we are not relying on the element to normalize out-of-bounds scroll values
11130                // so we need to sanitize ourselves
11131                this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
11132                this.handleScrollChange();
11133            }
11134        };
11135        ScrollGeomCache.prototype.setScrollLeft = function (top) {
11136            this.scrollController.setScrollLeft(top);
11137            if (!this.doesListening) {
11138                // we are not relying on the element to normalize out-of-bounds scroll values
11139                // so we need to sanitize ourselves
11140                this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
11141                this.handleScrollChange();
11142            }
11143        };
11144        ScrollGeomCache.prototype.getClientWidth = function () {
11145            return this.clientWidth;
11146        };
11147        ScrollGeomCache.prototype.getClientHeight = function () {
11148            return this.clientHeight;
11149        };
11150        ScrollGeomCache.prototype.getScrollWidth = function () {
11151            return this.scrollWidth;
11152        };
11153        ScrollGeomCache.prototype.getScrollHeight = function () {
11154            return this.scrollHeight;
11155        };
11156        ScrollGeomCache.prototype.handleScrollChange = function () {
11157        };
11158        return ScrollGeomCache;
11159    }(core.ScrollController));
11160    var ElementScrollGeomCache = /** @class */ (function (_super) {
11161        __extends(ElementScrollGeomCache, _super);
11162        function ElementScrollGeomCache(el, doesListening) {
11163            return _super.call(this, new core.ElementScrollController(el), doesListening) || this;
11164        }
11165        ElementScrollGeomCache.prototype.getEventTarget = function () {
11166            return this.scrollController.el;
11167        };
11168        ElementScrollGeomCache.prototype.computeClientRect = function () {
11169            return core.computeInnerRect(this.scrollController.el);
11170        };
11171        return ElementScrollGeomCache;
11172    }(ScrollGeomCache));
11173    var WindowScrollGeomCache = /** @class */ (function (_super) {
11174        __extends(WindowScrollGeomCache, _super);
11175        function WindowScrollGeomCache(doesListening) {
11176            return _super.call(this, new core.WindowScrollController(), doesListening) || this;
11177        }
11178        WindowScrollGeomCache.prototype.getEventTarget = function () {
11179            return window;
11180        };
11181        WindowScrollGeomCache.prototype.computeClientRect = function () {
11182            return {
11183                left: this.scrollLeft,
11184                right: this.scrollLeft + this.clientWidth,
11185                top: this.scrollTop,
11186                bottom: this.scrollTop + this.clientHeight
11187            };
11188        };
11189        // the window is the only scroll object that changes it's rectangle relative
11190        // to the document's topleft as it scrolls
11191        WindowScrollGeomCache.prototype.handleScrollChange = function () {
11192            this.clientRect = this.computeClientRect();
11193        };
11194        return WindowScrollGeomCache;
11195    }(ScrollGeomCache));
11196
11197    // If available we are using native "performance" API instead of "Date"
11198    // Read more about it on MDN:
11199    // https://developer.mozilla.org/en-US/docs/Web/API/Performance
11200    var getTime = typeof performance === 'function' ? performance.now : Date.now;
11201    /*
11202    For a pointer interaction, automatically scrolls certain scroll containers when the pointer
11203    approaches the edge.
11204
11205    The caller must call start + handleMove + stop.
11206    */
11207    var AutoScroller = /** @class */ (function () {
11208        function AutoScroller() {
11209            var _this = this;
11210            // options that can be set by caller
11211            this.isEnabled = true;
11212            this.scrollQuery = [window, '.fc-scroller'];
11213            this.edgeThreshold = 50; // pixels
11214            this.maxVelocity = 300; // pixels per second
11215            // internal state
11216            this.pointerScreenX = null;
11217            this.pointerScreenY = null;
11218            this.isAnimating = false;
11219            this.scrollCaches = null;
11220            // protect against the initial pointerdown being too close to an edge and starting the scroll
11221            this.everMovedUp = false;
11222            this.everMovedDown = false;
11223            this.everMovedLeft = false;
11224            this.everMovedRight = false;
11225            this.animate = function () {
11226                if (_this.isAnimating) { // wasn't cancelled between animation calls
11227                    var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset);
11228                    if (edge) {
11229                        var now = getTime();
11230                        _this.handleSide(edge, (now - _this.msSinceRequest) / 1000);
11231                        _this.requestAnimation(now);
11232                    }
11233                    else {
11234                        _this.isAnimating = false; // will stop animation
11235                    }
11236                }
11237            };
11238        }
11239        AutoScroller.prototype.start = function (pageX, pageY) {
11240            if (this.isEnabled) {
11241                this.scrollCaches = this.buildCaches();
11242                this.pointerScreenX = null;
11243                this.pointerScreenY = null;
11244                this.everMovedUp = false;
11245                this.everMovedDown = false;
11246                this.everMovedLeft = false;
11247                this.everMovedRight = false;
11248                this.handleMove(pageX, pageY);
11249            }
11250        };
11251        AutoScroller.prototype.handleMove = function (pageX, pageY) {
11252            if (this.isEnabled) {
11253                var pointerScreenX = pageX - window.pageXOffset;
11254                var pointerScreenY = pageY - window.pageYOffset;
11255                var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
11256                var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
11257                if (yDelta < 0) {
11258                    this.everMovedUp = true;
11259                }
11260                else if (yDelta > 0) {
11261                    this.everMovedDown = true;
11262                }
11263                if (xDelta < 0) {
11264                    this.everMovedLeft = true;
11265                }
11266                else if (xDelta > 0) {
11267                    this.everMovedRight = true;
11268                }
11269                this.pointerScreenX = pointerScreenX;
11270                this.pointerScreenY = pointerScreenY;
11271                if (!this.isAnimating) {
11272                    this.isAnimating = true;
11273                    this.requestAnimation(getTime());
11274                }
11275            }
11276        };
11277        AutoScroller.prototype.stop = function () {
11278            if (this.isEnabled) {
11279                this.isAnimating = false; // will stop animation
11280                for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
11281                    var scrollCache = _a[_i];
11282                    scrollCache.destroy();
11283                }
11284                this.scrollCaches = null;
11285            }
11286        };
11287        AutoScroller.prototype.requestAnimation = function (now) {
11288            this.msSinceRequest = now;
11289            requestAnimationFrame(this.animate);
11290        };
11291        AutoScroller.prototype.handleSide = function (edge, seconds) {
11292            var scrollCache = edge.scrollCache;
11293            var edgeThreshold = this.edgeThreshold;
11294            var invDistance = edgeThreshold - edge.distance;
11295            var velocity = // the closer to the edge, the faster we scroll
11296             (invDistance * invDistance) / (edgeThreshold * edgeThreshold) * // quadratic
11297                this.maxVelocity * seconds;
11298            var sign = 1;
11299            switch (edge.name) {
11300                case 'left':
11301                    sign = -1;
11302                // falls through
11303                case 'right':
11304                    scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
11305                    break;
11306                case 'top':
11307                    sign = -1;
11308                // falls through
11309                case 'bottom':
11310                    scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
11311                    break;
11312            }
11313        };
11314        // left/top are relative to document topleft
11315        AutoScroller.prototype.computeBestEdge = function (left, top) {
11316            var edgeThreshold = this.edgeThreshold;
11317            var bestSide = null;
11318            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
11319                var scrollCache = _a[_i];
11320                var rect = scrollCache.clientRect;
11321                var leftDist = left - rect.left;
11322                var rightDist = rect.right - left;
11323                var topDist = top - rect.top;
11324                var bottomDist = rect.bottom - top;
11325                // completely within the rect?
11326                if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
11327                    if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&
11328                        (!bestSide || bestSide.distance > topDist)) {
11329                        bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist };
11330                    }
11331                    if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&
11332                        (!bestSide || bestSide.distance > bottomDist)) {
11333                        bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist };
11334                    }
11335                    if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&
11336                        (!bestSide || bestSide.distance > leftDist)) {
11337                        bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist };
11338                    }
11339                    if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&
11340                        (!bestSide || bestSide.distance > rightDist)) {
11341                        bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist };
11342                    }
11343                }
11344            }
11345            return bestSide;
11346        };
11347        AutoScroller.prototype.buildCaches = function () {
11348            return this.queryScrollEls().map(function (el) {
11349                if (el === window) {
11350                    return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls
11351                }
11352                else {
11353                    return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls
11354                }
11355            });
11356        };
11357        AutoScroller.prototype.queryScrollEls = function () {
11358            var els = [];
11359            for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) {
11360                var query = _a[_i];
11361                if (typeof query === 'object') {
11362                    els.push(query);
11363                }
11364                else {
11365                    els.push.apply(els, Array.prototype.slice.call(document.querySelectorAll(query)));
11366                }
11367            }
11368            return els;
11369        };
11370        return AutoScroller;
11371    }());
11372
11373    /*
11374    Monitors dragging on an element. Has a number of high-level features:
11375    - minimum distance required before dragging
11376    - minimum wait time ("delay") before dragging
11377    - a mirror element that follows the pointer
11378    */
11379    var FeaturefulElementDragging = /** @class */ (function (_super) {
11380        __extends(FeaturefulElementDragging, _super);
11381        function FeaturefulElementDragging(containerEl) {
11382            var _this = _super.call(this, containerEl) || this;
11383            // options that can be directly set by caller
11384            // the caller can also set the PointerDragging's options as well
11385            _this.delay = null;
11386            _this.minDistance = 0;
11387            _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag
11388            _this.mirrorNeedsRevert = false;
11389            _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup
11390            _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation
11391            _this.isDelayEnded = false;
11392            _this.isDistanceSurpassed = false;
11393            _this.delayTimeoutId = null;
11394            _this.onPointerDown = function (ev) {
11395                if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going
11396                    _this.isInteracting = true;
11397                    _this.isDelayEnded = false;
11398                    _this.isDistanceSurpassed = false;
11399                    core.preventSelection(document.body);
11400                    core.preventContextMenu(document.body);
11401                    // prevent links from being visited if there's an eventual drag.
11402                    // also prevents selection in older browsers (maybe?).
11403                    // not necessary for touch, besides, browser would complain about passiveness.
11404                    if (!ev.isTouch) {
11405                        ev.origEvent.preventDefault();
11406                    }
11407                    _this.emitter.trigger('pointerdown', ev);
11408                    if (!_this.pointer.shouldIgnoreMove) {
11409                        // actions related to initiating dragstart+dragmove+dragend...
11410                        _this.mirror.setIsVisible(false); // reset. caller must set-visible
11411                        _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down
11412                        _this.startDelay(ev);
11413                        if (!_this.minDistance) {
11414                            _this.handleDistanceSurpassed(ev);
11415                        }
11416                    }
11417                }
11418            };
11419            _this.onPointerMove = function (ev) {
11420                if (_this.isInteracting) { // if false, still waiting for previous drag's revert
11421                    _this.emitter.trigger('pointermove', ev);
11422                    if (!_this.isDistanceSurpassed) {
11423                        var minDistance = _this.minDistance;
11424                        var distanceSq = void 0; // current distance from the origin, squared
11425                        var deltaX = ev.deltaX, deltaY = ev.deltaY;
11426                        distanceSq = deltaX * deltaX + deltaY * deltaY;
11427                        if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
11428                            _this.handleDistanceSurpassed(ev);
11429                        }
11430                    }
11431                    if (_this.isDragging) {
11432                        // a real pointer move? (not one simulated by scrolling)
11433                        if (ev.origEvent.type !== 'scroll') {
11434                            _this.mirror.handleMove(ev.pageX, ev.pageY);
11435                            _this.autoScroller.handleMove(ev.pageX, ev.pageY);
11436                        }
11437                        _this.emitter.trigger('dragmove', ev);
11438                    }
11439                }
11440            };
11441            _this.onPointerUp = function (ev) {
11442                if (_this.isInteracting) { // if false, still waiting for previous drag's revert
11443                    _this.isInteracting = false;
11444                    core.allowSelection(document.body);
11445                    core.allowContextMenu(document.body);
11446                    _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert
11447                    if (_this.isDragging) {
11448                        _this.autoScroller.stop();
11449                        _this.tryStopDrag(ev); // which will stop the mirror
11450                    }
11451                    if (_this.delayTimeoutId) {
11452                        clearTimeout(_this.delayTimeoutId);
11453                        _this.delayTimeoutId = null;
11454                    }
11455                }
11456            };
11457            var pointer = _this.pointer = new PointerDragging(containerEl);
11458            pointer.emitter.on('pointerdown', _this.onPointerDown);
11459            pointer.emitter.on('pointermove', _this.onPointerMove);
11460            pointer.emitter.on('pointerup', _this.onPointerUp);
11461            _this.mirror = new ElementMirror();
11462            _this.autoScroller = new AutoScroller();
11463            return _this;
11464        }
11465        FeaturefulElementDragging.prototype.destroy = function () {
11466            this.pointer.destroy();
11467        };
11468        FeaturefulElementDragging.prototype.startDelay = function (ev) {
11469            var _this = this;
11470            if (typeof this.delay === 'number') {
11471                this.delayTimeoutId = setTimeout(function () {
11472                    _this.delayTimeoutId = null;
11473                    _this.handleDelayEnd(ev);
11474                }, this.delay); // not assignable to number!
11475            }
11476            else {
11477                this.handleDelayEnd(ev);
11478            }
11479        };
11480        FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) {
11481            this.isDelayEnded = true;
11482            this.tryStartDrag(ev);
11483        };
11484        FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) {
11485            this.isDistanceSurpassed = true;
11486            this.tryStartDrag(ev);
11487        };
11488        FeaturefulElementDragging.prototype.tryStartDrag = function (ev) {
11489            if (this.isDelayEnded && this.isDistanceSurpassed) {
11490                if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
11491                    this.isDragging = true;
11492                    this.mirrorNeedsRevert = false;
11493                    this.autoScroller.start(ev.pageX, ev.pageY);
11494                    this.emitter.trigger('dragstart', ev);
11495                    if (this.touchScrollAllowed === false) {
11496                        this.pointer.cancelTouchScroll();
11497                    }
11498                }
11499            }
11500        };
11501        FeaturefulElementDragging.prototype.tryStopDrag = function (ev) {
11502            // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events
11503            // that come from the document to fire beforehand. much more convenient this way.
11504            this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev) // bound with args
11505            );
11506        };
11507        FeaturefulElementDragging.prototype.stopDrag = function (ev) {
11508            this.isDragging = false;
11509            this.emitter.trigger('dragend', ev);
11510        };
11511        // fill in the implementations...
11512        FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) {
11513            this.pointer.shouldIgnoreMove = bool;
11514        };
11515        FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) {
11516            this.mirror.setIsVisible(bool);
11517        };
11518        FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
11519            this.mirrorNeedsRevert = bool;
11520        };
11521        FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) {
11522            this.autoScroller.isEnabled = bool;
11523        };
11524        return FeaturefulElementDragging;
11525    }(core.ElementDragging));
11526
11527    /*
11528    When this class is instantiated, it records the offset of an element (relative to the document topleft),
11529    and continues to monitor scrolling, updating the cached coordinates if it needs to.
11530    Does not access the DOM after instantiation, so highly performant.
11531
11532    Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element
11533    and an determine if a given point is inside the combined clipping rectangle.
11534    */
11535    var OffsetTracker = /** @class */ (function () {
11536        function OffsetTracker(el) {
11537            this.origRect = core.computeRect(el);
11538            // will work fine for divs that have overflow:hidden
11539            this.scrollCaches = core.getClippingParents(el).map(function (el) {
11540                return new ElementScrollGeomCache(el, true); // listen=true
11541            });
11542        }
11543        OffsetTracker.prototype.destroy = function () {
11544            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
11545                var scrollCache = _a[_i];
11546                scrollCache.destroy();
11547            }
11548        };
11549        OffsetTracker.prototype.computeLeft = function () {
11550            var left = this.origRect.left;
11551            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
11552                var scrollCache = _a[_i];
11553                left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
11554            }
11555            return left;
11556        };
11557        OffsetTracker.prototype.computeTop = function () {
11558            var top = this.origRect.top;
11559            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
11560                var scrollCache = _a[_i];
11561                top += scrollCache.origScrollTop - scrollCache.getScrollTop();
11562            }
11563            return top;
11564        };
11565        OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) {
11566            var point = { left: pageX, top: pageY };
11567            for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
11568                var scrollCache = _a[_i];
11569                if (!isIgnoredClipping(scrollCache.getEventTarget()) &&
11570                    !core.pointInsideRect(point, scrollCache.clientRect)) {
11571                    return false;
11572                }
11573            }
11574            return true;
11575        };
11576        return OffsetTracker;
11577    }());
11578    // certain clipping containers should never constrain interactions, like <html> and <body>
11579    // https://github.com/fullcalendar/fullcalendar/issues/3615
11580    function isIgnoredClipping(node) {
11581        var tagName = node.tagName;
11582        return tagName === 'HTML' || tagName === 'BODY';
11583    }
11584
11585    /*
11586    Tracks movement over multiple droppable areas (aka "hits")
11587    that exist in one or more DateComponents.
11588    Relies on an existing draggable.
11589
11590    emits:
11591    - pointerdown
11592    - dragstart
11593    - hitchange - fires initially, even if not over a hit
11594    - pointerup
11595    - (hitchange - again, to null, if ended over a hit)
11596    - dragend
11597    */
11598    var HitDragging = /** @class */ (function () {
11599        function HitDragging(dragging, droppableStore) {
11600            var _this = this;
11601            // options that can be set by caller
11602            this.useSubjectCenter = false;
11603            this.requireInitial = true; // if doesn't start out on a hit, won't emit any events
11604            this.initialHit = null;
11605            this.movingHit = null;
11606            this.finalHit = null; // won't ever be populated if shouldIgnoreMove
11607            this.handlePointerDown = function (ev) {
11608                var dragging = _this.dragging;
11609                _this.initialHit = null;
11610                _this.movingHit = null;
11611                _this.finalHit = null;
11612                _this.prepareHits();
11613                _this.processFirstCoord(ev);
11614                if (_this.initialHit || !_this.requireInitial) {
11615                    dragging.setIgnoreMove(false);
11616                    _this.emitter.trigger('pointerdown', ev); // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
11617                }
11618                else {
11619                    dragging.setIgnoreMove(true);
11620                }
11621            };
11622            this.handleDragStart = function (ev) {
11623                _this.emitter.trigger('dragstart', ev);
11624                _this.handleMove(ev, true); // force = fire even if initially null
11625            };
11626            this.handleDragMove = function (ev) {
11627                _this.emitter.trigger('dragmove', ev);
11628                _this.handleMove(ev);
11629            };
11630            this.handlePointerUp = function (ev) {
11631                _this.releaseHits();
11632                _this.emitter.trigger('pointerup', ev);
11633            };
11634            this.handleDragEnd = function (ev) {
11635                if (_this.movingHit) {
11636                    _this.emitter.trigger('hitupdate', null, true, ev);
11637                }
11638                _this.finalHit = _this.movingHit;
11639                _this.movingHit = null;
11640                _this.emitter.trigger('dragend', ev);
11641            };
11642            this.droppableStore = droppableStore;
11643            dragging.emitter.on('pointerdown', this.handlePointerDown);
11644            dragging.emitter.on('dragstart', this.handleDragStart);
11645            dragging.emitter.on('dragmove', this.handleDragMove);
11646            dragging.emitter.on('pointerup', this.handlePointerUp);
11647            dragging.emitter.on('dragend', this.handleDragEnd);
11648            this.dragging = dragging;
11649            this.emitter = new core.EmitterMixin();
11650        }
11651        // sets initialHit
11652        // sets coordAdjust
11653        HitDragging.prototype.processFirstCoord = function (ev) {
11654            var origPoint = { left: ev.pageX, top: ev.pageY };
11655            var adjustedPoint = origPoint;
11656            var subjectEl = ev.subjectEl;
11657            var subjectRect;
11658            if (subjectEl !== document) {
11659                subjectRect = core.computeRect(subjectEl);
11660                adjustedPoint = core.constrainPoint(adjustedPoint, subjectRect);
11661            }
11662            var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
11663            if (initialHit) {
11664                if (this.useSubjectCenter && subjectRect) {
11665                    var slicedSubjectRect = core.intersectRects(subjectRect, initialHit.rect);
11666                    if (slicedSubjectRect) {
11667                        adjustedPoint = core.getRectCenter(slicedSubjectRect);
11668                    }
11669                }
11670                this.coordAdjust = core.diffPoints(adjustedPoint, origPoint);
11671            }
11672            else {
11673                this.coordAdjust = { left: 0, top: 0 };
11674            }
11675        };
11676        HitDragging.prototype.handleMove = function (ev, forceHandle) {
11677            var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
11678            if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
11679                this.movingHit = hit;
11680                this.emitter.trigger('hitupdate', hit, false, ev);
11681            }
11682        };
11683        HitDragging.prototype.prepareHits = function () {
11684            this.offsetTrackers = core.mapHash(this.droppableStore, function (interactionSettings) {
11685                interactionSettings.component.buildPositionCaches();
11686                return new OffsetTracker(interactionSettings.el);
11687            });
11688        };
11689        HitDragging.prototype.releaseHits = function () {
11690            var offsetTrackers = this.offsetTrackers;
11691            for (var id in offsetTrackers) {
11692                offsetTrackers[id].destroy();
11693            }
11694            this.offsetTrackers = {};
11695        };
11696        HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) {
11697            var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers;
11698            var bestHit = null;
11699            for (var id in droppableStore) {
11700                var component = droppableStore[id].component;
11701                var offsetTracker = offsetTrackers[id];
11702                if (offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
11703                    var originLeft = offsetTracker.computeLeft();
11704                    var originTop = offsetTracker.computeTop();
11705                    var positionLeft = offsetLeft - originLeft;
11706                    var positionTop = offsetTop - originTop;
11707                    var origRect = offsetTracker.origRect;
11708                    var width = origRect.right - origRect.left;
11709                    var height = origRect.bottom - origRect.top;
11710                    if (
11711                    // must be within the element's bounds
11712                    positionLeft >= 0 && positionLeft < width &&
11713                        positionTop >= 0 && positionTop < height) {
11714                        var hit = component.queryHit(positionLeft, positionTop, width, height);
11715                        if (hit &&
11716                            (
11717                            // make sure the hit is within activeRange, meaning it's not a deal cell
11718                            !component.props.dateProfile || // hack for DayTile
11719                                core.rangeContainsRange(component.props.dateProfile.activeRange, hit.dateSpan.range)) &&
11720                            (!bestHit || hit.layer > bestHit.layer)) {
11721                            // TODO: better way to re-orient rectangle
11722                            hit.rect.left += originLeft;
11723                            hit.rect.right += originLeft;
11724                            hit.rect.top += originTop;
11725                            hit.rect.bottom += originTop;
11726                            bestHit = hit;
11727                        }
11728                    }
11729                }
11730            }
11731            return bestHit;
11732        };
11733        return HitDragging;
11734    }());
11735    function isHitsEqual(hit0, hit1) {
11736        if (!hit0 && !hit1) {
11737            return true;
11738        }
11739        if (Boolean(hit0) !== Boolean(hit1)) {
11740            return false;
11741        }
11742        return core.isDateSpansEqual(hit0.dateSpan, hit1.dateSpan);
11743    }
11744
11745    /*
11746    Monitors when the user clicks on a specific date/time of a component.
11747    A pointerdown+pointerup on the same "hit" constitutes a click.
11748    */
11749    var DateClicking = /** @class */ (function (_super) {
11750        __extends(DateClicking, _super);
11751        function DateClicking(settings) {
11752            var _this = _super.call(this, settings) || this;
11753            _this.handlePointerDown = function (ev) {
11754                var dragging = _this.dragging;
11755                // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired
11756                dragging.setIgnoreMove(!_this.component.isValidDateDownEl(dragging.pointer.downEl));
11757            };
11758            // won't even fire if moving was ignored
11759            _this.handleDragEnd = function (ev) {
11760                var component = _this.component;
11761                var pointer = _this.dragging.pointer;
11762                if (!pointer.wasTouchScroll) {
11763                    var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit;
11764                    if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
11765                        component.calendar.triggerDateClick(initialHit.dateSpan, initialHit.dayEl, component.view, ev.origEvent);
11766                    }
11767                }
11768            };
11769            var component = settings.component;
11770            // we DO want to watch pointer moves because otherwise finalHit won't get populated
11771            _this.dragging = new FeaturefulElementDragging(component.el);
11772            _this.dragging.autoScroller.isEnabled = false;
11773            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
11774            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
11775            hitDragging.emitter.on('dragend', _this.handleDragEnd);
11776            return _this;
11777        }
11778        DateClicking.prototype.destroy = function () {
11779            this.dragging.destroy();
11780        };
11781        return DateClicking;
11782    }(core.Interaction));
11783
11784    /*
11785    Tracks when the user selects a portion of time of a component,
11786    constituted by a drag over date cells, with a possible delay at the beginning of the drag.
11787    */
11788    var DateSelecting = /** @class */ (function (_super) {
11789        __extends(DateSelecting, _super);
11790        function DateSelecting(settings) {
11791            var _this = _super.call(this, settings) || this;
11792            _this.dragSelection = null;
11793            _this.handlePointerDown = function (ev) {
11794                var _a = _this, component = _a.component, dragging = _a.dragging;
11795                var canSelect = component.opt('selectable') &&
11796                    component.isValidDateDownEl(ev.origEvent.target);
11797                // don't bother to watch expensive moves if component won't do selection
11798                dragging.setIgnoreMove(!canSelect);
11799                // if touch, require user to hold down
11800                dragging.delay = ev.isTouch ? getComponentTouchDelay(component) : null;
11801            };
11802            _this.handleDragStart = function (ev) {
11803                _this.component.calendar.unselect(ev); // unselect previous selections
11804            };
11805            _this.handleHitUpdate = function (hit, isFinal) {
11806                var calendar = _this.component.calendar;
11807                var dragSelection = null;
11808                var isInvalid = false;
11809                if (hit) {
11810                    dragSelection = joinHitsIntoSelection(_this.hitDragging.initialHit, hit, calendar.pluginSystem.hooks.dateSelectionTransformers);
11811                    if (!dragSelection || !_this.component.isDateSelectionValid(dragSelection)) {
11812                        isInvalid = true;
11813                        dragSelection = null;
11814                    }
11815                }
11816                if (dragSelection) {
11817                    calendar.dispatch({ type: 'SELECT_DATES', selection: dragSelection });
11818                }
11819                else if (!isFinal) { // only unselect if moved away while dragging
11820                    calendar.dispatch({ type: 'UNSELECT_DATES' });
11821                }
11822                if (!isInvalid) {
11823                    core.enableCursor();
11824                }
11825                else {
11826                    core.disableCursor();
11827                }
11828                if (!isFinal) {
11829                    _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging
11830                }
11831            };
11832            _this.handlePointerUp = function (pev) {
11833                if (_this.dragSelection) {
11834                    // selection is already rendered, so just need to report selection
11835                    _this.component.calendar.triggerDateSelect(_this.dragSelection, pev);
11836                    _this.dragSelection = null;
11837                }
11838            };
11839            var component = settings.component;
11840            var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
11841            dragging.touchScrollAllowed = false;
11842            dragging.minDistance = component.opt('selectMinDistance') || 0;
11843            dragging.autoScroller.isEnabled = component.opt('dragScroll');
11844            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
11845            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
11846            hitDragging.emitter.on('dragstart', _this.handleDragStart);
11847            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
11848            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
11849            return _this;
11850        }
11851        DateSelecting.prototype.destroy = function () {
11852            this.dragging.destroy();
11853        };
11854        return DateSelecting;
11855    }(core.Interaction));
11856    function getComponentTouchDelay(component) {
11857        var delay = component.opt('selectLongPressDelay');
11858        if (delay == null) {
11859            delay = component.opt('longPressDelay');
11860        }
11861        return delay;
11862    }
11863    function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
11864        var dateSpan0 = hit0.dateSpan;
11865        var dateSpan1 = hit1.dateSpan;
11866        var ms = [
11867            dateSpan0.range.start,
11868            dateSpan0.range.end,
11869            dateSpan1.range.start,
11870            dateSpan1.range.end
11871        ];
11872        ms.sort(core.compareNumbers);
11873        var props = {};
11874        for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) {
11875            var transformer = dateSelectionTransformers_1[_i];
11876            var res = transformer(hit0, hit1);
11877            if (res === false) {
11878                return null;
11879            }
11880            else if (res) {
11881                __assign(props, res);
11882            }
11883        }
11884        props.range = { start: ms[0], end: ms[3] };
11885        props.allDay = dateSpan0.allDay;
11886        return props;
11887    }
11888
11889    var EventDragging = /** @class */ (function (_super) {
11890        __extends(EventDragging, _super);
11891        function EventDragging(settings) {
11892            var _this = _super.call(this, settings) || this;
11893            // internal state
11894            _this.subjectSeg = null; // the seg being selected/dragged
11895            _this.isDragging = false;
11896            _this.eventRange = null;
11897            _this.relevantEvents = null; // the events being dragged
11898            _this.receivingCalendar = null;
11899            _this.validMutation = null;
11900            _this.mutatedRelevantEvents = null;
11901            _this.handlePointerDown = function (ev) {
11902                var origTarget = ev.origEvent.target;
11903                var _a = _this, component = _a.component, dragging = _a.dragging;
11904                var mirror = dragging.mirror;
11905                var initialCalendar = component.calendar;
11906                var subjectSeg = _this.subjectSeg = core.getElSeg(ev.subjectEl);
11907                var eventRange = _this.eventRange = subjectSeg.eventRange;
11908                var eventInstanceId = eventRange.instance.instanceId;
11909                _this.relevantEvents = core.getRelevantEvents(initialCalendar.state.eventStore, eventInstanceId);
11910                dragging.minDistance = ev.isTouch ? 0 : component.opt('eventDragMinDistance');
11911                dragging.delay =
11912                    // only do a touch delay if touch and this event hasn't been selected yet
11913                    (ev.isTouch && eventInstanceId !== component.props.eventSelection) ?
11914                        getComponentTouchDelay$1(component) :
11915                        null;
11916                mirror.parentNode = initialCalendar.el;
11917                mirror.revertDuration = component.opt('dragRevertDuration');
11918                var isValid = component.isValidSegDownEl(origTarget) &&
11919                    !core.elementClosest(origTarget, '.fc-resizer'); // NOT on a resizer
11920                dragging.setIgnoreMove(!isValid);
11921                // disable dragging for elements that are resizable (ie, selectable)
11922                // but are not draggable
11923                _this.isDragging = isValid &&
11924                    ev.subjectEl.classList.contains('fc-draggable');
11925            };
11926            _this.handleDragStart = function (ev) {
11927                var initialCalendar = _this.component.calendar;
11928                var eventRange = _this.eventRange;
11929                var eventInstanceId = eventRange.instance.instanceId;
11930                if (ev.isTouch) {
11931                    // need to select a different event?
11932                    if (eventInstanceId !== _this.component.props.eventSelection) {
11933                        initialCalendar.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId });
11934                    }
11935                }
11936                else {
11937                    // if now using mouse, but was previous touch interaction, clear selected event
11938                    initialCalendar.dispatch({ type: 'UNSELECT_EVENT' });
11939                }
11940                if (_this.isDragging) {
11941                    initialCalendar.unselect(ev); // unselect *date* selection
11942                    initialCalendar.publiclyTrigger('eventDragStart', [
11943                        {
11944                            el: _this.subjectSeg.el,
11945                            event: new core.EventApi(initialCalendar, eventRange.def, eventRange.instance),
11946                            jsEvent: ev.origEvent,
11947                            view: _this.component.view
11948                        }
11949                    ]);
11950                }
11951            };
11952            _this.handleHitUpdate = function (hit, isFinal) {
11953                if (!_this.isDragging) {
11954                    return;
11955                }
11956                var relevantEvents = _this.relevantEvents;
11957                var initialHit = _this.hitDragging.initialHit;
11958                var initialCalendar = _this.component.calendar;
11959                // states based on new hit
11960                var receivingCalendar = null;
11961                var mutation = null;
11962                var mutatedRelevantEvents = null;
11963                var isInvalid = false;
11964                var interaction = {
11965                    affectedEvents: relevantEvents,
11966                    mutatedEvents: core.createEmptyEventStore(),
11967                    isEvent: true,
11968                    origSeg: _this.subjectSeg
11969                };
11970                if (hit) {
11971                    var receivingComponent = hit.component;
11972                    receivingCalendar = receivingComponent.calendar;
11973                    if (initialCalendar === receivingCalendar ||
11974                        receivingComponent.opt('editable') && receivingComponent.opt('droppable')) {
11975                        mutation = computeEventMutation(initialHit, hit, receivingCalendar.pluginSystem.hooks.eventDragMutationMassagers);
11976                        if (mutation) {
11977                            mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, receivingCalendar.eventUiBases, mutation, receivingCalendar);
11978                            interaction.mutatedEvents = mutatedRelevantEvents;
11979                            if (!receivingComponent.isInteractionValid(interaction)) {
11980                                isInvalid = true;
11981                                mutation = null;
11982                                mutatedRelevantEvents = null;
11983                                interaction.mutatedEvents = core.createEmptyEventStore();
11984                            }
11985                        }
11986                    }
11987                    else {
11988                        receivingCalendar = null;
11989                    }
11990                }
11991                _this.displayDrag(receivingCalendar, interaction);
11992                if (!isInvalid) {
11993                    core.enableCursor();
11994                }
11995                else {
11996                    core.disableCursor();
11997                }
11998                if (!isFinal) {
11999                    if (initialCalendar === receivingCalendar && // TODO: write test for this
12000                        isHitsEqual(initialHit, hit)) {
12001                        mutation = null;
12002                    }
12003                    _this.dragging.setMirrorNeedsRevert(!mutation);
12004                    // render the mirror if no already-rendered mirror
12005                    // TODO: wish we could somehow wait for dispatch to guarantee render
12006                    _this.dragging.setMirrorIsVisible(!hit || !document.querySelector('.fc-mirror'));
12007                    // assign states based on new hit
12008                    _this.receivingCalendar = receivingCalendar;
12009                    _this.validMutation = mutation;
12010                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
12011                }
12012            };
12013            _this.handlePointerUp = function () {
12014                if (!_this.isDragging) {
12015                    _this.cleanup(); // because handleDragEnd won't fire
12016                }
12017            };
12018            _this.handleDragEnd = function (ev) {
12019                if (_this.isDragging) {
12020                    var initialCalendar_1 = _this.component.calendar;
12021                    var initialView = _this.component.view;
12022                    var _a = _this, receivingCalendar = _a.receivingCalendar, validMutation = _a.validMutation;
12023                    var eventDef = _this.eventRange.def;
12024                    var eventInstance = _this.eventRange.instance;
12025                    var eventApi = new core.EventApi(initialCalendar_1, eventDef, eventInstance);
12026                    var relevantEvents_1 = _this.relevantEvents;
12027                    var mutatedRelevantEvents = _this.mutatedRelevantEvents;
12028                    var finalHit = _this.hitDragging.finalHit;
12029                    _this.clearDrag(); // must happen after revert animation
12030                    initialCalendar_1.publiclyTrigger('eventDragStop', [
12031                        {
12032                            el: _this.subjectSeg.el,
12033                            event: eventApi,
12034                            jsEvent: ev.origEvent,
12035                            view: initialView
12036                        }
12037                    ]);
12038                    if (validMutation) {
12039                        // dropped within same calendar
12040                        if (receivingCalendar === initialCalendar_1) {
12041                            initialCalendar_1.dispatch({
12042                                type: 'MERGE_EVENTS',
12043                                eventStore: mutatedRelevantEvents
12044                            });
12045                            var transformed = {};
12046                            for (var _i = 0, _b = initialCalendar_1.pluginSystem.hooks.eventDropTransformers; _i < _b.length; _i++) {
12047                                var transformer = _b[_i];
12048                                __assign(transformed, transformer(validMutation, initialCalendar_1));
12049                            }
12050                            var eventDropArg = __assign({}, transformed, { el: ev.subjectEl, delta: validMutation.datesDelta, oldEvent: eventApi, event: new core.EventApi(// the data AFT
12050ER the mutation
12051                                initialCalendar_1, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null), revert: function () {
12052                                    initialCalendar_1.dispatch({
12053                                        type: 'MERGE_EVENTS',
12054                                        eventStore: relevantEvents_1
12055                                    });
12056                                }, jsEvent: ev.origEvent, view: initialView });
12057                            initialCalendar_1.publiclyTrigger('eventDrop', [eventDropArg]);
12058                            // dropped in different calendar
12059                        }
12060                        else if (receivingCalendar) {
12061                            initialCalendar_1.publiclyTrigger('eventLeave', [
12062                                {
12063                                    draggedEl: ev.subjectEl,
12064                                    event: eventApi,
12065                                    view: initialView
12066                                }
12067                            ]);
12068                            initialCalendar_1.dispatch({
12069                                type: 'REMOVE_EVENT_INSTANCES',
12070                                instances: _this.mutatedRelevantEvents.instances
12071                            });
12072                            receivingCalendar.dispatch({
12073                                type: 'MERGE_EVENTS',
12074                                eventStore: _this.mutatedRelevantEvents
12075                            });
12076                            if (ev.isTouch) {
12077                                receivingCalendar.dispatch({
12078                                    type: 'SELECT_EVENT',
12079                                    eventInstanceId: eventInstance.instanceId
12080                                });
12081                            }
12082                            var dropArg = __assign({}, receivingCalendar.buildDatePointApi(finalHit.dateSpan), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.component // should this be finalHit.component.view? See #4644
12083                             });
12084                            receivingCalendar.publiclyTrigger('drop', [dropArg]);
12085                            receivingCalendar.publiclyTrigger('eventReceive', [
12086                                {
12087                                    draggedEl: ev.subjectEl,
12088                                    event: new core.EventApi(// the data AFTER the mutation
12089                                    receivingCalendar, mutatedRelevantEvents.defs[eventDef.defId], mutatedRelevantEvents.instances[eventInstance.instanceId]),
12090                                    view: finalHit.component // should this be finalHit.component.view? See #4644
12091                                }
12092                            ]);
12093                        }
12094                    }
12095                    else {
12096                        initialCalendar_1.publiclyTrigger('_noEventDrop');
12097                    }
12098                }
12099                _this.cleanup();
12100            };
12101            var component = _this.component;
12102            var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
12103            dragging.pointer.selector = EventDragging.SELECTOR;
12104            dragging.touchScrollAllowed = false;
12105            dragging.autoScroller.isEnabled = component.opt('dragScroll');
12106            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsStore);
12107            hitDragging.useSubjectCenter = settings.useEventCenter;
12108            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
12109            hitDragging.emitter.on('dragstart', _this.handleDragStart);
12110            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
12111            hitDragging.emitter.on('pointerup', _this.handlePointerUp);
12112            hitDragging.emitter.on('dragend', _this.handleDragEnd);
12113            return _this;
12114        }
12115        EventDragging.prototype.destroy = function () {
12116            this.dragging.destroy();
12117        };
12118        // render a drag state on the next receivingCalendar
12119        EventDragging.prototype.displayDrag = function (nextCalendar, state) {
12120            var initialCalendar = this.component.calendar;
12121            var prevCalendar = this.receivingCalendar;
12122            // does the previous calendar need to be cleared?
12123            if (prevCalendar && prevCalendar !== nextCalendar) {
12124                // does the initial calendar need to be cleared?
12125                // if so, don't clear all the way. we still need to to hide the affectedEvents
12126                if (prevCalendar === initialCalendar) {
12127                    prevCalendar.dispatch({
12128                        type: 'SET_EVENT_DRAG',
12129                        state: {
12130                            affectedEvents: state.affectedEvents,
12131                            mutatedEvents: core.createEmptyEventStore(),
12132                            isEvent: true,
12133                            origSeg: state.origSeg
12134                        }
12135                    });
12136                    // completely clear the old calendar if it wasn't the initial
12137                }
12138                else {
12139                    prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
12140                }
12141            }
12142            if (nextCalendar) {
12143                nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state });
12144            }
12145        };
12146        EventDragging.prototype.clearDrag = function () {
12147            var initialCalendar = this.component.calendar;
12148            var receivingCalendar = this.receivingCalendar;
12149            if (receivingCalendar) {
12150                receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
12151            }
12152            // the initial calendar might have an dummy drag state from displayDrag
12153            if (initialCalendar !== receivingCalendar) {
12154                initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
12155            }
12156        };
12157        EventDragging.prototype.cleanup = function () {
12158            this.subjectSeg = null;
12159            this.isDragging = false;
12160            this.eventRange = null;
12161            this.relevantEvents = null;
12162            this.receivingCalendar = null;
12163            this.validMutation = null;
12164            this.mutatedRelevantEvents = null;
12165        };
12166        EventDragging.SELECTOR = '.fc-draggable, .fc-resizable'; // TODO: test this in IE11
12167        return EventDragging;
12168    }(core.Interaction));
12169    function computeEventMutation(hit0, hit1, massagers) {
12170        var dateSpan0 = hit0.dateSpan;
12171        var dateSpan1 = hit1.dateSpan;
12172        var date0 = dateSpan0.range.start;
12173        var date1 = dateSpan1.range.start;
12174        var standardProps = {};
12175        if (dateSpan0.allDay !== dateSpan1.allDay) {
12176            standardProps.allDay = dateSpan1.allDay;
12177            standardProps.hasEnd = hit1.component.opt('allDayMaintainDuration');
12178            if (dateSpan1.allDay) {
12179                // means date1 is already start-of-day,
12180                // but date0 needs to be converted
12181                date0 = core.startOfDay(date0);
12182            }
12183        }
12184        var delta = core.diffDates(date0, date1, hit0.component.dateEnv, hit0.component === hit1.component ?
12185            hit0.component.largeUnit :
12186            null);
12187        if (delta.milliseconds) { // has hours/minutes/seconds
12188            standardProps.allDay = false;
12189        }
12190        var mutation = {
12191            datesDelta: delta,
12192            standardProps: standardProps
12193        };
12194        for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) {
12195            var massager = massagers_1[_i];
12196            massager(mutation, hit0, hit1);
12197        }
12198        return mutation;
12199    }
12200    function getComponentTouchDelay$1(component) {
12201        var delay = component.opt('eventLongPressDelay');
12202        if (delay == null) {
12203            delay = component.opt('longPressDelay');
12204        }
12205        return delay;
12206    }
12207
12208    var EventDragging$1 = /** @class */ (function (_super) {
12209        __extends(EventDragging, _super);
12210        function EventDragging(settings) {
12211            var _this = _super.call(this, settings) || this;
12212            // internal state
12213            _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?
12214            _this.eventRange = null;
12215            _this.relevantEvents = null;
12216            _this.validMutation = null;
12217            _this.mutatedRelevantEvents = null;
12218            _this.handlePointerDown = function (ev) {
12219                var component = _this.component;
12220                var seg = _this.querySeg(ev);
12221                var eventRange = _this.eventRange = seg.eventRange;
12222                _this.dragging.minDistance = component.opt('eventDragMinDistance');
12223                // if touch, need to be working with a selected event
12224                _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) ||
12225                    (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId));
12226            };
12227            _this.handleDragStart = function (ev) {
12228                var calendar = _this.component.calendar;
12229                var eventRange = _this.eventRange;
12230                _this.relevantEvents = core.getRelevantEvents(calendar.state.eventStore, _this.eventRange.instance.instanceId);
12231                _this.draggingSeg = _this.querySeg(ev);
12232                calendar.unselect();
12233                calendar.publiclyTrigger('eventResizeStart', [
12234                    {
12235                        el: _this.draggingSeg.el,
12236                        event: new core.EventApi(calendar, eventRange.def, eventRange.instance),
12237                        jsEvent: ev.origEvent,
12238                        view: _this.component.view
12239                    }
12240                ]);
12241            };
12242            _this.handleHitUpdate = function (hit, isFinal, ev) {
12243                var calendar = _this.component.calendar;
12244                var relevantEvents = _this.relevantEvents;
12245                var initialHit = _this.hitDragging.initialHit;
12246                var eventInstance = _this.eventRange.instance;
12247                var mutation = null;
12248                var mutatedRelevantEvents = null;
12249                var isInvalid = false;
12250                var interaction = {
12251                    affectedEvents: relevantEvents,
12252                    mutatedEvents: core.createEmptyEventStore(),
12253                    isEvent: true,
12254                    origSeg: _this.draggingSeg
12255                };
12256                if (hit) {
12257                    mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-start-resizer'), eventInstance.range, calendar.pluginSystem.hooks.eventResizeJoinTransforms);
12258                }
12259                if (mutation) {
12260                    mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, calendar.eventUiBases, mutation, calendar);
12261                    interaction.mutatedEvents = mutatedRelevantEvents;
12262                    if (!_this.component.isInteractionValid(interaction)) {
12263                        isInvalid = true;
12264                        mutation = null;
12265                        mutatedRelevantEvents = null;
12266                        interaction.mutatedEvents = null;
12267                    }
12268                }
12269                if (mutatedRelevantEvents) {
12270                    calendar.dispatch({
12271                        type: 'SET_EVENT_RESIZE',
12272                        state: interaction
12273                    });
12274                }
12275                else {
12276                    calendar.dispatch({ type: 'UNSET_EVENT_RESIZE' });
12277                }
12278                if (!isInvalid) {
12279                    core.enableCursor();
12280                }
12281                else {
12282                    core.disableCursor();
12283                }
12284                if (!isFinal) {
12285                    if (mutation && isHitsEqual(initialHit, hit)) {
12286                        mutation = null;
12287                    }
12288                    _this.validMutation = mutation;
12289                    _this.mutatedRelevantEvents = mutatedRelevantEvents;
12290                }
12291            };
12292            _this.handleDragEnd = function (ev) {
12293                var calendar = _this.component.calendar;
12294                var view = _this.component.view;
12295                var eventDef = _this.eventRange.def;
12296                var eventInstance = _this.eventRange.instance;
12297                var eventApi = new core.EventApi(calendar, eventDef, eventInstance);
12298                var relevantEvents = _this.relevantEvents;
12299                var mutatedRelevantEvents = _this.mutatedRelevantEvents;
12300                calendar.publiclyTrigger('eventResizeStop', [
12301                    {
12302                        el: _this.draggingSeg.el,
12303                        event: eventApi,
12304                        jsEvent: ev.origEvent,
12305                        view: view
12306                    }
12307                ]);
12308                if (_this.validMutation) {
12309                    calendar.dispatch({
12310                        type: 'MERGE_EVENTS',
12311                        eventStore: mutatedRelevantEvents
12312                    });
12313                    calendar.publiclyTrigger('eventResize', [
12314                        {
12315                            el: _this.draggingSeg.el,
12316                            startDelta: _this.validMutation.startDelta || core.createDuration(0),
12317                            endDelta: _this.validMutation.endDelta || core.createDuration(0),
12318                            prevEvent: eventApi,
12319                            event: new core.EventApi(// the data AFTER the mutation
12320                            calendar, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null),
12321                            revert: function () {
12322                                calendar.dispatch({
12323                                    type: 'MERGE_EVENTS',
12324                                    eventStore: relevantEvents
12325                                });
12326                            },
12327                            jsEvent: ev.origEvent,
12328                            view: view
12329                        }
12330                    ]);
12331                }
12332                else {
12333                    calendar.publiclyTrigger('_noEventResize');
12334                }
12335                // reset all internal state
12336                _this.draggingSeg = null;
12337                _this.relevantEvents = null;
12338                _this.validMutation = null;
12339                // okay to keep eventInstance around. useful to set it in handlePointerDown
12340            };
12341            var component = settings.component;
12342            var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
12343            dragging.pointer.selector = '.fc-resizer';
12344            dragging.touchScrollAllowed = false;
12345            dragging.autoScroller.isEnabled = component.opt('dragScroll');
12346            var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
12347            hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
12348            hitDragging.emitter.on('dragstart', _this.handleDragStart);
12349            hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
12350            hitDragging.emitter.on('dragend', _this.handleDragEnd);
12351            return _this;
12352        }
12353        EventDragging.prototype.destroy = function () {
12354            this.dragging.destroy();
12355        };
12356        EventDragging.prototype.querySeg = function (ev) {
12357            return core.getElSeg(core.elementClosest(ev.subjectEl, this.component.fgSegSelector));
12358        };
12359        return EventDragging;
12360    }(core.Interaction));
12361    function computeMutation(hit0, hit1, isFromStart, instanceRange, transforms) {
12362        var dateEnv = hit0.component.dateEnv;
12363        var date0 = hit0.dateSpan.range.start;
12364        var date1 = hit1.dateSpan.range.start;
12365        var delta = core.diffDates(date0, date1, dateEnv, hit0.component.largeUnit);
12366        var props = {};
12367        for (var _i = 0, transforms_1 = transforms; _i < transforms_1.length; _i++) {
12368            var transform = transforms_1[_i];
12369            var res = transform(hit0, hit1);
12370            if (res === false) {
12371                return null;
12372            }
12373            else if (res) {
12374                __assign(props, res);
12375            }
12376        }
12377        if (isFromStart) {
12378            if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
12379                props.startDelta = delta;
12380                return props;
12381            }
12382        }
12383        else {
12384            if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
12385                props.endDelta = delta;
12386                return props;
12387            }
12388        }
12389        return null;
12390    }
12391
12392    var UnselectAuto = /** @class */ (function () {
12393        function UnselectAuto(calendar) {
12394            var _this = this;
12395            this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system
12396            this.onSelect = function (selectInfo) {
12397                if (selectInfo.jsEvent) {
12398                    _this.isRecentPointerDateSelect = true;
12399                }
12400            };
12401            this.onDocumentPointerUp = function (pev) {
12402                var _a = _this, calendar = _a.calendar, documentPointer = _a.documentPointer;
12403                var state = calendar.state;
12404                // touch-scrolling should never unfocus any type of selection
12405                if (!documentPointer.wasTouchScroll) {
12406                    if (state.dateSelection && // an existing date selection?
12407                        !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?
12408                    ) {
12409                        var unselectAuto = calendar.viewOpt('unselectAuto');
12410                        var unselectCancel = calendar.viewOpt('unselectCancel');
12411                        if (unselectAuto && (!unselectAuto || !core.elementClosest(documentPointer.downEl, unselectCancel))) {
12412                            calendar.unselect(pev);
12413                        }
12414                    }
12415                    if (state.eventSelection && // an existing event selected?
12416                        !core.elementClosest(documentPointer.downEl, EventDragging.SELECTOR) // interaction DIDN'T start on an event
12417                    ) {
12418                        calendar.dispatch({ type: 'UNSELECT_EVENT' });
12419                    }
12420                }
12421                _this.isRecentPointerDateSelect = false;
12422            };
12423            this.calendar = calendar;
12424            var documentPointer = this.documentPointer = new PointerDragging(document);
12425            documentPointer.shouldIgnoreMove = true;
12426            documentPointer.shouldWatchScroll = false;
12427            documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);
12428            /*
12429            TODO: better way to know about whether there was a selection with the pointer
12430            */
12431            calendar.on('select', this.onSelect);
12432        }
12433        UnselectAuto.prototype.destroy = function () {
12434            this.calendar.off('select', this.onSelect);
12435            this.documentPointer.destroy();
12436        };
12437        return UnselectAuto;
12438    }());
12439
12440    /*
12441    Given an already instantiated draggable object for one-or-more elements,
12442    Interprets any dragging as an attempt to drag an events that lives outside
12443    of a calendar onto a calendar.
12444    */
12445    var ExternalElementDragging = /** @class */ (function () {
12446        function ExternalElementDragging(dragging, suppliedDragMeta) {
12447            var _this = this;
12448            this.receivingCalendar = null;
12449            this.droppableEvent = null; // will exist for all drags, even if create:false
12450            this.suppliedDragMeta = null;
12451            this.dragMeta = null;
12452            this.handleDragStart = function (ev) {
12453                _this.dragMeta = _this.buildDragMeta(ev.subjectEl);
12454            };
12455            this.handleHitUpdate = function (hit, isFinal, ev) {
12456                var dragging = _this.hitDragging.dragging;
12457                var receivingCalendar = null;
12458                var droppableEvent = null;
12459                var isInvalid = false;
12460                var interaction = {
12461                    affectedEvents: core.createEmptyEventStore(),
12462                    mutatedEvents: core.createEmptyEventStore(),
12463                    isEvent: _this.dragMeta.create,
12464                    origSeg: null
12465                };
12466                if (hit) {
12467                    receivingCalendar = hit.component.calendar;
12468                    if (_this.canDropElOnCalendar(ev.subjectEl, receivingCalendar)) {
12469                        droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingCalendar);
12470                        interaction.mutatedEvents = core.eventTupleToStore(droppableEvent);
12471                        isInvalid = !core.isInteractionValid(interaction, receivingCalendar);
12472                        if (isInvalid) {
12473                            interaction.mutatedEvents = core.createEmptyEventStore();
12474                            droppableEvent = null;
12475                        }
12476                    }
12477                }
12478                _this.displayDrag(receivingCalendar, interaction);
12479                // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)
12480                // TODO: wish we could somehow wait for dispatch to guarantee render
12481                dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-mirror'));
12482                if (!isInvalid) {
12483                    core.enableCursor();
12484                }
12485                else {
12486                    core.disableCursor();
12487                }
12488                if (!isFinal) {
12489                    dragging.setMirrorNeedsRevert(!droppableEvent);
12490                    _this.receivingCalendar = receivingCalendar;
12491                    _this.droppableEvent = droppableEvent;
12492                }
12493            };
12494            this.handleDragEnd = function (pev) {
12495                var _a = _this, receivingCalendar = _a.receivingCalendar, droppableEvent = _a.droppableEvent;
12496                _this.clearDrag();
12497                if (receivingCalendar && droppableEvent) {
12498                    var finalHit = _this.hitDragging.finalHit;
12499                    var finalView = finalHit.component.view;
12500                    var dragMeta = _this.dragMeta;
12501                    var arg = __assign({}, receivingCalendar.buildDatePointApi(finalHit.dateSpan), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView });
12502                    receivingCalendar.publiclyTrigger('drop', [arg]);
12503                    if (dragMeta.create) {
12504                        receivingCalendar.dispatch({
12505                            type: 'MERGE_EVENTS',
12506                            eventStore: core.eventTupleToStore(droppableEvent)
12507                        });
12508                        if (pev.isTouch) {
12509                            receivingCalendar.dispatch({
12510                                type: 'SELECT_EVENT',
12511                                eventInstanceId: droppableEvent.instance.instanceId
12512                            });
12513                        }
12514                        // signal that an external event landed
12515                        receivingCalendar.publiclyTrigger('eventReceive', [
12516                            {
12517                                draggedEl: pev.subjectEl,
12518                                event: new core.EventApi(receivingCalendar, droppableEvent.def, droppableEvent.instance),
12519                                view: finalView
12520                            }
12521                        ]);
12522                    }
12523                }
12524                _this.receivingCalendar = null;
12525                _this.droppableEvent = null;
12526            };
12527            var hitDragging = this.hitDragging = new HitDragging(dragging, core.interactionSettingsStore);
12528            hitDragging.requireInitial = false; // will start outside of a component
12529            hitDragging.emitter.on('dragstart', this.handleDragStart);
12530            hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
12531            hitDragging.emitter.on('dragend', this.handleDragEnd);
12532            this.suppliedDragMeta = suppliedDragMeta;
12533        }
12534        ExternalElementDragging.prototype.buildDragMeta = function (sub
12534jectEl) {
12535            if (typeof this.suppliedDragMeta === 'object') {
12536                return core.parseDragMeta(this.suppliedDragMeta);
12537            }
12538            else if (typeof this.suppliedDragMeta === 'function') {
12539                return core.parseDragMeta(this.suppliedDragMeta(subjectEl));
12540            }
12541            else {
12542                return getDragMetaFromEl(subjectEl);
12543            }
12544        };
12545        ExternalElementDragging.prototype.displayDrag = function (nextCalendar, state) {
12546            var prevCalendar = this.receivingCalendar;
12547            if (prevCalendar && prevCalendar !== nextCalendar) {
12548                prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
12549            }
12550            if (nextCalendar) {
12551                nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state });
12552            }
12553        };
12554        ExternalElementDragging.prototype.clearDrag = function () {
12555            if (this.receivingCalendar) {
12556                this.receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
12557            }
12558        };
12559        ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingCalendar) {
12560            var dropAccept = receivingCalendar.opt('dropAccept');
12561            if (typeof dropAccept === 'function') {
12562                return dropAccept(el);
12563            }
12564            else if (typeof dropAccept === 'string' && dropAccept) {
12565                return Boolean(core.elementMatches(el, dropAccept));
12566            }
12567            return true;
12568        };
12569        return ExternalElementDragging;
12570    }());
12571    // Utils for computing event store from the DragMeta
12572    // ----------------------------------------------------------------------------------------------------
12573    function computeEventForDateSpan(dateSpan, dragMeta, calendar) {
12574        var defProps = __assign({}, dragMeta.leftoverProps);
12575        for (var _i = 0, _a = calendar.pluginSystem.hooks.externalDefTransforms; _i < _a.length; _i++) {
12576            var transform = _a[_i];
12577            __assign(defProps, transform(dateSpan, dragMeta));
12578        }
12579        var def = core.parseEventDef(defProps, dragMeta.sourceId, dateSpan.allDay, calendar.opt('forceEventDuration') || Boolean(dragMeta.duration), // hasEnd
12580        calendar);
12581        var start = dateSpan.range.start;
12582        // only rely on time info if drop zone is all-day,
12583        // otherwise, we already know the time
12584        if (dateSpan.allDay && dragMeta.startTime) {
12585            start = calendar.dateEnv.add(start, dragMeta.startTime);
12586        }
12587        var end = dragMeta.duration ?
12588            calendar.dateEnv.add(start, dragMeta.duration) :
12589            calendar.getDefaultEventEnd(dateSpan.allDay, start);
12590        var instance = core.createEventInstance(def.defId, { start: start, end: end });
12591        return { def: def, instance: instance };
12592    }
12593    // Utils for extracting data from element
12594    // ----------------------------------------------------------------------------------------------------
12595    function getDragMetaFromEl(el) {
12596        var str = getEmbeddedElData(el, 'event');
12597        var obj = str ?
12598            JSON.parse(str) :
12599            { create: false }; // if no embedded data, assume no event creation
12600        return core.parseDragMeta(obj);
12601    }
12602    core.config.dataAttrPrefix = '';
12603    function getEmbeddedElData(el, name) {
12604        var prefix = core.config.dataAttrPrefix;
12605        var prefixedName = (prefix ? prefix + '-' : '') + name;
12606        return el.getAttribute('data-' + prefixedName) || '';
12607    }
12608
12609    /*
12610    Makes an element (that is *external* to any calendar) draggable.
12611    Can pass in data that determines how an event will be created when dropped onto a calendar.
12612    Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.
12613    */
12614    var ExternalDraggable = /** @class */ (function () {
12615        function ExternalDraggable(el, settings) {
12616            var _this = this;
12617            if (settings === void 0) { settings = {}; }
12618            this.handlePointerDown = function (ev) {
12619                var dragging = _this.dragging;
12620                var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay;
12621                dragging.minDistance =
12622                    minDistance != null ?
12623                        minDistance :
12624                        (ev.isTouch ? 0 : core.globalDefaults.eventDragMinDistance);
12625                dragging.delay =
12626                    ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv
12627                        (longPressDelay != null ? longPressDelay : core.globalDefaults.longPressDelay) :
12628                        0;
12629            };
12630            this.handleDragStart = function (ev) {
12631                if (ev.isTouch &&
12632                    _this.dragging.delay &&
12633                    ev.subjectEl.classList.contains('fc-event')) {
12634                    _this.dragging.mirror.getMirrorEl().classList.add('fc-selected');
12635                }
12636            };
12637            this.settings = settings;
12638            var dragging = this.dragging = new FeaturefulElementDragging(el);
12639            dragging.touchScrollAllowed = false;
12640            if (settings.itemSelector != null) {
12641                dragging.pointer.selector = settings.itemSelector;
12642            }
12643            if (settings.appendTo != null) {
12644                dragging.mirror.parentNode = settings.appendTo; // TODO: write tests
12645            }
12646            dragging.emitter.on('pointerdown', this.handlePointerDown);
12647            dragging.emitter.on('dragstart', this.handleDragStart);
12648            new ExternalElementDragging(dragging, settings.eventData);
12649        }
12650        ExternalDraggable.prototype.destroy = function () {
12651            this.dragging.destroy();
12652        };
12653        return ExternalDraggable;
12654    }());
12655
12656    /*
12657    Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements.
12658    The third-party system is responsible for drawing the visuals effects of the drag.
12659    This class simply monitors for pointer movements and fires events.
12660    It also has the ability to hide the moving element (the "mirror") during the drag.
12661    */
12662    var InferredElementDragging = /** @class */ (function (_super) {
12663        __extends(InferredElementDragging, _super);
12664        function InferredElementDragging(containerEl) {
12665            var _this = _super.call(this, containerEl) || this;
12666            _this.shouldIgnoreMove = false;
12667            _this.mirrorSelector = '';
12668            _this.currentMirrorEl = null;
12669            _this.handlePointerDown = function (ev) {
12670                _this.emitter.trigger('pointerdown', ev);
12671                if (!_this.shouldIgnoreMove) {
12672                    // fire dragstart right away. does not support delay or min-distance
12673                    _this.emitter.trigger('dragstart', ev);
12674                }
12675            };
12676            _this.handlePointerMove = function (ev) {
12677                if (!_this.shouldIgnoreMove) {
12678                    _this.emitter.trigger('dragmove', ev);
12679                }
12680            };
12681            _this.handlePointerUp = function (ev) {
12682                _this.emitter.trigger('pointerup', ev);
12683                if (!_this.shouldIgnoreMove) {
12684                    // fire dragend right away. does not support a revert animation
12685                    _this.emitter.trigger('dragend', ev);
12686                }
12687            };
12688            var pointer = _this.pointer = new PointerDragging(containerEl);
12689            pointer.emitter.on('pointerdown', _this.handlePointerDown);
12690            pointer.emitter.on('pointermove', _this.handlePointerMove);
12691            pointer.emitter.on('pointerup', _this.handlePointerUp);
12692            return _this;
12693        }
12694        InferredElementDragging.prototype.destroy = function () {
12695            this.pointer.destroy();
12696        };
12697        InferredElementDragging.prototype.setIgnoreMove = function (bool) {
12698            this.shouldIgnoreMove = bool;
12699        };
12700        InferredElementDragging.prototype.setMirrorIsVisible = function (bool) {
12701            if (bool) {
12702                // restore a previously hidden element.
12703                // use the reference in case the selector class has already been removed.
12704                if (this.currentMirrorEl) {
12705                    this.currentMirrorEl.style.visibility = '';
12706                    this.currentMirrorEl = null;
12707                }
12708            }
12709            else {
12710                var mirrorEl = this.mirrorSelector ?
12711                    document.querySelector(this.mirrorSelector) :
12712                    null;
12713                if (mirrorEl) {
12714                    this.currentMirrorEl = mirrorEl;
12715                    mirrorEl.style.visibility = 'hidden';
12716                }
12717            }
12718        };
12719        return InferredElementDragging;
12720    }(core.ElementDragging));
12721
12722    /*
12723    Bridges third-party drag-n-drop systems with FullCalendar.
12724    Must be instantiated and destroyed by caller.
12725    */
12726    var ThirdPartyDraggable = /** @class */ (function () {
12727        function ThirdPartyDraggable(containerOrSettings, settings) {
12728            var containerEl = document;
12729            if (
12730            // wish we could just test instanceof EventTarget, but doesn't work in IE11
12731            containerOrSettings === document ||
12732                containerOrSettings instanceof Element) {
12733                containerEl = containerOrSettings;
12734                settings = settings || {};
12735            }
12736            else {
12737                settings = (containerOrSettings || {});
12738            }
12739            var dragging = this.dragging = new InferredElementDragging(containerEl);
12740            if (typeof settings.itemSelector === 'string') {
12741                dragging.pointer.selector = settings.itemSelector;
12742            }
12743            else if (containerEl === document) {
12744                dragging.pointer.selector = '[data-event]';
12745            }
12746            if (typeof settings.mirrorSelector === 'string') {
12747                dragging.mirrorSelector = settings.mirrorSelector;
12748            }
12749            new ExternalElementDragging(dragging, settings.eventData);
12750        }
12751        ThirdPartyDraggable.prototype.destroy = function () {
12752            this.dragging.destroy();
12753        };
12754        return ThirdPartyDraggable;
12755    }());
12756
12757    var main = core.createPlugin({
12758        componentInteractions: [DateClicking, DateSelecting, EventDragging, EventDragging$1],
12759        calendarInteractions: [UnselectAuto],
12760        elementDraggingImpl: FeaturefulElementDragging
12761    });
12762
12763    exports.Draggable = ExternalDraggable;
12764    exports.FeaturefulElementDragging = FeaturefulElementDragging;
12765    exports.PointerDragging = PointerDragging;
12766    exports.ThirdPartyDraggable = ThirdPartyDraggable;
12767    exports.default = main;
12768
12769    Object.defineProperty(exports, '__esModule', { value: true });
12770
12771}));
12772
12773},{"@fullcalendar/core":2}],6:[function(require,module,exports){
12774/*!
12775FullCalendar List View Plugin v4.3.0
12776Docs & License: https://fullcalendar.io/
12777(c) 2019 Adam Shaw
12778*/
12779
12780(function (global, factory) {
12781    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
12782    typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
12783    (global = global || self, factory(global.FullCalendarList = {}, global.FullCalendar));
12784}(this, function (exports, core) { 'use strict';
12785
12786    /*! *****************************************************************************
12787    Copyright (c) Microsoft Corporation. All rights reserved.
12788    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
12789    this file except in compliance with the License. You may obtain a copy of the
12790    License at http://www.apache.org/licenses/LICENSE-2.0
12791
12792    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
12793    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
12794    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
12795    MERCHANTABLITY OR NON-INFRINGEMENT.
12796
12797    See the Apache Version 2.0 License for specific language governing permissions
12798    and limitations under the License.
12799    ***************************************************************************** */
12800    /* global Reflect, Promise */
12801
12802    var extendStatics = function(d, b) {
12803        extendStatics = Object.setPrototypeOf ||
12804            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
12805            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
12806        return extendStatics(d, b);
12807    };
12808
12809    function __extends(d, b) {
12810        extendStatics(d, b);
12811        function __() { this.constructor = d; }
12812        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
12813    }
12814
12815    var ListEventRenderer = /** @class */ (function (_super) {
12816        __extends(ListEventRenderer, _super);
12817        function ListEventRenderer(listView) {
12818            var _this = _super.call(this, listView.context) || this;
12819            _this.listView = listView;
12820            return _this;
12821        }
12822        ListEventRenderer.prototype.attachSegs = function (segs) {
12823            if (!segs.length) {
12824                this.listView.renderEmptyMessage();
12825            }
12826            else {
12827                this.listView.renderSegList(segs);
12828            }
12829        };
12830        ListEventRenderer.prototype.detachSegs = function () {
12831        };
12832        // generates the HTML for a single event row
12833        ListEventRenderer.prototype.renderSegHtml = function (seg) {
12834            var _a = this.context, view = _a.view, theme = _a.theme;
12835            var eventRange = seg.eventRange;
12836            var eventDef = eventRange.def;
12837            var eventInstance = eventRange.instance;
12838            var eventUi = eventRange.ui;
12839            var url = eventDef.url;
12840            var classes = ['fc-list-item'].concat(eventUi.classNames);
12841            var bgColor = eventUi.backgroundColor;
12842            var timeHtml;
12843            if (eventDef.allDay) {
12844                timeHtml = core.getAllDayHtml(view);
12845            }
12846            else if (core.isMultiDayRange(eventRange.range)) {
12847                if (seg.isStart) {
12848                    timeHtml = core.htmlEscape(this._getTimeText(eventInstance.range.start, seg.end, false // allDay
12849                    ));
12850                }
12851                else if (seg.isEnd) {
12852                    timeHtml = core.htmlEscape(this._getTimeText(seg.start, eventInstance.range.end, false // allDay
12853                    ));
12854                }
12855                else { // inner segment that lasts the whole day
12856                    timeHtml = core.getAllDayHtml(view);
12857                }
12858            }
12859            else {
12860                // Display the normal time text for the *event's* times
12861                timeHtml = core.htmlEscape(this.getTimeText(eventRange));
12862            }
12863            if (url) {
12864                classes.push('fc-has-url');
12865            }
12866            return '<tr class="' + classes.join(' ') + '">' +
12867                (this.displayEventTime ?
12868                    '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' +
12869                        (timeHtml || '') +
12870                        '</td>' :
12871                    '') +
12872                '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' +
12873                '<span class="fc-event-dot"' +
12874                (bgColor ?
12875                    ' style="background-color:' + bgColor + '"' :
12876                    '') +
12877                '></span>' +
12878                '</td>' +
12879                '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' +
12880                '<a' + (url ? ' href="' + core.htmlEscape(url) + '"' : '') + '>
12880' +
12881                core.htmlEscape(eventDef.title || '') +
12882                '</a>' +
12883                '</td>' +
12884                '</tr>';
12885        };
12886        // like "4:00am"
12887        ListEventRenderer.prototype.computeEventTimeFormat = function () {
12888            return {
12889                hour: 'numeric',
12890                minute: '2-digit',
12891                meridiem: 'short'
12892            };
12893        };
12894        return ListEventRenderer;
12895    }(core.FgEventRenderer));
12896
12897    /*
12898    Responsible for the scroller, and forwarding event-related actions into the "grid".
12899    */
12900    var ListView = /** @class */ (function (_super) {
12901        __extends(ListView, _super);
12902        function ListView(context, viewSpec, dateProfileGenerator, parentEl) {
12903            var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
12904            _this.computeDateVars = core.memoize(computeDateVars);
12905            _this.eventStoreToSegs = core.memoize(_this._eventStoreToSegs);
12906            var eventRenderer = _this.eventRenderer = new ListEventRenderer(_this);
12907            _this.renderContent = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer));
12908            _this.el.classList.add('fc-list-view');
12909            var listViewClassNames = (_this.theme.getClass('listView') || '').split(' '); // wish we didn't have to do this
12910            for (var _i = 0, listViewClassNames_1 = listViewClassNames; _i < listViewClassNames_1.length; _i++) {
12911                var listViewClassName = listViewClassNames_1[_i];
12912                if (listViewClassName) { // in case input was empty string
12913                    _this.el.classList.add(listViewClassName);
12914                }
12915            }
12916            _this.scroller = new core.ScrollComponent('hidden', // overflow x
12917            'auto' // overflow y
12918            );
12919            _this.el.appendChild(_this.scroller.el);
12920            _this.contentEl = _this.scroller.el; // shortcut
12921            context.calendar.registerInteractiveComponent(_this, {
12922                el: _this.el
12923                // TODO: make aware that it doesn't do Hits
12924            });
12925            return _this;
12926        }
12927        ListView.prototype.render = function (props) {
12928            var _a = this.computeDateVars(props.dateProfile), dayDates = _a.dayDates, dayRanges = _a.dayRanges;
12929            this.dayDates = dayDates;
12930            this.renderContent(this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges));
12931        };
12932        ListView.prototype.destroy = function () {
12933            _super.prototype.destroy.call(this);
12934            this.renderContent.unrender();
12935            this.scroller.destroy(); // will remove the Grid too
12936            this.calendar.unregisterInteractiveComponent(this);
12937        };
12938        ListView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
12939            _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto);
12940            this.eventRenderer.computeSizes(isResize);
12941            this.eventRenderer.assignSizes(isResize);
12942            this.scroller.clear(); // sets height to 'auto' and clears overflow
12943            if (!isAuto) {
12944                this.scroller.setHeight(this.computeScrollerHeight(viewHeight));
12945            }
12946        };
12947        ListView.prototype.computeScrollerHeight = function (viewHeight) {
12948            return viewHeight -
12949                core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
12950        };
12951        ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) {
12952            return this.eventRangesToSegs(core.sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.nextDayThreshold).fg, dayRanges);
12953        };
12954        ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) {
12955            var segs = [];
12956            for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) {
12957                var eventRange = eventRanges_1[_i];
12958                segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges));
12959            }
12960            return segs;
12961        };
12962        ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) {
12963            var _a = this, dateEnv = _a.dateEnv, nextDayThreshold = _a.nextDayThreshold;
12964            var range = eventRange.range;
12965            var allDay = eventRange.def.allDay;
12966            var dayIndex;
12967            var segRange;
12968            var seg;
12969            var segs = [];
12970            for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) {
12971                segRange = core.intersectRanges(range, dayRanges[dayIndex]);
12972                if (segRange) {
12973                    seg = {
12974                        component: this,
12975                        eventRange: eventRange,
12976                        start: segRange.start,
12977                        end: segRange.end,
12978                        isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(),
12979                        isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(),
12980                        dayIndex: dayIndex
12981                    };
12982                    segs.push(seg);
12983                    // detect when range won't go fully into the next day,
12984                    // and mutate the latest seg to the be the end.
12985                    if (!seg.isEnd && !allDay &&
12986                        dayIndex + 1 < dayRanges.length &&
12987                        range.end <
12988                            dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) {
12989                        seg.end = range.end;
12990                        seg.isEnd = true;
12991                        break;
12992                    }
12993                }
12994            }
12995            return segs;
12996        };
12997        ListView.prototype.renderEmptyMessage = function () {
12998            this.contentEl.innerHTML =
12999                '<div class="fc-list-empty-wrap2">' + // TODO: try less wraps
13000                    '<div class="fc-list-empty-wrap1">' +
13001                    '<div class="fc-list-empty">' +
13002                    core.htmlEscape(this.opt('noEventsMessage')) +
13003                    '</div>' +
13004                    '</div>' +
13005                    '</div>';
13006        };
13007        // called by ListEventRenderer
13008        ListView.prototype.renderSegList = function (allSegs) {
13009            var segsByDay = this.groupSegsByDay(allSegs); // sparse array
13010            var dayIndex;
13011            var daySegs;
13012            var i;
13013            var tableEl = core.htmlToElement('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody></tbody></table>');
13014            var tbodyEl = tableEl.querySelector('tbody');
13015            for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) {
13016                daySegs = segsByDay[dayIndex];
13017                if (daySegs) { // sparse array, so might be undefined
13018                    // append a day header
13019                    tbodyEl.appendChild(this.buildDayHeaderRow(this.dayDates[dayIndex]));
13020                    daySegs = this.eventRenderer.sortEventSegs(daySegs);
13021                    for (i = 0;
13021 i < daySegs.length; i++) {
13022                        tbodyEl.appendChild(daySegs[i].el); // append event row
13023                    }
13024                }
13025            }
13026            this.contentEl.innerHTML = '';
13027            this.contentEl.appendChild(tableEl);
13028        };
13029        // Returns a sparse array of arrays, segs grouped by their dayIndex
13030        ListView.prototype.groupSegsByDay = function (segs) {
13031            var segsByDay = []; // sparse array
13032            var i;
13033            var seg;
13034            for (i = 0; i < segs.length; i++) {
13035                seg = segs[i];
13036                (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
13037                    .push(seg);
13038            }
13039            return segsByDay;
13040        };
13041        // generates the HTML for the day headers that live amongst the event rows
13042        ListView.prototype.buildDayHeaderRow = function (dayDate) {
13043            var dateEnv = this.dateEnv;
13044            var mainFormat = core.createFormatter(this.opt('listDayFormat')); // TODO: cache
13045            var altFormat = core.createFormatter(this.opt('listDayAltFormat')); // TODO: cache
13046            return core.createElement('tr', {
13047                className: 'fc-list-heading',
13048                'data-date': dateEnv.formatIso(dayDate, { omitTime: true })
13049            }, '<td class="' + (this.calendar.theme.getClass('tableListHeading') ||
13050                this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' +
13051                (mainFormat ?
13052                    core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-main' }, core.htmlEscape(dateEnv.format(dayDate, mainFormat)) // inner HTML
13053                    ) :
13054                    '') +
13055                (altFormat ?
13056                    core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-alt' }, core.htmlEscape(dateEnv.format(dayDate, altFormat)) // inner HTML
13057                    ) :
13058                    '') +
13059                '</td>');
13060        };
13061        return ListView;
13062    }(core.View));
13063    ListView.prototype.fgSegSelector = '.fc-list-item'; // which elements accept event actions
13064    function computeDateVars(dateProfile) {
13065        var dayStart = core.startOfDay(dateProfile.renderRange.start);
13066        var viewEnd = dateProfile.renderRange.end;
13067        var dayDates = [];
13068        var dayRanges = [];
13069        while (dayStart < viewEnd) {
13070            dayDates.push(dayStart);
13071            dayRanges.push({
13072                start: dayStart,
13073                end: core.addDays(dayStart, 1)
13074            });
13075            dayStart = core.addDays(dayStart, 1);
13076        }
13077        return { dayDates: dayDates, dayRanges: dayRanges };
13078    }
13079
13080    var main = core.createPlugin({
13081        views: {
13082            list: {
13083                class: ListView,
13084                buttonTextKey: 'list',
13085                listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' } // like "January 1, 2016"
13086            },
13087            listDay: {
13088                type: 'list',
13089                duration: { days: 1 },
13090                listDayFormat: { weekday: 'long' } // day-of-week is all we need. full date is probably in header
13091            },
13092            listWeek: {
13093                type: 'list',
13094                duration: { weeks: 1 },
13095                listDayFormat: { weekday: 'long' },
13096                listDayAltFormat: { month: 'long', day: 'numeric', year: 'numeric' }
13097            },
13098            listMonth: {
13099                type: 'list',
13100                duration: { month: 1 },
13101                listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have
13102            },
13103            listYear: {
13104                type: 'list',
13105                duration: { year: 1 },
13106                listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have
13107            }
13108        }
13109    });
13110
13111    exports.ListView = ListView;
13112    exports.default = main;
13113
13114    Object.defineProperty(exports, '__esModule', { value: true });
13115
13116}));
13117
13118},{"@fullcalendar/core":2}],7:[function(require,module,exports){
13119/*!
13120FullCalendar Moment Plugin v4.3.0
13121Docs & License: https://fullcalendar.io/
13122(c) 2019 Adam Shaw
13123*/
13124
13125(function (global, factory) {
13126    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('moment'), require('@fullcalendar/core')) :
13127    typeof define === 'function' && define.amd ? define(['exports', 'moment', '@fullcalendar/core'], factory) :
13128    (global = global || self, factory(global.FullCalendarMoment = {}, global.moment, global.FullCalendar));
13129}(this, function (exports, momentNs, core) { 'use strict';
13130
13131    var moment = momentNs; // the directly callable function
13132    function toMoment(date, calendar) {
13133        if (!(calendar instanceof core.Calendar)) {
13134            throw new Error('must supply a Calendar instance');
13135        }
13136        return convertToMoment(date, calendar.dateEnv.timeZone, null, calendar.dateEnv.locale.codes[0]);
13137    }
13138    function toDuration(fcDuration) {
13139        return moment.duration(fcDuration); // moment accepts all the props that fc.Duration already has!
13140    }
13141    function formatWithCmdStr(cmdStr, arg) {
13142        var cmd = parseCmdStr(cmdStr);
13143        if (arg.end) {
13144            var startMom = convertToMoment(arg.start.array, arg.timeZone, arg.start.timeZoneOffset, arg.localeCodes[0]);
13145            var endMom = convertToMoment(arg.end.array, arg.timeZone, arg.end.timeZoneOffset, arg.localeCodes[0]);
13146            return formatRange(cmd, createMomentFormatFunc(startMom), createMomentFormatFunc(endMom), arg.separator);
13147        }
13148        return convertToMoment(arg.date.array, arg.timeZone, arg.date.timeZoneOffset, arg.localeCodes[0]).format(cmd.whole); // TODO: test for this
13149    }
13150    var main = core.createPlugin({
13151        cmdFormatter: formatWithCmdStr
13152    });
13153    function createMomentFormatFunc(mom) {
13154        return function (cmdStr) {
13155            return cmdStr ? mom.format(cmdStr) : ''; // because calling with blank string results in ISO8601 :(
13156        };
13157    }
13158    function convertToMoment(input, timeZone, timeZoneOffset, locale) {
13159        var mom;
13160        if (timeZone === 'local') {
13161            mom = moment(input);
13162        }
13163        else if (timeZone === 'UTC') {
13164            mom = moment.utc(input);
13165        }
13166        else if (moment.tz) {
13167            mom = moment.tz(input, timeZone);
13168        }
13169        else {
13170            mom = moment.utc(input);
13171            if (timeZoneOffset != null) {
13172                mom.utcOffset(timeZoneOffset);
13173            }
13174        }
13175        mom.locale(locale);
13176        return mom;
13177    }
13178    function parseCmdStr(cmdStr) {
13179        var parts = cmdStr.match(/^(.*?)\{(.*)\}(.*)$/); // TODO: lookbehinds for escape characters
13180        if (parts) {
13181            var middle = parseCmdStr(parts[2]);
13182            return {
13183                head: parts[1],
13184                middle: middle,
13185                tail: parts[3],
13186                whole: parts[1] + middle.whole + parts[3]
13187            };
13188        }
13189        else {
13190            return {
13191                head: null,
13192                middle: null,
13193                tail: null,
13194                whole: cmdStr
13195            };
13196        }
13197    }
13198    function formatRange(cmd, formatStart, formatEnd, separator) {
13199        if (cmd.middle) {
13200            var startHead = formatStart(cmd.head);
13201            var startMiddle = formatRange(cmd.middle, formatStart, formatEnd, separator);
13202            var startTail = formatStart(cmd.tail);
13203            var endHead = formatEnd(cmd.head);
13204            var endMiddle = formatRange(cmd.middle, formatStart, formatEnd, separator);
13205            var endTail = formatEnd(cmd.tail);
13206            if (startHead === endHead && startTail === endTail) {
13207                return startHead +
13208                    (startMiddle === endMiddle ? startMiddle : startMiddle + separator + endMiddle) +
13209                    startTail;
13210            }
13211        }
13212        var startWhole = formatStart(cmd.whole);
13213        var endWhole = formatEnd(cmd.whole);
13214        if (startWhole === endWhole) {
13215            return startWhole;
13216        }
13217        else {
13218            return startWhole + separator + endWhole;
13219        }
13220    }
13221
13222    exports.default = main;
13223    exports.toDuration = toDuration;
13224    exports.toMoment = toMoment;
13225
13226    Object.defineProperty(exports, '__esModule', { value: true });
13227
13228}));
13229
13230},{"@fullcalendar/core":2,"moment":14}],8:[function(require,module,exports){
13231/*!
13232FullCalendar Time Grid Plugin v4.3.0
13233Docs & License: https://fullcalendar.io/
13234(c) 2019 Adam Shaw
13235*/
13236
13237(function (global, factory) {
13238    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core'), require('@fullcalendar/daygrid')) :
13239    typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core', '@fullcalendar/daygrid'], factory) :
13240    (global = global || self, factory(global.FullCalendarTimeGrid = {}, global.FullCalendar, global.FullCalendarDayGrid));
13241}(this, function (exports, core, daygrid) { 'use strict';
13242
13243    /*! *****************************************************************************
13244    Copyright (c) Microsoft Corporation. All rights reserved.
13245    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
13246    this file except in compliance with the License. You may obtain a copy of the
13247    License at http://www.apache.org/licenses/LICENSE-2.0
13248
13249    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13250    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
13251    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
13252    MERCHANTABLITY OR NON-INFRINGEMENT.
13253
13254    See the Apache Version 2.0 License for specific language governing permissions
13255    and limitations under the License.
13256    ***************************************************************************** */
13257    /* global Reflect, Promise */
13258
13259    var extendStatics = function(d, b) {
13260        extendStatics = Object.setPrototypeOf ||
13261            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
13262            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
13263        return extendStatics(d, b);
13264    };
13265
13266    function __extends(d, b) {
13267        extendStatics(d, b);
13268        function __() { this.constructor = d; }
13269        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13270    }
13271
13272    var __assign = function() {
13273        __assign = Object.assign || function __assign(t) {
13274            for (var s, i = 1, n = arguments.length; i < n; i++) {
13275                s = arguments[i];
13276                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
13277            }
13278            return t;
13279        };
13280        return __assign.apply(this, arguments);
13281    };
13282
13283    /*
13284    Only handles foreground segs.
13285    Does not own rendering. Use for low-level util methods by TimeGrid.
13286    */
13287    var TimeGridEventRenderer = /** @class */ (function (_super) {
13288        __extends(TimeGridEventRenderer, _super);
13289        function TimeGridEventRenderer(timeGrid) {
13290            var _this = _super.call(this, timeGrid.context) || this;
13291            _this.timeGrid = timeGrid;
13292            _this.fullTimeFormat = core.createFormatter({
13293                hour: 'numeric',
13294                minute: '2-digit',
13295                separator: _this.context.options.defaultRangeSeparator
13296            });
13297            return _this;
13298        }
13299        // Given an array of foreground segments, render a DOM element for each, computes position,
13300        // and attaches to the column inner-container elements.
13301        TimeGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
13302            var segsByCol = this.timeGrid.groupSegsByCol(segs);
13303            // order the segs within each column
13304            // TODO: have groupSegsByCol do this?
13305            for (var col = 0; col < segsByCol.length; col++) {
13306                segsByCol[col] = this.sortEventSegs(segsByCol[col]);
13307            }
13308            this.segsByCol = segsByCol;
13309            this.timeGrid.attachSegsByCol(segsByCol, this.timeGrid.fgContainerEls);
13310        };
13311        TimeGridEventRenderer.prototype.detachSegs = function (segs) {
13312            segs.forEach(function (seg) {
13313                core.removeElement(seg.el);
13314            });
13315            this.segsByCol = null;
13316        };
13317        TimeGridEventRenderer.prototype.computeSegSizes = function (allSegs) {
13318            var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
13319            var colCnt = timeGrid.colCnt;
13320            timeGrid.computeSegVerticals(allSegs); // horizontals relies on this
13321            if (segsByCol) {
13322                for (var col = 0; col < colCnt; col++) {
13323                    this.computeSegHorizontals(segsByCol[col]); // compute horizontal coordinates, z-index's, and reorder the array
13324                }
13325            }
13326        };
13327        TimeGridEventRenderer.prototype.assignSegSizes = function (allSegs) {
13328            var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
13329            var colCnt = timeGrid.colCnt;
13330            timeGrid.assignSegVerticals(allSegs); // horizontals relies on this
13331            if (segsByCol) {
13332                for (var col = 0; col < colCnt; col++) {
13333                    this.assignSegCss(segsByCol[col]);
13334                }
13335            }
13336        };
13337        // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined
13338        TimeGridEventRenderer.prototype.computeEventTimeFormat = function () {
13339            return {
13340                hour: 'numeric',
13341                minute: '2-digit',
13342                meridiem: false
13343            };
13344        };
13345        // Computes a default `displayEventEnd` value if one is not expliclty defined
13346        TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () {
13347            return true;
13348        };
13349        // Renders the HTML for a single event segment's default rendering
13350        TimeGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) {
13351            var view = this.context.view;
13352            var eventRange = seg.eventRange;
13353            var eventDef = eventRange.def;
13354            var eventUi = eventRange.ui;
13355            var allDay = eventDef.allDay;
13356            var isDraggable = view.computeEventDraggable(eventDef, eventUi);
13357            var isResizableFromStart = seg.isStart && view.computeEventStartResizable(eventDef, eventUi);
13358            var isResizableFromEnd = seg.isEnd && view.computeEventEndResizable(eventDef, eventUi);
13359            var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo);
13360            var skinCss = core.cssToStr(this.getSkinCss(eventUi));
13361            var timeText;
13362            var fullTimeText; // more verbose time text. for the print stylesheet
13363            var startTimeText; // just the start time text
13364            classes.unshift('fc-time-grid-event');
13365            // if the event appears to span more than one day...
13366            if (core.isMultiDayRange(eventRange.range)) {
13367                // Don't display time text on segments that run entirely through a day.
13368                // That would appear as midnight-midnight and would look dumb.
13369                // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
13370                if (seg.isStart || seg.isEnd) {
13371                    var unzonedStart = seg.start;
13372                    var unzonedEnd = seg.end;
13373                    timeText = this._getTimeText(unzonedStart, unzonedEnd, allDay); // TODO: give the timezones
13374                    fullTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, this.fullTimeFormat);
13375                    startTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, null, false); // displayEnd=false
13376                }
13377            }
13378            else {
13379                // Display the normal time text for the *event's* times
13380                timeText = this.getTimeText(eventRange);
13381                fullTimeText = this.getTimeText(eventRange, this.fullTimeFormat);
13382                startTimeText = this.getTimeText(eventRange, null, false); // displayEnd=false
13383            }
13384            return '<a class="' + classes.join(' ') + '"' +
13385                (eventDef.url ?
13386                    ' href="' + core.htmlEscape(eventDef.url) + '"' :
13387                    '') +
13388                (skinCss ?
13389                    ' style="' + skinCss + '"' :
13390                    '') +
13391                '>' +
13392                '<div class="fc-content">' +
13393                (timeText ?
13394                    '<div class="fc-time"' +
13395                        ' data-start="' + core.htmlEscape(startTimeText) + '"' +
13396                        ' data-full="' + core.htmlEscape(fullTimeText) + '"' +
13397                        '>' +
13398                        '<span>' + core.htmlEscape(timeText) + '</span>' +
13399                        '</div>' :
13400                    '') +
13401                (eventDef.title ?
13402                    '<div class="fc-title">' +
13403                        core.htmlEscape(eventDef.title) +
13404                        '</div>' :
13405                    '') +
13406                '</div>' +
13407                /* TODO: write CSS for this
13408                (isResizableFromStart ?
13409                  '<div class="fc-resizer fc-start-resizer"></div>' :
13410                  ''
13411                  ) +
13412                */
13413                (isResizableFromEnd ?
13414                    '<div class="fc-resizer fc-end-resizer"></div>' :
13415                    '') +
13416                '</a>';
13417        };
13418        // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
13419        // Assumed the segs are already ordered.
13420        // NOTE: Also reorders the given array by date!
13421        TimeGridEventRenderer.prototype.computeSegHorizontals = function (segs) {
13422            var levels;
13423            var level0;
13424            var i;
13425            levels = buildSlotSegLevels(segs);
13426            computeForwardSlotSegs(levels);
13427            if ((level0 = levels[0])) {
13428                for (i = 0; i < level0.length; i++) {
13429                    computeSlotSegPressures(level0[i]);
13430                }
13431                for (i = 0; i < level0.length; i++) {
13432                    this.computeSegForwardBack(level0[i], 0, 0);
13433                }
13434            }
13435        };
13436        // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
13437        // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
13438        // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
13439        //
13440        // The segment might be part of a "series", which means consecutive segments with the same pressure
13441        // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
13442        // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
13443        // coordinate of the first segment in the series.
13444        TimeGridEventRenderer.prototype.computeSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) {
13445            var forwardSegs = seg.forwardSegs;
13446            var i;
13447            if (seg.forwardCoord === undefined) { // not already computed
13448                if (!forwardSegs.length) {
13449                    // if there are no forward segments, this segment should butt up against the edge
13450                    seg.forwardCoord = 1;
13451                }
13452                else {
13453                    // sort highest pressure first
13454                    this.sortForwardSegs(forwardSegs);
13455                    // this segment's forwardCoord will be calculated from the backwardCoord of the
13456                    // highest-pressure forward segment.
13457                    this.computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
13458                    seg.forwardCoord = forwardSegs[0].backwardCoord;
13459                }
13460                // calculate the backwardCoord from the forwardCoord. consider the series
13461                seg.backwardCoord = seg.forwardCoord -
13462                    (seg.forwardCoord - seriesBackwardCoord) / // available width for series
13463                        (seriesBackwardPressure + 1); // # of segments in the series
13464                // use this segment's coordinates to computed the coordinates of the less-pressurized
13465                // forward segments
13466                for (i = 0; i < forwardSegs.length; i++) {
13467                    this.computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
13468                }
13469            }
13470        };
13471        TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) {
13472            var objs = forwardSegs.map(buildTimeGridSegCompareObj);
13473            var specs = [
13474                // put higher-pressure first
13475                { field: 'forwardPressure', order: -1 },
13476                // put segments that are closer to initial edge first (and favor ones with no coords yet)
13477                { field: 'backwardCoord', order: 1 }
13478            ].concat(this.context.view.eventOrderSpecs);
13479            objs.sort(function (obj0, obj1) {
13480                return core.compareByFieldSpecs(obj0, obj1, specs);
13481            });
13482            return objs.map(function (c) {
13483                return c._seg;
13484            });
13485        };
13486        // Given foreground event segments that have already had their position coordinates computed,
13487        // assigns position-related CSS values to their elements.
13488        TimeGridEventRenderer.prototype.assignSegCss = function (segs) {
13489            for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
13490                var seg = segs_1[_i];
13491                core.applyStyle(seg.el, this.generateSegCss(seg));
13492                if (seg.level > 0) {
13493                    seg.el.classList.add('fc-time-grid-event-inset');
13494                }
13495                // if the event is short that the title will be cut off,
13496                // attach a className that condenses the title into the time area.
13497                if (seg.eventRange.def.title && seg.bottom - seg.top < 30) {
13498                    seg.el.classList.add('fc-short'); // TODO: "condensed" is a better name
13499                }
13500            }
13501        };
13502        // Generates an object with CSS properties/values that should be applied to an event segment element.
13503        // Contains important positioning-related properties that should be applied to any event element, customized or not.
13504        TimeGridEventRenderer.prototype.generateSegCss = function (seg) {
13505            var shouldOverlap = this.context.options.slotEventOverlap;
13506            var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
13507            var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
13508            var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first
13509            var isRtl = this.timeGrid.isRtl;
13510            var left; // amount of space from left edge, a fraction of the total width
13511            var right; // amount of space from right edge, a fraction of the total width
13512            if (shouldOverlap) {
13513                // double the width, but don't go beyond the maximum forward coordinate (1.0)
13514                forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
13515            }
13516            if (isRtl) {
13517                left = 1 - forwardCoord;
13518                right = backwardCoord;
13519            }
13520            else {
13521                left = backwardCoord;
13522                right = 1 - forwardCoord;
13523            }
13524            props.zIndex = seg.level + 1; // convert from 0-base to 1-based
13525            props.left = left * 100 + '%';
13526            props.right = right * 100 + '%';
13527            if (shouldOverlap && seg.forwardPressure) {
13528                // add padding to the edge so that forward stacked events don't cover the resizer's icon
13529                props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
13530            }
13531            return props;
13532        };
13533        return TimeGridEventRenderer;
13534    }(core.FgEventRenderer));
13535    // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
13536    // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
13537    function buildSlotSegLevels(segs) {
13538        var levels = [];
13539        var i;
13540        var seg;
13541        var j;
13542        for (i = 0; i < segs.length; i++) {
13543            seg = segs[i];
13544            // go through all the levels and stop on the first level where there are no collisions
13545            for (j = 0; j < levels.length; j++) {
13546                if (!computeSlotSegCollisions(seg, levels[j]).length) {
13547                    break;
13548                }
13549            }
13550            seg.level = j;
13551            (levels[j] || (levels[j] = [])).push(seg);
13552        }
13553        return levels;
13554    }
13555    // For every segment, figure out the other segments that are in subsequent
13556    // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
13557    function computeForwardSlotSegs(levels) {
13558        var i;
13559        var level;
13560        var j;
13561        var seg;
13562        var k;
13563        for (i = 0; i < levels.length; i++) {
13564            level = levels[i];
13565            for (j = 0; j < level.length; j++) {
13566                seg = level[j];
13567                seg.forwardSegs = [];
13568                for (k = i + 1; k < levels.length; k++) {
13569                    computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
13570                }
13571            }
13572        }
13573    }
13574    // Figure out which path forward (via seg.forwardSegs) results in the longest path until
13575    // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
13576    function computeSlotSegPressures(seg) {
13577        var forwardSegs = seg.forwardSegs;
13578        var forwardPressure = 0;
13579        var i;
13580        var forwardSeg;
13581        if (seg.forwardPressure === undefined) { // not already computed
13582            for (i = 0; i < forwardSegs.length; i++) {
13583                forwardSeg = forwardSegs[i];
13584                // figure out the child's maximum forward path
13585                computeSlotSegPressures(forwardSeg);
13586                // either use the existing maximum, or use the child's forward pressure
13587                // plus one (for the forwardSeg itself)
13588                forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
13589            }
13590            seg.forwardPressure = forwardPressure;
13591        }
13592    }
13593    // Find all the segments in `otherSegs` that vertically collide with `seg`.
13594    // Append into an optionally-supplied `results` array and return.
13595    function computeSlotSegCollisions(seg, otherSegs, results) {
13596        if (results === void 0) { results = []; }
13597        for (var i = 0; i < otherSegs.length; i++) {
13598            if (isSlotSegCollision(seg, otherSegs[i])) {
13599                results.push(otherSegs[i]);
13600            }
13601        }
13602        return results;
13603    }
13604    // Do these segments occupy the same vertical space?
13605    function isSlotSegCollision(seg1, seg2) {
13606        return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
13607    }
13608    function buildTimeGridSegCompareObj(seg) {
13609        var obj = core.buildSegCompareObj(seg);
13610        obj.forwardPressure = seg.forwardPressure;
13611        obj.backwardCoord = seg.backwardCoord;
13612        return obj;
13613    }
13614
13615    var TimeGridMirrorRenderer = /** @class */ (function (_super) {
13616        __extends(TimeGridMirrorRenderer, _super);
13617        function TimeGridMirrorRenderer() {
13618            return _super !== null && _super.apply(this, arguments) || this;
13619        }
13620        TimeGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
13621            this.segsByCol = this.timeGrid.groupSegsByCol(segs);
13622            this.timeGrid.attachSegsByCol(this.segsByCol, this.timeGrid.mirrorContainerEls);
13623            this.sourceSeg = mirrorInfo.sourceSeg;
13624        };
13625        TimeGridMirrorRenderer.prototype.generateSegCss = function (seg) {
13626            var props = _super.prototype.generateSegCss.call(this, seg);
13627            var sourceSeg = this.sourceSeg;
13628            if (sourceSeg && sourceSeg.col === seg.col) {
13629                var sourceSegProps = _super.prototype.generateSegCss.call(this, sourceSeg);
13630                props.left = sourceSegProps.left;
13631                props.right = sourceSegProps.right;
13632                props.marginLeft = sourceSegProps.marginLeft;
13633                props.marginRight = sourceSegProps.marginRight;
13634            }
13635            return props;
13636        };
13637        return TimeGridMirrorRenderer;
13638    }(TimeGridEventRenderer));
13639
13640    var TimeGridFillRenderer = /** @class */ (function (_super) {
13641        __extends(TimeGridFillRenderer, _super);
13642        function TimeGridFillRenderer(timeGrid) {
13643            var _this = _super.call(this, timeGrid.context) || this;
13644            _this.timeGrid = timeGrid;
13645            return _this;
13646        }
13647        TimeGridFillRenderer.prototype.attachSegs = function (type, segs) {
13648            var timeGrid = this.timeGrid;
13649            var containerEls;
13650            // TODO: more efficient lookup
13651            if (type === 'bgEvent') {
13652                containerEls = timeGrid.bgContainerEls;
13653            }
13654            else if (type === 'businessHours') {
13655                containerEls = timeGrid.businessContainerEls;
13656            }
13657            else if (type === 'highlight') {
13658                containerEls = timeGrid.highlightContainerEls;
13659            }
13660            timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls);
13661            return segs.map(function (seg) {
13662                return seg.el;
13663            });
13664        };
13665        TimeGridFillRenderer.prototype.computeSegSizes = function (segs) {
13666            this.timeGrid.computeSegVerticals(segs);
13667        };
13668        TimeGridFillRenderer.prototype.assignSegSizes = function (segs) {
13669            this.timeGrid.assignSegVerticals(segs);
13670        };
13671        return TimeGridFillRenderer;
13672    }(core.FillRenderer));
13673
13674    /* A component that renders one or more columns of vertical time slots
13675    ----------------------------------------------------------------------------------------------------------------------*/
13676    // potential nice values for the slot-duration and interval-duration
13677    // from largest to smallest
13678    var AGENDA_STOCK_SUB_DURATIONS = [
13679        { hours: 1 },
13680        { minutes: 30 },
13681        { minutes: 15 },
13682        { seconds: 30 },
13683        { seconds: 15 }
13684    ];
13685    var TimeGrid = /** @class */ (function (_super) {
13686        __extends(TimeGrid, _super);
13687        function TimeGrid(context, el, renderProps) {
13688            var _this = _super.call(this, context, el) || this;
13689            _this.isSlatSizesDirty = false;
13690            _this.isColSizesDirty = false;
13691            _this.renderSlats = core.memoizeRendering(_this._renderSlats);
13692            var eventRenderer = _this.eventRenderer = new TimeGridEventRenderer(_this);
13693            var fillRenderer = _this.fillRenderer = new TimeGridFillRenderer(_this);
13694            _this.mirrorRenderer = new TimeGridMirrorRenderer(_this);
13695            var renderColumns = _this.renderColumns = core.memoizeRendering(_this._renderColumns, _this._unrenderColumns);
13696            _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderColumns]);
13697            _this.renderDateSelection = core.memoizeRendering(_this._renderDateSelection, _this._unrenderDateSelection, [renderColumns]);
13698            _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderColumns]);
13699            _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderColumns]);
13700            _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
13701            _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderColumns]);
13702            _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderColumns]);
13703            _this.processOptions();
13704            el.innerHTML =
13705                '<div class="fc-bg"></div>' +
13706                    '<div class="fc-slats"></div>' +
13707                    '<hr class="fc-divider ' + _this.theme.getClass('widgetHeader') + '" style="display:none" />';
13708            _this.rootBgContainerEl = el.querySelector('.fc-bg');
13709            _this.slatContainerEl = el.querySelector('.fc-slats');
13710            _this.bottomRuleEl = el.querySelector('.fc-divider');
13711            _this.renderProps = renderProps;
13712            return _this;
13713        }
13714        /* Options
13715        ------------------------------------------------------------------------------------------------------------------*/
13716        // Parses various options into properties of this object
13717        TimeGrid.prototype.processOptions = function () {
13718            var slotDuration = this.opt('slotDuration');
13719            var snapDuration = this.opt('snapDuration');
13720            var snapsPerSlot;
13721            var input;
13722            slotDuration = core.createDuration(slotDuration);
13723            snapDuration = snapDuration ? core.createDuration(snapDuration) : slotDuration;
13724            snapsPerSlot = core.wholeDivideDurations(slotDuration, snapDuration);
13725            if (snapsPerSlot === null) {
13726                snapDuration = slotDuration;
13727                snapsPerSlot = 1;
13728                // TODO: say warning?
13729            }
13730            this.slotDuration = slotDuration;
13731            this.snapDuration = snapDuration;
13732            this.snapsPerSlot = snapsPerSlot;
13733            // might be an array value (for TimelineView).
13734            // if so, getting the most granular entry (the last one probably).
13735            input = this.opt('slotLabelFormat');
13736            if (Array.isArray(input)) {
13737                input = input[input.length - 1];
13738            }
13739            this.labelFormat = core.createFormatter(input || {
13740                hour: 'numeric',
13741                minute: '2-digit',
13742                omitZeroMinute: true,
13743                meridiem: 'short'
13744            });
13745            input = this.opt('slotLabelInterval');
13746            this.labelInterval = input ?
13747                core.createDuration(input) :
13748                this.computeLabelInterval(slotDuration);
13749        };
13750        // Computes an automatic value for slotLabelInterval
13751        TimeGrid.prototype.computeLabelInterval = function (slotDuration) {
13752            var i;
13753            var labelInterval;
13754            var slotsPerLabel;
13755            // find the smallest stock label interval that results in more than one slots-per-label
13756            for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
13757                labelInterval = core.createDuration(AGENDA_STOCK_SUB_DURATIONS[i]);
13758                slotsPerLabel = core.wholeDivideDurations(labelInterval, slotDuration);
13759                if (slotsPerLabel !== null && slotsPerLabel > 1) {
13760                    return labelInterval;
13761                }
13762            }
13763            return slotDuration; // fall back
13764        };
13765        /* Rendering
13766        ------------------------------------------------------------------------------------------------------------------*/
13767        TimeGrid.prototype.render = function (props) {
13768            var cells = props.cells;
13769            this.colCnt = cells.length;
13770            this.renderSlats(props.dateProfile);
13771            this.renderColumns(props.cells, props.dateProfile);
13772            this.renderBusinessHours(props.businessHourSegs);
13773            this.renderDateSelection(props.dateSelectionSegs);
13774            this.renderFgEvents(props.fgEventSegs);
13775            this.renderBgEvents(props.bgEventSegs);
13776            this.renderEventSelection(props.eventSelection);
13777            this.renderEventDrag(props.eventDrag);
13778            this.renderEventResize(props.eventResize);
13779        };
13780        TimeGrid.prototype.destroy = function () {
13781            _super.prototype.destroy.call(this);
13782            // should unrender everything else too
13783            this.renderSlats.unrender();
13784            this.renderColumns.unrender();
13785        };
13786        TimeGrid.prototype.updateSize = function (isResize) {
13787            var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer;
13788            if (isResize || this.isSlatSizesDirty) {
13789                this.buildSlatPositions();
13790                this.isSlatSizesDirty = false;
13791            }
13792            if (isResize || this.isColSizesDirty) {
13793                this.buildColPositions();
13794                this.isColSizesDirty = false;
13795            }
13796            fillRenderer.computeSizes(isResize);
13797            eventRenderer.computeSizes(isResize);
13798            mirrorRenderer.computeSizes(isResize);
13799            fillRenderer.assignSizes(isResize);
13800            eventRenderer.assignSizes(isResize);
13801            mirrorRenderer.assignSizes(isResize);
13802        };
13803        TimeGrid.prototype._renderSlats = function (dateProfile) {
13804            var theme = this.theme;
13805            this.slatContainerEl.innerHTML =
13806                '<table class="' + theme.getClass('tableGrid') + '">' +
13807                    this.renderSlatRowHtml(dateProfile) +
13808                    '</table>';
13809            this.slatEls = core.findElements(this.slatContainerEl, 'tr');
13810            this.slatPositions = new core.PositionCache(this.el, this.slatEls, false, true // vertical
13811            );
13812            this.isSlatSizesDirty = true;
13813        };
13814        // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
13815        TimeGrid.prototype.renderSlatRowHtml = function (dateProfile) {
13816            var _a = this, dateEnv = _a.dateEnv, theme = _a.theme, isRtl = _a.isRtl;
13817            var html = '';
13818            var dayStart = core.startOfDay(dateProfile.renderRange.start);
13819            var slotTime = dateProfile.minTime;
13820            var slotIterator = core.createDuration(0);
13821            var slotDate; // will be on the view's first day, but we only care about its time
13822            var isLabeled;
13823            var axisHtml;
13824            // Calculate the time for each slot
13825            while (core.asRoughMs(slotTime) < core.asRoughMs(dateProfile.maxTime)) {
13826                slotDate = dateEnv.add(dayStart, slotTime);
13827                isLabeled = core.wholeDivideDurations(slotIterator, this.labelInterval) !== null;
13828                axisHtml =
13829                    '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '">' +
13830                        (isLabeled ?
13831                            '<span>' + // for matchCellWidths
13832                                core.htmlEscape(dateEnv.format(slotDate, this.labelFormat)) +
13833                                '</span>' :
13834                            '') +
13835                        '</td>';
13836                html +=
13837                    '<tr data-time="' + core.formatIsoTimeString(slotDate) + '"' +
13838                        (isLabeled ? '' : ' class="fc-minor"') +
13839                        '>' +
13840                        (!isRtl ? axisHtml : '') +
13841                        '<td class="' + theme.getClass('widgetContent') + '"></td>' +
13842                        (isRtl ? axisHtml : '') +
13843                        '</tr>';
13844                slotTime = core.addDurations(slotTime, this.slotDuration);
13845                slotIterator = core.addDurations(slotIterator, this.slotDuration);
13846            }
13847            return html;
13848        };
13849        TimeGrid.prototype._renderColumns = function (cells, dateProfile) {
13850            var _a = this, theme = _a.theme, dateEnv = _a.dateEnv, view = _a.view;
13851            var bgRow = new daygrid.DayBgRow(this.context);
13852            this.rootBgContainerEl.innerHTML =
13853                '<table class="' + theme.getClass('tableGrid') + '">' +
13854                    bgRow.renderHtml({
13855                        cells: cells,
13856                        dateProfile: dateProfile,
13857                        renderIntroHtml: this.renderProps.renderBgIntroHtml
13858                    }) +
13859                    '</table>';
13860            this.colEls = core.findElements(this.el, '.fc-day, .fc-disabled-day');
13861            for (var col = 0; col < this.colCnt; col++) {
13862                this.publiclyTrigger('dayRender', [
13863                    {
13864                        date: dateEnv.toDate(cells[col].date),
13865                        el: this.colEls[col],
13866                        view: view
13867                    }
13868                ]);
13869            }
13870            if (this.isRtl) {
13871                this.colEls.reverse();
13872            }
13873            this.colPositions = new core.PositionCache(this.el, this.colEls, true, // horizontal
13874            false);
13875            this.renderContentSkeleton();
13876            this.isColSizesDirty = true;
13877        };
13878        TimeGrid.prototype._unrenderColumns = function () {
13879            this.unrenderContentSkeleton();
13880        };
13881        /* Content Skeleton
13882        ------------------------------------------------------------------------------------------------------------------*/
13883        // Renders the DOM that the view's content will live in
13884        TimeGrid.prototype.renderContentSkeleton = function () {
13885            var parts = [];
13886            var skeletonEl;
13887            parts.push(this.renderProps.renderIntroHtml());
13888            for (var i = 0; i < this.colCnt; i++) {
13889                parts.push('<td>' +
13890                    '<div class="fc-content-col">' +
13891                    '<div class="fc-event-container fc-mirror-container"></div>' +
13892                    '<div class="fc-event-container"></div>' +
13893                    '<div class="fc-highlight-container"></div>' +
13894                    '<div class="fc-bgevent-container"></div>' +
13895                    '<div class="fc-business-container"></div>' +
13896                    '</div>' +
13897                    '</td>');
13898            }
13899            if (this.isRtl) {
13900                parts.reverse();
13901            }
13902            skeletonEl = this.contentSkeletonEl = core.htmlToElement('<div class="fc-content-skeleton">' +
13903                '<table>' +
13904                '<tr>' + parts.join('') + '</tr>' +
13905                '</table>' +
13906                '</div>');
13907            this.colContainerEls = core.findElements(skeletonEl, '.fc-content-col');
13908            this.mirrorContainerEls = core.findElements(skeletonEl, '.fc-mirror-container');
13909            this.fgContainerEls = core.findElements(skeletonEl, '.fc-event-container:not(.fc-mirror-container)');
13910            this.bgContainerEls = core.findElements(skeletonEl, '.fc-bgevent-container');
13911            this.highlightContainerEls = core.findElements(skeletonEl, '.fc-highlight-container');
13912            this.businessContainerEls = core.findElements(skeletonEl, '.fc-business-container');
13913            if (this.isRtl) {
13914                this.colContainerEls.reverse();
13915                this.mirrorContainerEls.reverse();
13916                this.fgContainerEls.reverse();
13917                this.bgContainerEls.reverse();
13918                this.highlightContainerEls.reverse();
13919                this.businessContainerEls.reverse();
13920            }
13921            this.el.appendChild(skeletonEl);
13922        };
13923        TimeGrid.prototype.unrenderContentSkeleton = function () {
13924            core.removeElement(this.contentSkeletonEl);
13925        };
13926        // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
13927        TimeGrid.prototype.groupSegsByCol = function (segs) {
13928            var segsByCol = [];
13929            var i;
13930            for (i = 0; i < this.colCnt; i++) {
13931                segsByCol.push([]);
13932            }
13933            for (i = 0; i < segs.length; i++) {
13934                segsByCol[segs[i].col].push(segs[i]);
13935            }
13936            return segsByCol;
13937        };
13938        // Given segments grouped by column, insert the segments' elements into a parallel array of container
13939        // elements, each living within a column.
13940        TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) {
13941            var col;
13942            var segs;
13943            var i;
13944            for (col = 0; col < this.colCnt; col++) { // iterate each column grouping
13945                segs = segsByCol[col];
13946                for (i = 0; i < segs.length; i++) {
13947                    containerEls[col].appendChild(segs[i].el);
13948                }
13949            }
13950        };
13951        /* Now Indicator
13952        ------------------------------------------------------------------------------------------------------------------*/
13953        TimeGrid.prototype.getNowIndicatorUnit = function () {
13954            return 'minute'; // will refresh on the minute
13955        };
13956        TimeGrid.prototype.renderNowIndicator = function (segs, date) {
13957            // HACK: if date columns not ready for some reason (scheduler)
13958            if (!this.colContainerEls) {
13959                return;
13960            }
13961            var top = this.computeDateTop(date);
13962            var nodes = [];
13963            var i;
13964            // render lines within the columns
13965            for (i = 0; i < segs.length; i++) {
13966                var lineEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-line' });
13967                lineEl.style.top = top + 'px';
13968                this.colContainerEls[segs[i].col].appendChild(lineEl);
13969                nodes.push(lineEl);
13970            }
13971            // render an arrow over the axis
13972            if (segs.length > 0) { // is the current time in view?
13973                var arrowEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-arrow' });
13974                arrowEl.style.top = top + 'px';
13975                this.contentSkeletonEl.appendChild(arrowEl);
13976                nodes.push(arrowEl);
13977            }
13978            this.nowIndicatorEls = nodes;
13979        };
13980        TimeGrid.prototype.unrenderNowIndicator = function () {
13981            if (this.nowIndicatorEls) {
13982                this.nowIndicatorEls.forEach(core.removeElement);
13983                this.nowIndicatorEls = null;
13984            }
13985        };
13986        /* Coordinates
13987        ------------------------------------------------------------------------------------------------------------------*/
13988        TimeGrid.prototype.getTotalSlatHeight = function () {
13989            return this.slatContainerEl.getBoundingClientRect().height;
13990        };
13991        // Computes the top coordinate, relative to the bounds of the grid, of the given date.
13992        // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
13993        TimeGrid.prototype.computeDateTop = function (when, startOfDayDate) {
13994            if (!startOfDayDate) {
13995                startOfDayDate = core.startOfDay(when);
13996            }
13997            return this.computeTimeTop(core.createDuration(when.valueOf() - startOfDayDate.valueOf()));
13998        };
13999        // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
14000        TimeGrid.prototype.computeTimeTop = function (duration) {
14001            var len = this.slatEls.length;
14002            var dateProfile = this.props.dateProfile;
14003            var slatCoverage = (duration.milliseconds - core.asRoughMs(dateProfile.minTime)) / core.asRoughMs(this.slotDuration); // floating-point value of # of slots covered
14004            var slatIndex;
14005            var slatRemainder;
14006            // compute a floating-point number for how many slats should be progressed through.
14007            // from 0 to number of slats (inclusive)
14008            // constrained because minTime/maxTime might be customized.
14009            slatCoverage = Math.max(0, slatCoverage);
14010            slatCoverage = Math.min(len, slatCoverage);
14011            // an integer index of the furthest whole slat
14012            // from 0 to number slats (*exclusive*, so len-1)
14013            slatIndex = Math.floor(slatCoverage);
14014            slatIndex = Math.min(slatIndex, len - 1);
14015            // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
14016            // could be 1.0 if slatCoverage is covering *all* the slots
14017            slatRemainder = slatCoverage - slatIndex;
14018            return this.slatPositions.tops[slatIndex] +
14019                this.slatPositions.getHeight(slatIndex) * slatRemainder;
14020        };
14021        // For each segment in an array, computes and assigns its top and bottom properties
14022        TimeGrid.prototype.computeSegVerticals = function (segs) {
14023            var eventMinHeight = this.opt('timeGridEventMinHeight');
14024            var i;
14025            var seg;
14026            var dayDate;
14027            for (i = 0; i < segs.length; i++) {
14028                seg = segs[i];
14029                dayDate = this.props.cells[seg.col].date;
14030                seg.top = this.computeDateTop(seg.start, dayDate);
14031                seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.end, dayDate));
14032            }
14033        };
14034        // Given segments that already have their top/bottom properties computed, applies those values to
14035        // the segments' elements.
14036        TimeGrid.prototype.assignSegVerticals = function (segs) {
14037            var i;
14038            var seg;
14039            for (i = 0; i < segs.length; i++) {
14040                seg = segs[i];
14041                core.applyStyle(seg.el, this.generateSegVerticalCss(seg));
14042            }
14043        };
14044        // Generates an object with CSS properties for the top/bottom coordinates of a segment element
14045        TimeGrid.prototype.generateSegVerticalCss = function (seg) {
14046            return {
14047                top: seg.top,
14048                bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container
14049            };
14050        };
14051        /* Sizing
14052        ------------------------------------------------------------------------------------------------------------------*/
14053        TimeGrid.prototype.buildPositionCaches = function () {
14054            this.buildColPositions();
14055            this.buildSlatPositions();
14056        };
14057        TimeGrid.prototype.buildColPositions = function () {
14058            this.colPositions.build();
14059        };
14060        TimeGrid.prototype.buildSlatPositions = function () {
14061            this.slatPositions.build();
14062        };
14063        /* Hit System
14064        ------------------------------------------------------------------------------------------------------------------*/
14065        TimeGrid.prototype.positionToHit = function (positionLeft, positionTop) {
14066            var _a = this, dateEnv = _a.dateEnv, snapsPerSlot = _a.snapsPerSlot, slatPositions = _a.slatPositions, colPositions = _a.colPositions;
14067            var colIndex = colPositions.leftToIndex(positionLeft);
14068            var slatIndex = slatPositions.topToIndex(positionTop);
14069            if (colIndex != null && slatIndex != null) {
14070                var slatTop = slatPositions.tops[slatIndex];
14071                var slatHeight = slatPositions.getHeight(slatIndex);
14072                var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
14073                var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
14074                var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
14075                var dayDate = this.props.cells[colIndex].date;
14076                var time = core.addDurations(this.props.dateProfile.minTime, core.multiplyDuration(this.snapDuration, snapIndex));
14077                var start = dateEnv.add(dayDate, time);
14078                var end = dateEnv.add(start, this.snapDuration);
14079                return {
14080                    col: colIndex,
14081                    dateSpan: {
14082                        range: { start: start, end: end },
14083                        allDay: false
14084                    },
14085                    dayEl: this.colEls[colIndex],
14086                    relativeRect: {
14087                        left: colPositions.lefts[colIndex],
14088                        right: colPositions.rights[colIndex],
14089                        top: slatTop,
14090                        bottom: slatTop + slatHeight
14091                    }
14092                };
14093            }
14094        };
14095        /* Event Drag Visualization
14096        ------------------------------------------------------------------------------------------------------------------*/
14097        TimeGrid.prototype._renderEventDrag = function (state) {
14098            if (state) {
14099                this.eventRenderer.hideByHash(state.affectedInstances);
14100                if (state.isEvent) {
14101                    this.mirrorRenderer.renderSegs(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
14102                }
14103                else {
14104                    this.fillRenderer.renderSegs('highlight', state.segs);
14105                }
14106            }
14107        };
14108        TimeGrid.prototype._unrenderEventDrag = function (state) {
14109            if (state) {
14110                this.eventRenderer.showByHash(state.affectedInstances);
14111                this.mirrorRenderer.unrender(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
14112                this.fillRenderer.unrender('highlight');
14113            }
14114        };
14115        /* Event Resize Visualization
14116        ------------------------------------------------------------------------------------------------------------------*/
14117        TimeGrid.prototype._renderEventResize = function (state) {
14118            if (state) {
14119                this.eventRenderer.hideByHash(state.affectedInstances);
14120                this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
14121            }
14122        };
14123        TimeGrid.prototype._unrenderEventResize = function (state) {
14124            if (state) {
14125                this.eventRenderer.showByHash(state.affectedInstances);
14126                this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
14127            }
14128        };
14129        /* Selection
14130        ------------------------------------------------------------------------------------------------------------------*/
14131        // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
14132        TimeGrid.prototype._renderDateSelection = function (segs) {
14133            if (segs) {
14134                if (this.opt('selectMirror')) {
14135                    this.mirrorRenderer.renderSegs(segs, { isSelecting: true });
14136                }
14137                else {
14138                    this.fillRenderer.renderSegs('highlight', segs);
14139                }
14140            }
14141        };
14142        TimeGrid.prototype._unrenderDateSelection = function (segs) {
14143            this.mirrorRenderer.unrender(segs, { isSelecting: true });
14144            this.fillRenderer.unrender('highlight');
14145        };
14146        return TimeGrid;
14147    }(core.DateComponent));
14148
14149    var AllDaySplitter = /** @class */ (function (_super) {
14150        __extends(AllDaySplitter, _super);
14151        function AllDaySplitter() {
14152            return _super !== null && _super.apply(this, arguments) || this;
14153        }
14154        AllDaySplitter.prototype.getKeyInfo = function () {
14155            return {
14156                allDay: {},
14157                timed: {}
14158            };
14159        };
14160        AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
14161            if (dateSpan.allDay) {
14162                return ['allDay'];
14163            }
14164            else {
14165                return ['timed'];
14166            }
14167        };
14168        AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
14169            if (!eventDef.allDay) {
14170                return ['timed'];
14171            }
14172            else if (core.hasBgRendering(eventDef)) {
14173                return ['timed', 'allDay'];
14174            }
14175            else {
14176                return ['allDay'];
14177            }
14178        };
14179        return AllDaySplitter;
14180    }(core.Splitter));
14181
14182    var TIMEGRID_ALL_DAY_EVENT_LIMIT = 5;
14183    var WEEK_HEADER_FORMAT = core.createFormatter({ week: 'short' });
14184    /* An abstract class for all timegrid-related views. Displays one more columns with time slots running vertically.
14185    ----------------------------------------------------------------------------------------------------------------------*/
14186    // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
14187    // Responsible for managing width/height.
14188    var TimeGridView = /** @class */ (function (_super) {
14189        __extends(TimeGridView, _super);
14190        function TimeGridView(context, viewSpec, dateProfileGenerator, parentEl) {
14191            var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
14192            _this.splitter = new AllDaySplitter();
14193            /* Header Render Methods
14194            ------------------------------------------------------------------------------------------------------------------*/
14195            // Generates the HTML that will go before the day-of week header cells
14196            _this.renderHeadIntroHtml = function () {
14197                var _a = _this, theme = _a.theme, dateEnv = _a.dateEnv;
14198                var range = _this.props.dateProfile.renderRange;
14199                var dayCnt = core.diffDays(range.start, range.end);
14200                var weekText;
14201                if (_this.opt('weekNumbers')) {
14202                    weekText = dateEnv.format(range.start, WEEK_HEADER_FORMAT);
14203                    return '' +
14204                        '<th class="fc-axis fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '>' +
14205                        core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
14206                        _this, { date: range.start, type: 'week', forceOff: dayCnt > 1 }, core.htmlEscape(weekText) // inner HTML
14207                        ) +
14208                        '</th>';
14209                }
14210                else {
14211                    return '<th class="fc-axis ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '></th>';
14212                }
14213            };
14214            /* Time Grid Render Methods
14215            ------------------------------------------------------------------------------------------------------------------*/
14216            // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
14217            _this.renderTimeGridBgIntroHtml = function () {
14218                var theme = _this.theme;
14219                return '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '></td>';
14220            };
14221            // Generates the HTML that goes before all other types of cells.
14222            // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
14223            _this.renderTimeGridIntroHtml = function () {
14224                return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
14225            };
14226            /* Day Grid Render Methods
14227            ------------------------------------------------------------------------------------------------------------------*/
14228            // Generates the HTML that goes before the all-day cells
14229            _this.renderDayGridBgIntroHtml = function () {
14230                var theme = _this.theme;
14231                return '' +
14232                    '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '>' +
14233                    '<span>' + // needed for matchCellWidths
14234                    core.getAllDayHtml(_this) +
14235                    '</span>' +
14236                    '</td>';
14237            };
14238            // Generates the HTML that goes before all other types of cells.
14239            // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
14240            _this.renderDayGridIntroHtml = function () {
14241                return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
14242            };
14243            _this.el.classList.add('fc-timeGrid-view');
14244            _this.el.innerHTML = _this.renderSkeletonHtml();
14245            _this.scroller = new core.ScrollComponent('hidden', // overflow x
14246            'auto' // overflow y
14247            );
14248            var timeGridWrapEl = _this.scroller.el;
14249            _this.el.querySelector('.fc-body > tr > td').appendChild(timeGridWrapEl);
14250            timeGridWrapEl.classList.add('fc-time-grid-container');
14251            var timeGridEl = core.createElement('div', { className: 'fc-time-grid' });
14252            timeGridWrapEl.appendChild(timeGridEl);
14253            _this.timeGrid = new TimeGrid(_this.context, timeGridEl, {
14254                renderBgIntroHtml: _this.renderTimeGridBgIntroHtml,
14255                renderIntroHtml: _this.renderTimeGridIntroHtml
14256            });
14257            if (_this.opt('allDaySlot')) { // should we display the "all-day" area?
14258                _this.dayGrid = new daygrid.DayGrid(// the all-day subcomponent of this view
14259                _this.context, _this.el.querySelector('.fc-day-grid'), {
14260                    renderNumberIntroHtml: _this.renderDayGridIntroHtml,
14261                    renderBgIntroHtml: _this.renderDayGridBgIntroHtml,
14262                    renderIntroHtml: _this.renderDayGridIntroHtml,
14263                    colWeekNumbersVisible: false,
14264                    cellWeekNumbersVisible: false
14265                });
14266                // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
14267                var dividerEl = _this.el.querySelector('.fc-divider');
14268                _this.dayGrid.bottomCoordPadding = dividerEl.getBoundingClientRect().height;
14269            }
14270            return _this;
14271        }
14272        TimeGridView.prototype.destroy = function () {
14273            _super.prototype.destroy.call(this);
14274            this.timeGrid.destroy();
14275            if (this.dayGrid) {
14276                this.dayGrid.destroy();
14277            }
14278            this.scroller.destroy();
14279        };
14280        /* Rendering
14281        ------------------------------------------------------------------------------------------------------------------*/
14282        // Builds the HTML skeleton for the view.
14283        // The day-grid and time-grid components will render inside containers defined by this HTML.
14284        TimeGridView.prototype.renderSkeletonHtml = function () {
14285            var theme = this.theme;
14286            return '' +
14287                '<table class="' + theme.getClass('tableGrid') + '">' +
14288                (this.opt('columnHeader') ?
14289                    '<thead class="fc-head">' +
14290                        '<tr>' +
14291                        '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
14292                        '</tr>' +
14293                        '</thead>' :
14294                    '') +
14295                '<tbody class="fc-body">' +
14296                '<tr>' +
14297                '<td class="' + theme.getClass('widgetContent') + '">' +
14298                (this.opt('allDaySlot') ?
14299                    '<div class="fc-day-grid"></div>' +
14300                        '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" />' :
14301                    '') +
14302                '</td>' +
14303                '</tr>' +
14304                '</tbody>' +
14305                '</table>';
14306        };
14307        /* Now Indicator
14308        ------------------------------------------------------------------------------------------------------------------*/
14309        TimeGridView.prototype.getNowIndicatorUnit = function () {
14310            return this.timeGrid.getNowIndicatorUnit();
14311        };
14312        // subclasses should implement
14313        // renderNowIndicator(date: DateMarker) {
14314        // }
14315        TimeGridView.prototype.unrenderNowIndicator = function () {
14316            this.timeGrid.unrenderNowIndicator();
14317        };
14318        /* Dimensions
14319        ------------------------------------------------------------------------------------------------------------------*/
14320        TimeGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
14321            _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first
14322            this.timeGrid.updateSize(isResize);
14323            if (this.dayGrid) {
14324                this.dayGrid.updateSize(isResize);
14325            }
14326        };
14327        // Adjusts the vertical dimensions of the view to the specified values
14328        TimeGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
14329            var _this = this;
14330            var eventLimit;
14331            var scrollerHeight;
14332            var scrollbarWidths;
14333            // make all axis cells line up
14334            this.axisWidth = core.matchCellWidths(core.findElements(this.el, '.fc-axis'));
14335            // hack to give the view some height prior to timeGrid's columns being rendered
14336            // TODO: separate setting height from scroller VS timeGrid.
14337            if (!this.timeGrid.colEls) {
14338                if (!isAuto) {
14339                    scrollerHeight = this.computeScrollerHeight(viewHeight);
14340                    this.scroller.setHeight(scrollerHeight);
14341                }
14342                return;
14343            }
14344            // set of fake row elements that must compensate when scroller has scrollbars
14345            var noScrollRowEls = core.findElements(this.el, '.fc-row').filter(function (node) {
14346                return !_this.scroller.el.contains(node);
14347            });
14348            // reset all dimensions back to the original state
14349            this.timeGrid.bottomRuleEl.style.display = 'none'; // will be shown later if this <hr> is necessary
14350            this.scroller.clear(); // sets height to 'auto' and clears overflow
14351            noScrollRowEls.forEach(core.uncompensateScroll);
14352            // limit number of events in the all-day area
14353            if (this.dayGrid) {
14354                this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
14355                eventLimit = this.opt('eventLimit');
14356                if (eventLimit && typeof eventLimit !== 'number') {
14357                    eventLimit = TIMEGRID_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number
14358                }
14359                if (eventLimit) {
14360                    this.dayGrid.limitRows(eventLimit);
14361                }
14362            }
14363            if (!isAuto) { // should we force dimensions of the scroll container?
14364                scrollerHeight = this.computeScrollerHeight(viewHeight);
14365                this.scroller.setHeight(scrollerHeight);
14366                scrollbarWidths = this.scroller.getScrollbarWidths();
14367                if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
14368                    // make the all-day and header rows lines up
14369                    noScrollRowEls.forEach(function (rowEl) {
14370                        core.compensateScroll(rowEl, scrollbarWidths);
14371                    });
14372                    // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
14373                    // and reapply the desired height to the scroller.
14374                    scrollerHeight = this.computeScrollerHeight(viewHeight);
14375                    this.scroller.setHeight(scrollerHeight);
14376                }
14377                // guarantees the same scrollbar widths
14378                this.scroller.lockOverflow(scrollbarWidths);
14379                // if there's any space below the slats, show the horizontal rule.
14380                // this won't cause any new overflow, because lockOverflow already called.
14381                if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) {
14382                    this.timeGrid.bottomRuleEl.style.display = '';
14383                }
14384            }
14385        };
14386        // given a desired total height of the view, returns what the height of the scroller should be
14387        TimeGridView.prototype.computeScrollerHeight = function (viewHeight) {
14388            return viewHeight -
14389                core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
14390        };
14391        /* Scroll
14392        ------------------------------------------------------------------------------------------------------------------*/
14393        // Computes the initial pre-configured scroll state prior to allowing the user to change it
14394        TimeGridView.prototype.computeDateScroll = function (duration) {
14395            var top = this.timeGrid.computeTimeTop(duration);
14396            // zoom can give weird floating-point values. rather scroll a little bit further
14397            top = Math.ceil(top);
14398            if (top) {
14399                top++; // to overcome top border that slots beyond the first have. looks better
14400            }
14401            return { top: top };
14402        };
14403        TimeGridView.prototype.queryDateScroll = function () {
14404            return { top: this.scroller.getScrollTop() };
14405        };
14406        TimeGridView.prototype.applyDateScroll = function (scroll) {
14407            if (scroll.top !== undefined) {
14408                this.scroller.setScrollTop(scroll.top);
14409            }
14410        };
14411        // Generates an HTML attribute string for setting the width of the axis, if it is known
14412        TimeGridView.prototype.axisStyleAttr = function () {
14413            if (this.axisWidth != null) {
14414                return 'style="width:' + this.axisWidth + 'px"';
14415            }
14416            return '';
14417        };
14418        return TimeGridView;
14419    }(core.View));
14420    TimeGridView.prototype.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering
14421
14422    var SimpleTimeGrid = /** @class */ (function (_super) {
14423        __extends(SimpleTimeGrid, _super);
14424        function SimpleTimeGrid(context, timeGrid) {
14425            var _this = _super.call(this, context, timeGrid.el) || this;
14426            _this.buildDayRanges = core.memoize(buildDayRanges);
14427            _this.slicer = new TimeGridSlicer();
14428            _this.timeGrid = timeGrid;
14429            context.calendar.registerInteractiveComponent(_this, {
14430                el: _this.timeGrid.el
14431            });
14432            return _this;
14433        }
14434        SimpleTimeGrid.prototype.destroy = function () {
14435            _super.prototype.destroy.call(this);
14436            this.calendar.unregisterInteractiveComponent(this);
14437        };
14438        SimpleTimeGrid.prototype.render = function (props) {
14439            var dateProfile = props.dateProfile, dayTable = props.dayTable;
14440            var dayRanges = this.dayRanges = this.buildDayRanges(dayTable, dateProfile, this.dateEnv);
14441            this.timeGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, null, this.timeGrid, dayRanges), { dateProfile: dateProfile, cells: dayTable.cells[0] }));
14442        };
14443        SimpleTimeGrid.prototype.renderNowIndicator = function (date) {
14444            this.timeGrid.renderNowIndicator(this.slicer.sliceNowDate(date, this.timeGrid, this.dayRanges), date);
14445        };
14446        SimpleTimeGrid.prototype.buildPositionCaches = function () {
14447            this.timeGrid.buildPositionCaches();
14448        };
14449        SimpleTimeGrid.prototype.queryHit = function (positionLeft, positionTop) {
14450            var rawHit = this.timeGrid.positionToHit(positionLeft, positionTop);
14451            if (rawHit) {
14452                return {
14453                    component: this.timeGrid,
14454                    dateSpan: rawHit.dateSpan,
14455                    dayEl: rawHit.dayEl,
14456                    rect: {
14457                        left: rawHit.relativeRect.left,
14458                        right: rawHit.relativeRect.right,
14459                        top: rawHit.relativeRect.top,
14460                        bottom: rawHit.relativeRect.bottom
14461                    },
14462                    layer: 0
14463                };
14464            }
14465        };
14466        return SimpleTimeGrid;
14467    }(core.DateComponent));
14468    function buildDayRanges(dayTable, dateProfile, dateEnv) {
14469        var ranges = [];
14470        for (var _i = 0, _a = dayTable.headerDates; _i < _a.length; _i++) {
14471            var date = _a[_i];
14472            ranges.push({
14473                start: dateEnv.add(date, dateProfile.minTime),
14474                end: dateEnv.add(date, dateProfile.maxTime)
14475            });
14476        }
14477        return ranges;
14478    }
14479    var TimeGridSlicer = /** @class */ (function (_super) {
14480        __extends(TimeGridSlicer, _super);
14481        function TimeGridSlicer() {
14482            return _super !== null && _super.apply(this, arguments) || this;
14483        }
14484        TimeGridSlicer.prototype.sliceRange = function (range, dayRanges) {
14485            var segs = [];
14486            for (var col = 0; col < dayRanges.length; col++) {
14487                var segRange = core.intersectRanges(range, dayRanges[col]);
14488                if (segRange) {
14489                    segs.push({
14490                        start: segRange.start,
14491                        end: segRange.end,
14492                        isStart: segRange.start.valueOf() === range.start.valueOf(),
14493                        isEnd: segRange.end.valueOf() === range.end.valueOf(),
14494                        col: col
14495                    });
14496                }
14497            }
14498            return segs;
14499        };
14500        return TimeGridSlicer;
14501    }(core.Slicer));
14502
14503    var TimeGridView$1 = /** @class */ (function (_super) {
14504        __extends(TimeGridView, _super);
14505        function TimeGridView(_context, viewSpec, dateProfileGenerator, parentEl) {
14506            var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this;
14507            _this.buildDayTable = core.memoize(buildDayTable);
14508            if (_this.opt('columnHeader')) {
14509                _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container'));
14510            }
14511            _this.simpleTimeGrid = new SimpleTimeGrid(_this.context, _this.timeGrid);
14512            if (_this.dayGrid) {
14513                _this.simpleDayGrid = new daygrid.SimpleDayGrid(_this.context, _this.dayGrid);
14514            }
14515            return _this;
14516        }
14517        TimeGridView.prototype.destroy = function () {
14518            _super.prototype.destroy.call(this);
14519            if (this.header) {
14520                this.header.destroy();
14521            }
14522            this.simpleTimeGrid.destroy();
14523            if (this.simpleDayGrid) {
14524                this.simpleDayGrid.destroy();
14525            }
14526        };
14527        TimeGridView.prototype.render = function (props) {
14528            _super.prototype.render.call(this, props); // for flags for updateSize
14529            var dateProfile = this.props.dateProfile;
14530            var dayTable = this.buildDayTable(dateProfile, this.dateProfileGenerator);
14531            var splitProps = this.splitter.splitProps(props);
14532            if (this.header) {
14533                this.header.receiveProps({
14534                    dateProfile: dateProfile,
14535                    dates: dayTable.headerDates,
14536                    datesRepDistinctDays: true,
14537                    renderIntroHtml: this.renderHeadIntroHtml
14538                });
14539            }
14540            this.simpleTimeGrid.receiveProps(__assign({}, splitProps['timed'], { dateProfile: dateProfile,
14541                dayTable: dayTable }));
14542            if (this.simpleDayGrid) {
14543                this.simpleDayGrid.receiveProps(__assign({}, splitProps['allDay'], { dateProfile: dateProfile,
14544                    dayTable: dayTable, nextDayThreshold: this.nextDayThreshold, isRigid: false }));
14545            }
14546        };
14547        TimeGridView.prototype.renderNowIndicator = function (date) {
14548            this.simpleTimeGrid.renderNowIndicator(date);
14549        };
14550        return TimeGridView;
14551    }(TimeGridView));
14552    function buildDayTable(dateProfile, dateProfileGenerator) {
14553        var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator);
14554        return new core.DayTable(daySeries, false);
14555    }
14556
14557    var main = core.createPlugin({
14558        defaultView: 'timeGridWeek',
14559        views: {
14560            timeGrid: {
14561                class: TimeGridView$1,
14562                allDaySlot: true,
14563                slotDuration: '00:30:00',
14564                slotEventOverlap: true // a bad name. confused with overlap/constraint system
14565            },
14566            timeGridDay: {
14567                type: 'timeGrid',
14568                duration: { days: 1 }
14569            },
14570            timeGridWeek: {
14571                type: 'timeGrid',
14572                duration: { weeks: 1 }
14573            }
14574        }
14575    });
14576
14577    exports.AbstractTimeGridView = TimeGridView;
14578    exports.TimeGrid = TimeGrid;
14579    exports.TimeGridSlicer = TimeGridSlicer;
14580    exports.TimeGridView = TimeGridView$1;
14581    exports.buildDayRanges = buildDayRanges;
14582    exports.buildDayTable = buildDayTable;
14583    exports.default = main;
14584
14585    Object.defineProperty(exports, '__esModule', { value: true });
14586
14587}));
14588
14589}
14589,{"@fullcalendar/core":2,"@fullcalendar/daygrid":3}],9:[function(require,module,exports){
vendor: 14,690 bytes, line 14590
14590!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AOS=t():e.AOS=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return e[o].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="dist/",t(0)}([function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}var i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},r=n(1),a=(o(r),n(6)),u=o(a),c=n(7),s=o(c),f=n(8),d=o(f),l=n(9),p=o(l),m=n(10),b=o(m),v=n(11),y=o(v),g=n(14),h=o(g),w=[],k=!1,x={offset:120,delay:0,easing:"ease",duration:400,disable:!1,once:!1,startEvent:"DOMContentLoaded",throttleDelay:99,debounceDelay:50,disableMutationObserver:!1},j=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(e&&(k=!0),k)return w=(0,y.default)(w,x),(0,b.default)(w,x.once),w},O=function(){w=(0,h.default)(),j()},M=function(){w.forEach(function(e,t){e.node.removeAttribute("data-aos"),e.node.removeAttribute("data-aos-easing"),e.node.removeAttribute("data-aos-duration"),e.node.removeAttribute("data-aos-delay")})},S=function(e){return e===!0||"mobile"===e&&p.default.mobile()||"phone"===e&&p.default.phone()||"tablet"===e&&p.default.tablet()||"function"==typeof e&&e()===!0},_=function(e){x=i(x,e),w=(0,h.default)();var t=document.all&&!window.atob;return S(x.disable)||t?M():(x.disableMutationObserver||d.default.isSupported()||(console.info('\n      aos: MutationObserver is not supported on this browser,\n      code mutations observing has been disabled.\n      You may have to call "refreshHard()" by yourself.\n    '),x.disableMutationObserver=!0),document.querySelector("body").setAttribute("data-aos-easing",x.easing),document.querySelector("body").setAttribute("data-aos-duration",x.duration),document.querySelector("body").setAttribute("data-aos-delay",x.delay),"DOMContentLoaded"===x.startEvent&&["complete","interactive"].indexOf(document.readyState)>-1?j(!0):"load"===x.startEvent?window.addEventListener(x.startEvent,function(){j(!0)}):document.addEventListener(x.startEvent,function(){j(!0)}),window.addEventListener("resize",(0,s.default)(j,x.debounceDelay,!0)),window.addEventListener("orientationchange",(0,s.default)(j,x.debounceDelay,!0)),window.addEventListener("scroll",(0,u.default)(function(){(0,b.default)(w,x.once)},x.throttleDelay)),x.disableMutationObserver||d.default.ready("[data-aos]",O),w)};e.exports={init:_,refresh:j,refreshHard:O}},function(e,t){},,,,,function(e,t){(function(t){"use strict";function n(e,t,n){function o(t){var n=b,o=v;return b=v=void 0,k=t,g=e.apply(o,n)}function r(e){return k=e,h=setTimeout(f,t),M?o(e):g}function a(e){var n=e-w,o=e-k,i=t-n;return S?j(i,y-o):i}function c(e){var n=e-w,o=e-k;return void 0===w||n>=t||n<0||S&&o>=y}function f(){var e=O();return c(e)?d(e):void(h=setTimeout(f,a(e)))}function d(e){return h=void 0,_&&b?o(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),k=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(O())}function m(){var e=O(),n=c(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(S)return h=setTimeout(f,t),o(w)}return void 0===h&&(h=setTimeout(f,t)),g}var b,v,y,g,h,w,k=0,M=!1,S=!1,_=!0;if("function"!=typeof e)throw new TypeError(s);return t=u(t)||0,i(n)&&(M=!!n.leading,S="maxWait"in n,y=S?x(u(n.maxWait)||0,t):y,_="trailing"in n?!!n.trailing:_),m.cancel=l,m.flush=p,m}function o(e,t,o){var r=!0,a=!0;if("function"!=typeof e)throw new TypeError(s);return i(o)&&(r="leading"in o?!!o.leading:r,a="trailing"in o?!!o.trailing:a),n(e,t,{leading:r,maxWait:t,trailing:a})}function i(e){var t="undefined"==typeof e?"undefined":c(e);return!!e&&("object"==t||"function"==t)}function r(e){return!!e&&"object"==("undefined"==typeof e?"undefined":c(e))}function a(e){return"symbol"==("undefined"==typeof e?"undefined":c(e))||r(e)&&k.call(e)==d}function u(e){if("number"==typeof e)return e;if(a(e))return f;if(i(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(l,"");var n=m.test(e);return n||b.test(e)?v(e.slice(2),n?2:8):p.test(e)?f:+e}var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},s="Expected a function",f=NaN,d="[object Symbol]",l=/^\s+|\s+$/g,p=/^[-+]0x[0-9a-f]+$/i,m=/^0b[01]+$/i,b=/^0o[0-7]+$/i,v=parseInt,y="object"==("undefined"==typeof t?"undefined":c(t))&&t&&t.Object===Object&&t,g="object"==("undefined"==typeof self?"undefined":c(self))&&self&&self.Object===Object&&self,h=y||g||Function("return this")(),w=Object.prototype,k=w.toString,x=Math.max,j=Math.min,O=function(){return h.Date.now()};e.exports=o}).call(t,function(){return this}())},function(e,t){(function(t){"use strict";function n(e,t,n){function i(t){var n=b,o=v;return b=v=void 0,O=t,g=e.apply(o,n)}function r(e){return O=e,h=setTimeout(f,t),M?i(e):g}function u(e){var n=e-w,o=e-O,i=t-n;return S?x(i,y-o):i}function s(e){var n=e-w,o=e-O;return void 0===w||n>=t||n<0||S&&o>=y}function f(){var e=j();return s(e)?d(e):void(h=setTimeout(f,u(e)))}function d(e){return h=void 0,_&&b?i(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),O=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(j())}function m(){var e=j(),n=s(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(S)return h=setTimeout(f,t),i(w)}return void 0===h&&(h=setTimeout(f,t)),g}var b,v,y,g,h,w,O=0,M=!1,S=!1,_=!0;if("function"!=typeof e)throw new TypeError(c);return t=a(t)||0,o(n)&&(M=!!n.leading,S="maxWait"in n,y=S?k(a(n.maxWait)||0,t):y,_="trailing"in n?!!n.trailing:_),m.cancel=l,m.flush=p,m}function o(e){var t="undefined"==typeof e?"undefined":u(e);return!!e&&("object"==t||"function"==t)}function i(e){return!!e&&"object"==("undefined"==typeof e?"undefined":u(e))}function r(e){return"symbol"==("undefined"==typeof e?"undefined":u(e))||i(e)&&w.call(e)==f}function a(e){if("number"==typeof e)return e;if(r(e))return s;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(d,"");var n=p.test(e);return n||m.test(e)?b(e.slice(2),n?2:8):l.test(e)?s:+e}var u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c="Expected a function",s=NaN,f="[object Symbol]",d=/^\s+|\s+$/g,l=/^[-+]0x[0-9a-f]+$/i,p=/^0b[01]+$/i,m=/^0o[0-7]+$/i,b=parseInt,v="object"==("undefined"==typeof t?"undefined":u(t))&&t&&t.Object===Object&&t,y="object"==("undefined"==typeof self?"undefined":u(self))&&self&&self.Object===Object&&self,g=v||y||Function("return this")(),h=Object.prototype,w=h.toString,k=Math.max,x=Math.min,j=function(){return g.Date.now()};e.exports=n}).call(t,function(){return this}())},function(e,t){"use strict";function n(e){var t=void 0,o=void 0,i=void 0;for(t=0;t<e.length;t+=1){if(o=e[t],o.dataset&&o.dataset.aos)return!0;if(i=o.children&&n(o.children))return!0}return!1}function o(){return window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver}function i(){return!!o()}function r(e,t){var n=window.document,i=o(),r=new i(a);u=t,r.observe(n.documentElement,{childList:!0,subtree:!0,removedNodes:!0})}function a(e){e&&e.forEach(function(e){var t=Array.prototype.slice.call(e.addedNodes),o=Array.prototype.slice.call(e.removedNodes),i=t.concat(o);if(n(i))return u()})}Object.defineProperty(t,"__esModule",{value:!0});var u=function(){};t.default={isSupported:i,ready:r}},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(){return navigator.userAgent||navigator.vendor||window.opera||""}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),r=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,a=/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,u=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i,c=/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,s=function(){function e(){n(this,e)}return i(e,[{key:"phone",value:function(){var e=o();return!(!r.test(e)&&!a.test(e.substr(0,4)))}},{key:"mobile",value:function(){var e=o();return!(!u.test(e)&&!c.test(e.substr(0,4)))}},{key:"tablet",value:function(){return this.mobile()&&!this.phone()}}]),e}();t.default=new s},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e,t,n){var o=e.node.getAttribute("data-aos-once");t>e.position?e.node.classList.add("aos-animate"):"undefined"!=typeof o&&("false"===o||!n&&"true"!==o)&&e.node.classList.remove("aos-animate")},o=function(e,t){var o=window.pageYOffset,i=window.innerHeight;e.forEach(function(e,r){n(e,i+o,t)})};t.default=o},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(12),r=o(i),a=function(e,t){return e.forEach(function(e,n){e.node.classList.add("aos-init"),e.position=(0,r.default)(e.node,t.offset)}),e};t.default=a},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(13),r=o(i),a=function(e,t){var n=0,o=0,i=window.innerHeight,a={offset:e.getAttribute("data-aos-offset"),anchor:e.getAttribute("data-aos-anchor"),anchorPlacement:e.getAttribute("data-aos-anchor-placement")};switch(a.offset&&!isNaN(a.offset)&&(o=parseInt(a.offset)),a.anchor&&document.querySelectorAll(a.anchor)&&(e=document.querySelectorAll(a.anchor)[0]),n=(0,r.default)(e).top,a.anchorPlacement){case"top-bottom":break;case"center-bottom":n+=e.offsetHeight/2;break;case"bottom-bottom":n+=e.offsetHeight;break;case"top-center":n+=i/2;break;case"bottom-center":n+=i/2+e.offsetHeight;break;case"center-center":n+=i/2+e.offsetHeight/2;break;case"top-top":n+=i;break;case"bottom-top":n+=e.offsetHeight+i;break;case"center-top":n+=e.offsetHeight/2+i}return a.anchorPlacement||a.offset||isNaN(t)||(o=t),n+o};t.default=a},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){for(var t=0,n=0;e&&!isNaN(e.offsetLeft)&&!isNaN(e.offsetTop);)t+=e.offsetLeft-("BODY"!=e.tagName?e.scrollLeft:0),n+=e.offsetTop-("BODY"!=e.tagName?e.scrollTop:0),e=e.offsetParent;return{top:n,left:t}};t.default=n},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){return e=e||document.querySelectorAll("[data-aos]"),Array.prototype.map.call(e,function(e){return{node:e}})};t.default=n}])});
vendor: 13,029 bytes, lines 14590-14916
14590
14591},{}],10:[function(require,module,exports){
14592/*!
14593  hey, [be]Lazy.js - v1.8.2 - 2016.10.25
14594  A fast, small and dependency free lazy load script (https://github.com/dinbror/blazy)
14595  (c) Bjoern Klinggaard - @bklinggaard - http://dinbror.dk/blazy
14596*/
14597;
14598(function(root, blazy) {
14599    if (typeof define === 'function' && define.amd) {
14600        // AMD. Register bLazy as an anonymous module
14601        define(blazy);
14602    } else if (typeof exports === 'object') {
14603        // Node. Does not work with strict CommonJS, but
14604        // only CommonJS-like environments that support module.exports,
14605        // like Node.
14606        module.exports = blazy();
14607    } else {
14608        // Browser globals. Register bLazy on window
14609        root.Blazy = blazy();
14610    }
14611})(this, function() {
14612    'use strict';
14613
14614    //private vars
14615    var _source, _viewport, _isRetina, _supportClosest, _attrSrc = 'src', _attrSrcset = 'srcset';
14616
14617    // constructor
14618    return function Blazy(options) {
14619        //IE7- fallback for missing querySelectorAll support
14620        if (!document.querySelectorAll) {
14621            var s = document.createStyleSheet();
14622            document.querySelectorAll = function(r, c, i, j, a) {
14623                a = document.all, c = [], r = r.replace(/\[for\b/gi, '[htmlFor').split(',');
14624                for (i = r.length; i--;) {
14625                    s.addRule(r[i], 'k:v');
14626                    for (j = a.length; j--;) a[j].currentStyle.k && c.push(a[j]);
14627                    s.removeRule(0);
14628                }
14629                return c;
14630            };
14631        }
14632
14633        //options and helper vars
14634        var scope = this;
14635        var util = scope._util = {};
14636        util.elements = [];
14637        util.destroyed = true;
14638        scope.options = options || {};
14639        scope.options.error = scope.options.error || false;
14640        scope.options.offset = scope.options.offset || 100;
14641        scope.options.root = scope.options.root || document;
14642        scope.options.success = scope.options.success || false;
14643        scope.options.selector = scope.options.selector || '.b-lazy';
14644        scope.options.separator = scope.options.separator || '|';
14645        scope.options.containerClass = scope.options.container;
14646        scope.options.container = scope.options.containerClass ? document.querySelectorAll(scope.options.containerClass) : false;
14647        scope.options.errorClass = scope.options.errorClass || 'b-error';
14648        scope.options.breakpoints = scope.options.breakpoints || false;
14649        scope.options.loadInvisible = scope.options.loadInvisible || false;
14650        scope.options.successClass = scope.options.successClass || 'b-loaded';
14651        scope.options.validateDelay = scope.options.validateDelay || 25;
14652        scope.options.saveViewportOffsetDelay = scope.options.saveViewportOffsetDelay || 50;
14653        scope.options.srcset = scope.options.srcset || 'data-srcset';
14654        scope.options.src = _source = scope.options.src || 'data-src';
14655        _supportClosest = Element.prototype.closest;
14656        _isRetina = window.devicePixelRatio > 1;
14657        _viewport = {};
14658        _viewport.top = 0 - scope.options.offset;
14659        _viewport.left = 0 - scope.options.offset;
14660
14661
14662        /* public functions
14663         ************************************/
14664        scope.revalidate = function() {
14665            initialize(scope);
14666        };
14667        scope.load = function(elements, force) {
14668            var opt = this.options;
14669            if (elements && elements.length === undefined) {
14670                loadElement(elements, force, opt);
14671            } else {
14672                each(elements, function(element) {
14673                    loadElement(element, force, opt);
14674                });
14675            }
14676        };
14677        scope.destroy = function() {            
14678            var util = scope._util;
14679            if (scope.options.container) {
14680                each(scope.options.container, function(object) {
14681                    unbindEvent(object, 'scroll', util.validateT);
14682                });
14683            }
14684            unbindEvent(window, 'scroll', util.validateT);
14685            unbindEvent(window, 'resize', util.validateT);
14686            unbindEvent(window, 'resize', util.saveViewportOffsetT);
14687            util.count = 0;
14688            util.elements.length = 0;
14689            util.destroyed = true;
14690        };
14691
14692        //throttle, ensures that we don't call the functions too often
14693        util.validateT = throttle(function() {
14694            validate(scope);
14695        }, scope.options.validateDelay, scope);
14696        util.saveViewportOffsetT = throttle(function() {
14697            saveViewportOffset(scope.options.offset);
14698        }, scope.options.saveViewportOffsetDelay, scope);
14699        saveViewportOffset(scope.options.offset);
14700
14701        //handle multi-served image src (obsolete)
14702        each(scope.options.breakpoints, function(object) {
14703            if (object.width >= window.screen.width) {
14704                _source = object.src;
14705                return false;
14706            }
14707        });
14708
14709        // start lazy load
14710        setTimeout(function() {
14711            initialize(scope);
14712        }); // "dom ready" fix
14713
14714    };
14715
14716
14717    /* Private helper functions
14718     ************************************/
14719    function initialize(self) {
14720        var util = self._util;
14721        // First we create an array of elements to lazy load
14722        util.elements = toArray(self.options);
14723        util.count = util.elements.length;
14724        // Then we bind resize and scroll events if not already binded
14725        if (util.destroyed) {
14726            util.destroyed = false;
14727            if (self.options.container) {
14728                each(self.options.container, function(object) {
14729                    bindEvent(object, 'scroll', util.validateT);
14730                });
14731            }
14732            bindEvent(window, 'resize', util.saveViewportOffsetT);
14733            bindEvent(window, 'resize', util.validateT);
14734            bindEvent(window, 'scroll', util.validateT);
14735        }
14736        // And finally, we start to lazy load.
14737        validate(self);
14738    }
14739
14740    function validate(self) {
14741        var util = self._util;
14742        for (var i = 0; i < util.count; i++) {
14743            var element = util.elements[i];
14744            if (elementInView(element, self.options) || hasClass(element, self.options.successClass)) {
14745                self.load(element);
14746                util.elements.splice(i, 1);
14747                util.count--;
14748                i--;
14749            }
14750        }
14751        if (util.count === 0) {
14752            self.destroy();
14753        }
14754    }
14755
14756    function elementInView(ele, options) {
14757        var rect = ele.getBoundingClientRect();
14758
14759        if(options.container && _supportClosest){
14760            // Is element inside a container?
14761            var elementContainer = ele.closest(options.containerClass);
14762            if(elementContainer){
14763                var containerRect = elementContainer.getBoundingClientRect();
14764                // Is container in view?
14765                if(inView(containerRect, _viewport)){
14766                    var top = containerRect.top - options.offset;
14767                    var right = containerRect.right + options.offset;
14768                    var bottom = containerRect.bottom + options.offset;
14769                    var left = containerRect.left - options.offset;
14770                    var containerRectWithOffset = {
14771                        top: top > _viewport.top ? top : _viewport.top,
14772                        right: right < _viewport.right ? right : _viewport.right,
14773                        bottom: bottom < _viewport.bottom ? bottom : _viewport.bottom,
14774                        left: left > _viewport.left ? left : _viewport.left
14775                    };
14776                    // Is element in view of container?
14777                    return inView(rect, containerRectWithOffset);
14778                } else {
14779                    return false;
14780                }
14781            }
14782        }      
14783        return inView(rect, _viewport);
14784    }
14785
14786    function inView(rect, viewport){
14787        // Intersection
14788        return rect.right >= viewport.left &&
14789               rect.bottom >= viewport.top && 
14790               rect.left <= viewport.right && 
14791               rect.top <= viewport.bottom;
14792    }
14793
14794    function loadElement(ele, force, options) {
14795        // if element is visible, not loaded or forced
14796        if (!hasClass(ele, options.successClass) && (force || options.loadInvisible || (ele.offsetWidth > 0 && ele.offsetHeight > 0))) {
14797            var dataSrc = getAttr(ele, _source) || getAttr(ele, options.src); // fallback to default 'data-src'
14798            if (dataSrc) {
14799                var dataSrcSplitted = dataSrc.split(options.separator);
14800                var src = dataSrcSplitted[_isRetina && dataSrcSplitted.length > 1 ? 1 : 0];
14801                var srcset = getAttr(ele, options.srcset);
14802                var isImage = equal(ele, 'img');
14803                var parent = ele.parentNode;
14804                var isPicture = parent && equal(parent, 'picture');
14805                // Image or background image
14806                if (isImage || ele.src === undefined) {
14807                    var img = new Image();
14808                    // using EventListener instead of onerror and onload
14809                    // due to bug introduced in chrome v50 
14810                    // (https://productforums.google.com/forum/#!topic/chrome/p51Lk7vnP2o)
14811                    var onErrorHandler = function() {
14812                        if (options.error) options.error(ele, "invalid");
14813                        addClass(ele, options.errorClass);
14814                        unbindEvent(img, 'error', onErrorHandler);
14815                        unbindEvent(img, 'load', onLoadHandler);
14816                    };
14817                    var onLoadHandler = function() {
14818                        // Is element an image
14819                        if (isImage) {
14820                            if(!isPicture) {
14821                                handleSources(ele, src, srcset);
14822                            }
14823                        // or background-image
14824                        } else {
14825                            ele.style.backgroundImage = 'url("' + src + '")';
14826                        }
14827                        itemLoaded(ele, options);
14828                        unbindEvent(img, 'load', onLoadHandler);
14829                        unbindEvent(img, 'error', onErrorHandler);
14830                    };
14831                    
14832                    // Picture element
14833                    if (isPicture) {
14834                        img = ele; // Image tag inside picture element wont get preloaded
14835                        each(parent.getElementsByTagName('source'), function(source) {
14836                            handleSource(source, _attrSrcset, options.srcset);
14837                        });
14838                    }
14839                    bindEvent(img, 'error', onErrorHandler);
14840                    bindEvent(img, 'load', onLoadHandler);
14841                    handleSources(img, src, srcset); // Preload
14842
14843                } else { // An item with src like iframe, unity games, simpel video etc
14844                    ele.src = src;
14845                    itemLoaded(ele, options);
14846                }
14847            } else {
14848                // video with child source
14849                if (equal(ele, 'video')) {
14850                    each(ele.getElementsByTagName('source'), function(source) {
14851                        handleSource(source, _attrSrc, options.src);
14852                    });
14853                    ele.load();
14854                    itemLoaded(ele, options);
14855                } else {
14856                    if (options.error) options.error(ele, "missing");
14857                    addClass(ele, options.errorClass);
14858                }
14859            }
14860        }
14861    }
14862
14863    function itemLoaded(ele, options) {
14864        addClass(ele, options.successClass);
14865        if (options.success) options.success(ele);
14866        // cleanup markup, remove data source attributes
14867        removeAttr(ele, options.src);
14868        removeAttr(ele, options.srcset);
14869        each(options.breakpoints, function(object) {
14870            removeAttr(ele, object.src);
14871        });
14872    }
14873
14874    function handleSource(ele, attr, dataAttr) {
14875        var dataSrc = getAttr(ele, dataAttr);
14876        if (dataSrc) {
14877            setAttr(ele, attr, dataSrc);
14878            removeAttr(ele, dataAttr);
14879        }
14880    }
14881
14882    function handleSources(ele, src, srcset){
14883        if(srcset) {
14884            setAttr(ele, _attrSrcset, srcset); //srcset
14885        }
14886        ele.src = src; //src 
14887    }
14888
14889    function setAttr(ele, attr, value){
14890        ele.setAttribute(attr, value);
14891    }
14892
14893    function getAttr(ele, attr) {
14894        return ele.getAttribute(attr);
14895    }
14896
14897    function removeAttr(ele, attr){
14898        ele.removeAttribute(attr); 
14899    }
14900
14901    function equal(ele, str) {
14902        return ele.nodeName.toLowerCase() === str;
14903    }
14904
14905    function hasClass(ele, className) {
14906        return (' ' + ele.className + ' ').indexOf(' ' + className + ' ') !== -1;
14907    }
14908
14909    function addClass(ele, className) {
14910        if (!hasClass(ele, className)) {
14911            ele.className += ' ' + className;
14912        }
14913    }
14914
14915    function toArray(options) {
14916        var array = [];
14917        var nodelist = (options.root).querySelectorAll(options.selector);
14918        for (var i = nodelist.length; i--; array.unshift(nodelist[i])) {}
14919        return array;
14920    }
14921
14922    function saveViewportOffset(offset) {
14923        _viewport.bottom = (window.innerHeight || document.documentElement.clientHeight) + offset;
14924        _viewport.right = (window.innerWidth || document.documentElement.clientWidth) + offset;
14925    }
14926
14927    function bindEvent(ele, type, fn) {
14928        if (ele.attachEvent) {
14929            ele.attachEvent && ele.attachEvent('on' + type, fn);
14930        } else {
14931            ele.addEventListener(type, fn, { capture: false, passive: true });
14932        }
14933    }
14934
14935    function unbindEvent(ele, type, fn) {
14936        if (ele.detachEvent) {
14937            ele.detachEvent && ele.detachEvent('on' + type, fn);
14938        } else {
14939            ele.removeEventListener(type, fn, { capture: false, passive: true });
14940        }
14941    }
14942
14943    function each(object, fn) {
14944        if (object && fn) {
14945            var l = object.length;
14946            for (var i = 0; i < l && fn(object[i], i) !== false; i++) {}
14947        }
14948    }
14949
14950    function throttle(fn, minDelay, scope) {
14951        var lastCall = 0;
14952        return function() {
14953            var now = +new Date();
14954            if (now - lastCall < minDelay) {
14955                return;
14956            }
14957            lastCall = now;
14958            fn.apply(scope, arguments);
14959        };
14960    }
14961});
14962
14963},{}],11:[function(require,module,exports){
14964/*!
14965  * Bootstrap v4.3.1 (https://getbootstrap.com/)
14966  * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
14967  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
14968  */
14969(function (global, factory) {
14970  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery'), require('popper.js')) :
14971  typeof define === 'function' && define.amd ? define(['exports', 'jquery', 'popper.js'], factory) :
14972  (global = global || self, factory(global.bootstrap = {}, global.jQuery, global.Popper));
14973}(this, function (exports, $, Popper) { 'use strict';
14974
14975  $ = $ && $.hasOwnProperty('default') ? $['default'] : $;
14976  Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper;
14977
14978  function _defineProperties(target, props) {
14979    for (var i = 0; i < props.length; i++) {
14980      var descriptor = props[i];
14981      descriptor.enumerable = descriptor.enumerable || false;
14982      descriptor.configurable = true;
14983      if ("value" in descriptor) descriptor.writable = true;
14984      Object.defineProperty(target, descriptor.key, descriptor);
14985    }
14986  }
14987
14988  function _createClass(Constructor, protoProps, staticProps) {
14989    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
14990    if (staticProps) _defineProperties(Constructor, staticProps);
14991    return Constructor;
14992  }
14993
14994  function _defineProperty(obj, key, value) {
14995    if (key in obj) {
14996      Object.defineProperty(obj, key, {
14997        value: value,
14998        enumerable: true,
14999        configurable: true,
15000        writable: true
15001      });
15002    } else {
15003      obj[key] = value;
15004    }
15005
15006    return obj;
15007  }
15008
15009  function _objectSpread(target) {
15010    for (var i = 1; i < arguments.length; i++) {
15011      var source = arguments[i] != null ? arguments[i] : {};
15012      var ownKeys = Object.keys(source);
15013
15014      if (typeof Object.getOwnPropertySymbols === 'function') {
15015        ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
15016          return Object.getOwnPropertyDescriptor(source, sym).enumerable;
15017        }));
15018      }
15019
15020      ownKeys.forEach(function (key) {
15021        _defineProperty(target, key, source[key]);
15022      });
15023    }
15024
15025    return target;
15026  }
15027
15028  function _inheritsLoose(subClass, superClass) {
15029    subClass.prototype = Object.create(superClass.prototype);
15030    subClass.prototype.constructor = subClass;
15031    subClass.__proto__ = superClass;
15032  }
15033
15034  /**
15035   * --------------------------------------------------------------------------
15036   * Bootstrap (v4.3.1): util.js
15037   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15038   * --------------------------------------------------------------------------
15039   */
15040  /**
15041   * ------------------------------------------------------------------------
15042   * Private TransitionEnd Helpers
15043   * ------------------------------------------------------------------------
15044   */
15045
15046  var TRANSITION_END = 'transitionend';
15047  var MAX_UID = 1000000;
15048  var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
15049
15050  function toType(obj) {
15051    return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
15052  }
15053
15054  function getSpecialTransitionEndEvent() {
15055    return {
15056      bindType: TRANSITION_END,
15057      delegateType: TRANSITION_END,
15058      handle: function handle(event) {
15059        if ($(event.target).is(this)) {
15060          return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
15061        }
15062
15063        return undefined; // eslint-disable-line no-undefined
15064      }
15065    };
15066  }
15067
15068  function transitionEndEmulator(duration) {
15069    var _this = this;
15070
15071    var called = false;
vendor: 5,614 bytes, lines 15072-15256
15072    $(this).one(Util.TRANSITION_END, function () {
15073      called = true;
15074    });
15075    setTimeout(function () {
15076      if (!called) {
15077        Util.triggerTransitionEnd(_this);
15078      }
15079    }, duration);
15080    return this;
15081  }
15082
15083  function setTransitionEndSupport() {
15084    $.fn.emulateTransitionEnd = transitionEndEmulator;
15085    $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
15086  }
15087  /**
15088   * --------------------------------------------------------------------------
15089   * Public Util Api
15090   * --------------------------------------------------------------------------
15091   */
15092
15093
15094  var Util = {
15095    TRANSITION_END: 'bsTransitionEnd',
15096    getUID: function getUID(prefix) {
15097      do {
15098        // eslint-disable-next-line no-bitwise
15099        prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here
15100      } while (document.getElementById(prefix));
15101
15102      return prefix;
15103    },
15104    getSelectorFromElement: function getSelectorFromElement(element) {
15105      var selector = element.getAttribute('data-target');
15106
15107      if (!selector || selector === '#') {
15108        var hrefAttr = element.getAttribute('href');
15109        selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : '';
15110      }
15111
15112      try {
15113        return document.querySelector(selector) ? selector : null;
15114      } catch (err) {
15115        return null;
15116      }
15117    },
15118    getTransitionDurationFromElement: function getTransitionDurationFromElement(element) {
15119      if (!element) {
15120        return 0;
15121      } // Get transition-duration of the element
15122
15123
15124      var transitionDuration = $(element).css('transition-duration');
15125      var transitionDelay = $(element).css('transition-delay');
15126      var floatTransitionDuration = parseFloat(transitionDuration);
15127      var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
15128
15129      if (!floatTransitionDuration && !floatTransitionDelay) {
15130        return 0;
15131      } // If multiple durations are defined, take the first
15132
15133
15134      transitionDuration = transitionDuration.split(',')[0];
15135      transitionDelay = transitionDelay.split(',')[0];
15136      return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
15137    },
15138    reflow: function reflow(element) {
15139      return element.offsetHeight;
15140    },
15141    triggerTransitionEnd: function triggerTransitionEnd(element) {
15142      $(element).trigger(TRANSITION_END);
15143    },
15144    // TODO: Remove in v5
15145    supportsTransitionEnd: function supportsTransitionEnd() {
15146      return Boolean(TRANSITION_END);
15147    },
15148    isElement: function isElement(obj) {
15149      return (obj[0] || obj).nodeType;
15150    },
15151    typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
15152      for (var property in configTypes) {
15153        if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
15154          var expectedTypes = configTypes[property];
15155          var value = config[property];
15156          var valueType = value && Util.isElement(value) ? 'element' : toType(value);
15157
15158          if (!new RegExp(expectedTypes).test(valueType)) {
15159            throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\"."));
15160          }
15161        }
15162      }
15163    },
15164    findShadowRoot: function findShadowRoot(element) {
15165      if (!document.documentElement.attachShadow) {
15166        return null;
15167      } // Can find the shadow root otherwise it'll return the document
15168
15169
15170      if (typeof element.getRootNode === 'function') {
15171        var root = element.getRootNode();
15172        return root instanceof ShadowRoot ? root : null;
15173      }
15174
15175      if (element instanceof ShadowRoot) {
15176        return element;
15177      } // when we don't find a shadow root
15178
15179
15180      if (!element.parentNode) {
15181        return null;
15182      }
15183
15184      return Util.findShadowRoot(element.parentNode);
15185    }
15186  };
15187  setTransitionEndSupport();
15188
15189  /**
15190   * ------------------------------------------------------------------------
15191   * Constants
15192   * ------------------------------------------------------------------------
15193   */
15194
15195  var NAME = 'alert';
15196  var VERSION = '4.3.1';
15197  var DATA_KEY = 'bs.alert';
15198  var EVENT_KEY = "." + DATA_KEY;
15199  var DATA_API_KEY = '.data-api';
15200  var JQUERY_NO_CONFLICT = $.fn[NAME];
15201  var Selector = {
15202    DISMISS: '[data-dismiss="alert"]'
15203  };
15204  var Event = {
15205    CLOSE: "close" + EVENT_KEY,
15206    CLOSED: "closed" + EVENT_KEY,
15207    CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
15208  };
15209  var ClassName = {
15210    ALERT: 'alert',
15211    FADE: 'fade',
15212    SHOW: 'show'
15213    /**
15214     * ------------------------------------------------------------------------
15215     * Class Definition
15216     * ------------------------------------------------------------------------
15217     */
15218
15219  };
15220
15221  var Alert =
15222  /*#__PURE__*/
15223  function () {
15224    function Alert(element) {
15225      this._element = element;
15226    } // Getters
15227
15228
15229    var _proto = Alert.prototype;
15230
15231    // Public
15232    _proto.close = function close(element) {
15233      var rootElement = this._element;
15234
15235      if (element) {
15236        rootElement = this._getRootElement(element);
15237      }
15238
15239      var customEvent = this._triggerCloseEvent(rootElement);
15240
15241      if (customEvent.isDefaultPrevented()) {
15242        return;
15243      }
15244
15245      this._removeElement(rootElement);
15246    };
15247
15248    _proto.dispose = function dispose() {
15249      $.removeData(this._element, DATA_KEY);
15250      this._element = null;
15251    } // Private
15252    ;
15253
15254    _proto._getRootElement = function _getRootElement(element) {
15255      var selector = Util.getSelectorFromElement(element);
15256      var parent = false;
15257
15258      if (selector) {
15259        parent = document.querySelector(selector);
15260      }
15261
15262      if (!parent) {
15263        parent = $(element).closest("." + ClassName.ALERT)[0];
15264      }
15265
15266      return parent;
15267    };
15268
15269    _proto._triggerCloseEvent = function _triggerCloseEvent(element) {
15270      var closeEvent = $.Event(Event.CLOSE);
15271      $(element).trigger(closeEvent);
15272      return closeEvent;
15273    };
15274
15275    _proto._removeElement = function _removeElement(element) {
15276      var _this = this;
15277
15278      $(element).removeClass(ClassName.SHOW);
15279
15280      if (!$(element).hasClass(ClassName.FADE)) {
15281        this._destroyElement(element);
15282
15283        return;
15284      }
15285
15286      var transitionDuration = Util.getTransitionDurationFromElement(element);
15287      $(element).one(Util.TRANSITION_END, function (event) {
15288        return _this._destroyElement(element, event);
15289      }).emulateTransitionEnd(transitionDuration);
15290    };
15291
15292    _proto._destroyElement = function _destroyElement(element) {
15293      $(element).detach().trigger(Event.CLOSED).remove();
15294    } // Static
15295    ;
15296
15297    Alert._jQueryInterface = function _jQueryInterface(config) {
15298      return this.each(function () {
15299        var $element = $(this);
15300        var data = $element.data(DATA_KEY);
15301
15302        if (!data) {
15303          data = new Alert(this);
15304          $element.data(DATA_KEY, data);
15305        }
15306
15307        if (config === 'close') {
15308          data[config](this);
15309        }
15310      });
15311    };
15312
15313    Alert._handleDismiss = function _handleDismiss(alertInstance) {
15314      return function (event) {
15315        if (event) {
15316          event.preventDefault();
15317        }
15318
15319        alertInstance.close(this);
15320      };
15321    };
15322
15323    _createClass(Alert, null, [{
15324      key: "VERSION",
15325      get: function get() {
15326        return VERSION;
15327      }
15328    }]);
15329
15330    return Alert;
15331  }();
15332  /**
15333   * ------------------------------------------------------------------------
15334   * Data Api implementation
15335   * ------------------------------------------------------------------------
15336   */
15337
15338
15339  $(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert()));
15340  /**
15341   * ------------------------------------------------------------------------
15342   * jQuery
15343   * ------------------------------------------------------------------------
15344   */
15345
15346  $.fn[NAME] = Alert._jQueryInterface;
15347  $.fn[NAME].Constructor = Alert;
15348
15349  $.fn[NAME].noConflict = function () {
15350    $.fn[NAME] = JQUERY_NO_CONFLICT;
15351    return Alert._jQueryInterface;
15352  };
15353
15354  /**
15355   * ------------------------------------------------------------------------
15356   * Constants
15357   * ------------------------------------------------------------------------
15358   */
15359
15360  var NAME$1 = 'button';
15361  var VERSION$1 = '4.3.1';
15362  var DATA_KEY$1 = 'bs.button';
15363  var EVENT_KEY$1 = "." + DATA_KEY$1;
15364  var DATA_API_KEY$1 = '.data-api';
15365  var JQUERY_NO_CONFLICT$1 = $.fn[NAME$1];
15366  var ClassName$1 = {
15367    ACTIVE: 'active',
15368    BUTTON: 'btn',
15369    FOCUS: 'focus'
15370  };
15371  var Selector$1 = {
15372    DATA_TOGGLE_CARROT: '[data-toggle^="button"]',
15373    DATA_TOGGLE: '[data-toggle="buttons"]',
15374    INPUT: 'input:not([type="hidden"])',
15375    ACTIVE: '.active',
15376    BUTTON: '.btn'
15377  };
15378  var Event$1 = {
15379    CLICK_DATA_API: "click" + EVENT_KEY$1 + DATA_API_KEY$1,
15380    FOCUS_BLUR_DATA_API: "focus" + EVENT_KEY$1 + DATA_API_KEY$1 + " " + ("blur" + EVENT_KEY$1 + DATA_API_KEY$1)
15381    /**
15382     * ------------------------------------------------------------------------
15383     * Class Definition
15384     * ------------------------------------------------------------------------
15385     */
15386
15387  };
15388
15389  var Button =
15390  /*#__PURE__*/
15391  function () {
15392    function Button(element) {
15393      this._element = element;
15394    } // Getters
15395
15396
15397    var _proto = Button.prototype;
15398
15399    // Public
15400    _proto.toggle = function toggle() {
15401      var triggerChangeEvent = true;
15402      var addAriaPressed = true;
15403      var rootElement = $(this._element).closest(Selector$1.DATA_TOGGLE)[0];
15404
15405      if (rootElement) {
15406        var input = this._element.querySelector(Selector$1.INPUT);
15407
15408        if (input) {
15409          if (input.type === 'radio') {
15410            if (input.checked && this._element.classList.contains(ClassName$1.ACTIVE)) {
15411              triggerChangeEvent = false;
vendor: 4,952 bytes, lines 15412-15581
15412            } else {
15413              var activeElement = rootElement.querySelector(Selector$1.ACTIVE);
15414
15415              if (activeElement) {
15416                $(activeElement).removeClass(ClassName$1.ACTIVE);
15417              }
15418            }
15419          }
15420
15421          if (triggerChangeEvent) {
15422            if (input.hasAttribute('disabled') || rootElement.hasAttribute('disabled') || input.classList.contains('disabled') || rootElement.classList.contains('disabled')) {
15423              return;
15424            }
15425
15426            input.checked = !this._element.classList.contains(ClassName$1.ACTIVE);
15427            $(input).trigger('change');
15428          }
15429
15430          input.focus();
15431          addAriaPressed = false;
15432        }
15433      }
15434
15435      if (addAriaPressed) {
15436        this._element.setAttribute('aria-pressed', !this._element.classList.contains(ClassName$1.ACTIVE));
15437      }
15438
15439      if (triggerChangeEvent) {
15440        $(this._element).toggleClass(ClassName$1.ACTIVE);
15441      }
15442    };
15443
15444    _proto.dispose = function dispose() {
15445      $.removeData(this._element, DATA_KEY$1);
15446      this._element = null;
15447    } // Static
15448    ;
15449
15450    Button._jQueryInterface = function _jQueryInterface(config) {
15451      return this.each(function () {
15452        var data = $(this).data(DATA_KEY$1);
15453
15454        if (!data) {
15455          data = new Button(this);
15456          $(this).data(DATA_KEY$1, data);
15457        }
15458
15459        if (config === 'toggle') {
15460          data[config]();
15461        }
15462      });
15463    };
15464
15465    _createClass(Button, null, [{
15466      key: "VERSION",
15467      get: function get() {
15468        return VERSION$1;
15469      }
15470    }]);
15471
15472    return Button;
15473  }();
15474  /**
15475   * ------------------------------------------------------------------------
15476   * Data Api implementation
15477   * ------------------------------------------------------------------------
15478   */
15479
15480
15481  $(document).on(Event$1.CLICK_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) {
15482    event.preventDefault();
15483    var button = event.target;
15484
15485    if (!$(button).hasClass(ClassName$1.BUTTON)) {
15486      button = $(button).closest(Selector$1.BUTTON);
15487    }
15488
15489    Button._jQueryInterface.call($(button), 'toggle');
15490  }).on(Event$1.FOCUS_BLUR_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) {
15491    var button = $(event.target).closest(Selector$1.BUTTON)[0];
15492    $(button).toggleClass(ClassName$1.FOCUS, /^focus(in)?$/.test(event.type));
15493  });
15494  /**
15495   * ------------------------------------------------------------------------
15496   * jQuery
15497   * ------------------------------------------------------------------------
15498   */
15499
15500  $.fn[NAME$1] = Button._jQueryInterface;
15501  $.fn[NAME$1].Constructor = Button;
15502
15503  $.fn[NAME$1].noConflict = function () {
15504    $.fn[NAME$1] = JQUERY_NO_CONFLICT$1;
15505    return Button._jQueryInterface;
15506  };
15507
15508  /**
15509   * ------------------------------------------------------------------------
15510   * Constants
15511   * ------------------------------------------------------------------------
15512   */
15513
15514  var NAME$2 = 'carousel';
15515  var VERSION$2 = '4.3.1';
15516  var DATA_KEY$2 = 'bs.carousel';
15517  var EVENT_KEY$2 = "." + DATA_KEY$2;
15518  var DATA_API_KEY$2 = '.data-api';
15519  var JQUERY_NO_CONFLICT$2 = $.fn[NAME$2];
15520  var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key
15521
15522  var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key
15523
15524  var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
15525
15526  var SWIPE_THRESHOLD = 40;
15527  var Default = {
15528    interval: 5000,
15529    keyboard: true,
15530    slide: false,
15531    pause: 'hover',
15532    wrap: true,
15533    touch: true
15534  };
15535  var DefaultType = {
15536    interval: '(number|boolean)',
15537    keyboard: 'boolean',
15538    slide: '(boolean|string)',
15539    pause: '(string|boolean)',
15540    wrap: 'boolean',
15541    touch: 'boolean'
15542  };
15543  var Direction = {
15544    NEXT: 'next',
15545    PREV: 'prev',
15546    LEFT: 'left',
15547    RIGHT: 'right'
15548  };
15549  var Event$2 = {
15550    SLIDE: "slide" + EVENT_KEY$2,
15551    SLID: "slid" + EVENT_KEY$2,
15552    KEYDOWN: "keydown" + EVENT_KEY$2,
15553    MOUSEENTER: "mouseenter" + EVENT_KEY$2,
15554    MOUSELEAVE: "mouseleave" + EVENT_KEY$2,
15555    TOUCHSTART: "touchstart" + EVENT_KEY$2,
15556    TOUCHMOVE: "touchmove" + EVENT_KEY$2,
15557    TOUCHEND: "touchend" + EVENT_KEY$2,
15558    POINTERDOWN: "pointerdown" + EVENT_KEY$2,
15559    POINTERUP: "pointerup" + EVENT_KEY$2,
15560    DRAG_START: "dragstart" + EVENT_KEY$2,
15561    LOAD_DATA_API: "load" + EVENT_KEY$2 + DATA_API_KEY$2,
15562    CLICK_DATA_API: "click" + EVENT_KEY$2 + DATA_API_KEY$2
15563  };
15564  var ClassName$2 = {
15565    CAROUSEL: 'carousel',
15566    ACTIVE: 'active',
15567    SLIDE: 'slide',
15568    RIGHT: 'carousel-item-right',
15569    LEFT: 'carousel-item-left',
15570    NEXT: 'carousel-item-next',
15571    PREV: 'carousel-item-prev',
15572    ITEM: 'carousel-item',
15573    POINTER_EVENT: 'pointer-event'
15574  };
15575  var Selector$2 = {
15576    ACTIVE: '.active',
15577    ACTIVE_ITEM: '.active.carousel-item',
15578    ITEM: '.carousel-item',
15579    ITEM_IMG: '.carousel-item img',
15580    NEXT_PREV: '.carousel-item-next, .carousel-item-prev',
15581    INDICATORS: '.carousel-indicators',
15582    DATA_SLIDE: '[data-slide], [data-slide-to]',
15583    DATA_RIDE: '[data-ride="carousel"]'
15584  };
15585  var PointerType = {
15586    TOUCH: 'touch',
15587    PEN: 'pen'
15588    /**
15589     * ------------------------------------------------------------------------
15590     * Class Definition
15591     * ------------------------------------------------------------------------
15592     */
15593
15594  };
15595
15596  var Carousel =
15597  /*#__PURE__*/
15598  function () {
15599    function Carousel(element, config) {
15600      this._items = null;
15601      this._interval = null;
15602      this._activeElement = null;
15603      this._isPaused = false;
15604      this._isSliding = false;
15605      this.touchTimeout = null;
15606      this.touchStartX = 0;
15607      this.touchDeltaX = 0;
15608      this._config = this._getConfig(config);
15609      this._element = element;
15610      this._indicatorsElement = this._element.querySelector(Selector$2.INDICATORS);
15611      this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
15612      this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent);
15613
15614      this._addEventListeners();
15615    } // Getters
15616
15617
15618    var _proto = Carousel.prototype;
15619
15620    // Public
15621    _proto.next = function next() {
15622      if (!this._isSliding) {
15623        this._slide(Direction.NEXT);
15624      }
15625    };
15626
15627    _proto.nextWhenVisible = function nextWhenVisible() {
15628      // Don't call next when the page isn't visible
15629      // or the carousel or its parent isn't visible
15630      if (!document.hidden && $(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden') {
15631        this.next();
15632      }
15633    };
15634
15635    _proto.prev = function prev() {
15636      if (!this._isSliding) {
15637        this._slide(Direction.PREV);
15638      }
15639    };
15640
15641    _proto.pause = function pause(event) {
15642      if (!event) {
15643        this._isPaused = true;
15644      }
15645
15646      if (this._element.querySelector(Selector$2.NEXT_PREV)) {
15647        Util.triggerTransitionEnd(this._element);
15648        this.cycle(true);
15649      }
15650
15651      clearInterval(this._interval);
15652      this._interval = null;
15653    };
15654
15655    _proto.cycle = function cycle(event) {
15656      if (!event) {
15657        this._isPaused = false;
15658      }
15659
15660      if (this._interval) {
15661        clearInterval(this._interval);
15662        this._interval = null;
15663      }
15664
15665      if (this._config.interval && !this._isPaused) {
15666        this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);
15667      }
15668    };
15669
15670    _proto.to = function to(index) {
15671      var _this = this;
15672
15673      this._activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM);
15674
15675      var activeIndex = this._getItemIndex(this._activeElement);
15676
15677      if (index > this._items.length - 1 || index < 0) {
15678        return;
15679      }
15680
15681      if (this._isSliding) {
15682        $(this._element).one(Event$2.SLID, function () {
15683          return _this.to(index);
15684        });
15685        return;
15686      }
15687
15688      if (activeIndex === index) {
15689        this.pause();
15690        this.cycle();
15691        return;
15692      }
15693
15694      var direction = index > activeIndex ? Direction.NEXT : Direction.PREV;
15695
15696      this._slide(direction, this._items[index]);
15697    };
15698
15699    _proto.dispose = function dispose() {
15700      $(this._element).off(EVENT_KEY$2);
15701      $.removeData(this._element, DATA_KEY$2);
15702      this._items = null;
15703      this._config = null;
15704      this._element = null;
15705      this._interval = null;
15706      this._isPaused = null;
15707      this._isSliding = null;
15708      this._activeElement = null;
15709      this._indicatorsElement = null;
15710    } // Private
15711    ;
15712
15713    _proto._getConfig = function _getConfig(config) {
15714      config = _objectSpread({}, Default, config);
15715      Util.typeCheckConfig(NAME$2, config, DefaultType);
15716      return config;
15717    };
15718
15719    _proto._handleSwipe = function _handleSwipe() {
15720      var absDeltax = Math.abs(this.touchDeltaX);
15721
15722      if (absDeltax <= SWIPE_THRESHOLD) {
15723        return;
15724      }
15725
15726      var direction = absDeltax / this.touchDeltaX; // swipe left
15727
15728      if (direction > 0) {
15729        this.prev();
15730      } // swipe right
15731
15732
15733      if (direction < 0) {
15734        this.next();
15735      }
15736    };
15737
15738    _proto._addEventListeners = function _addEventListeners() {
15739      var _this2 = this;
15740
15741      if (this._config.keyboard) {
15742        $(this._element).on(Event$2.KEYDOWN, function (event) {
15743          return _this2._keydown(event);
15744        });
15745      }
15746
15747      if (this._config.pause === 'hover') {
15748        $(this._element).on(Event$2.MOUSEENTER, function (event) {
15749          return _this2.pause(event);
15750        }).on(Event$2.MOUSELEAVE, function (event) {
15751          return _this2.cycle(event);
15752        });
15753      }
15754
15755      if (this._config.touch) {
15756        this._addTouchEventListeners();
15757      }
15758    };
15759
15760    _proto._addTouchEventListeners = function _addTouchEventListeners() {
15761      var _this3 = this;
15762
15763      if (!this._touchSupported) {
15764        return;
15765      }
15766
15767      var start = function start(event) {
15768        if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
15769          _this3.touchStartX = event.originalEvent.clientX;
15770        } else if (!_this3._pointerEvent) {
15771          _this3.touchStartX = event.originalEvent.touches[0].clientX;
15772        }
15773      };
15774
15775      var move = function move(event) {
15776        // ensure swiping with one touch and not pinching
15777        if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {
15778          _this3.touchDeltaX = 0;
15779        } else {
15780          _this3.touchDeltaX = event.originalEvent.touches[0].clientX - _this3.touchStartX;
15781        }
15782      };
15783
15784      var end = function end(event) {
15785        if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
15786          _this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX;
15787        }
15788
15789        _this3._handleSwipe();
15790
15791        if (_this3._config.pause === 'hover') {
15792          // If it's a touch-enabled device, mouseenter/leave are fired as
15793          // part of the mouse compatibility events on first tap - the carousel
15794          // would stop cycling until user tapped out of it;
15795          // here, we listen for touchend, explicitly pause the carousel
15796          // (as if it's the second time we tap on it, mouseenter compat event
15797          // is NOT fired) and after a timeout (to allow for mouse compatibility
15798          // events to fire) we explicitly restart cycling
15799          _this3.pause();
15800
15801          if (_this3.touchTimeout) {
15802            clearTimeout(_this3.touchTimeout);
15803          }
15804
15805          _this3.touchTimeout = setTimeout(function (event) {
15806            return _this3.cycle(event);
15807          }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval);
15808        }
15809      };
15810
15811      $(this._element.querySelectorAll(Selector$2.ITEM_IMG)).on(Event$2.DRAG_START, function (e) {
15812        return e.preventDefault();
15813      });
15814
15815      if (this._pointerEvent) {
15816        $(this._element).on(Event$2.POINTERDOWN, function (event) {
15817          return start(event);
15818        });
15819        $(this._element).on(Event$2.POINTERUP, function (event) {
15820          return end(event);
15821        });
15822
15823        this._element.classList.add(ClassName$2.POINTER_EVENT);
15824      } else {
15825        $(this._element).on(Event$2.TOUCHSTART, function (event) {
15826          return start(event);
15827        });
15828        $(this._element).on(Event$2.TOUCHMOVE, function (event) {
15829          return move(event);
15830        });
15831        $(this._element).on(Event$2.TOUCHEND, function (event) {
15832          return end(event);
15833        });
15834      }
15835    };
15836
15837    _proto._keydown = function _keydown(event) {
15838      if (/input|textarea/i.test(event.target.tagName)) {
15839        return;
15840      }
15841
15842      switch (event.which) {
15843        case ARROW_LEFT_KEYCODE:
15844          event.preventDefault();
15845          this.prev();
15846          break;
15847
15848        case ARROW_RIGHT_KEYCODE:
15849          event.preventDefault();
15850          this.next();
15851          break;
15852
15853        default:
15854      }
15855    };
15856
15857    _proto._getItemIndex = function _getItemIndex(element) {
15858      this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(Selector$2.ITEM)) : [];
15859      return this._items.indexOf(element);
15860    };
15861
15862    _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) {
15863      var isNextDirection = direction === Direction.NEXT;
15864      var isPrevDirection = direction === Direction.PREV;
15865
15866      var activeIndex = this._getItemIndex(activeElement);
15867
15868      var lastItemIndex = this._items.length - 1;
15869      var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;
15870
15871      if (isGoingToWrap && !this._config.wrap) {
15872        return activeElement;
15873      }
15874
15875      var delta = direction === Direction.PREV ? -1 : 1;
15876      var itemIndex = (activeIndex + delta) % this._items.length;
15877      return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
15878    };
15879
15880    _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) {
15881      var targetIndex = this._getItemIndex(relatedTarget);
15882
15883      var fromIndex = this._getItemIndex(this._element.querySelector(Selector$2.ACTIVE_ITEM));
15884
15885      var slideEvent = $.Event(Event$2.SLIDE, {
15886        relatedTarget: relatedTarget,
15887        direction: eventDirectionName,
15888        from: fromIndex,
15889        to: targetIndex
15890      });
15891      $(this._element).trigger(slideEvent);
15892      return slideEvent;
15893    };
15894
15895    _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) {
15896      if (this._indicatorsElement) {
15897        var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector$2.ACTIVE));
15898        $(indicators).removeClass(ClassName$2.ACTIVE);
15899
15900        var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
15901
15902        if (nextIndicator) {
15903          $(nextIndicator).addClass(ClassName$2.ACTIVE);
15904        }
15905      }
15906    };
15907
15908    _proto._slide = function _slide(direction, element) {
15909      var _this4 = this;
15910
15911      var activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM);
15912
15913      var activeElementIndex = this._getItemIndex(activeElement);
15914
15915      var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
15916
15917      var nextElementIndex = this._getItemIndex(nextElement);
15918
15919      var isCycling = Boolean(this._interval);
15920      var directionalClassName;
15921      var orderClassName;
15922      var eventDirectionName;
15923
15924      if (direction === Direction.NEXT) {
15925        directionalClassName = ClassName$2.LEFT;
15926        orderClassName = ClassName$2.NEXT;
15927        eventDirectionName = Direction.LEFT;
15928      } else {
15929        directionalClassName = ClassName$2.RIGHT;
15930        orderClassName = ClassName$2.PREV;
15931        eventDirectionName = Direction.RIGHT;
15932      }
15933
15934      if (nextElement && $(nextElement).hasClass(ClassName$2.ACTIVE)) {
15935        this._isSliding = false;
15936        return;
15937      }
15938
15939      var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
15940
15941      if (slideEvent.isDefaultPrevented()) {
15942        return;
15943      }
15944
15945      if (!activeElement || !nextElement) {
15946        // Some weirdness is happening, so we bail
15947        return;
15948      }
15949
15950      this._isSliding = true;
15951
15952      if (isCycling) {
15953        this.pause();
15954      }
15955
15956      this._setActiveIndicatorElement(nextElement);
15957
15958      var slidEvent = $.Event(Event$2.SLID, {
15959        relatedTarget: nextElement,
15960        direction: eventDirectionName,
15961        from: activeElementIndex,
15962        to: nextElementIndex
15963      });
15964
15965      if ($(this._element).hasClass(ClassName$2.SLIDE)) {
15966        $(nextElement).addClass(orderClassName);
15967        Util.reflow(nextElement);
15968        $(activeElement).addClass(directionalClassName);
15969        $(nextElement).addClass(directionalClassName);
15970        var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10);
15971
15972        if (nextElementInterval) {
15973          this._config.defaultInterval = this._config.defaultInterval || this._config.interval;
15974          this._config.interval = nextElementInterval;
15975        } else {
15976          this._config.interval = this._config.defaultInterval || this._config.interval;
15977        }
15978
15979        var transitionDuration = Util.getTransitionDurationFromElement(activeElement);
15980        $(activeElement).one(Util.TRANSITION_END, function () {
15981          $(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(ClassName$2.ACTIVE);
15982          $(activeElement).removeClass(ClassName$2.ACTIVE + " " + orderClassName + " " + directionalClassName);
15983          _this4._isSliding = false;
15984          setTimeout(function () {
15985            return $(_this4._element).trigger(slidEvent);
15986          }, 0);
15987        }).emulateTransitionEnd(transitionDuration);
15988      } else {
15989        $(activeElement).removeClass(ClassName$2.ACTIVE);
15990        $(nextElement).addClass(ClassName$2.ACTIVE);
15991        this._isSliding = false;
15992        $(this._element).trigger(slidEvent);
15993      }
15994
15995      if (isCycling) {
15996        this.cycle();
15997      }
15998    } // Static
15999    ;
16000
16001    Carousel._jQueryInterface = function _jQueryInterface(config) {
16002      return this.each(function () {
16003        var data = $(this).data(DATA_KEY$2);
16004
16005        var _config = _objectSpread({}, Default, $(this).data());
16006
16007        if (typeof config === 'object') {
16008          _config = _objectSpread({}, _config, config);
16009        }
16010
16011        var action = typeof config === 'string' ? config : _config.slide;
16012
16013        if (!data) {
16014          data = new Carousel(this, _config);
16015          $(this).data(DATA_KEY$2, data);
16016        }
16017
16018        if (typeof config === 'number') {
16019          data.to(config);
16020        } else if (typeof action === 'string') {
16021          if (typeof data[action] === 'undefined') {
16022            throw new TypeError("No method named \"" + action + "\"");
16023          }
16024
16025          data[action]();
16026        } else if (_config.interval && _config.ride) {
16027          data.pause();
16028          data.cycle();
16029        }
16030      });
16031    };
16032
16033    Carousel._dataApiClickHandler = function _dataApiClickHandler(event) {
16034      var selector = Util.getSelectorFromElement(this);
16035
16036      if (!selector) {
16037        return;
16038      }
16039
16040      var target = $(selector)[0];
16041
16042      if (!target || !$(target).hasClass(ClassName$2.CAROUSEL)) {
16043        return;
16044      }
16045
16046      var config = _objectSpread({}, $(target).data(), $(this).data());
16047
16048      var slideIndex = this.getAttribute('data-slide-to');
16049
16050      if (slideIndex) {
16051        config.interval = false;
16052      }
16053
16054      Carousel._jQueryInterface.call($(target), config);
16055
16056      if (slideIndex) {
16057        $(target).data(DATA_KEY$2).to(slideIndex);
16058      }
16059
16060      event.preventDefault();
16061    };
16062
16063    _createClass(Carousel, null, [{
16064      key: "VERSION",
16065      get: function get() {
16066        return VERSION$2;
16067      }
16068    }, {
16069      key: "Default",
16070      get: function get() {
16071        return Default;
16072      }
16073    }]);
16074
16075    return Carousel;
16076  }();
16077  /**
16078   * ------------------------------------------------------------------------
16079   * Data Api implementation
16080   * ------------------------------------------------------------------------
16081   */
16082
16083
16084  $(document).on(Event$2.CLICK_DATA_API, Selector$2.DATA_SLIDE, Carousel._dataApiClickHandler);
16085  $(window).on(Event$2.LOAD_DATA_API, function () {
16086    var carousels = [].slice.call(document.querySelectorAll(Selector$2.DATA_RIDE));
16087
16088    for (var i = 0, len = carousels.length; i < len; i++) {
16089      var $carousel = $(carousels[i]);
16090
16091      Carousel._jQueryInterface.call($carousel, $carousel.data());
16092    }
16093  });
16094  /**
16095   * ------------------------------------------------------------------------
16096   * jQuery
16097   * ------------------------------------------------------------------------
16098   */
16099
16100  $.fn[NAME$2] = Carousel._jQueryInterface;
16101  $.fn[NAME$2].Constructor = Carousel;
16102
16103  $.fn[NAME$2].noConflict = function () {
16104    $.fn[NAME$2] = JQUERY_NO_CONFLICT$2;
16105    return Carousel._jQueryInterface;
16106  };
16107
16108  /**
16109   * ------------------------------------------------------------------------
16110   * Constants
16111   * ------------------------------------------------------------------------
16112   */
16113
16114  var NAME$3 = 'collapse';
16115  var VERSION$3 = '4.3.1';
16116  var DATA_KEY$3 = 'bs.collapse';
16117  var EVENT_KEY$3 = "." + DATA_KEY$3;
16118  var DATA_API_KEY$3 = '.data-api';
16119  var JQUERY_NO_CONFLICT$3 = $.fn[NAME$3];
16120  var Default$1 = {
16121    toggle: true,
16122    parent: ''
16123  };
16124  var DefaultType$1 = {
16125    toggle: 'boolean',
16126    parent: '(string|element)'
16127  };
16128  var Event$3 = {
16129    SHOW: "show" + EVENT_KEY$3,
16130    SHOWN: "shown" + EVENT_KEY$3,
16131    HIDE: "hide" + EVENT_KEY$3,
16132    HIDDEN: "hidden" + EVENT_KEY$3,
16133    CLICK_DATA_API: "click" + EVENT_KEY$3 + DATA_API_KEY$3
16134  };
16135  var ClassName$3 = {
16136    SHOW: 'show',
16137    COLLAPSE: 'collapse',
16138    COLLAPSING: 'collapsing',
16139    COLLAPSED: 'collapsed'
16140  };
16141  var Dimension = {
16142    WIDTH: 'width',
16143    HEIGHT: 'height'
16144  };
16145  var Selector$3 = {
16146    ACTIVES: '.show, .collapsing',
16147    DATA_TOGGLE: '[data-toggle="collapse"]'
16148    /**
16149     * ------------------------------------------------------------------------
16150     * Class Definition
16151     * ------------------------------------------------------------------------
16152     */
16153
16154  };
16155
16156  var Collapse =
16157  /*#__PURE__*/
16158  function () {
16159    function Collapse(element, config) {
16160      this._isTransitioning = false;
16161      this._element = element;
16162      this._config = this._getConfig(config);
16163      this._triggerArray = [].slice.call(document.querySelectorAll("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]")));
16164      var toggleList = [].slice.call(document.querySelectorAll(Selector$3.DATA_TOGGLE));
16165
16166      for (var i = 0, len = toggleList.length; i < len; i++) {
16167        var elem = toggleList[i];
16168        var selector = Util.getSelectorFromElement(elem);
16169        var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) {
16170          return foundElem === element;
16171        });
16172
16173        if (selector !== null && filterElement.length > 0) {
16174          this._selector = selector;
16175
16176          this._triggerArray.push(elem);
16177        }
16178      }
16179
16180      this._parent = this._config.parent ? this._getParent() : null;
16181
16182      if (!this._config.parent) {
16183        this._addAriaAndCollapsedClass(this._element, this._triggerArray);
16184      }
16185
16186      if (this._config.toggle) {
16187        this.toggle();
16188      }
16189    } // Getters
16190
16191
16192    var _proto = Collapse.prototype;
16193
16194    // Public
16195    _proto.toggle = function toggle() {
16196      if ($(this._element).hasClass(ClassName$3.SHOW)) {
16197        this.hide();
16198      } else {
16199        this.show();
16200      }
16201    };
16202
16203    _proto.show = function show() {
16204      var _this = this;
16205
16206      if (this._isTransitioning || $(this._element).hasClass(ClassName$3.SHOW)) {
16207        return;
16208      }
16209
16210      var actives;
16211      var activesData;
16212
16213      if (this._parent) {
16214        actives = [].slice.call(this._parent.querySelectorAll(Selector$3.ACTIVES)).filter(function (elem) {
16215          if (typeof _this._config.parent === 'string') {
16216            return elem.getAttribute('data-parent') === _this._config.parent;
16217          }
16218
16219          return elem.classList.contains(ClassName$3.COLLAPSE);
16220        });
16221
16222        if (actives.length === 0) {
16223          actives = null;
16224        }
16225      }
16226
16227      if (actives) {
16228        activesData = $(actives).not(this._selector).data(DATA_KEY$3);
16229
16230        if (activesData && activesData._isTransitioning) {
16231          return;
16232        }
16233      }
16234
16235      var startEvent = $.Event(Event$3.SHOW);
16236      $(this._element).trigger(startEvent);
16237
16238      if (startEvent.isDefaultPrevented()) {
16239        return;
16240      }
16241
16242      if (actives) {
16243        Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide');
16244
16245        if (!activesData) {
16246          $(actives).data(DATA_KEY$3, null);
16247        }
16248      }
16249
16250      var dimension = this._getDimension();
16251
16252      $(this._element).removeClass(ClassName$3.COLLAPSE).addClass(ClassName$3.COLLAPSING);
16253      this._element.style[dimension] = 0;
16254
16255      if (this._triggerArray.length) {
16256        $(this._triggerArray).removeClass(ClassName$3.COLLAPSED).attr('aria-expanded', true);
16257      }
16258
16259      this.setTransitioning(true);
16260
16261      var complete = function complete() {
16262        $(_this._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).addClass(ClassName$3.SHOW);
16263        _this._element.style[dimension] = '';
16264
16265        _this.setTransitioning(false);
16266
16267        $(_this._element).trigger(Event$3.SHOWN);
16268      };
16269
16270      var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
16271      var scrollSize = "scroll" + capitalizedDimension;
16272      var transitionDuration = Util.getTransitionDurationFromElement(this._element);
16273      $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
16274      this._element.style[dimension] = this._element[scrollSize] + "px";
16275    };
16276
16277    _proto.hide = function hide() {
16278      var _this2 = this;
16279
16280      if (this._isTransitioning || !$(this._element).hasClass(ClassName$3.SHOW)) {
16281        return;
16282      }
16283
16284      var startEvent = $.Event(Event$3.HIDE);
16285      $(this._element).trigger(startEvent);
16286
16287      if (startEvent.isDefaultPrevented()) {
16288        return;
16289      }
16290
16291      var dimension = this._getDimension();
16292
16293      this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px";
16294      Util.reflow(this._element);
16295      $(this._element).addClass(ClassName$3.COLLAPSING).removeClass(ClassName$3.COLLAPSE).removeClass(ClassName$3.SHOW);
16296      var triggerArrayLength = this._triggerArray.length;
16297
16298      if (triggerArrayLength > 0) {
16299        for (var i = 0; i < triggerArrayLength; i++) {
16300          var trigger = this._triggerArray[i];
16301          var selector = Util.getSelectorFromElement(trigger);
16302
16303          if (selector !== null) {
16304            var $elem = $([].slice.call(document.querySelectorAll(selector)));
16305
16306            if (!$elem.hasClass(ClassName$3.SHOW)) {
16307              $(trigger).addClass(ClassName$3.COLLAPSED).attr('aria-expanded', false);
16308            }
16309          }
16310        }
16311      }
16312
16313      this.setTransitioning(true);
16314
16315      var complete = function complete() {
16316        _this2.setTransitioning(false);
16317
16318        $(_this2._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).trigger(Event$3.HIDDEN);
16319      };
16320
16321      this._element.style[dimension] = '';
16322      var transitionDuration = Util.getTransitionDurationFromElement(this._element);
16323      $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
16324    };
16325
16326    _proto.setTransitioning = function setTransitioning(isTransitioning) {
16327      this._isTransitioning = isTransitioning;
16328    };
16329
16330    _proto.dispose = function dispose() {
16331      $.removeData(this._element, DATA_KEY$3);
16332      this._config = null;
16333      this._parent = null;
16334      this._element = null;
16335      this._triggerArray = null;
16336      this._isTransitioning = null;
16337    } // Private
16338    ;
16339
16340    _proto._getConfig = function _getConfig(config) {
16341      config = _objectSpread({}, Default$1, config);
16342      config.toggle = Boolean(config.toggle); // Coerce string values
16343
16344      Util.typeCheckConfig(NAME$3, config, DefaultType$1);
16345      return config;
16346    };
16347
16348    _proto._getDimension = function _getDimension() {
16349      var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
16350      return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
16351    };
16352
16353    _proto._getParent = function _getParent() {
16354      var _this3 = this;
16355
16356      var parent;
16357
16358      if (Util.isElement(this._config.parent)) {
16359        parent = this._config.parent; // It's a jQuery object
16360
16361        if (typeof this._config.parent.jquery !== 'undefined') {
16362          parent = this._config.parent[0];
16363        }
16364      } else {
16365        parent = document.querySelector(this._config.parent);
16366      }
16367
16368      var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]";
16369      var children = [].slice.call(parent.querySelectorAll(selector));
16370      $(children).each(function (i, element) {
16371        _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
16372      });
16373      return parent;
16374    };
16375
16376    _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {
16377      var isOpen = $(element).hasClass(ClassName$3.SHOW);
16378
16379      if (triggerArray.length) {
16380        $(triggerArray).toggleClass(ClassName$3.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
16381      }
16382    } // Static
16383    ;
16384
16385    Collapse._getTargetFromElement = function _getTargetFromElement(element) {
16386      var selector = Util.getSelectorFromElement(element);
16387      return selector ? document.querySelector(selector) : null;
16388    };
16389
16390    Collapse._jQueryInterface = function _jQueryInterface(config) {
16391      return this.each(function () {
16392        var $this = $(this);
16393        var data = $this.data(DATA_KEY$3);
16394
16395        var _config = _objectSpread({}, Default$1, $this.data(), typeof config === 'object' && config ? config : {});
16396
16397        if (!data && _config.toggle && /show|hide/.test(config)) {
16398          _config.toggle = false;
16399        }
16400
16401        if (!data) {
16402          data = new Collapse(this, _config);
16403          $this.data(DATA_KEY$3, data);
16404        }
16405
16406        if (typeof config === 'string') {
16407          if (typeof data[config] === 'undefined') {
16408            throw new TypeError("No method named \"" + config + "\"");
16409          }
16410
16411          data[config]();
16412        }
16413      });
16414    };
16415
16416    _createClass(Collapse, null, [{
16417      key: "VERSION",
16418      get: function get() {
16419        return VERSION$3;
16420      }
16421    }, {
16422      key: "Default",
16423      get: function get() {
16424        return Default$1;
16425      }
16426    }]);
16427
16428    return Collapse;
16429  }();
16430  /**
16431   * ------------------------------------------------------------------------
16432   * Data Api implementation
16433   * ------------------------------------------------------------------------
16434   */
16435
16436
16437  $(document).on(Event$3.CLICK_DATA_API, Selector$3.DATA_TOGGLE, function (event) {
16438    // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
16439    if (event.currentTarget.tagName === 'A') {
16440      event.preventDefault();
16441    }
16442
16443    var $trigger = $(this);
16444    var selector = Util.getSelectorFromElement(this);
16445    var selectors = [].slice.call(document.querySelectorAll(selector));
16446    $(selectors).each(function () {
16447      var $target = $(this);
16448      var data = $target.data(DATA_KEY$3);
16449      var config = data ? 'toggle' : $trigger.data();
16450
16451      Collapse._jQueryInterface.call($target, config);
16452    });
16453  });
16454  /**
16455   * ------------------------------------------------------------------------
16456   * jQuery
16457   * ------------------------------------------------------------------------
16458   */
16459
16460  $.fn[NAME$3] = Collapse._jQueryInterface;
16461  $.fn[NAME$3].Constructor = Collapse;
16462
16463  $.fn[NAME$3].noConflict = function () {
16464    $.fn[NAME$3] = JQUERY_NO_CONFLICT$3;
16465    return Collapse._jQueryInterface;
16466  };
16467
16468  /**
16469   * ------------------------------------------------------------------------
16470   * Constants
16471   * ------------------------------------------------------------------------
16472   */
16473
16474  var NAME$4 = 'dropdown';
16475  var VERSION$4 = '4.3.1';
16476  var DATA_KEY$4 = 'bs.dropdown';
16477  var EVENT_KEY$4 = "." + DATA_KEY$4;
16478  var DATA_API_KEY$4 = '.data-api';
16479  var JQUERY_NO_CONFLICT$4 = $.fn[NAME$4];
16480  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
16481
16482  var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
16483
16484  var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
16485
16486  var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
16487
16488  var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
16489
16490  var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
16491
16492  var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);
16493  var Event$4 = {
16494    HIDE: "hide" + EVENT_KEY$4,
16495    HIDDEN: "hidden" + EVENT_KEY$4,
16496    SHOW: "show" + EVENT_KEY$4,
16497    SHOWN: "shown" + EVENT_KEY$4,
16498    CLICK: "click" + EVENT_KEY$4,
16499    CLICK_DATA_API: "click" + EVENT_KEY$4 + DATA_API_KEY$4,
16500    KEYDOWN_DATA_API: "keydown" + EVENT_KEY$4 + DATA_API_KEY$4,
16501    KEYUP_DATA_API: "keyup" + EVENT_KEY$4 + DATA_API_KEY$4
16502  };
16503  var ClassName$4 = {
16504    DISABLED: 'disabled',
16505    SHOW: 'show',
16506    DROPUP: 'dropup',
16507    DROPRIGHT: 'dropright',
16508    DROPLEFT: 'dropleft',
16509    MENURIGHT: 'dropdown-menu-right',
16510    MENULEFT: 'dropdown-menu-left',
16511    POSITION_STATIC: 'position-static'
16512  };
16513  var Selector$4 = {
16514    DATA_TOGGLE: '[data-toggle="dropdown"]',
16515    FORM_CHILD: '.dropdown form',
16516    MENU: '.dropdown-menu',
16517    NAVBAR_NAV: '.navbar-nav',
16518    VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
16519  };
16520  var AttachmentMap = {
16521    TOP: 'top-start',
16522    TOPEND: 'top-end',
16523    BOTTOM: 'bottom-start',
16524    BOTTOMEND: 'bottom-end',
16525    RIGHT: 'right-start',
16526    RIGHTEND: 'right-end',
16527    LEFT: 'left-start',
16528    LEFTEND: 'left-end'
16529  };
16530  var Default$2 = {
16531    offset: 0,
16532    flip: true,
16533    boundary: 'scrollParent',
16534    reference: 'toggle',
16535    display: 'dynamic'
16536  };
16537  var DefaultType$2 = {
16538    offset: '(number|string|function)',
16539    flip: 'boolean',
16540    boundary: '(string|element)',
16541    reference: '(string|element)',
16542    display: 'string'
16543    /**
16544     * ------------------------------------------------------------------------
16545     * Class Definition
16546     * ------------------------------------------------------------------------
16547     */
16548
16549  };
16550
16551  var Dropdown =
16552  /*#__PURE__*/
16553  function () {
16554    function Dropdown(element, config) {
16555      this._element = element;
16556      this._popper = null;
16557      this._config = this._getConfig(config);
16558      this._menu = this._getMenuElement();
16559      this._inNavbar = this._detectNavbar();
16560
16561      this._addEventListeners();
16562    } // Getters
16563
16564
16565    var _proto = Dropdown.prototype;
16566
16567    // Public
16568    _proto.toggle = function toggle() {
16569      if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED)) {
16570        return;
16571      }
16572
16573      var parent = Dropdown._getParentFromElement(this._element);
16574
16575      var isActive = $(this._menu).hasClass(ClassName$4.SHOW);
16576
16577      Dropdown._clearMenus();
16578
16579      if (isActive) {
16580        return;
16581      }
16582
16583      var relatedTarget = {
16584        relatedTarget: this._element
16585      };
16586      var showEvent = $.Event(Event$4.SHOW, relatedTarget);
16587      $(parent).trigger(showEvent);
16588
16589      if (showEvent.isDefaultPrevented()) {
16590        return;
16591      } // Disable totally Popper.js for Dropdown in Navbar
16592
16593
16594      if (!this._inNavbar) {
16595        /**
16596         * Check for Popper dependency
16597         * Popper - https://popper.js.org
16598         */
16599        if (typeof Popper === 'undefined') {
16600          throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)');
16601        }
16602
16603        var referenceElement = this._element;
16604
16605        if (this._config.reference === 'parent') {
16606          referenceElement = parent;
16607        } else if (Util.isElement(this._config.reference)) {
16608          referenceElement = this._config.reference; // Check if it's jQuery element
16609
16610          if (typeof this._config.reference.jquery !== 'undefined') {
16611            referenceElement = this._config.reference[0];
16612          }
16613        } // If boundary is not `scrollParent`, then set position to `static`
16614        // to allow the menu to "escape" the scroll parent's boundaries
16615        // https://github.com/twbs/bootstrap/issues/24251
16616
16617
16618        if (this._config.boundary !== 'scrollParent') {
16619          $(parent).addClass(ClassName$4.POSITION_STATIC);
16620        }
16621
16622        this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());
16623      } // If this is a touch-enabled device we add extra
16624      // empty mouseover listeners to the body's immediate children;
16625      // only needed because of broken event delegation on iOS
16626      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
16627
16628
16629      if ('ontouchstart' in document.documentElement && $(parent).closest(Selector$4.NAVBAR_NAV).length === 0) {
16630        $(document.body).children().on('mouseover', null, $.noop);
16631      }
16632
16633      this._element.focus();
16634
16635      this._element.setAttribute('aria-expanded', true);
16636
16637      $(this._menu).toggleClass(ClassName$4.SHOW);
16638      $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.SHOWN, relatedTarget));
16639    };
16640
16641    _proto.show = function show() {
16642      if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || $(this._menu).hasClass(ClassName$4.SHOW)) {
16643        return;
16644      }
16645
16646      var relatedTarget = {
16647        relatedTarget: this._element
16648      };
16649      var showEvent = $.Event(Event$4.SHOW, relatedTarget);
16650
16651      var parent = Dropdown._getParentFromElement(this._element);
16652
16653      $(parent).trigger(showEvent);
16654
16655      if (showEvent.isDefaultPrevented()) {
16656        return;
16657      }
16658
16659      $(this._menu).toggleClass(ClassName$4.SHOW);
16660      $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.SHOWN, relatedTarget));
16661    };
16662
16663    _proto.hide = function hide() {
16664      if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || !$(this._menu).hasClass(ClassName$4.SHOW)) {
16665        return;
16666      }
16667
16668      var relatedTarget = {
16669        relatedTarget: this._element
16670      };
16671      var hideEvent = $.Event(Event$4.HIDE, relatedTarget);
16672
16673      var parent = Dropdown._getParentFromElement(this._element);
16674
16675      $(parent).trigger(hideEvent);
16676
16677      if (hideEvent.isDefaultPrevented()) {
16678        return;
16679      }
16680
16681      $(this._menu).toggleClass(ClassName$4.SHOW);
16682      $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget));
16683    };
16684
16685    _proto.dispose = function dispose() {
16686      $.removeData(this._element, DATA_KEY$4);
16687      $(this._element).off(EVENT_KEY$4);
16688      this._element = null;
16689      this._menu = null;
16690
16691      if (this._popper !== null) {
16692        this._popper.destroy();
16693
16694        this._popper = null;
16695      }
16696    };
16697
16698    _proto.update = function update() {
16699      this._inNavbar = this._detectNavbar();
16700
16701      if (this._popper !== null) {
16702        this._popper.scheduleUpdate();
16703      }
16704    } // Private
16705    ;
16706
16707    _proto._addEventListeners = function _addEventListeners() {
16708      var _this = this;
16709
16710      $(this._element).on(Event$4.CLICK, function (event) {
16711        event.preventDefault();
16712        event.stopPropagation();
16713
16714        _this.toggle();
16715      });
16716    };
16717
16718    _proto._getConfig = function _getConfig(config) {
16719      config = _objectSpread({}, this.constructor.Default, $(this._element).data(), config);
16720      Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
16721      return config;
16722    };
16723
16724    _proto._getMenuElement = function _getMenuElement() {
16725      if (!this._menu) {
16726        var parent = Dropdown._getParentFromElement(this._element);
16727
16728        if (parent) {
16729          this._menu = parent.querySelector(Selector$4.MENU);
16730        }
16731      }
16732
16733      return this._menu;
16734    };
16735
16736    _proto._getPlacement = function _getPlacement() {
16737      var $parentDropdown = $(this._element.parentNode);
16738      var placement = AttachmentMap.BOTTOM; // Handle dropup
16739
16740      if ($parentDropdown.hasClass(ClassName$4.DROPUP)) {
16741        placement = AttachmentMap.TOP;
16742
16743        if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) {
16744          placement = AttachmentMap.TOPEND;
16745        }
16746      } else if ($parentDropdown.hasClass(ClassName$4.DROPRIGHT)) {
16747        placement = AttachmentMap.RIGHT;
16748      } else if ($parentDropdown.hasClass(ClassName$4.DROPLEFT)) {
16749        placement = AttachmentMap.LEFT;
16750      } else if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) {
16751        placement = AttachmentMap.BOTTOMEND;
16752      }
16753
16754      return placement;
16755    };
16756
16757    _proto._detectNavbar = function _detectNavbar() {
16758      return $(this._element).closest('.navbar').length > 0;
16759    };
16760
16761    _proto._getOffset = function _getOffset() {
16762      var _this2 = this;
16763
16764      var offset = {};
16765
16766      if (typeof this._config.offset === 'function') {
16767        offset.fn = function (data) {
16768          data.offsets = _objectSpread({}, data.offsets, _this2._config.offset(data.offsets, _this2._element) || {});
16769          return data;
16770        };
16771      } else {
16772        offset.offset = this._config.offset;
16773      }
16774
16775      return offset;
16776    };
16777
16778    _proto._getPopperConfig = function _getPopperConfig() {
16779      var popperConfig = {
16780        placement: this._getPlacement(),
16781        modifiers: {
16782          offset: this._getOffset(),
16783          flip: {
16784            enabled: this._config.flip
16785          },
16786          preventOverflow: {
16787            boundariesElement: this._config.boundary
16788          }
16789        } // Disable Popper.js if we have a static display
16790
16791      };
16792
16793      if (this._config.display === 'static') {
16794        popperConfig.modifiers.applyStyle = {
16795          enabled: false
16796        };
16797      }
16798
16799      return popperConfig;
16800    } // Static
16801    ;
16802
16803    Dropdown._jQueryInterface = function _jQueryInterface(config) {
16804      return this.each(function () {
16805        var data = $(this).data(DATA_KEY$4);
16806
16807        var _config = typeof config === 'object' ? config : null;
16808
16809        if (!data) {
16810          data = new Dropdown(this, _config);
16811          $(this).data(DATA_KEY$4, data);
16812        }
16813
16814        if (typeof config === 'string') {
16815          if (typeof data[config] === 'undefined') {
16816            throw new TypeError("No method named \"" + config + "\"");
16817          }
16818
16819          data[config]();
16820        }
16821      });
16822    };
16823
16824    Dropdown._clearMenus = function _clearMenus(event) {
16825      if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
16826        return;
16827      }
16828
16829      var toggles = [].slice.call(document.querySelectorAll(Selector$4.DATA_TOGGLE));
16830
16831      for (var i = 0, len = toggles.length; i < len; i++) {
16832        var parent = Dropdown._getParentFromElement(toggles[i]);
16833
16834        var context = $(toggles[i]).data(DATA_KEY$4);
16835        var relatedTarget = {
16836          relatedTarget: toggles[i]
16837        };
16838
16839        if (event && event.type === 'click') {
16840          relatedTarget.clickEvent = event;
16841        }
16842
16843        if (!context) {
16844          continue;
16845        }
16846
16847        var dropdownMenu = context._menu;
16848
16849        if (!$(parent).hasClass(ClassName$4.SHOW)) {
16850          continue;
16851        }
16852
16853        if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {
16854          continue;
16855        }
16856
16857        var hideEvent = $.Event(Event$4.HIDE, relatedTarget);
16858        $(parent).trigger(hideEvent);
16859
16860        if (hideEvent.isDefaultPrevented()) {
16861          continue;
16862        } // If this is a touch-enabled device we remove the extra
16863        // empty mouseover listeners we added for iOS support
16864
16865
16866        if ('ontouchstart' in document.documentElement) {
16867          $(document.body).children().off('mouseover', null, $.noop);
16868        }
16869
16870        toggles[i].setAttribute('aria-expanded', 'false');
16871        $(dropdownMenu).removeClass(ClassName$4.SHOW);
16872        $(parent).removeClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget));
16873      }
16874    };
16875
16876    Dropdown._getParentFromElement = function _getParentFromElement(element) {
16877      var parent;
16878      var selector = Util.getSelectorFromElement(element);
16879
16880      if (selector) {
16881        parent = document.querySelector(selector);
16882      }
16883
16884      return parent || element.parentNode;
16885    } // eslint-disable-next-line complexity
16886    ;
16887
16888    Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
16889      // If not input/textarea:
16890      //  - And not a key in REGEXP_KEYDOWN => not a dropdown command
16891      // If input/textarea:
16892      //  - If space key => not a dropdown command
16893      //  - If key is other than escape
16894      //    - If key is not up or down => not a dropdown command
16895      //    - If trigger inside the menu =>
16895 not a dropdown command
16896      if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(Selector$4.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
16897        return;
16898      }
16899
16900      event.preventDefault();
16901      event.stopPropagation();
16902
16903      if (this.disabled || $(this).hasClass(ClassName$4.DISABLED)) {
16904        return;
16905      }
16906
16907      var parent = Dropdown._getParentFromElement(this);
16908
16909      var isActive = $(parent).hasClass(ClassName$4.SHOW);
16910
16911      if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
16912        if (event.which === ESCAPE_KEYCODE) {
16913          var toggle = parent.querySelector(Selector$4.DATA_TOGGLE);
16914          $(toggle).trigger('focus');
16915        }
16916
16917        $(this).trigger('click');
16918        return;
16919      }
16920
16921      var items = [].slice.call(parent.querySelectorAll(Selector$4.VISIBLE_ITEMS));
16922
16923      if (items.length === 0) {
16924        return;
16925      }
16926
16927      var index = items.indexOf(event.target);
16928
16929      if (event.which === ARROW_UP_KEYCODE && index > 0) {
16930        // Up
16931        index--;
16932      }
16933
16934      if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
16935        // Down
16936        index++;
16937      }
16938
16939      if (index < 0) {
16940        index = 0;
16941      }
16942
16943      items[index].focus();
16944    };
16945
16946    _createClass(Dropdown, null, [{
16947      key: "VERSION",
16948      get: function get() {
16949        return VERSION$4;
16950      }
16951    }, {
16952      key: "Default",
16953      get: function get() {
16954        return Default$2;
16955      }
16956    }, {
16957      key: "DefaultType",
16958      get: function get() {
16959        return DefaultType$2;
16960      }
16961    }]);
16962
16963    return Dropdown;
16964  }();
16965  /**
16966   * ------------------------------------------------------------------------
16967   * Data Api implementation
16968   * ------------------------------------------------------------------------
16969   */
16970
16971
16972  $(document).on(Event$4.KEYDOWN_DATA_API, Selector$4.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event$4.KEYDOWN_DATA_API, Selector$4.MENU, Dropdown._dataApiKeydownHandler).on(Event$4.CLICK_DATA_API + " " + Event$4.KEYUP_DATA_API, Dropdown._clearMenus).on(Event$4.CLICK_DATA_API, Selector$4.DATA_TOGGLE, function (event) {
16973    event.preventDefault();
16974    event.stopPropagation();
16975
16976    Dropdown._jQueryInterface.call($(this), 'toggle');
16977  }).on(Event$4.CLICK_DATA_API, Selector$4.FORM_CHILD, function (e) {
16978    e.stopPropagation();
16979  });
16980  /**
16981   * ------------------------------------------------------------------------
16982   * jQuery
16983   * ------------------------------------------------------------------------
16984   */
16985
16986  $.fn[NAME$4] = Dropdown._jQueryInterface;
16987  $.fn[NAME$4].Constructor = Dropdown;
16988
16989  $.fn[NAME$4].noConflict = function () {
16990    $.fn[NAME$4] = JQUERY_NO_CONFLICT$4;
16991    return Dropdown._jQueryInterface;
16992  };
16993
16994  /**
16995   * ------------------------------------------------------------------------
16996   * Constants
16997   * ------------------------------------------------------------------------
16998   */
16999
17000  var NAME$5 = 'modal';
17001  var VERSION$5 = '4.3.1';
17002  var DATA_KEY$5 = 'bs.modal';
17003  var EVENT_KEY$5 = "." + DATA_KEY$5;
17004  var DATA_API_KEY$5 = '.data-api';
17005  var JQUERY_NO_CONFLICT$5 = $.fn[NAME$5];
17006  var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key
17007
17008  var Default$3 = {
17009    backdrop: true,
17010    keyboard: true,
17011    focus: true,
17012    show: true
17013  };
17014  var DefaultType$3 = {
17015    backdrop: '(boolean|string)',
17016    keyboard: 'boolean',
17017    focus: 'boolean',
17018    show: 'boolean'
17019  };
17020  var Event$5 = {
17021    HIDE: "hide" + EVENT_KEY$5,
17022    HIDDEN: "hidden" + EVENT_KEY$5,
17023    SHOW: "show" + EVENT_KEY$5,
17024    SHOWN: "shown" + EVENT_KEY$5,
17025    FOCUSIN: "focusin" + EVENT_KEY$5,
17026    RESIZE: "resize" + EVENT_KEY$5,
17027    CLICK_DISMISS: "click.dismiss" + EVENT_KEY$5,
17028    KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY$5,
17029    MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY$5,
17030    MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY$5,
17031    CLICK_DATA_API: "click" + EVENT_KEY$5 + DATA_API_KEY$5
17032  };
17033  var ClassName$5 = {
17034    SCROLLABLE: 'modal-dialog-scrollable',
17035    SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
17036    BACKDROP: 'modal-backdrop',
17037    OPEN: 'modal-open',
17038    FADE: 'fade',
17039    SHOW: 'show'
17040  };
17041  var Selector$5 = {
17042    DIALOG: '.modal-dialog',
17043    MODAL_BODY: '.modal-body',
17044    DATA_TOGGLE: '[data-toggle="modal"]',
17045    DATA_DISMISS: '[data-dismiss="modal"]',
17046    FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
17047    STICKY_CONTENT: '.sticky-top'
17048    /**
17049     * ------------------------------------------------------------------------
17050     * Class Definition
17051     * ------------------------------------------------------------------------
17052     */
17053
17054  };
17055
17056  var Modal =
17057  /*#__PURE__*/
17058  function () {
17059    function Modal(element, config) {
17060      this._config = this._getConfig(config);
17061      this._element = element;
17062      this._dialog = element.querySelector(Selector$5.DIALOG);
17063      this._backdrop = null;
17064      this._isShown = false;
17065      this._isBodyOverflowing = false;
17066      this._ignoreBackdropClick = false;
17067      this._isTransitioning = false;
17068      this._scrollbarWidth = 0;
17069    } // Getters
17070
17071
17072    var _proto = Modal.prototype;
17073
17074    // Public
17075    _proto.toggle = function toggle(relatedTarget) {
17076      return this._isShown ? this.hide() : this.show(relatedTarget);
17077    };
17078
17079    _proto.show = function show(relatedTarget) {
17080      var _this = this;
17081
17082      if (this._isShown || this._isTransitioning) {
17083        return;
17084      }
17085
17086      if ($(this._element).hasClass(ClassName$5.FADE)) {
17087        this._isTransitioning = true;
17088      }
17089
17090      var showEvent = $.Event(Event$5.SHOW, {
17091        relatedTarget: relatedTarget
17092      });
17093      $(this._element).trigger(showEvent);
17094
17095      if (this._isShown || showEvent.isDefaultPrevented()) {
17096        return;
17097      }
17098
17099      this._isShown = true;
17100
17101      this._checkScrollbar();
17102
17103      this._setScrollbar();
17104
17105      this._adjustDialog();
17106
17107      this._setEscapeEvent();
17108
17109      this._setResizeEvent();
17110
17111      $(this._element).on(Event$5.CLICK_DISMISS, Selector$5.DATA_DISMISS, function (event) {
17112        return _this.hide(event);
17113      });
17114      $(this._dialog).on(Event$5.MOUSEDOWN_DISMISS, function () {
17115        $(_this._element).one(Event$5.MOUSEUP_DISMISS, function (event) {
17116          if ($(event.target).is(_this._element)) {
17117            _this._ignoreBackdropClick = true;
17118          }
17119        });
17120      });
17121
17122      this._showBackdrop(function () {
17123        return _this._showElement(relatedTarget);
17124      });
17125    };
17126
17127    _proto.hide = function hide(event) {
17128      var _this2 = this;
17129
17130      if (event) {
17131        event.preventDefault();
17132      }
17133
17134      if (!this._isShown || this._isTransitioning) {
17135        return;
17136      }
17137
17138      var hideEvent = $.Event(Event$5.HIDE);
17139      $(this._element).trigger(hideEvent);
17140
17141      if (!this._isShown || hideEvent.isDefaultPrevented()) {
17142        return;
17143      }
17144
17145      this._isShown = false;
17146      var transition = $(this._element).hasClass(ClassName$5.FADE);
17147
17148      if (transition) {
17149        this._isTransitioning = true;
17150      }
17151
17152      this._setEscapeEvent();
17153
17154      this._setResizeEvent();
17155
17156      $(document).off(Event$5.FOCUSIN);
17157      $(this._element).removeClass(ClassName$5.SHOW);
17158      $(this._element).off(Event$5.CLICK_DISMISS);
17159      $(this._dialog).off(Event$5.MOUSEDOWN_DISMISS);
17160
17161      if (transition) {
17162        var transitionDuration = Util.getTransitionDurationFromElement(this._element);
17163        $(this._element).one(Util.TRANSITION_END, function (event) {
17164          return _this2._hideModal(event);
17165        }).emulateTransitionEnd(transitionDuration);
17166      } else {
17167        this._hideModal();
17168      }
17169    };
17170
17171    _proto.dispose = function dispose() {
17172      [window, this._element, this._dialog].forEach(function (htmlElement) {
17173        return $(htmlElement).off(EVENT_KEY$5);
17174      });
17175      /**
17176       * `document` has 2 events `Event.FOCUSIN` and `Event.CLICK_DATA_API`
17177       * Do not move `document` in `htmlElements` array
17178       * It will remove `Event.CLICK_DATA_API` event that should remain
17179       */
17180
17181      $(document).off(Event$5.FOCUSIN);
17182      $.removeData(this._element, DATA_KEY$5);
17183      this._config = null;
17184      this._element = null;
17185      this._dialog = null;
17186      this._backdrop = null;
17187      this._isShown = null;
17188      this._isBodyOverflowing = null;
17189      this._ignoreBackdropClick = null;
17190      this._isTransitioning = null;
17191      this._scrollbarWidth = null;
17192    };
17193
17194    _proto.handleUpdate = function handleUpdate() {
17195      this._adjustDialog();
17196    } // Private
17197    ;
17198
17199    _proto._getConfig = function _getConfig(config) {
17200      config = _objectSpread({}, Default$3, config);
17201      Util.typeCheckConfig(NAME$5, config, DefaultType$3);
17202      return config;
17203    };
17204
17205    _proto._showElement = function _showElement(relatedTarget) {
17206      var _this3 = this;
17207
17208      var transition = $(this._element).hasClass(ClassName$5.FADE);
17209
17210      if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
17211        // Don't move modal's DOM position
17212        document.body.appendChild(this._element);
17213      }
17214
17215      this._element.style.display = 'block';
17216
17217      this._element.removeAttribute('aria-hidden');
17218
17219      this._element.setAttribute('aria-modal', true);
17220
17221      if ($(this._dialog).hasClass(ClassName$5.SCROLLABLE)) {
17222        this._dialog.querySelector(Selector$5.MODAL_BODY).scrollTop = 0;
17223      } else {
17224        this._element.scrollTop = 0;
17225      }
17226
17227      if (transition) {
17228        Util.reflow(this._element);
17229      }
17230
17231      $(this._element).addClass(ClassName$5.SHOW);
17232
17233      if (this._config.focus) {
17234        this._enforceFocus();
17235      }
17236
17237      var shownEvent = $.Event(Event$5.SHOWN, {
17238        relatedTarget: relatedTarget
17239      });
17240
17241      var transitionComplete = function transitionComplete() {
17242        if (_this3._config.focus) {
17243          _this3._element.focus();
17244        }
17245
17246        _this3._isTransitioning = false;
17247        $(_this3._element).trigger(shownEvent);
17248      };
17249
17250      if (transition) {
17251        var transitionDuration = Util.getTransitionDurationFromElement(this._dialog);
17252        $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration);
17253      } else {
17254        transitionComplete();
17255      }
17256    };
17257
17258    _proto._enforceFocus = function _enforceFocus() {
17259      var _this4 = this;
17260
17261      $(document).off(Event$5.FOCUSIN) // Guard against infinite focus loop
17262      .on(Event$5.FOCUSIN, function (event) {
17263        if (document !== event.target && _this4._element !== event.target && $(_this4._element).has(event.target).length === 0) {
17264          _this4._element.focus();
17265        }
17266      });
17267    };
17268
17269    _proto._setEscapeEvent = function _setEscapeEvent() {
17270      var _this5 = this;
17271
17272      if (this._isShown && this._config.keyboard) {
17273        $(this._element).on(Event$5.KEYDOWN_DISMISS, function (event) {
17274          if (event.which === ESCAPE_KEYCODE$1) {
17275            event.preventDefault();
17276
17277            _this5.hide();
17278          }
17279        });
17280      } else if (!this._isShown) {
17281        $(this._element).off(Event$5.KEYDOWN_DISMISS);
17282      }
17283    };
17284
17285    _proto._setResizeEvent = function _setResizeEvent() {
17286      var _this6 = this;
17287
17288      if (this._isShown) {
17289        $(window).on(Event$5.RESIZE, function (event) {
17290          return _this6.handleUpdate(event);
17291        });
17292      } else {
17293        $(window).off(Event$5.RESIZE);
17294      }
17295    };
17296
17297    _proto._hideModal = function _hideModal() {
17298      var _this7 = this;
17299
17300      this._element.style.display = 'none';
17301
17302      this._element.setAttribute('aria-hidden', true);
17303
17304      this._element.removeAttribute('aria-modal');
17305
17306      this._isTransitioning = false;
17307
17308      this._showBackdrop(function () {
17309        $(document.body).removeClass(ClassName$5.OPEN);
17310
17311        _this7._resetAdjustments();
17312
17313        _this7._resetScrollbar();
17314
17315        $(_this7._element).trigger(Event$5.HIDDEN);
17316      });
17317    };
17318
17319    _proto._removeBackdrop = function _removeBackdrop() {
17320      if (this._backdrop) {
17321        $(this._backdrop).remove();
17322        this._backdrop = null;
17323      }
17324    };
17325
17326    _proto._showBackdrop = function _showBackdrop(callback) {
17327      var _this8 = this;
17328
17329      var animate = $(this._element).hasClass(ClassName$5.FADE) ? ClassName$5.FADE : '';
17330
17331      if (this._isShown && this._config.backdrop) {
17332        this._backdrop = document.createElement('div');
17333        this._backdrop.className = ClassName$5.BACKDROP;
17334
17335        if (animate) {
17336          this._backdrop.classList.add(animate);
17337        }
17338
17339        $(this._backdrop).appendTo(document.body);
17340        $(this._element).on(Event$5.CLICK_DISMISS, function (event) {
17341          if (_this8._ignoreBackdropClick) {
17342            _this8._ignoreBackdropClick = false;
17343            return;
17344          }
17345
17346          if (event.target !== event.currentTarget) {
17347            return;
17348          }
17349
17350          if (_this8._config.backdrop === 'static') {
17351            _this8._element.focus();
17352          } else {
17353            _this8.hide();
17354          }
17355        });
17356
17357        if (animate) {
17358          Util.reflow(this._backdrop);
17359        }
17360
17361        $(this._backdrop).addClass(ClassName$5.SHOW);
17362
17363        if (!callback) {
17364          return;
17365        }
17366
17367        if (!animate) {
17368          callback();
17369          return;
17370        }
17371
17372        var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
17373        $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration);
17374      } else if (!this._isShown && this._backdrop) {
17375        $(this._backdrop).removeClass(ClassName$5.SHOW);
17376
17377        var callbackRemove = function callbackRemove() {
17378          _this8._removeBackdrop();
17379
17380          if (callback) {
17381            callback();
17382          }
17383        };
17384
17385        if ($(this._element).hasClass(ClassName$5.FADE)) {
17386          var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
17387
17388          $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration);
17389        } else {
17390          callbackRemove();
17391        }
17392      } else if (callback) {
17393        callback();
17394      }
17395    } // ----------------------------------------------------------------------
17396    // the following methods are used to handle overflowing modals
17397    // todo (fat): these should probably be refactored out of modal.js
17398    // ----------------------------------------------------------------------
17399    ;
17400
17401    _proto._adjustDialog = function _adjustDialog() {
17402      var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
17403
17404      if (!this._isBodyOverflowing && isModalOverflowing) {
17405        this._element.style.paddingLeft = this._scrollbarWidth + "px";
17406      }
17407
17408      if (this._isBodyOverflowing && !isModalOverflowing) {
17409        this._element.style.paddingRight = this._scrollbarWidth + "px";
17410      }
17411    };
17412
17413    _proto._resetAdjustments = function _resetAdjustments() {
17414      this._element.style.paddingLeft = '';
17415      this._element.style.paddingRight = '';
17416    };
17417
17418    _proto._checkScrollbar = function _checkScrollbar() {
17419      var rect = document.body.getBoundingClientRect();
17420      this._isBodyOverflowing = rect.left + rect.right < window.innerWidth;
17421      this._scrollbarWidth = this._getScrollbarWidth();
17422    };
17423
17424    _proto._setScrollbar = function _setScrollbar() {
17425      var _this9 = this;
17426
17427      if (this._isBodyOverflowing) {
17428        // Note: DOMNode.style.paddingRight returns the actual value or '' if not set
17429        //   while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
17430        var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT));
17431        var stickyContent = [].slice.call(document.querySelectorAll(Selector$5.STICKY_CONTENT)); // Adjust fixed content padding
17432
17433        $(fixedContent).each(function (index, element) {
17434          var actualPadding = element.style.paddingRight;
17435          var calculatedPadding = $(element).css('padding-right');
17436          $(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this9._scrollbarWidth + "px");
17437        }); // Adjust sticky content margin
17438
17439        $(stickyContent).each(function (index, element) {
17440          var actualMargin = element.style.marginRight;
17441          var calculatedMargin = $(element).css('margin-right');
17442          $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this9._scrollbarWidth + "px");
17443        }); // Adjust body padding
17444
17445        var actualPadding = document.body.style.paddingRight;
17446        var calculatedPadding = $(document.body).css('padding-right');
17447        $(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px");
17448      }
17449
17450      $(document.body).addClass(ClassName$5.OPEN);
17451    };
17452
17453    _proto._resetScrollbar = function _resetScrollbar() {
17454      // Restore fixed content padding
17455      var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT));
17456      $(fixedContent).each(function (index, element) {
17457        var padding = $(element).data('padding-right');
17458        $(element).removeData('padding-right');
17459        element.style.paddingRight = padding ? padding : '';
17460      }); // Restore sticky content
17461
17462      var elements = [].slice.call(document.querySelectorAll("" + Selector$5.STICKY_CONTENT));
17463      $(elements).each(function (index, element) {
17464        var margin = $(element).data('margin-right');
17465
17466        if (typeof margin !== 'undefined') {
17467          $(element).css('margin-right', margin).removeData('margin-right');
17468        }
17469      }); // Restore body padding
17470
17471      var padding = $(document.body).data('padding-right');
17472      $(document.body).removeData('padding-right');
17473      document.body.style.paddingRight = padding ? padding : '';
17474    };
17475
17476    _proto._getScrollbarWidth = function _getScrollbarWidth() {
17477      // thx d.walsh
17478      var scrollDiv = document.createElement('div');
17479      scrollDiv.className = ClassName$5.SCROLLBAR_MEASURER;
17480      document.body.appendChild(scrollDiv);
17481      var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
17482      document.body.removeChild(scrollDiv);
17483      return scrollbarWidth;
17484    } // Static
17485    ;
17486
17487    Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {
17488      return this.each(function () {
17489        var data = $(this).data(DATA_KEY$5);
17490
17491        var _config = _objectSpread({}, Default$3, $(this).data(), typeof config === 'object' && config ? config : {});
17492
17493        if (!data) {
17494          data = new Modal(this, _config);
17495          $(this).data(DATA_KEY$5, data);
17496        }
17497
17498        if (typeof config === 'string') {
17499          if (typeof data[config] === 'undefined') {
17500            throw new TypeError("No method named \"" + config + "\"");
17501          }
17502
17503          data[config](relatedTarget);
17504        } else if (_config.show) {
17505          data.show(relatedTarget);
17506        }
17507      });
17508    };
17509
17510    _createClass(Modal, null, [{
17511      key: "VERSION",
17512      get: function get() {
17513        return VERSION$5;
17514      }
17515    }, {
17516      key: "Default",
17517      get: function get() {
17518        return Default$3;
17519      }
17520    }]);
17521
17522    return Modal;
17523  }();
17524  /**
17525   * ------------------------------------------------------------------------
17526   * Data Api implementation
17527   * ------------------------------------------------------------------------
17528   */
17529
17530
17531  $(document).on(Event$5.CLICK_DATA_API, Selector$5.DATA_TOGGLE, function (event) {
17532    var _this10 = this;
17533
17534    var target;
17535    var selector = Util.getSelectorFromElement(this);
17536
17537    if (selector) {
17538      target = document.querySelector(selector);
17539    }
17540
17541    var config = $(target).data(DATA_KEY$5) ? 'toggle' : _objectSpread({}, $(target).data(), $(this).data());
17542
17543    if (this.tagName === 'A' || this.tagName === 'AREA') {
17544      event.preventDefault();
17545    }
17546
17547    var $target = $(target).one(Event$5.SHOW, function (showEvent) {
17548      if (showEvent.isDefaultPrevented()) {
17549        // Only register focus restorer if modal will actually get shown
17550        return;
17551      }
17552
17553      $target.one(Event$5.HIDDEN, function () {
17554        if ($(_this10).is(':visible')) {
17555          _this10.focus();
17556        }
17557      });
17558    });
17559
17560    Modal._jQueryInterface.call($(target), config, this);
17561  });
17562  /**
17563   * ------------------------------------------------------------------------
17564   * jQuery
17565   * ------------------------------------------------------------------------
17566   */
17567
17568  $.fn[NAME$5] = Modal._jQueryInterface;
17569  $.fn[NAME$5].Constructor = Modal;
17570
17571  $.fn[NAME$5].noConflict = function () {
17572    $.fn[NAME$5] = JQUERY_NO_CONFLICT$5;
17573    return Modal._jQueryInterface;
17574  };
17575
17576  /**
17577   * --------------------------------------------------------------------------
17578   * Bootstrap (v4.3.1): tools/sanitizer.js
17579   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
17580   * --------------------------------------------------------------------------
17581   */
17582  var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
17583  var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
17584  var DefaultWhitelist = {
17585    // Global attributes allowed on any supplied element below.
17586    '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
17587    a: ['target', 'href', 'title', 'rel'],
17588    area: [],
17589    b: [],
17590    br: [],
17591    col: [],
17592    code: [],
17593    div: [],
17594    em: [],
17595    hr: [],
17596    h1: [],
17597    h2: [],
17598    h3: [],
17599    h4: [],
17600    h5: [],
17601    h6: [],
17602    i: [],
17603    img: ['src', 'alt', 'title', 'width', 'height'],
17604    li: [],
17605    ol: [],
17606    p: [],
17607    pre: [],
17608    s: [],
17609    small: [],
17610    span: [],
17611    sub: [],
17612    sup: [],
17613    strong: [],
17614    u: [],
17615    ul: []
17616    /**
17617     * A pattern that recognizes a commonly useful subset of URLs that are safe.
17618     *
17619     * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
17620     */
17621
17622  };
17623  var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
17624  /**
17625   * A pattern that matches safe data URLs. Only matches image, video and audio types.
17626   *
17627   * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
17628   */
17629
17630  var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;
17631
17632  function allowedAttribute(attr, allowedAttributeList) {
17633    var attrName = attr.nodeName.toLowerCase();
17634
17635    if (allowedAttributeList.indexOf(attrName) !== -1) {
17636      if (uriAttrs.indexOf(attrName) !== -1) {
17637        return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN));
17638      }
17639
17640      return true;
17641    }
17642
17643    var regExp = allowedAttributeList.filter(function (attrRegex) {
vendor: 4,926 bytes, lines 17644-17825
17644      return attrRegex instanceof RegExp;
17645    }); // Check if a regular expression validates the attribute.
17646
17647    for (var i = 0, l = regExp.length; i < l; i++) {
17648      if (attrName.match(regExp[i])) {
17649        return true;
17650      }
17651    }
17652
17653    return false;
17654  }
17655
17656  function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
17657    if (unsafeHtml.length === 0) {
17658      return unsafeHtml;
17659    }
17660
17661    if (sanitizeFn && typeof sanitizeFn === 'function') {
17662      return sanitizeFn(unsafeHtml);
17663    }
17664
17665    var domParser = new window.DOMParser();
17666    var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
17667    var whitelistKeys = Object.keys(whiteList);
17668    var elements = [].slice.call(createdDocument.body.querySelectorAll('*'));
17669
17670    var _loop = function _loop(i, len) {
17671      var el = elements[i];
17672      var elName = el.nodeName.toLowerCase();
17673
17674      if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {
17675        el.parentNode.removeChild(el);
17676        return "continue";
17677      }
17678
17679      var attributeList = [].slice.call(el.attributes);
17680      var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);
17681      attributeList.forEach(function (attr) {
17682        if (!allowedAttribute(attr, whitelistedAttributes)) {
17683          el.removeAttribute(attr.nodeName);
17684        }
17685      });
17686    };
17687
17688    for (var i = 0, len = elements.length; i < len; i++) {
17689      var _ret = _loop(i, len);
17690
17691      if (_ret === "continue") continue;
17692    }
17693
17694    return createdDocument.body.innerHTML;
17695  }
17696
17697  /**
17698   * ------------------------------------------------------------------------
17699   * Constants
17700   * ------------------------------------------------------------------------
17701   */
17702
17703  var NAME$6 = 'tooltip';
17704  var VERSION$6 = '4.3.1';
17705  var DATA_KEY$6 = 'bs.tooltip';
17706  var EVENT_KEY$6 = "." + DATA_KEY$6;
17707  var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6];
17708  var CLASS_PREFIX = 'bs-tooltip';
17709  var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
17710  var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];
17711  var DefaultType$4 = {
17712    animation: 'boolean',
17713    template: 'string',
17714    title: '(string|element|function)',
17715    trigger: 'string',
17716    delay: '(number|object)',
17717    html: 'boolean',
17718    selector: '(string|boolean)',
17719    placement: '(string|function)',
17720    offset: '(number|string|function)',
17721    container: '(string|element|boolean)',
17722    fallbackPlacement: '(string|array)',
17723    boundary: '(string|element)',
17724    sanitize: 'boolean',
17725    sanitizeFn: '(null|function)',
17726    whiteList: 'object'
17727  };
17728  var AttachmentMap$1 = {
17729    AUTO: 'auto',
17730    TOP: 'top',
17731    RIGHT: 'right',
17732    BOTTOM: 'bottom',
17733    LEFT: 'left'
17734  };
17735  var Default$4 = {
17736    animation: true,
17737    template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>',
17738    trigger: 'hover focus',
17739    title: '',
17740    delay: 0,
17741    html: false,
17742    selector: false,
17743    placement: 'top',
17744    offset: 0,
17745    container: false,
17746    fallbackPlacement: 'flip',
17747    boundary: 'scrollParent',
17748    sanitize: true,
17749    sanitizeFn: null,
17750    whiteList: DefaultWhitelist
17751  };
17752  var HoverState = {
17753    SHOW: 'show',
17754    OUT: 'out'
17755  };
17756  var Event$6 = {
17757    HIDE: "hide" + EVENT_KEY$6,
17758    HIDDEN: "hidden" + EVENT_KEY$6,
17759    SHOW: "show" + EVENT_KEY$6,
17760    SHOWN: "shown" + EVENT_KEY$6,
17761    INSERTED: "inserted" + EVENT_KEY$6,
17762    CLICK: "click" + EVENT_KEY$6,
17763    FOCUSIN: "focusin" + EVENT_KEY$6,
17764    FOCUSOUT: "focusout" + EVENT_KEY$6,
17765    MOUSEENTER: "mouseenter" + EVENT_KEY$6,
17766    MOUSELEAVE: "mouseleave" + EVENT_KEY$6
17767  };
17768  var ClassName$6 = {
17769    FADE: 'fade',
17770    SHOW: 'show'
17771  };
17772  var Selector$6 = {
17773    TOOLTIP: '.tooltip',
17774    TOOLTIP_INNER: '.tooltip-inner',
17775    ARROW: '.arrow'
17776  };
17777  var Trigger = {
17778    HOVER: 'hover',
17779    FOCUS: 'focus',
17780    CLICK: 'click',
17781    MANUAL: 'manual'
17782    /**
17783     * ------------------------------------------------------------------------
17784     * Class Definition
17785     * ------------------------------------------------------------------------
17786     */
17787
17788  };
17789
17790  var Tooltip =
17791  /*#__PURE__*/
17792  function () {
17793    function Tooltip(element, config) {
17794      /**
17795       * Check for Popper dependency
17796       * Popper - https://popper.js.org
17797       */
17798      if (typeof Popper === 'undefined') {
17799        throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)');
17800      } // private
17801
17802
17803      this._isEnabled = true;
17804      this._timeout = 0;
17805      this._hoverState = '';
17806      this._activeTrigger = {};
17807      this._popper = null; // Protected
17808
17809      this.element = element;
17810      this.config = this._getConfig(config);
17811      this.tip = null;
17812
17813      this._setListeners();
17814    } // Getters
17815
17816
17817    var _proto = Tooltip.prototype;
17818
17819    // Public
17820    _proto.enable = function enable() {
17821      this._isEnabled = true;
17822    };
17823
17824    _proto.disable = function disable() {
17825      this._isEnabled = false;
17826    };
17827
17828    _proto.toggleEnabled = function toggleEnabled() {
17829      this._isEnabled = !this._isEnabled;
17830    };
17831
17832    _proto.toggle = function toggle(event) {
17833      if (!this._isEnabled) {
17834        return;
17835      }
17836
17837      if (event) {
17838        var dataKey = this.constructor.DATA_KEY;
17839        var context = $(event.currentTarget).data(dataKey);
17840
17841        if (!context) {
17842          context = new this.constructor(event.currentTarget, this._getDelegateConfig());
17843          $(event.currentTarget).data(dataKey, context);
17844        }
17845
17846        context._activeTrigger.click = !context._activeTrigger.click;
17847
17848        if (context._isWithActiveTrigger()) {
17849          context._enter(null, context);
17850        } else {
17851          context._leave(null, context);
17852        }
17853      } else {
17854        if ($(this.getTipElement()).hasClass(ClassName$6.SHOW)) {
17855          this._leave(null, this);
17856
17857          return;
17858        }
17859
17860        this._enter(null, this);
17861      }
17862    };
17863
17864    _proto.dispose = function dispose() {
17865      clearTimeout(this._timeout);
17866      $.removeData(this.element, this.constructor.DATA_KEY);
17867      $(this.element).off(this.constructor.EVENT_KEY);
17868      $(this.element).closest('.modal').off('hide.bs.modal');
17869
17870      if (this.tip) {
17871        $(this.tip).remove();
17872      }
17873
17874      this._isEnabled = null;
17875      this._timeout = null;
17876      this._hoverState = null;
17877      this._activeTrigger = null;
17878
17879      if (this._popper !== null) {
17880        this._popper.destroy();
17881      }
17882
17883      this._popper = null;
17884      this.element = null;
17885      this.config = null;
17886      this.tip = null;
17887    };
17888
17889    _proto.show = function show() {
17890      var _this = this;
17891
17892      if ($(this.element).css('display') === 'none') {
17893        throw new Error('Please use show on visible elements');
17894      }
17895
17896      var showEvent = $.Event(this.constructor.Event.SHOW);
17897
17898      if (this.isWithContent() && this._isEnabled) {
17899        $(this.element).trigger(showEvent);
17900        var shadowRoot = Util.findShadowRoot(this.element);
17901        var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element);
17902
17903        if (showEvent.isDefaultPrevented() || !isInTheDom) {
17904          return;
17905        }
17906
17907        var tip = this.getTipElement();
17908        var tipId = Util.getUID(this.constructor.NAME);
17909        tip.setAttribute('id', tipId);
17910        this.element.setAttribute('aria-describedby', tipId);
17911        this.setContent();
17912
17913        if (this.config.animation) {
17914          $(tip).addClass(ClassName$6.FADE);
17915        }
17916
17917        var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
17918
17919        var attachment = this._getAttachment(placement);
17920
17921        this.addAttachmentClass(attachment);
17922
17923        var container = this._getContainer();
17924
17925        $(tip).data(this.constructor.DATA_KEY, this);
17926
17927        if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
17928          $(tip).appendTo(container);
17929        }
17930
17931        $(this.element).trigger(this.constructor.Event.INSERTED);
17932        this._popper = new Popper(this.element, tip, {
17933          placement: attachment,
17934          modifiers: {
17935            offset: this._getOffset(),
17936            flip: {
17937              behavior: this.config.fallbackPlacement
17938            },
17939            arrow: {
17940              element: Selector$6.ARROW
17941            },
17942            preventOverflow: {
17943              boundariesElement: this.config.boundary
17944            }
17945          },
17946          onCreate: function onCreate(data) {
17947            if (data.originalPlacement !== data.placement) {
17948              _this._handlePopperPlacementChange(data);
17949            }
17950          },
17951          onUpdate: function onUpdate(data) {
17952            return _this._handlePopperPlacementChange(data);
17953          }
17954        });
17955        $(tip).addClass(ClassName$6.SHOW); // If this is a touch-enabled device we add extra
17956        // empty mouseover listeners to the body's immediate children;
17957        // only needed because of broken event delegation on iOS
17958        // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
17959
17960        if ('ontouchstart' in document.documentElement) {
17961          $(document.body).children().on('mouseover', null, $.noop);
17962        }
17963
17964        var complete = function complete() {
17965          if (_this.config.animation) {
17966            _this._fixTransition();
17967          }
17968
17969          var prevHoverState = _this._hoverState;
17970          _this._hoverState = null;
17971          $(_this.element).trigger(_this.constructor.Event.SHOWN);
17972
17973          if (prevHoverState === HoverState.OUT) {
17974            _this._leave(null, _this);
17975          }
17976        };
17977
17978        if ($(this.tip).hasClass(ClassName$6.FADE)) {
17979          var transitionDuration = Util.getTransitionDurationFromElement(this.tip);
17980          $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
17981        } else {
17982          complete();
17983        }
17984      }
17985    };
17986
17987    _proto.hide = function hide(callback) {
17988      var _this2 = this;
17989
17990      var tip = this.getTipElement();
17991      var hideEvent = $.Event(this.constructor.Event.HIDE);
17992
17993      var complete = function complete() {
17994        if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) {
17995          tip.parentNode.removeChild(tip);
17996        }
17997
17998        _this2._cleanTipClass();
17999
18000        _this2.element.removeAttribute('aria-describedby');
18001
18002        $(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
18003
18004        if (_this2._popper !== null) {
18005          _this2._popper.destroy();
18006        }
18007
18008        if (callback) {
18009          callback();
18010        }
18011      };
18012
18013      $(this.element).trigger(hideEvent);
18014
18015      if (hideEvent.isDefaultPrevented()) {
18016        return;
18017      }
18018
18019      $(tip).removeClass(ClassName$6.SHOW); // If this is a touch-enabled device we remove the extra
18020      // empty mouseover listeners we added for iOS support
18021
18022      if ('ontouchstart' in document.documentElement) {
18023        $(document.body).children().off('mouseover', null, $.noop);
18024      }
18025
18026      this._activeTrigger[Trigger.CLICK] = false;
18027      this._activeTrigger[Trigger.FOCUS] = false;
18028      this._activeTrigger[Trigger.HOVER] = false;
18029
18030      if ($(this.tip).hasClass(ClassName$6.FADE)) {
18031        var transitionDuration = Util.getTransitionDurationFromElement(tip);
18032        $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
18033      } else {
18034        complete();
18035      }
18036
18037      this._hoverState = '';
18038    };
18039
18040    _proto.update = function update() {
18041      if (this._popper !== null) {
18042        this._popper.scheduleUpdate();
18043      }
18044    } // Protected
18045    ;
18046
18047    _proto.isWithContent = function isWithContent() {
18048      return Boolean(this.getTitle());
18049    };
18050
18051    _proto.addAttachmentClass = function addAttachmentClass(attachment) {
18052      $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
18053    };
18054
18055    _proto.getTipElement = function getTipElement() {
18056      this.tip = this.tip || $(this.config.template)[0];
18057      return this.tip;
18058    };
18059
18060    _proto.setContent = function setContent() {
18061      var tip = this.getTipElement();
18062      this.setElementContent($(tip.querySelectorAll(Selector$6.TOOLTIP_INNER)), this.getTitle());
18063      $(tip).removeClass(ClassName$6.FADE + " " + ClassName$6.SHOW);
18064    };
18065
18066    _proto.setElementContent = function setElementContent($element, content) {
18067      if (typeof content === 'object' && (content.nodeType || content.jquery)) {
18068        // Content is a DOM node or a jQuery
18069        if (this.config.html) {
18070          if (!$(content).parent().is($element)) {
18071            $element.empty().append(content);
18072          }
18073        } else {
18074          $element.text($(content).text());
18075        }
18076
18077        return;
18078      }
18079
18080      if (this.config.html) {
18081        if (this.config.sanitize) {
18082          content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn);
18083        }
18084
18085        $element.html(content);
18086      } else {
18087        $element.text(content);
18088      }
18089    };
18090
18091    _proto.getTitle = function getTitle() {
18092      var title = this.element.getAttribute('data-original-title');
18093
18094      if (!title) {
18095        title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
18096      }
18097
18098      return title;
18099    } // Private
18100    ;
18101
18102    _proto._getOffset = function _getOffset() {
18103      var _this3 = this;
18104
18105      var offset = {};
18106
18107      if (typeof this.config.offset === 'function') {
18108        offset.fn = function (data) {
18109          data.offsets = _objectSpread({}, data.offsets, _this3.config.offset(data.offsets, _this3.element) || {});
18110          return data;
18111        };
18112      } else {
18113        offset.offset = this.config.offset;
18114      }
18115
18116      return offset;
18117    };
18118
18119    _proto._getContainer = function _getContainer() {
18120      if (this.config.container === false) {
18121        return document.body;
18122      }
18123
18124      if (Util.isElement(this.config.container)) {
18125        return $(this.config.container);
18126      }
18127
18128      return $(document).find(this.config.container);
18129    };
18130
18131    _proto._getAttachment = function _getAttachment(placement) {
18132      return AttachmentMap$1[placement.toUpperCase()];
18133    };
18134
18135    _proto._setListeners = function _setListeners() {
18136      var _this4 = this;
18137
18138      var triggers = this.config.trigger.split(' ');
18139      triggers.forEach(function (trigger) {
18140        if (trigger === 'click') {
18141          $(_this4.element).on(_this4.constructor.Event.CLICK, _this4.config.selector, function (event) {
18142            return _this4.toggle(event);
18143          });
18144        } else if (trigger !== Trigger.MANUAL) {
18145          var eventIn = trigger === Trigger.HOVER ? _this4.constructor.Event.MOUSEENTER : _this4.constructor.Event.FOCUSIN;
18146          var eventOut = trigger === Trigger.HOVER ? _this4.constructor.Event.MOUSELEAVE : _this4.constructor.Event.FOCUSOUT;
18147          $(_this4.element).on(eventIn, _this4.config.selector, function (event) {
18148            return _this4._enter(event);
18149          }).on(eventOut, _this4.config.selector, function (event) {
18150            return _this4._leave(event);
18151          });
18152        }
18153      });
18154      $(this.element).closest('.modal').on('hide.bs.modal', function () {
18155        if (_this4.element) {
18156          _this4.hide();
18157        }
18158      });
18159
18160      if (this.config.selector) {
18161        this.config = _objectSpread({}, this.config, {
18162          trigger: 'manual',
18163          selector: ''
18164        });
18165      } else {
18166        this._fixTitle();
18167      }
18168    };
18169
18170    _proto._fixTitle = function _fixTitle() {
18171      var titleType = typeof this.element.getAttribute('data-original-title');
18172
18173      if (this.element.getAttribute('title') || titleType !== 'string') {
18174        this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
18175        this.element.setAttribute('title', '');
18176      }
18177    };
18178
18179    _proto._enter = function _enter(event, context) {
18180      var dataKey = this.constructor.DATA_KEY;
18181      context = context || $(event.currentTarget).data(dataKey);
18182
18183      if (!context) {
18184        context = new this.constructor(event.currentTarget, this._getDelegateConfig());
18185        $(event.currentTarget).data(dataKey, context);
18186      }
18187
18188      if (event) {
18189        context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true;
18190      }
18191
18192      if ($(context.getTipElement()).hasClass(ClassName$6.SHOW) || context._hoverState === HoverState.SHOW) {
18193        context._hoverState = HoverState.SHOW;
18194        return;
18195      }
18196
18197      clearTimeout(context._timeout);
18198      context._hoverState = HoverState.SHOW;
18199
18200      if (!context.config.delay || !context.config.delay.show) {
18201        context.show();
18202        return;
18203      }
18204
18205      context._timeout = setTimeout(function () {
18206        if (context._hoverState === HoverState.SHOW) {
18207          context.show();
18208        }
18209      }, context.config.delay.show);
18210    };
18211
18212    _proto._leave = function _leave(event, context) {
18213      var dataKey = this.constructor.DATA_KEY;
18214      context = context || $(event.currentTarget).data(dataKey);
18215
18216      if (!context) {
18217        context = new this.constructor(event.currentTarget, this._getDelegateConfig());
18218        $(event.currentTarget).data(dataKey, context);
18219      }
18220
18221      if (event) {
18222        context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;
vendor: 4,166 bytes, lines 18223-18385
18223      }
18224
18225      if (context._isWithActiveTrigger()) {
18226        return;
18227      }
18228
18229      clearTimeout(context._timeout);
18230      context._hoverState = HoverState.OUT;
18231
18232      if (!context.config.delay || !context.config.delay.hide) {
18233        context.hide();
18234        return;
18235      }
18236
18237      context._timeout = setTimeout(function () {
18238        if (context._hoverState === HoverState.OUT) {
18239          context.hide();
18240        }
18241      }, context.config.delay.hide);
18242    };
18243
18244    _proto._isWithActiveTrigger = function _isWithActiveTrigger() {
18245      for (var trigger in this._activeTrigger) {
18246        if (this._activeTrigger[trigger]) {
18247          return true;
18248        }
18249      }
18250
18251      return false;
18252    };
18253
18254    _proto._getConfig = function _getConfig(config) {
18255      var dataAttributes = $(this.element).data();
18256      Object.keys(dataAttributes).forEach(function (dataAttr) {
18257        if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {
18258          delete dataAttributes[dataAttr];
18259        }
18260      });
18261      config = _objectSpread({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {});
18262
18263      if (typeof config.delay === 'number') {
18264        config.delay = {
18265          show: config.delay,
18266          hide: config.delay
18267        };
18268      }
18269
18270      if (typeof config.title === 'number') {
18271        config.title = config.title.toString();
18272      }
18273
18274      if (typeof config.content === 'number') {
18275        config.content = config.content.toString();
18276      }
18277
18278      Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType);
18279
18280      if (config.sanitize) {
18281        config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn);
18282      }
18283
18284      return config;
18285    };
18286
18287    _proto._getDelegateConfig = function _getDelegateConfig() {
18288      var config = {};
18289
18290      if (this.config) {
18291        for (var key in this.config) {
18292          if (this.constructor.Default[key] !== this.config[key]) {
18293            config[key] = this.config[key];
18294          }
18295        }
18296      }
18297
18298      return config;
18299    };
18300
18301    _proto._cleanTipClass = function _cleanTipClass() {
18302      var $tip = $(this.getTipElement());
18303      var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
18304
18305      if (tabClass !== null && tabClass.length) {
18306        $tip.removeClass(tabClass.join(''));
18307      }
18308    };
18309
18310    _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) {
18311      var popperInstance = popperData.instance;
18312      this.tip = popperInstance.popper;
18313
18314      this._cleanTipClass();
18315
18316      this.addAttachmentClass(this._getAttachment(popperData.placement));
18317    };
18318
18319    _proto._fixTransition = function _fixTransition() {
18320      var tip = this.getTipElement();
18321      var initConfigAnimation = this.config.animation;
18322
18323      if (tip.getAttribute('x-placement') !== null) {
18324        return;
18325      }
18326
18327      $(tip).removeClass(ClassName$6.FADE);
18328      this.config.animation = false;
18329      this.hide();
18330      this.show();
18331      this.config.animation = initConfigAnimation;
18332    } // Static
18333    ;
18334
18335    Tooltip._jQueryInterface = function _jQueryInterface(config) {
18336      return this.each(function () {
18337        var data = $(this).data(DATA_KEY$6);
18338
18339        var _config = typeof config === 'object' && config;
18340
18341        if (!data && /dispose|hide/.test(config)) {
18342          return;
18343        }
18344
18345        if (!data) {
18346          data = new Tooltip(this, _config);
18347          $(this).data(DATA_KEY$6, data);
18348        }
18349
18350        if (typeof config === 'string') {
18351          if (typeof data[config] === 'undefined') {
18352            throw new TypeError("No method named \"" + config + "\"");
18353          }
18354
18355          data[config]();
18356        }
18357      });
18358    };
18359
18360    _createClass(Tooltip, null, [{
18361      key: "VERSION",
18362      get: function get() {
18363        return VERSION$6;
18364      }
18365    }, {
18366      key: "Default",
18367      get: function get() {
18368        return Default$4;
18369      }
18370    }, {
18371      key: "NAME",
18372      get: function get() {
18373        return NAME$6;
18374      }
18375    }, {
18376      key: "DATA_KEY",
18377      get: function get() {
18378        return DATA_KEY$6;
18379      }
18380    }, {
18381      key: "Event",
18382      get: function get() {
18383        return Event$6;
18384      }
18385    }, {
18386      key: "EVENT_KEY",
18387      get: function get() {
18388        return EVENT_KEY$6;
18389      }
18390    }, {
18391      key: "DefaultType",
18392      get: function get() {
18393        return DefaultType$4;
18394      }
18395    }]);
18396
18397    return Tooltip;
18398  }();
18399  /**
18400   * ------------------------------------------------------------------------
18401   * jQuery
18402   * ------------------------------------------------------------------------
18403   */
18404
18405
18406  $.fn[NAME$6] = Tooltip._jQueryInterface;
18407  $.fn[NAME$6].Constructor = Tooltip;
18408
18409  $.fn[NAME$6].noConflict = function () {
18410    $.fn[NAME$6] = JQUERY_NO_CONFLICT$6;
18411    return Tooltip._jQueryInterface;
18412  };
18413
18414  /**
18415   * ------------------------------------------------------------------------
18416   * Constants
18417   * ------------------------------------------------------------------------
18418   */
18419
18420  var NAME$7 = 'popover';
18421  var VERSION$7 = '4.3.1';
18422  var DATA_KEY$7 = 'bs.popover';
18423  var EVENT_KEY$7 = "." + DATA_KEY$7;
18424  var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7];
18425  var CLASS_PREFIX$1 = 'bs-popover';
18426  var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g');
18427
18428  var Default$5 = _objectSpread({}, Tooltip.Default, {
18429    placement: 'right',
18430    trigger: 'click',
18431    content: '',
18432    template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
18433  });
18434
18435  var DefaultType$5 = _objectSpread({}, Tooltip.DefaultType, {
18436    content: '(string|element|function)'
18437  });
18438
18439  var ClassName$7 = {
18440    FADE: 'fade',
18441    SHOW: 'show'
18442  };
18443  var Selector$7 = {
18444    TITLE: '.popover-header',
18445    CONTENT: '.popover-body'
18446  };
18447  var Event$7 = {
18448    HIDE: "hide" + EVENT_KEY$7,
18449    HIDDEN: "hidden" + EVENT_KEY$7,
18450    SHOW: "show" + EVENT_KEY$7,
18451    SHOWN: "shown" + EVENT_KEY$7,
18452    INSERTED: "inserted" + EVENT_KEY$7,
18453    CLICK: "click" + EVENT_KEY$7,
18454    FOCUSIN: "focusin" + EVENT_KEY$7,
18455    FOCUSOUT: "focusout" + EVENT_KEY$7,
18456    MOUSEENTER: "mouseenter" + EVENT_KEY$7,
18457    MOUSELEAVE: "mouseleave" + EVENT_KEY$7
18458    /**
18459     * ------------------------------------------------------------------------
18460     * Class Definition
18461     * ------------------------------------------------------------------------
18462     */
18463
18464  };
18465
18466  var Popover =
18467  /*#__PURE__*/
18468  function (_Tooltip) {
18469    _inheritsLoose(Popover, _Tooltip);
18470
18471    function Popover() {
18472      return _Tooltip.apply(this, arguments) || this;
18473    }
18474
18475    var _proto = Popover.prototype;
18476
18477    // Overrides
18478    _proto.isWithContent = function isWithContent() {
18479      return this.getTitle() || this._getContent();
18480    };
18481
18482    _proto.addAttachmentClass = function addAttachmentClass(attachment) {
18483      $(this.getTipElement()).addClass(CLASS_PREFIX$1 + "-" + attachment);
18484    };
18485
18486    _proto.getTipElement = function getTipElement() {
18487      this.tip = this.tip || $(this.config.template)[0];
18488      return this.tip;
18489    };
18490
18491    _proto.setContent = function setContent() {
18492      var $tip = $(this.getTipElement()); // We use append for html objects to maintain js events
18493
18494      this.setElementContent($tip.find(Selector$7.TITLE), this.getTitle());
18495
18496      var content = this._getContent();
18497
18498      if (typeof content === 'function') {
18499        content = content.call(this.element);
18500      }
18501
18502      this.setElementContent($tip.find(Selector$7.CONTENT), content);
18503      $tip.removeClass(ClassName$7.FADE + " " + ClassName$7.SHOW);
18504    } // Private
18505    ;
18506
18507    _proto._getContent = function _getContent() {
18508      return this.element.getAttribute('data-content') || this.config.content;
18509    };
18510
18511    _proto._cleanTipClass = function _cleanTipClass() {
18512      var $tip = $(this.getTipElement());
18513      var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX$1);
18514
18515      if (tabClass !== null && tabClass.length > 0) {
18516        $tip.removeClass(tabClass.join(''));
18517      }
18518    } // Static
18519    ;
18520
18521    Popover._jQueryInterface = function _jQueryInterface(config) {
18522      return this.each(function () {
18523        var data = $(this).data(DATA_KEY$7);
18524
18525        var _config = typeof config === 'object' ? config : null;
18526
18527        if (!data && /dispose|hide/.test(config)) {
18528          return;
18529        }
18530
18531        if (!data) {
18532          data = new Popover(this, _config);
18533          $(this).data(DATA_KEY$7, data);
18534        }
18535
18536        if (typeof config === 'string') {
18537          if (typeof data[config] === 'undefined') {
18538            throw new TypeError("No method named \"" + config + "\"");
18539          }
18540
18541          data[config]();
18542        }
18543      });
18544    };
18545
18546    _createClass(Popover, null, [{
18547      key: "VERSION",
18548      // Getters
18549      get: function get() {
18550        return VERSION$7;
18551      }
18552    }, {
18553      key: "Default",
18554      get: function get() {
18555        return Default$5;
18556      }
18557    }, {
18558      key: "NAME",
18559      get: function get() {
18560        return NAME$7;
18561      }
18562    }, {
18563      key: "DATA_KEY",
18564      get: function get() {
18565        return DATA_KEY$7;
18566      }
18567    }, {
18568      key: "Event",
18569      get: function get() {
18570        return Event$7;
18571      }
18572    }, {
18573      key: "EVENT_KEY",
18574      get: function get() {
18575        return EVENT_KEY$7;
18576      }
18577    }, {
18578      key: "DefaultType",
18579      get: function get() {
18580        return DefaultType$5;
18581      }
18582    }]);
18583
18584    return Popover;
18585  }(Tooltip);
18586  /**
18587   * ------------------------------------------------------------------------
18588   * jQuery
18589   * ------------------------------------------------------------------------
18590   */
18591
18592
18593  $.fn[NAME$7] = Popover._jQueryInterface;
18594  $.fn[NAME$7].Constructor = Popover;
18595
18596  $.fn[NAME$7].noConflict = function () {
18597    $.fn[NAME$7] = JQUERY_NO_CONFLICT$7;
18598    return Popover._jQueryInterface;
18599  };
18600
18601  /**
18602   * ------------------------------------------------------------------------
18603   * Constants
18604   * ------------------------------------------------------------------------
18605   */
18606
18607  var NAME$8 = 'scrollspy';
18608  var VERSION$8 = '4.3.1';
18609  var DATA_KEY$8 = 'bs.scrollspy';
18610  var EVENT_KEY$8 = "." + DATA_KEY$8;
18611  var DATA_API_KEY$6 = '.data-api';
18612  var JQUERY_NO_CONFLICT$8 = $.fn[NAME$8];
18613  var Default$6 = {
18614    offset: 10,
18615    method: 'auto',
18616    target: ''
18617  };
18618  var DefaultType$6 = {
18619    offset: 'number',
18620    method: 'string',
18621    target: '(string|element)'
18622  };
18623  var Event$8 = {
18624    ACTIVATE: "activate" + EVENT_KEY$8,
18625    SCROLL: "scroll" + EVENT_KEY$8,
18626    LOAD_DATA_API: "load" + EVENT_KEY$8 + DATA_API_KEY$6
18627  };
18628  var ClassName$8 = {
18629    DROPDOWN_ITEM: 'dropdown-item',
18630    DROPDOWN_MENU: 'dropdown-menu',
18631    ACTIVE: 'active'
18632  };
18633  var Selector$8 = {
18634    DATA_SPY: '[data-spy="scroll"]',
18635    ACTIVE: '.active',
18636    NAV_LIST_GROUP: '.nav, .list-group',
18637    NAV_LINKS: '.nav-link',
18638    NAV_ITEMS: '.nav-item',
18639    LIST_ITEMS: '.list-group-item',
18640    DROPDOWN: '.dropdown',
18641    DROPDOWN_ITEMS: '.dropdown-item',
18642    DROPDOWN_TOGGLE: '.dropdown-toggle'
18643  };
18644  var OffsetMethod = {
18645    OFFSET: 'offset',
18646    POSITION: 'position'
18647    /**
18648     * ------------------------------------------------------------------------
18649     * Class Definition
18650     * ------------------------------------------------------------------------
18651     */
18652
18653  };
18654
18655  var ScrollSpy =
18656  /*#__PURE__*/
18657  function () {
18658    function ScrollSpy(element, config) {
18659      var _this = this;
18660
18661      this._element = element;
18662      this._scrollElement = element.tagName === 'BODY' ? window : element;
18663      this._config = this._getConfig(config);
18664      this._selector = this._config.target + " " + Selector$8.NAV_LINKS + "," + (this._config.target + " " + Selector$8.LIST_ITEMS + ",") + (this._config.target + " " + Selector$8.DROPDOWN_ITEMS);
18665      this._offsets = [];
18666      this._targets = [];
18667      this._activeTarget = null;
18668      this._scrollHeight = 0;
18669      $(this._scrollElement).on(Event$8.SCROLL, function (event) {
18670        return _this._process(event);
18671      });
18672      this.refresh();
18673
18674      this._process();
18675    } // Getters
18676
18677
18678    var _proto = ScrollSpy.prototype;
18679
18680    // Public
18681    _proto.refresh = function refresh() {
18682      var _this2 = this;
18683
18684      var autoMethod = this._scrollElement === this._scrollElement.window ? OffsetMethod.OFFSET : OffsetMethod.POSITION;
18685      var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
18686      var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
18687      this._offsets = [];
18688      this._targets = [];
18689      this._scrollHeight = this._getScrollHeight();
18690      var targets = [].slice.call(document.querySelectorAll(this._selector));
18691      targets.map(function (element) {
18692        var target;
18693        var targetSelector = Util.getSelectorFromElement(element);
18694
vendor: 4,133 bytes, lines 18695-18823
18695        if (targetSelector) {
18696          target = document.querySelector(targetSelector);
18697        }
18698
18699        if (target) {
18700          var targetBCR = target.getBoundingClientRect();
18701
18702          if (targetBCR.width || targetBCR.height) {
18703            // TODO (fat): remove sketch reliance on jQuery position/offset
18704            return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
18705          }
18706        }
18707
18708        return null;
18709      }).filter(function (item) {
18710        return item;
18711      }).sort(function (a, b) {
18712        return a[0] - b[0];
18713      }).forEach(function (item) {
18714        _this2._offsets.push(item[0]);
18715
18716        _this2._targets.push(item[1]);
18717      });
18718    };
18719
18720    _proto.dispose = function dispose() {
18721      $.removeData(this._element, DATA_KEY$8);
18722      $(this._scrollElement).off(EVENT_KEY$8);
18723      this._element = null;
18724      this._scrollElement = null;
18725      this._config = null;
18726      this._selector = null;
18727      this._offsets = null;
18728      this._targets = null;
18729      this._activeTarget = null;
18730      this._scrollHeight = null;
18731    } // Private
18732    ;
18733
18734    _proto._getConfig = function _getConfig(config) {
18735      config = _objectSpread({}, Default$6, typeof config === 'object' && config ? config : {});
18736
18737      if (typeof config.target !== 'string') {
18738        var id = $(config.target).attr('id');
18739
18740        if (!id) {
18741          id = Util.getUID(NAME$8);
18742          $(config.target).attr('id', id);
18743        }
18744
18745        config.target = "#" + id;
18746      }
18747
18748      Util.typeCheckConfig(NAME$8, config, DefaultType$6);
18749      return config;
18750    };
18751
18752    _proto._getScrollTop = function _getScrollTop() {
18753      return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
18754    };
18755
18756    _proto._getScrollHeight = function _getScrollHeight() {
18757      return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
18758    };
18759
18760    _proto._getOffsetHeight = function _getOffsetHeight() {
18761      return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
18762    };
18763
18764    _proto._process = function _process() {
18765      var scrollTop = this._getScrollTop() + this._config.offset;
18766
18767      var scrollHeight = this._getScrollHeight();
18768
18769      var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
18770
18771      if (this._scrollHeight !== scrollHeight) {
18772        this.refresh();
18773      }
18774
18775      if (scrollTop >= maxScroll) {
18776        var target = this._targets[this._targets.length - 1];
18777
18778        if (this._activeTarget !== target) {
18779          this._activate(target);
18780        }
18781
18782        return;
18783      }
18784
18785      if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
18786        this._activeTarget = null;
18787
18788        this._clear();
18789
18790        return;
18791      }
18792
18793      var offsetLength = this._offsets.length;
18794
18795      for (var i = offsetLength; i--;) {
18796        var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
18797
18798        if (isActiveTarget) {
18799          this._activate(this._targets[i]);
18800        }
18801      }
18802    };
18803
18804    _proto._activate = function _activate(target) {
18805      this._activeTarget = target;
18806
18807      this._clear();
18808
18809      var queries = this._selector.split(',').map(function (selector) {
18810        return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]";
18811      });
18812
18813      var $link = $([].slice.call(document.querySelectorAll(queries.join(','))));
18814
18815      if ($link.hasClass(ClassName$8.DROPDOWN_ITEM)) {
18816        $link.closest(Selector$8.DROPDOWN).find(Selector$8.DROPDOWN_TOGGLE).addClass(ClassName$8.ACTIVE);
18817        $link.addClass(ClassName$8.ACTIVE);
18818      } else {
18819        // Set triggered link as active
18820        $link.addClass(ClassName$8.ACTIVE); // Set triggered links parents as active
18821        // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
18822
18823        $link.parents(Selector$8.NAV_LIST_GROUP).prev(Selector$8.NAV_LINKS + ", " + Selector$8.
18823LIST_ITEMS).addClass(ClassName$8.ACTIVE); // Handle special case when .nav-link is inside .nav-item
18824
18825        $link.parents(Selector$8.NAV_LIST_GROUP).prev(Selector$8.NAV_ITEMS).children(Selector$8.NAV_LINKS).addClass(ClassName$8.ACTIVE);
18826      }
18827
18828      $(this._scrollElement).trigger(Event$8.ACTIVATE, {
18829        relatedTarget: target
18830      });
18831    };
18832
18833    _proto._clear = function _clear() {
18834      [].slice.call(document.querySelectorAll(this._selector)).filter(function (node) {
18835        return node.classList.contains(ClassName$8.ACTIVE);
18836      }).forEach(function (node) {
18837        return node.classList.remove(ClassName$8.ACTIVE);
18838      });
18839    } // Static
18840    ;
18841
18842    ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
18843      return this.each(function () {
18844        var data = $(this).data(DATA_KEY$8);
18845
18846        var _config = typeof config === 'object' && config;
18847
18848        if (!data) {
18849          data = new ScrollSpy(this, _config);
18850          $(this).data(DATA_KEY$8, data);
18851        }
18852
18853        if (typeof config === 'string') {
18854          if (typeof data[config] === 'undefined') {
18855            throw new TypeError("No method named \"" + config + "\"");
18856          }
18857
18858          data[config]();
18859        }
18860      });
18861    };
18862
18863    _createClass(ScrollSpy, null, [{
18864      key: "VERSION",
18865      get: function get() {
18866        return VERSION$8;
18867      }
18868    }, {
18869      key: "Default",
18870      get: function get() {
18871        return Default$6;
18872      }
18873    }]);
18874
18875    return ScrollSpy;
18876  }();
18877  /**
18878   * ------------------------------------------------------------------------
18879   * Data Api implementation
18880   * ------------------------------------------------------------------------
18881   */
18882
18883
18884  $(window).on(Event$8.LOAD_DATA_API, function () {
18885    var scrollSpys = [].slice.call(document.querySelectorAll(Selector$8.DATA_SPY));
18886    var scrollSpysLength = scrollSpys.length;
18887
18888    for (var i = scrollSpysLength; i--;) {
18889      var $spy = $(scrollSpys[i]);
18890
18891      ScrollSpy._jQueryInterface.call($spy, $spy.data());
18892    }
18893  });
18894  /**
18895   * ------------------------------------------------------------------------
18896   * jQuery
18897   * ------------------------------------------------------------------------
18898   */
18899
18900  $.fn[NAME$8] = ScrollSpy._jQueryInterface;
18901  $.fn[NAME$8].Constructor = ScrollSpy;
18902
18903  $.fn[NAME$8].noConflict = function () {
18904    $.fn[NAME$8] = JQUERY_NO_CONFLICT$8;
18905    return ScrollSpy._jQueryInterface;
18906  };
18907
18908  /**
18909   * ------------------------------------------------------------------------
18910   * Constants
18911   * ------------------------------------------------------------------------
18912   */
18913
18914  var NAME$9 = 'tab';
18915  var VERSION$9 = '4.3.1';
18916  var DATA_KEY$9 = 'bs.tab';
18917  var EVENT_KEY$9 = "." + DATA_KEY$9;
18918  var DATA_API_KEY$7 = '.data-api';
18919  var JQUERY_NO_CONFLICT$9 = $.fn[NAME$9];
18920  var Event$9 = {
18921    HIDE: "hide" + EVENT_KEY$9,
18922    HIDDEN: "hidden" + EVENT_KEY$9,
18923    SHOW: "show" + EVENT_KEY$9,
18924    SHOWN: "shown" + EVENT_KEY$9,
18925    CLICK_DATA_API: "click" + EVENT_KEY$9 + DATA_API_KEY$7
18926  };
18927  var ClassName$9 = {
18928    DROPDOWN_MENU: 'dropdown-menu',
18929    ACTIVE: 'active',
18930    DISABLED: 'disabled',
18931    FADE: 'fade',
18932    SHOW: 'show'
18933  };
18934  var Selector$9 = {
18935    DROPDOWN: '.dropdown',
18936    NAV_LIST_GROUP: '.nav, .list-group',
18937    ACTIVE: '.active',
18938    ACTIVE_UL: '> li > .active',
18939    DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
18940    DROPDOWN_TOGGLE: '.dropdown-toggle',
18941    DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active'
18942    /**
18943     * ------------------------------------------------------------------------
18944     * Class Definition
18945     * ------------------------------------------------------------------------
18946     */
18947
18948  };
18949
18950  var Tab =
18951  /*#__PURE__*/
18952  function () {
18953    function Tab(element) {
18954      this._element = element;
18955    } // Getters
18956
18957
18958    var _proto = Tab.prototype;
18959
18960    // Public
18961    _proto.show = function show() {
18962      var _this = this;
18963
18964      if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $(this._element).hasClass(ClassName$9.ACTIVE) || $(this._element).hasClass(ClassName$9.DISABLED)) {
18965        return;
18966      }
18967
18968      var target;
18969      var previous;
18970      var listElement = $(this._element).closest(Selector$9.NAV_LIST_GROUP)[0];
18971      var selector = Util.getSelectorFromElement(this._element);
18972
18973      if (listElement) {
18974        var itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? Selector$9.ACTIVE_UL : Selector$9.ACTIVE;
18975        previous = $.makeArray($(listElement).find(itemSelector));
18976        previous = previous[previous.length - 1];
18977      }
18978
18979      var hideEvent = $.Event(Event$9.HIDE, {
18980        relatedTarget: this._element
18981      });
18982      var showEvent = $.Event(Event$9.SHOW, {
18983        relatedTarget: previous
18984      });
18985
18986      if (previous) {
18987        $(previous).trigger(hideEvent);
18988      }
18989
18990      $(this._element).trigger(showEvent);
18991
18992      if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
18993        return;
18994      }
18995
18996      if (selector) {
18997        target = document.querySelector(selector);
18998      }
18999
19000      this._activate(this._element, listElement);
19001
19002      var complete = function complete() {
19003        var hiddenEvent = $.Event(Event$9.HIDDEN, {
19004          relatedTarget: _this._element
19005        });
19006        var shownEvent = $.Event(Event$9.SHOWN, {
19007          relatedTarget: previous
19008        });
19009        $(previous).trigger(hiddenEvent);
19010        $(_this._element).trigger(shownEvent);
19011      };
19012
19013      if (target) {
19014        this._activate(target, target.parentNode, complete);
19015      } else {
19016        complete();
19017      }
19018    };
19019
19020    _proto.dispose = function dispose() {
19021      $.removeData(this._element, DATA_KEY$9);
19022      this._element = null;
19023    } // Private
19024    ;
19025
19026    _proto._activate = function _activate(element, container, callback) {
19027      var _this2 = this;
19028
19029      var activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? $(container).find(Selector$9.ACTIVE_UL) : $(container).children(Selector$9.ACTIVE);
19030      var active = activeElements[0];
19031      var isTransitioning = callback && active && $(active).hasClass(ClassName$9.FADE);
19032
19033      var complete = function complete() {
19034        return _this2._transitionComplete(element, active, callback);
19035      };
19036
19037      if (active && isTransitioning) {
19038        var transitionDuration = Util.getTransitionDurationFromElement(active);
19039        $(active).removeClass(ClassName$9.SHOW).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
19040      } else {
19041        complete();
19042      }
19043    };
19044
19045    _proto._transitionComplete = function _transitionComplete(element, active, callback) {
19046      if (active) {
19047        $(active).removeClass(ClassName$9.ACTIVE);
19048        var dropdownChild = $(active.parentNode).find(Selector$9.DROPDOWN_ACTIVE_CHILD)[0];
19049
19050        if (dropdownChild) {
19051          $(dropdownChild).removeClass(ClassName$9.ACTIVE);
19052        }
19053
19054        if (active.getAttribute('role') === 'tab') {
19055          active.setAttribute('aria-selected', false);
19056        }
19057      }
19058
19059      $(element).addClass(ClassName$9.ACTIVE);
19060
19061      if (element.getAttribute('role') === 'tab') {
19062        element.setAttribute('aria-selected', true);
19063      }
19064
19065      Util.reflow(element);
19066
19067      if (element.classList.contains(ClassName$9.FADE)) {
19068        element.classList.add(ClassName$9.SHOW);
19069      }
19070
19071      if (element.parentNode && $(element.parentNode).hasClass(ClassName$9.DROPDOWN_MENU)) {
19072        var dropdownElement = $(element).closest(Selector$9.DROPDOWN)[0];
19073
19074        if (dropdownElement) {
19075          var dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(Selector$9.DROPDOWN_TOGGLE));
19076          $(dropdownToggleList).addClass(ClassName$9.ACTIVE);
19077        }
19078
19079        element.setAttribute('aria-expanded', true);
19080      }
19081
19082      if (callback) {
19083        callback();
19084      }
19085    } // Static
19086    ;
19087
19088    Tab._jQueryInterface = function _jQueryInterface(config) {
19089      return this.each(function () {
19090        var $this = $(this);
19091        var data = $this.data(DATA_KEY$9);
19092
19093        if (!data) {
19094          data = new Tab(this);
19095          $this.data(DATA_KEY$9, data);
19096        }
19097
19098        if (typeof config === 'string') {
19099          if (typeof data[config] === 'undefined') {
19100            throw new TypeError("No method named \"" + config + "\"");
19101          }
19102
19103          data[config]();
19104        }
19105      });
19106    };
19107
19108    _createClass(Tab, null, [{
19109      key: "VERSION",
19110      get: function get() {
19111        return VERSION$9;
19112      }
19113    }]);
19114
19115    return Tab;
19116  }();
19117  /**
19118   * ------------------------------------------------------------------------
19119   * Data Api implementation
19120   * ------------------------------------------------------------------------
19121   */
19122
19123
19124  $(document).on(Event$9.CLICK_DATA_API, Selector$9.DATA_TOGGLE, function (event) {
19125    event.preventDefault();
19126
19127    Tab._jQueryInterface.call($(this), 'show');
19128  });
19129  /**
19130   * ------------------------------------------------------------------------
19131   * jQuery
19132   * ------------------------------------------------------------------------
19133   */
19134
19135  $.fn[NAME$9] = Tab._jQueryInterface;
19136  $.fn[NAME$9].Constructor = Tab;
19137
19138  $.fn[NAME$9].noConflict = function () {
19139    $.fn[NAME$9] = JQUERY_NO_CONFLICT$9;
19140    return Tab._jQueryInterface;
19141  };
19142
19143  /**
19144   * ------------------------------------------------------------------------
19145   * Constants
19146   * ------------------------------------------------------------------------
19147   */
19148
19149  var NAME$a = 'toast';
19150  var VERSION$a = '4.3.1';
19151  var DATA_KEY$a = 'bs.toast';
19152  var EVENT_KEY$a = "." + DATA_KEY$a;
19153  var JQUERY_NO_CONFLICT$a = $.fn[NAME$a];
19154  var Event$a = {
19155    CLICK_DISMISS: "click.dismiss" + EVENT_KEY$a,
19156    HIDE: "hide" + EVENT_KEY$a,
19157    HIDDEN: "hidden" + EVENT_KEY$a,
19158    SHOW: "show" + EVENT_KEY$a,
19159    SHOWN: "shown" + EVENT_KEY$a
19160  };
19161  var ClassName$a = {
19162    FADE: 'fade',
19163    HIDE: 'hide',
19164    SHOW: 'show',
19165    SHOWING: 'showing'
19166  };
19167  var DefaultType$7 = {
19168    animation: 'boolean',
19169    autohide: 'boolean',
19170    delay: 'number'
19171  };
19172  var Default$7 = {
19173    animation: true,
19174    autohide: true,
19175    delay: 500
19176  };
19177  var Selector$a = {
19178    DATA_DISMISS: '[data-dismiss="toast"]'
19179    /**
19180     * ------------------------------------------------------------------------
19181     * Class Definition
19182     * ------------------------------------------------------------------------
19183     */
19184
19185  };
19186
19187  var Toast =
19188  /*#__PURE__*/
19189  function () {
19190    function Toast(element, config) {
19191      this._element = element;
19192      this._config = this._getConfig(config);
19193      this._timeout = null;
19194
19195      this._setListeners();
19196    } // Getters
19197
19198
19199    var _proto = Toast.prototype;
19200
19201    // Public
19202    _proto.show = function show() {
19203      var _this = this;
19204
19205      $(this._element).trigger(Event$a.SHOW);
19206
19207      if (this._config.animation) {
19208        this._element.classList.add(ClassName$a.FADE);
19209      }
19210
19211      var complete = function complete() {
19212        _this._element.classList.remove(ClassName$a.SHOWING);
19213
19214        _this._element.classList.add(ClassName$a.SHOW);
19215
19216        $(_this._element).trigger(Event$a.SHOWN);
19217
19218        if (_this._config.autohide) {
19219          _this.hide();
19220        }
19221      };
19222
19223      this._element.classList.remove(ClassName$a.HIDE);
19224
19225      this._element.classList.add(ClassName$a.SHOWING);
19226
19227      if (this._config.animation) {
19228        var transitionDuration = Util.getTransitionDurationFromElement(this._element);
19229        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
19230      } else {
19231        complete();
19232      }
19233    };
19234
19235    _proto.hide = function hide(withoutTimeout) {
19236      var _this2 = this;
19237
19238      if (!this._element.classList.contains(ClassName$a.SHOW)) {
19239        return;
19240      }
19241
19242      $(this._element).trigger(Event$a.HIDE);
19243
19244      if (withoutTimeout) {
19245        this._close();
19246      } else {
19247        this._timeout = setTimeout(function () {
19248          _this2._close();
19249        }, this._config.delay);
19250      }
19251    };
19252
19253    _proto.dispose = function dispose() {
19254      clearTimeout(this._timeout);
19255      this._timeout = null;
19256
19257      if (this._element.classList.contains(ClassName$a.SHOW)) {
19258        this._element.classList.remove(ClassName$a.SHOW);
19259      }
19260
19261      $(this._element).off(Event$a.CLICK_DISMISS);
19262      $.removeData(this._element, DATA_KEY$a);
19263      this._element = null;
19264      this._config = null;
19265    } // Private
19266    ;
19267
19268    _proto._getConfig = function _getConfig(config) {
19269      config = _objectSpread({}, Default$7, $(this._element).data(), typeof config === 'object' && config ? config : {});
19270      Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType);
19271      return config;
19272    };
19273
19274    _proto._setListeners = function _setListeners() {
19275      var _this3 = this;
19276
19277      $(this._element).on(Event$a.CLICK_DISMISS, Selector$a.DATA_DISMISS, function () {
19278        return _this3.hide(true);
19279      });
19280    };
19281
19282    _proto._close = function _close() {
19283      var _this4 = this;
19284
19285      var complete = function complete() {
19286        _this4._element.classList.add(ClassName$a.HIDE);
19287
19288        $(_this4._element).trigger(Event$a.HIDDEN);
19289      };
19290
19291      this._element.classList.remove(ClassName$a.SHOW);
19292
19293      if (this._config.animation) {
19294        var transitionDuration = Util.getTransitionDurationFromElement(this._element);
19295        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
19296      } else {
19297        complete();
19298      }
19299    } // Static
19300    ;
19301
19302    Toast._jQueryInterface = function _jQueryInterface(config) {
19303      return this.each(function () {
19304        var $element = $(this);
19305        var data = $element.data(DATA_KEY$a);
19306
19307        var _config = typeof config === 'object' && config;
19308
19309        if (!data) {
19310          data = new Toast(this, _config);
19311          $element.data(DATA_KEY$a, data);
19312        }
19313
19314        if (typeof config === 'string') {
19315          if (typeof data[config] === 'undefined') {
19316            throw new TypeError("No method named \"" + config + "\"");
19317          }
19318
19319          data[config](this);
19320        }
19321      });
19322    };
19323
19324    _createClass(Toast, null, [{
19325      key: "VERSION",
19326      get: function get() {
19327        return VERSION$a;
19328      }
19329    }, {
19330      key: "DefaultType",
19331      get: function get() {
19332        return DefaultType$7;
19333      }
19334    }, {
19335      key: "Default",
19336      get: function get() {
19337        return Default$7;
19338      }
19339    }]);
19340
19341    return Toast;
19342  }();
19343  /**
19344   * ------------------------------------------------------------------------
19345   * jQuery
19346   * ------------------------------------------------------------------------
19347   */
19348
19349
19350  $.fn[NAME$a] = Toast._jQueryInterface;
19351  $.fn[NAME$a].Constructor = Toast;
19352
19353  $.fn[NAME$a].noConflict = function () {
19354    $.fn[NAME$a] = JQUERY_NO_CONFLICT$a;
19355    return Toast._jQueryInterface;
19356  };
19357
19358  /**
19359   * --------------------------------------------------------------------------
19360   * Bootstrap (v4.3.1): index.js
19361   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
19362   * --------------------------------------------------------------------------
19363   */
19364
19365  (function () {
19366    if (typeof $ === 'undefined') {
19367      throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.');
19368    }
19369
19370    var version = $.fn.jquery.split(' ')[0].split('.');
19371    var minMajor = 1;
19372    var ltMajor = 2;
19373    var minMinor = 9;
19374    var minPatch = 1;
19375    var maxMajor = 4;
19376
19377    if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
19378      throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0');
19379    }
19380  })();
19381
19382  exports.Util = Util;
19383  exports.Alert = Alert;
19384  exports.Button = Button;
19385  exports.Carousel = Carousel;
19386  exports.Collapse = Collapse;
19387  exports.Dropdown = Dropdown;
19388  exports.Modal = Modal;
19389  exports.Popover = Popover;
19390  exports.Scrollspy = ScrollSpy;
19391  exports.Tab = Tab;
19392  exports.Toast = Toast;
19393  exports.Tooltip = Tooltip;
19394
19395  Object.defineProperty(exports, '__esModule', { value: true });
19396
19397}));
19398
19399
19400},{"jquery":13,"popper.js":15}],12:[function(require,module,exports){
19401/**
19402* @version: 3.0.5
19403* @author: Dan Grossman http://www.dangrossman.info/
19404* @copyright: Copyright (c) 2012-2019 Dan Grossman. All rights reserved.
19405* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php
19406* @website: http://www.daterangepicker.com/
19407*/
19408// Following the UMD template https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js
19409(function (root, factory) {
19410    if (typeof define === 'function' && define.amd) {
19411        // AMD. Make globaly available as well
19412        define(['moment', 'jquery'], function (moment, jquery) {
19413            if (!jquery.fn) jquery.fn = {}; // webpack server rendering
19414            if (typeof moment !== 'function' && moment.default) moment = moment.default
19415            return factory(moment, jquery);
19416        });
19417    } else if (typeof module === 'object' && module.exports) {
19418        // Node / Browserify
19419        //isomorphic issue
19420        var jQuery = (typeof window != 'undefined') ? window.jQuery : undefined;
19421        if (!jQuery) {
19422            jQuery = require('jquery');
19423            if (!jQuery.fn) jQuery.fn = {};
19424        }
19425        var moment = (typeof window != 'undefined' && typeof window.moment != 'undefined') ? window.moment : require('moment');
19426        module.exports = factory(moment, jQuery);
19427    } else {
19428        // Browser globals
19429        root.daterangepicker = factory(root.moment, root.jQuery);
19430    }
19431}(this, function(moment, $) {
19432    var DateRangePicker = function(element, options, cb) {
19433
19434        //default settings for options
19435        this.parentEl = 'body';
19436        this.element = $(element);
19437        this.startDate = moment().startOf('day');
19438        this.endDate = moment().endOf('day');
19439        this.minDate = false;
19440        this.maxDate = false;
19441        this.maxSpan = false;
19442        this.autoApply = false;
19443        this.singleDatePicker = false;
19444        this.showDropdowns = false;
19445        this.minYear = moment().subtract(100, 'year').format('YYYY');
19446        this.maxYear = moment().add(100, 'year').format('YYYY');
19447        this.showWeekNumbers = false;
19448        this.showISOWeekNumbers = false;
19449        this.showCustomRangeLabel = true;
19450        this.timePicker = false;
19451        this.timePicker24Hour = false;
19452        this.timePickerIncrement = 1;
19453        this.timePickerSeconds = false;
19454        this.linkedCalendars = true;
19455        this.autoUpdateInput = true;
19456        this.alwaysShowCalendars = false;
19457        this.ranges = {};
19458
19459        this.opens = 'right';
19460        if (this.element.hasClass('pull-right'))
19461            this.opens = 'left';
19462
19463        this.drops = 'down';
19464        if (this.element.hasClass('dropup'))
19465            this.drops = 'up';
19466
vendor: 19,404 bytes, lines 19467-19931
19467        this.buttonClasses = 'btn btn-sm';
19468        this.applyButtonClasses = 'btn-primary';
19469        this.cancelButtonClasses = 'btn-default';
19470
19471        this.locale = {
19472            direction: 'ltr',
19473            format: moment.localeData().longDateFormat('L'),
19474            separator: ' - ',
19475            applyLabel: 'Apply',
19476            cancelLabel: 'Cancel',
19477            weekLabel: 'W',
19478            customRangeLabel: 'Custom Range',
19479            daysOfWeek: moment.weekdaysMin(),
19480            monthNames: moment.monthsShort(),
19481            firstDay: moment.localeData().firstDayOfWeek()
19482        };
19483
19484        this.callback = function() { };
19485
19486        //some state information
19487        this.isShowing = false;
19488        this.leftCalendar = {};
19489        this.rightCalendar = {};
19490
19491        //custom options from user
19492        if (typeof options !== 'object' || options === null)
19493            options = {};
19494
19495        //allow setting options with data attributes
19496        //data-api options will be overwritten with custom javascript options
19497        options = $.extend(this.element.data(), options);
19498
19499        //html template for the picker UI
19500        if (typeof options.template !== 'string' && !(options.template instanceof $))
19501            options.template =
19502            '<div class="daterangepicker">' +
19503                '<div class="ranges"></div>' +
19504                '<div class="drp-calendar left">' +
19505                    '<div class="calendar-table"></div>' +
19506                    '<div class="calendar-time"></div>' +
19507                '</div>' +
19508                '<div class="drp-calendar right">' +
19509                    '<div class="calendar-table"></div>' +
19510                    '<div class="calendar-time"></div>' +
19511                '</div>' +
19512                '<div class="drp-buttons">' +
19513                    '<span class="drp-selected"></span>' +
19514                    '<button class="cancelBtn" type="button"></button>' +
19515                    '<button class="applyBtn" disabled="disabled" type="button"></button> ' +
19516                '</div>' +
19517            '</div>';
19518
19519        this.parentEl = (options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl);
19520        this.container = $(options.template).appendTo(this.parentEl);
19521
19522        //
19523        // handle all the possible options overriding defaults
19524        //
19525
19526        if (typeof options.locale === 'object') {
19527
19528            if (typeof options.locale.direction === 'string')
19529                this.locale.direction = options.locale.direction;
19530
19531            if (typeof options.locale.format === 'string')
19532                this.locale.format = options.locale.format;
19533
19534            if (typeof options.locale.separator === 'string')
19535                this.locale.separator = options.locale.separator;
19536
19537            if (typeof options.locale.daysOfWeek === 'object')
19538                this.locale.daysOfWeek = options.locale.daysOfWeek.slice();
19539
19540            if (typeof options.locale.monthNames === 'object')
19541              this.locale.monthNames = options.locale.monthNames.slice();
19542
19543            if (typeof options.locale.firstDay === 'number')
19544              this.locale.firstDay = options.locale.firstDay;
19545
19546            if (typeof options.locale.applyLabel === 'string')
19547              this.locale.applyLabel = options.locale.applyLabel;
19548
19549            if (typeof options.locale.cancelLabel === 'string')
19550              this.locale.cancelLabel = options.locale.cancelLabel;
19551
19552            if (typeof options.locale.weekLabel === 'string')
19553              this.locale.weekLabel = options.locale.weekLabel;
19554
19555            if (typeof options.locale.customRangeLabel === 'string'){
19556                //Support unicode chars in the custom range name.
19557                var elem = document.createElement('textarea');
19558                elem.innerHTML = options.locale.customRangeLabel;
19559                var rangeHtml = elem.value;
19560                this.locale.customRangeLabel = rangeHtml;
19561            }
19562        }
19563        this.container.addClass(this.locale.direction);
19564
19565        if (typeof options.startDate === 'string')
19566            this.startDate = moment(options.startDate, this.locale.format);
19567
19568        if (typeof options.endDate === 'string')
19569            this.endDate = moment(options.endDate, this.locale.format);
19570
19571        if (typeof options.minDate === 'string')
19572            this.minDate = moment(options.minDate, this.locale.format);
19573
19574        if (typeof options.maxDate === 'string')
19575            this.maxDate = moment(options.maxDate, this.locale.format);
19576
19577        if (typeof options.startDate === 'object')
19578            this.startDate = moment(options.startDate);
19579
19580        if (typeof options.endDate === 'object')
19581            this.endDate = moment(options.endDate);
19582
19583        if (typeof options.minDate === 'object')
19584            this.minDate = moment(options.minDate);
19585
19586        if (typeof options.maxDate === 'object')
19587            this.maxDate = moment(options.maxDate);
19588
19589        // sanity check for bad options
19590        if (this.minDate && this.startDate.isBefore(this.minDate))
19591            this.startDate = this.minDate.clone();
19592
19593        // sanity check for bad options
19594        if (this.maxDate && this.endDate.isAfter(this.maxDate))
19595            this.endDate = this.maxDate.clone();
19596
19597        if (typeof options.applyButtonClasses === 'string')
19598            this.applyButtonClasses = options.applyButtonClasses;
19599
19600        if (typeof options.applyClass === 'string') //backwards compat
19601            this.applyButtonClasses = options.applyClass;
19602
19603        if (typeof options.cancelButtonClasses === 'string')
19604            this.cancelButtonClasses = options.cancelButtonClasses;
19605
19606        if (typeof options.cancelClass === 'string') //backwards compat
19607            this.cancelButtonClasses = options.cancelClass;
19608
19609        if (typeof options.maxSpan === 'object')
19610            this.maxSpan = options.maxSpan;
19611
19612        if (typeof options.dateLimit === 'object') //backwards compat
19613            this.maxSpan = options.dateLimit;
19614
19615        if (typeof options.opens === 'string')
19616            this.opens = options.opens;
19617
19618        if (typeof options.drops === 'string')
19619            this.drops = options.drops;
19620
19621        if (typeof options.showWeekNumbers === 'boolean')
19622            this.showWeekNumbers = options.showWeekNumbers;
19623
19624        if (typeof options.showISOWeekNumbers === 'boolean')
19625            this.showISOWeekNumbers = options.showISOWeekNumbers;
19626
19627        if (typeof options.buttonClasses === 'string')
19628            this.buttonClasses = options.buttonClasses;
19629
19630        if (typeof options.buttonClasses === 'object')
19631            this.buttonClasses = options.buttonClasses.join(' ');
19632
19633        if (typeof options.showDropdowns === 'boolean')
19634            this.showDropdowns = options.showDropdowns;
19635
19636        if (typeof options.minYear === 'number')
19637            this.minYear = options.minYear;
19638
19639        if (typeof options.maxYear === 'number')
19640            this.maxYear = options.maxYear;
19641
19642        if (typeof options.showCustomRangeLabel === 'boolean')
19643            this.showCustomRangeLabel = options.showCustomRangeLabel;
19644
19645        if (typeof options.singleDatePicker === 'boolean') {
19646            this.singleDatePicker = options.singleDatePicker;
19647            if (this.singleDatePicker)
19648                this.endDate = this.startDate.clone();
19649        }
19650
19651        if (typeof options.timePicker === 'boolean')
19652            this.timePicker = options.timePicker;
19653
19654        if (typeof options.timePickerSeconds === 'boolean')
19655            this.timePickerSeconds = options.timePickerSeconds;
19656
19657        if (typeof options.timePickerIncrement === 'number')
19658            this.timePickerIncrement = options.timePickerIncrement;
19659
19660        if (typeof options.timePicker24Hour === 'boolean')
19661            this.timePicker24Hour = options.timePicker24Hour;
19662
19663        if (typeof options.autoApply === 'boolean')
19664            this.autoApply = options.autoApply;
19665
19666        if (typeof options.autoUpdateInput === 'boolean')
19667            this.autoUpdateInput = options.autoUpdateInput;
19668
19669        if (typeof options.linkedCalendars === 'boolean')
19670            this.linkedCalendars = options.linkedCalendars;
19671
19672        if (typeof options.isInvalidDate === 'function')
19673            this.isInvalidDate = options.isInvalidDate;
19674
19675        if (typeof options.isCustomDate === 'function')
19676            this.isCustomDate = options.isCustomDate;
19677
19678        if (typeof options.alwaysShowCalendars === 'boolean')
19679            this.alwaysShowCalendars = options.alwaysShowCalendars;
19680
19681        // update day names order to firstDay
19682        if (this.locale.firstDay != 0) {
19683            var iterator = this.locale.firstDay;
19684            while (iterator > 0) {
19685                this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift());
19686                iterator--;
19687            }
19688        }
19689
19690        var start, end, range;
19691
19692        //if no start/end dates set, check if an input element contains initial values
19693        if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') {
19694            if ($(this.element).is(':text')) {
19695                var val = $(this.element).val(),
19696                    split = val.split(this.locale.separator);
19697
19698                start = end = null;
19699
19700                if (split.length == 2) {
19701                    start = moment(split[0], this.locale.format);
19702                    end = moment(split[1], this.locale.format);
19703                } else if (this.singleDatePicker && val !== "") {
19704                    start = moment(val, this.locale.format);
19705                    end = moment(val, this.locale.format);
19706                }
19707                if (start !== null && end !== null) {
19708                    this.setStartDate(start);
19709                    this.setEndDate(end);
19710                }
19711            }
19712        }
19713
19714        if (typeof options.ranges === 'object') {
19715            for (range in options.ranges) {
19716
19717                if (typeof options.ranges[range][0] === 'string')
19718                    start = moment(options.ranges[range][0], this.locale.format);
19719                else
19720                    start = moment(options.ranges[range][0]);
19721
19722                if (typeof options.ranges[range][1] === 'string')
19723                    end = moment(options.ranges[range][1], this.locale.format);
19724                else
19725                    end = moment(options.ranges[range][1]);
19726
19727                // If the start or end date exceed those allowed by the minDate or maxSpan
19728                // options, shorten the range to the allowable period.
19729                if (this.minDate && start.isBefore(this.minDate))
19730                    start = this.minDate.clone();
19731
19732                var maxDate = this.maxDate;
19733                if (this.maxSpan && maxDate && start.clone().add(this.maxSpan).isAfter(maxDate))
19734                    maxDate = start.clone().add(this.maxSpan);
19735                if (maxDate && end.isAfter(maxDate))
19736                    end = maxDate.clone();
19737
19738                // If the end of the range is before the minimum or the start of the range is
19739                // after the maximum, don't display this range option at all.
19740                if ((this.minDate && end.isBefore(this.minDate, this.timepicker ? 'minute' : 'day'))
19741                  || (maxDate && start.isAfter(maxDate, this.timepicker ? 'minute' : 'day')))
19742                    continue;
19743
19744                //Support unicode chars in the range names.
19745                var elem = document.createElement('textarea');
19746                elem.innerHTML = range;
19747                var rangeHtml = elem.value;
19748
19749                this.ranges[rangeHtml] = [start, end];
19750            }
19751
19752            var list = '<ul>';
19753            for (range in this.ranges) {
19754                list += '<li data-range-key="' + range + '">' + range + '</li>';
19755            }
19756            if (this.showCustomRangeLabel) {
19757                list += '<li data-range-key="' + this.locale.customRangeLabel + '">' + this.locale.customRangeLabel + '</li>';
19758            }
19759            list += '</ul>';
19760            this.container.find('.ranges').prepend(list);
19761        }
19762
19763        if (typeof cb === 'function') {
19764            this.callback = cb;
19765        }
19766
19767        if (!this.timePicker) {
19768            this.startDate = this.startDate.startOf('day');
19769            this.endDate = this.endDate.endOf('day');
19770            this.container.find('.calendar-time').hide();
19771        }
19772
19773        //can't be used together for now
19774        if (this.timePicker && this.autoApply)
19775            this.autoApply = false;
19776
19777        if (this.autoApply) {
19778            this.container.addClass('auto-apply');
19779        }
19780
19781        if (typeof options.ranges === 'object')
19782            this.container.addClass('show-ranges');
19783
19784        if (this.singleDatePicker) {
19785            this.container.addClass('single');
19786            this.container.find('.drp-calendar.left').addClass('single');
19787            this.container.find('.drp-calendar.left').show();
19788            this.container.find('.drp-calendar.right').hide();
19789            if (!this.timePicker) {
19790                this.container.addClass('auto-apply');
19791            }
19792        }
19793
19794        if ((typeof options.ranges === 'undefined' && !this.singleDatePicker) || this.alwaysShowCalendars) {
19795            this.container.addClass('show-calendar');
19796        }
19797
19798        this.container.addClass('opens' + this.opens);
19799
19800        //apply CSS classes and labels to buttons
19801        this.container.find('.applyBtn, .cancelBtn').addClass(this.buttonClasses);
19802        if (this.applyButtonClasses.length)
19803            this.container.find('.applyBtn').addClass(this.applyButtonClasses);
19804        if (this.cancelButtonClasses.length)
19805            this.container.find('.cancelBtn').addClass(this.cancelButtonClasses);
19806        this.container.find('.applyBtn').html(this.locale.applyLabel);
19807        this.container.find('.cancelBtn').html(this.locale.cancelLabel);
19808
19809        //
19810        // event listeners
19811        //
19812
19813        this.container.find('.drp-calendar')
19814            .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this))
19815            .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this))
19816            .on('mousedown.daterangepicker', 'td.available', $.proxy(this.clickDate, this))
19817            .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this))
19818            .on('change.daterangepicker', 'select.yearselect', $.proxy(this.monthOrYearChanged, this))
19819            .on('change.daterangepicker', 'select.monthselect', $.proxy(this.monthOrYearChanged, this))
19820            .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.timeChanged, this))
19821
19822        this.container.find('.ranges')
19823            .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this))
19824
19825        this.container.find('.drp-buttons')
19826            .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))
19827            .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this))
19828
19829        if (this.element.is('input') || this.element.is('button')) {
19830            this.element.on({
19831                'click.daterangepicker': $.proxy(this.show, this),
19832                'focus.daterangepicker': $.proxy(this.show, this),
19833                'keyup.daterangepicker': $.proxy(this.elementChanged, this),
19834                'keydown.daterangepicker': $.proxy(this.keydown, this) //IE 11 compatibility
19835            });
19836        } else {
19837            this.element.on('click.daterangepicker', $.proxy(this.toggle, this));
19838            this.element.on('keydown.daterangepicker', $.proxy(this.toggle, this));
19839        }
19840
19841        //
19842        // if attached to a text input, set the initial value
19843        //
19844
19845        this.updateElement();
19846
19847    };
19848
19849    DateRangePicker.prototype = {
19850
19851        constructor: DateRangePicker,
19852
19853        setStartDate: function(startDate) {
19854            if (typeof startDate === 'string')
19855                this.startDate = moment(startDate, this.locale.format);
19856
19857            if (typeof startDate === 'object')
19858                this.startDate = moment(startDate);
19859
19860            if (!this.timePicker)
19861                this.startDate = this.startDate.startOf('day');
19862
19863            if (this.timePicker && this.timePickerIncrement)
19864                this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
19865
19866            if (this.minDate && this.startDate.isBefore(this.minDate)) {
19867                this.startDate = this.minDate.clone();
19868                if (this.timePicker && this.timePickerIncrement)
19869                    this.startDate.minute(Math.round(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
19870            }
19871
19872            if (this.maxDate && this.startDate.isAfter(this.maxDate)) {
19873                this.startDate = this.maxDate.clone();
19874                if (this.timePicker && this.timePickerIncrement)
19875                    this.startDate.minute(Math.floor(this.startDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
19876            }
19877
19878            if (!this.isShowing)
19879                this.updateElement();
19880
19881            this.updateMonthsInView();
19882        },
19883
19884        setEndDate: function(endDate) {
19885            if (typeof endDate === 'string')
19886                this.endDate = moment(endDate, this.locale.format);
19887
19888            if (typeof endDate === 'object')
19889                this.endDate = moment(endDate);
19890
19891            if (!this.timePicker)
19892                this.endDate = this.endDate.endOf('day');
19893
19894            if (this.timePicker && this.timePickerIncrement)
19895                this.endDate.minute(Math.round(this.endDate.minute() / this.timePickerIncrement) * this.timePickerIncrement);
19896
19897            if (this.endDate.isBefore(this.startDate))
19898                this.endDate = this.startDate.clone();
19899
19900            if (this.maxDate && this.endDate.isAfter(this.maxDate))
19901                this.endDate = this.maxDate.clone();
19902
19903            if (this.maxSpan && this.startDate.clone().add(this.maxSpan).isBefore(this.endDate))
19904                this.endDate = this.startDate.clone().add(this.maxSpan);
19905
19906            this.previousRightTime = this.endDate.clone();
19907
19908            this.container.find('.drp-selected').html(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
19909
19910            if (!this.isShowing)
19911                this.updateElement();
19912
19913            this.updateMonthsInView();
19914        },
19915
19916        isInvalidDate: function() {
19917            return false;
19918        },
19919
19920        isCustomDate: function() {
19921            return false;
19922        },
19923
19924        updateView: function() {
19925            if (this.timePicker) {
19926                this.renderTimePicker('left');
19927                this.renderTimePicker('right');
19928                if (!this.endDate) {
19929                    this.container.find('.right .calendar-time select').attr('disabled', 'disabled').addClass('disabled');
19930                } else {
19931                    this.container.find('.right .calendar-time select').removeAttr('disabled'
vendor: 22,094 bytes, lines 19931-20417
19931).removeClass('disabled');
19932                }
19933            }
19934            if (this.endDate)
19935                this.container.find('.drp-selected').html(this.startDate.format(this.locale.format) + this.locale.separator + this.endDate.format(this.locale.format));
19936            this.updateMonthsInView();
19937            this.updateCalendars();
19938            this.updateFormInputs();
19939        },
19940
19941        updateMonthsInView: function() {
19942            if (this.endDate) {
19943
19944                //if both dates are visible already, do nothing
19945                if (!this.singleDatePicker && this.leftCalendar.month && this.rightCalendar.month &&
19946                    (this.startDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.startDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM'))
19947                    &&
19948                    (this.endDate.format('YYYY-MM') == this.leftCalendar.month.format('YYYY-MM') || this.endDate.format('YYYY-MM') == this.rightCalendar.month.format('YYYY-MM'))
19949                    ) {
19950                    return;
19951                }
19952
19953                this.leftCalendar.month = this.startDate.clone().date(2);
19954                if (!this.linkedCalendars && (this.endDate.month() != this.startDate.month() || this.endDate.year() != this.startDate.year())) {
19955                    this.rightCalendar.month = this.endDate.clone().date(2);
19956                } else {
19957                    this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
19958                }
19959
19960            } else {
19961                if (this.leftCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM') && this.rightCalendar.month.format('YYYY-MM') != this.startDate.format('YYYY-MM')) {
19962                    this.leftCalendar.month = this.startDate.clone().date(2);
19963                    this.rightCalendar.month = this.startDate.clone().date(2).add(1, 'month');
19964                }
19965            }
19966            if (this.maxDate && this.linkedCalendars && !this.singleDatePicker && this.rightCalendar.month > this.maxDate) {
19967              this.rightCalendar.month = this.maxDate.clone().date(2);
19968              this.leftCalendar.month = this.maxDate.clone().date(2).subtract(1, 'month');
19969            }
19970        },
19971
19972        updateCalendars: function() {
19973
19974            if (this.timePicker) {
19975                var hour, minute, second;
19976                if (this.endDate) {
19977                    hour = parseInt(this.container.find('.left .hourselect').val(), 10);
19978                    minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
19979                    if (isNaN(minute)) {
19980                        minute = parseInt(this.container.find('.left .minuteselect option:last').val(), 10);
19981                    }
19982                    second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
19983                    if (!this.timePicker24Hour) {
19984                        var ampm = this.container.find('.left .ampmselect').val();
19985                        if (ampm === 'PM' && hour < 12)
19986                            hour += 12;
19987                        if (ampm === 'AM' && hour === 12)
19988                            hour = 0;
19989                    }
19990                } else {
19991                    hour = parseInt(this.container.find('.right .hourselect').val(), 10);
19992                    minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
19993                    if (isNaN(minute)) {
19994                        minute = parseInt(this.container.find('.right .minuteselect option:last').val(), 10);
19995                    }
19996                    second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
19997                    if (!this.timePicker24Hour) {
19998                        var ampm = this.container.find('.right .ampmselect').val();
19999                        if (ampm === 'PM' && hour < 12)
20000                            hour += 12;
20001                        if (ampm === 'AM' && hour === 12)
20002                            hour = 0;
20003                    }
20004                }
20005                this.leftCalendar.month.hour(hour).minute(minute).second(second);
20006                this.rightCalendar.month.hour(hour).minute(minute).second(second);
20007            }
20008
20009            this.renderCalendar('left');
20010            this.renderCalendar('right');
20011
20012            //highlight any predefined range matching the current start and end dates
20013            this.container.find('.ranges li').removeClass('active');
20014            if (this.endDate == null) return;
20015
20016            this.calculateChosenLabel();
20017        },
20018
20019        renderCalendar: function(side) {
20020
20021            //
20022            // Build the matrix of dates that will populate the calendar
20023            //
20024
20025            var calendar = side == 'left' ? this.leftCalendar : this.rightCalendar;
20026            var month = calendar.month.month();
20027            var year = calendar.month.year();
20028            var hour = calendar.month.hour();
20029            var minute = calendar.month.minute();
20030            var second = calendar.month.second();
20031            var daysInMonth = moment([year, month]).daysInMonth();
20032            var firstDay = moment([year, month, 1]);
20033            var lastDay = moment([year, month, daysInMonth]);
20034            var lastMonth = moment(firstDay).subtract(1, 'month').month();
20035            var lastYear = moment(firstDay).subtract(1, 'month').year();
20036            var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth();
20037            var dayOfWeek = firstDay.day();
20038
20039            //initialize a 6 rows x 7 columns array for the calendar
20040            var calendar = [];
20041            calendar.firstDay = firstDay;
20042            calendar.lastDay = lastDay;
20043
20044            for (var i = 0; i < 6; i++) {
20045                calendar[i] = [];
20046            }
20047
20048            //populate the calendar with date objects
20049            var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1;
20050            if (startDay > daysInLastMonth)
20051                startDay -= 7;
20052
20053            if (dayOfWeek == this.locale.firstDay)
20054                startDay = daysInLastMonth - 6;
20055
20056            var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]);
20057
20058            var col, row;
20059            for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) {
20060                if (i > 0 && col % 7 === 0) {
20061                    col = 0;
20062                    row++;
20063                }
20064                calendar[row][col] = curDate.clone().hour(hour).minute(minute).second(second);
20065                curDate.hour(12);
20066
20067                if (this.minDate && calendar[row][col].format('YYYY-MM-DD') == this.minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this.minDate) && side == 'left') {
20068                    calendar[row][col] = this.minDate.clone();
20069                }
20070
20071                if (this.maxDate && calendar[row][col].format('YYYY-MM-DD') == this.maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this.maxDate) && side == 'right') {
20072                    calendar[row][col] = this.maxDate.clone();
20073                }
20074
20075            }
20076
20077            //make the calendar object available to hoverDate/clickDate
20078            if (side == 'left') {
20079                this.leftCalendar.calendar = calendar;
20080            } else {
20081                this.rightCalendar.calendar = calendar;
20082            }
20083
20084            //
20085            // Display the calendar
20086            //
20087
20088            var minDate = side == 'left' ? this.minDate : this.startDate;
20089            var maxDate = this.maxDate;
20090            var selected = side == 'left' ? this.startDate : this.endDate;
20091            var arrow = this.locale.direction == 'ltr' ? {left: 'chevron-left', right: 'chevron-right'} : {left: 'chevron-right', right: 'chevron-left'};
20092
20093            var html = '<table class="table-condensed">';
20094            html += '<thead>';
20095            html += '<tr>';
20096
20097            // add empty cell for week number
20098            if (this.showWeekNumbers || this.showISOWeekNumbers)
20099                html += '<th></th>';
20100
20101            if ((!minDate || minDate.isBefore(calendar.firstDay)) && (!this.linkedCalendars || side == 'left')) {
20102                html += '<th class="prev available"><span></span></th>';
20103            } else {
20104                html += '<th></th>';
20105            }
20106
20107            var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY");
20108
20109            if (this.showDropdowns) {
20110                var currentMonth = calendar[1][1].month();
20111                var currentYear = calendar[1][1].year();
20112                var maxYear = (maxDate && maxDate.year()) || (this.maxYear);
20113                var minYear = (minDate && minDate.year()) || (this.minYear);
20114                var inMinYear = currentYear == minYear;
20115                var inMaxYear = currentYear == maxYear;
20116
20117                var monthHtml = '<select class="monthselect">';
20118                for (var m = 0; m < 12; m++) {
20119                    if ((!inMinYear || (minDate && m >= minDate.month())) && (!inMaxYear || (maxDate && m <= maxDate.month()))) {
20120                        monthHtml += "<option value='" + m + "'" +
20121                            (m === currentMonth ? " selected='selected'" : "") +
20122                            ">" + this.locale.monthNames[m] + "</option>";
20123                    } else {
20124                        monthHtml += "<option value='" + m + "'" +
20125                            (m === currentMonth ? " selected='selected'" : "") +
20126                            " disabled='disabled'>" + this.locale.monthNames[m] + "</option>";
20127                    }
20128                }
20129                monthHtml += "</select>";
20130
20131                var yearHtml = '<select class="yearselect">';
20132                for (var y = minYear; y <= maxYear; y++) {
20133                    yearHtml += '<option value="' + y + '"' +
20134                        (y === currentYear ? ' selected="selected"' : '') +
20135                        '>' + y + '</option>';
20136                }
20137                yearHtml += '</select>';
20138
20139                dateHtml = monthHtml + yearHtml;
20140            }
20141
20142            html += '<th colspan="5" class="month">' + dateHtml + '</th>';
20143            if ((!maxDate || maxDate.isAfter(calendar.lastDay)) && (!this.linkedCalendars || side == 'right' || this.singleDatePicker)) {
20144                html += '<th class="next available"><span></span></th>';
20145            } else {
20146                html += '<th></th>';
20147            }
20148
20149            html += '</tr>';
20150            html += '<tr>';
20151
20152            // add week number label
20153            if (this.showWeekNumbers || this.showISOWeekNumbers)
20154                html += '<th class="week">' + this.locale.weekLabel + '</th>';
20155
20156            $.each(this.locale.daysOfWeek, function(index, dayOfWeek) {
20157                html += '<th>' + dayOfWeek + '</th>';
20158            });
20159
20160            html += '</tr>';
20161            html += '</thead>';
20162            html += '<tbody>';
20163
20164            //adjust maxDate to reflect the maxSpan setting in order to
20165            //grey out end dates beyond the maxSpan
20166            if (this.endDate == null && this.maxSpan) {
20167                var maxLimit = this.startDate.clone().add(this.maxSpan).endOf('day');
20168                if (!maxDate || maxLimit.isBefore(maxDate)) {
20169                    maxDate = maxLimit;
20170                }
20171            }
20172
20173            for (var row = 0; row < 6; row++) {
20174                html += '<tr>';
20175
20176                // add week number
20177                if (this.showWeekNumbers)
20178                    html += '<td class="week">' + calendar[row][0].week() + '</td>';
20179                else if (this.showISOWeekNumbers)
20180                    html += '<td class="week">' + calendar[row][0].isoWeek() + '</td>';
20181
20182                for (var col = 0; col < 7; col++) {
20183
20184                    var classes = [];
20185
20186                    //highlight today's date
20187                    if (calendar[row][col].isSame(new Date(), "day"))
20188                        classes.push('today');
20189
20190                    //highlight weekends
20191                    if (calendar[row][col].isoWeekday() > 5)
20192                        classes.push('weekend');
20193
20194                    //grey out the dates in other months displayed at beginning and end of this calendar
20195                    if (calendar[row][col].month() != calendar[1][1].month())
20196                        classes.push('off', 'ends');
20197
20198                    //don't allow selection of dates before the minimum date
20199                    if (this.minDate && calendar[row][col].isBefore(this.minDate, 'day'))
20200                        classes.push('off', 'disabled');
20201
20202                    //don't allow selection of dates after the maximum date
20203                    if (maxDate && calendar[row][col].isAfter(maxDate, 'day'))
20204                        classes.push('off', 'disabled');
20205
20206                    //don't allow selection of date if a custom function decides it's invalid
20207                    if (this.isInvalidDate(calendar[row][col]))
20208                        classes.push('off', 'disabled');
20209
20210                    //highlight the currently selected start date
20211                    if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD'))
20212                        classes.push('active', 'start-date');
20213
20214                    //highlight the currently selected end date
20215                    if (this.endDate != null && calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD'))
20216                        classes.push('active', 'end-date');
20217
20218                    //highlight dates in-between the selected dates
20219                    if (this.endDate != null && calendar[row][col] > this.startDate && calendar[row][col] < this.endDate)
20220                        classes.push('in-range');
20221
20222                    //apply custom classes for this date
20223                    var isCustom = this.isCustomDate(calendar[row][col]);
20224                    if (isCustom !== false) {
20225                        if (typeof isCustom === 'string')
20226                            classes.push(isCustom);
20227                        else
20228                            Array.prototype.push.apply(classes, isCustom);
20229                    }
20230
20231                    var cname = '', disabled = false;
20232                    for (var i = 0; i < classes.length; i++) {
20233                        cname += classes[i] + ' ';
20234                        if (classes[i] == 'disabled')
20235                            disabled = true;
20236                    }
20237                    if (!disabled)
20238                        cname += 'available';
20239
20240                    html += '<td class="' + cname.replace(/^\s+|\s+$/g, '') + '" data-title="' + 'r' + row + 'c' + col + '">' + calendar[row][col].date() + '</td>';
20241
20242                }
20243                html += '</tr>';
20244            }
20245
20246            html += '</tbody>';
20247            html += '</table>';
20248
20249            this.container.find('.drp-calendar.' + side + ' .calendar-table').html(html);
20250
20251        },
20252
20253        renderTimePicker: function(side) {
20254
20255            // Don't bother updating the time picker if it's currently disabled
20256            // because an end date hasn't been clicked yet
20257            if (side == 'right' && !this.endDate) return;
20258
20259            var html, selected, minDate, maxDate = this.maxDate;
20260
20261            if (this.maxSpan && (!this.maxDate || this.startDate.clone().add(this.maxSpan).isBefore(this.maxDate)))
20262                maxDate = this.startDate.clone().add(this.maxSpan);
20263
20264            if (side == 'left') {
20265                selected = this.startDate.clone();
20266                minDate = this.minDate;
20267            } else if (side == 'right') {
20268                selected = this.endDate.clone();
20269                minDate = this.startDate;
20270
20271                //Preserve the time already selected
20272                var timeSelector = this.container.find('.drp-calendar.right .calendar-time');
20273                if (timeSelector.html() != '') {
20274
20275                    selected.hour(!isNaN(selected.hour()) ? selected.hour() : timeSelector.find('.hourselect option:selected').val());
20276                    selected.minute(!isNaN(selected.minute()) ? selected.minute() : timeSelector.find('.minuteselect option:selected').val());
20277                    selected.second(!isNaN(selected.second()) ? selected.second() : timeSelector.find('.secondselect option:selected').val());
20278
20279                    if (!this.timePicker24Hour) {
20280                        var ampm = timeSelector.find('.ampmselect option:selected').val();
20281                        if (ampm === 'PM' && selected.hour() < 12)
20282                            selected.hour(selected.hour() + 12);
20283                        if (ampm === 'AM' && selected.hour() === 12)
20284                            selected.hour(0);
20285                    }
20286
20287                }
20288
20289                if (selected.isBefore(this.startDate))
20290                    selected = this.startDate.clone();
20291
20292                if (maxDate && selected.isAfter(maxDate))
20293                    selected = maxDate.clone();
20294
20295            }
20296
20297            //
20298            // hours
20299            //
20300
20301            html = '<select class="hourselect">';
20302
20303            var start = this.timePicker24Hour ? 0 : 1;
20304            var end = this.timePicker24Hour ? 23 : 12;
20305
20306            for (var i = start; i <= end; i++) {
20307                var i_in_24 = i;
20308                if (!this.timePicker24Hour)
20309                    i_in_24 = selected.hour() >= 12 ? (i == 12 ? 12 : i + 12) : (i == 12 ? 0 : i);
20310
20311                var time = selected.clone().hour(i_in_24);
20312                var disabled = false;
20313                if (minDate && time.minute(59).isBefore(minDate))
20314                    disabled = true;
20315                if (maxDate && time.minute(0).isAfter(maxDate))
20316                    disabled = true;
20317
20318                if (i_in_24 == selected.hour() && !disabled) {
20319                    html += '<option value="' + i + '" selected="selected">' + i + '</option>';
20320                } else if (disabled) {
20321                    html += '<option value="' + i + '" disabled="disabled" class="disabled">' + i + '</option>';
20322                } else {
20323                    html += '<option value="' + i + '">' + i + '</option>';
20324                }
20325            }
20326
20327            html += '</select> ';
20328
20329            //
20330            // minutes
20331            //
20332
20333            html += ': <select class="minuteselect">';
20334
20335            for (var i = 0; i < 60; i += this.timePickerIncrement) {
20336                var padded = i < 10 ? '0' + i : i;
20337                var time = selected.clone().minute(i);
20338
20339                var disabled = false;
20340                if (minDate && time.second(59).isBefore(minDate))
20341                    disabled = true;
20342                if (maxDate && time.second(0).isAfter(maxDate))
20343                    disabled = true;
20344
20345                if (selected.minute() == i && !disabled) {
20346                    html += '<option value="' + i + '" selected="selected">' + padded + '</option>';
20347                } else if (disabled) {
20348                    html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>';
20349                } else {
20350                    html += '<option value="' + i + '">' + padded + '</option>';
20351                }
20352            }
20353
20354            html += '</select> ';
20355
20356            //
20357            // seconds
20358            //
20359
20360            if (this.timePickerSeconds) {
20361                html += ': <select class="secondselect">';
20362
20363                for (var i = 0; i < 60; i++) {
20364                    var padded = i < 10 ? '0' + i : i;
20365                    var time = selected.clone().second(i);
20366
20367                    var disabled = false;
20368                    if (minDate && time.isBefore(minDate))
20369                        disabled = true;
20370                    if (maxDate && time.isAfter(maxDate))
20371                        disabled = true;
20372
20373                    if (selected.second() == i && !disabled) {
20374                        html += '<option value="' + i + '" selected="selected">' + padded + '</option>';
20375                    } else if (disabled) {
20376                        html += '<option value="' + i + '" disabled="disabled" class="disabled">' + padded + '</option>';
20377                    } else {
20378                        html += '<option value="' + i + '">' + padded + '</option>';
20379                    }
20380                }
20381
20382                html += '</select> ';
20383            }
20384
20385            //
20386            // AM/PM
20387            //
20388
20389            if (!this.timePicker24Hour) {
20390                html += '<select class="ampmselect">';
20391
20392                var am_html = '';
20393                var pm_html = '';
20394
20395                if (minDate && selected.clone().hour(12).minute(0).second(0).isBefore(minDate))
20396                    am_html = ' disabled="disabled" class="disabled"';
20397
20398                if (maxDate && selected.clone().hour(0).minute(0).second(0).isAfter(maxDate))
20399                    pm_html = ' disabled="disabled" class="disabled"';
20400
20401                if (selected.hour() >= 12) {
20402                    html += '<option value="AM"' + am_html + '>AM</option><option value="PM" selected="selected"' + pm_html + '>PM</option>';
20403                } else {
20404                    html += '<option value="AM" selected="selected"' + am_html + '>AM</option><option value="PM"' + pm_html + '>PM</option>';
20405                }
20406
20407                html += '</select>';
20408            }
20409
20410            this.container.find('.drp-calendar.' + side + ' .calendar-time').html(html);
20411
20412        },
20413
20414        updateFormInputs: function() {
20415
20416            if (this.singleDatePicker || (this.endDate && (this.startDate.isBefore(this.endDate) || this.startDate.isSame(this.endDate)))) {
20417                this.container.find('button.applyBtn').
vendor: 1,312 bytes, lines 20417-20449
20417removeAttr('disabled');
20418            } else {
20419                this.container.find('button.applyBtn').attr('disabled', 'disabled');
20420            }
20421
20422        },
20423
20424        move: function() {
20425            var parentOffset = { top: 0, left: 0 },
20426                containerTop;
20427            var parentRightEdge = $(window).width();
20428            if (!this.parentEl.is('body')) {
20429                parentOffset = {
20430                    top: this.parentEl.offset().top - this.parentEl.scrollTop(),
20431                    left: this.parentEl.offset().left - this.parentEl.scrollLeft()
20432                };
20433                parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left;
20434            }
20435
20436            if (this.drops == 'up')
20437                containerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;
20438            else
20439                containerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;
20440
20441            // Force the container to it's actual width
20442            this.container.css({
20443              top: 0,
20444              left: 0,
20445              right: 'auto'
20446            });
20447            var containerWidth = this.container.outerWidth();
20448
20449            this.container[this.drops == 'up' ? 'addClass' : 'removeClass']('drop-
vendor: 21,720 bytes, lines 20449-20965
20449up');
20450
20451            if (this.opens == 'left') {
20452                var containerRight = parentRightEdge - this.element.offset().left - this.element.outerWidth();
20453                if (containerWidth + containerRight > $(window).width()) {
20454                    this.container.css({
20455                        top: containerTop,
20456                        right: 'auto',
20457                        left: 9
20458                    });
20459                } else {
20460                    this.container.css({
20461                        top: containerTop,
20462                        right: containerRight,
20463                        left: 'auto'
20464                    });
20465                }
20466            } else if (this.opens == 'center') {
20467                var containerLeft = this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2
20468                                        - containerWidth / 2;
20469                if (containerLeft < 0) {
20470                    this.container.css({
20471                        top: containerTop,
20472                        right: 'auto',
20473                        left: 9
20474                    });
20475                } else if (containerLeft + containerWidth > $(window).width()) {
20476                    this.container.css({
20477                        top: containerTop,
20478                        left: 'auto',
20479                        right: 0
20480                    });
20481                } else {
20482                    this.container.css({
20483                        top: containerTop,
20484                        left: containerLeft,
20485                        right: 'auto'
20486                    });
20487                }
20488            } else {
20489                var containerLeft = this.element.offset().left - parentOffset.left;
20490                if (containerLeft + containerWidth > $(window).width()) {
20491                    this.container.css({
20492                        top: containerTop,
20493                        left: 'auto',
20494                        right: 0
20495                    });
20496                } else {
20497                    this.container.css({
20498                        top: containerTop,
20499                        left: containerLeft,
20500                        right: 'auto'
20501                    });
20502                }
20503            }
20504        },
20505
20506        show: function(e) {
20507            if (this.isShowing) return;
20508
20509            // Create a click proxy that is private to this instance of datepicker, for unbinding
20510            this._outsideClickProxy = $.proxy(function(e) { this.outsideClick(e); }, this);
20511
20512            // Bind global datepicker mousedown for hiding and
20513            $(document)
20514              .on('mousedown.daterangepicker', this._outsideClickProxy)
20515              // also support mobile devices
20516              .on('touchend.daterangepicker', this._outsideClickProxy)
20517              // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them
20518              .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy)
20519              // and also close when focus changes to outside the picker (eg. tabbing between controls)
20520              .on('focusin.daterangepicker', this._outsideClickProxy);
20521
20522            // Reposition the picker if the window is resized while it's open
20523            $(window).on('resize.daterangepicker', $.proxy(function(e) { this.move(e); }, this));
20524
20525            this.oldStartDate = this.startDate.clone();
20526            this.oldEndDate = this.endDate.clone();
20527            this.previousRightTime = this.endDate.clone();
20528
20529            this.updateView();
20530            this.container.show();
20531            this.move();
20532            this.element.trigger('show.daterangepicker', this);
20533            this.isShowing = true;
20534        },
20535
20536        hide: function(e) {
20537            if (!this.isShowing) return;
20538
20539            //incomplete date selection, revert to last values
20540            if (!this.endDate) {
20541                this.startDate = this.oldStartDate.clone();
20542                this.endDate = this.oldEndDate.clone();
20543            }
20544
20545            //if a new date range was selected, invoke the user callback function
20546            if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate))
20547                this.callback(this.startDate.clone(), this.endDate.clone(), this.chosenLabel);
20548
20549            //if picker is attached to a text input, update it
20550            this.updateElement();
20551
20552            $(document).off('.daterangepicker');
20553            $(window).off('.daterangepicker');
20554            this.container.hide();
20555            this.element.trigger('hide.daterangepicker', this);
20556            this.isShowing = false;
20557        },
20558
20559        toggle: function(e) {
20560            if (this.isShowing) {
20561                this.hide();
20562            } else {
20563                this.show();
20564            }
20565        },
20566
20567        outsideClick: function(e) {
20568            var target = $(e.target);
20569            // if the page is clicked anywhere except within the daterangerpicker/button
20570            // itself then call this.hide()
20571            if (
20572                // ie modal dialog fix
20573                e.type == "focusin" ||
20574                target.closest(this.element).length ||
20575                target.closest(this.container).length ||
20576                target.closest('.calendar-table').length
20577                ) return;
20578            this.hide();
20579            this.element.trigger('outsideClick.daterangepicker', this);
20580        },
20581
20582        showCalendars: function() {
20583            this.container.addClass('show-calendar');
20584            this.move();
20585            this.element.trigger('showCalendar.daterangepicker', this);
20586        },
20587
20588        hideCalendars: function() {
20589            this.container.removeClass('show-calendar');
20590            this.element.trigger('hideCalendar.daterangepicker', this);
20591        },
20592
20593        clickRange: function(e) {
20594            var label = e.target.getAttribute('data-range-key');
20595            this.chosenLabel = label;
20596            if (label == this.locale.customRangeLabel) {
20597                this.showCalendars();
20598            } else {
20599                var dates = this.ranges[label];
20600                this.startDate = dates[0];
20601                this.endDate = dates[1];
20602
20603                if (!this.timePicker) {
20604                    this.startDate.startOf('day');
20605                    this.endDate.endOf('day');
20606                }
20607
20608                if (!this.alwaysShowCalendars)
20609                    this.hideCalendars();
20610                this.clickApply();
20611            }
20612        },
20613
20614        clickPrev: function(e) {
20615            var cal = $(e.target).parents('.drp-calendar');
20616            if (cal.hasClass('left')) {
20617                this.leftCalendar.month.subtract(1, 'month');
20618                if (this.linkedCalendars)
20619                    this.rightCalendar.month.subtract(1, 'month');
20620            } else {
20621                this.rightCalendar.month.subtract(1, 'month');
20622            }
20623            this.updateCalendars();
20624        },
20625
20626        clickNext: function(e) {
20627            var cal = $(e.target).parents('.drp-calendar');
20628            if (cal.hasClass('left')) {
20629                this.leftCalendar.month.add(1, 'month');
20630            } else {
20631                this.rightCalendar.month.add(1, 'month');
20632                if (this.linkedCalendars)
20633                    this.leftCalendar.month.add(1, 'month');
20634            }
20635            this.updateCalendars();
20636        },
20637
20638        hoverDate: function(e) {
20639
20640            //ignore dates that can't be selected
20641            if (!$(e.target).hasClass('available')) return;
20642
20643            var title = $(e.target).attr('data-title');
20644            var row = title.substr(1, 1);
20645            var col = title.substr(3, 1);
20646            var cal = $(e.target).parents('.drp-calendar');
20647            var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
20648
20649            //highlight the dates between the start date and the date being hovered as a potential end date
20650            var leftCalendar = this.leftCalendar;
20651            var rightCalendar = this.rightCalendar;
20652            var startDate = this.startDate;
20653            if (!this.endDate) {
20654                this.container.find('.drp-calendar tbody td').each(function(index, el) {
20655
20656                    //skip week numbers, only look at dates
20657                    if ($(el).hasClass('week')) return;
20658
20659                    var title = $(el).attr('data-title');
20660                    var row = title.substr(1, 1);
20661                    var col = title.substr(3, 1);
20662                    var cal = $(el).parents('.drp-calendar');
20663                    var dt = cal.hasClass('left') ? leftCalendar.calendar[row][col] : rightCalendar.calendar[row][col];
20664
20665                    if ((dt.isAfter(startDate) && dt.isBefore(date)) || dt.isSame(date, 'day')) {
20666                        $(el).addClass('in-range');
20667                    } else {
20668                        $(el).removeClass('in-range');
20669                    }
20670
20671                });
20672            }
20673
20674        },
20675
20676        clickDate: function(e) {
20677
20678            if (!$(e.target).hasClass('available')) return;
20679
20680            var title = $(e.target).attr('data-title');
20681            var row = title.substr(1, 1);
20682            var col = title.substr(3, 1);
20683            var cal = $(e.target).parents('.drp-calendar');
20684            var date = cal.hasClass('left') ? this.leftCalendar.calendar[row][col] : this.rightCalendar.calendar[row][col];
20685
20686            //
20687            // this function needs to do a few things:
20688            // * alternate between selecting a start and end date for the range,
20689            // * if the time picker is enabled, apply the hour/minute/second from the select boxes to the clicked date
20690            // * if autoapply is enabled, and an end date was chosen, apply the selection
20691            // * if single date picker mode, and time picker isn't enabled, apply the selection immediately
20692            // * if one of the inputs above the calendars was focused, cancel that manual input
20693            //
20694
20695            if (this.endDate || date.isBefore(this.startDate, 'day')) { //picking start
20696                if (this.timePicker) {
20697                    var hour = parseInt(this.container.find('.left .hourselect').val(), 10);
20698                    if (!this.timePicker24Hour) {
20699                        var ampm = this.container.find('.left .ampmselect').val();
20700                        if (ampm === 'PM' && hour < 12)
20701                            hour += 12;
20702                        if (ampm === 'AM' && hour === 12)
20703                            hour = 0;
20704                    }
20705                    var minute = parseInt(this.container.find('.left .minuteselect').val(), 10);
20706                    if (isNaN(minute)) {
20707                        minute = parseInt(this.container.find('.left .minuteselect option:last').val(), 10);
20708                    }
20709                    var second = this.timePickerSeconds ? parseInt(this.container.find('.left .secondselect').val(), 10) : 0;
20710                    date = date.clone().hour(hour).minute(minute).second(second);
20711                }
20712                this.endDate = null;
20713                this.setStartDate(date.clone());
20714            } else if (!this.endDate && date.isBefore(this.startDate)) {
20715                //special case: clicking the same date for start/end,
20716                //but the time of the end date is before the start date
20717                this.setEndDate(this.startDate.clone());
20718            } else { // picking end
20719                if (this.timePicker) {
20720                    var hour = parseInt(this.container.find('.right .hourselect').val(), 10);
20721                    if (!this.timePicker24Hour) {
20722                        var ampm = this.container.find('.right .ampmselect').val();
20723                        if (ampm === 'PM' && hour < 12)
20724                            hour += 12;
20725                        if (ampm === 'AM' && hour === 12)
20726                            hour = 0;
20727                    }
20728                    var minute = parseInt(this.container.find('.right .minuteselect').val(), 10);
20729                    if (isNaN(minute)) {
20730                        minute = parseInt(this.container.find('.right .minuteselect option:last').val(), 10);
20731                    }
20732                    var second = this.timePickerSeconds ? parseInt(this.container.find('.right .secondselect').val(), 10) : 0;
20733                    date = date.clone().hour(hour).minute(minute).second(second);
20734                }
20735                this.setEndDate(date.clone());
20736                if (this.autoApply) {
20737                  this.calculateChosenLabel();
20738                  this.clickApply();
20739                }
20740            }
20741
20742            if (this.singleDatePicker) {
20743                this.setEndDate(this.startDate);
20744                if (!this.timePicker)
20745                    this.clickApply();
20746            }
20747
20748            this.updateView();
20749
20750            //This is to cancel the blur event handler if the mouse was in one of the inputs
20751            e.stopPropagation();
20752
20753        },
20754
20755        calculateChosenLabel: function () {
20756            var customRange = true;
20757            var i = 0;
20758            for (var range in this.ranges) {
20759              if (this.timePicker) {
20760                    var format = this.timePickerSeconds ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD HH:mm";
20761                    //ignore times when comparing dates if time picker seconds is not enabled
20762                    if (this.startDate.format(format) == this.ranges[range][0].format(format) && this.endDate.format(format) == this.ranges[range][1].format(format)) {
20763                        customRange = false;
20764                        this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key');
20765                        break;
20766                    }
20767                } else {
20768                    //ignore times when comparing dates if time picker is not enabled
20769                    if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) {
20770                        customRange = false;
20771                        this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')').addClass('active').attr('data-range-key');
20772                        break;
20773                    }
20774                }
20775                i++;
20776            }
20777            if (customRange) {
20778                if (this.showCustomRangeLabel) {
20779                    this.chosenLabel = this.container.find('.ranges li:last').addClass('active').attr('data-range-key');
20780                } else {
20781                    this.chosenLabel = null;
20782                }
20783                this.showCalendars();
20784            }
20785        },
20786
20787        clickApply: function(e) {
20788            this.hide();
20789            this.element.trigger('apply.daterangepicker', this);
20790        },
20791
20792        clickCancel: function(e) {
20793            this.startDate = this.oldStartDate;
20794            this.endDate = this.oldEndDate;
20795            this.hide();
20796            this.element.trigger('cancel.daterangepicker', this);
20797        },
20798
20799        monthOrYearChanged: function(e) {
20800            var isLeft = $(e.target).closest('.drp-calendar').hasClass('left'),
20801                leftOrRight = isLeft ? 'left' : 'right',
20802                cal = this.container.find('.drp-calendar.'+leftOrRight);
20803
20804            // Month must be Number for new moment versions
20805            var month = parseInt(cal.find('.monthselect').val(), 10);
20806            var year = cal.find('.yearselect').val();
20807
20808            if (!isLeft) {
20809                if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) {
20810                    month = this.startDate.month();
20811                    year = this.startDate.year();
20812                }
20813            }
20814
20815            if (this.minDate) {
20816                if (year < this.minDate.year() || (year == this.minDate.year() && month < this.minDate.month())) {
20817                    month = this.minDate.month();
20818                    year = this.minDate.year();
20819                }
20820            }
20821
20822            if (this.maxDate) {
20823                if (year > this.maxDate.year() || (year == this.maxDate.year() && month > this.maxDate.month())) {
20824                    month = this.maxDate.month();
20825                    year = this.maxDate.year();
20826                }
20827            }
20828
20829            if (isLeft) {
20830                this.leftCalendar.month.month(month).year(year);
20831                if (this.linkedCalendars)
20832                    this.rightCalendar.month = this.leftCalendar.month.clone().add(1, 'month');
20833            } else {
20834                this.rightCalendar.month.month(month).year(year);
20835                if (this.linkedCalendars)
20836                    this.leftCalendar.month = this.rightCalendar.month.clone().subtract(1, 'month');
20837            }
20838            this.updateCalendars();
20839        },
20840
20841        timeChanged: function(e) {
20842
20843            var cal = $(e.target).closest('.drp-calendar'),
20844                isLeft = cal.hasClass('left');
20845
20846            var hour = parseInt(cal.find('.hourselect').val(), 10);
20847            var minute = parseInt(cal.find('.minuteselect').val(), 10);
20848            if (isNaN(minute)) {
20849                minute = parseInt(cal.find('.minuteselect option:last').val(), 10);
20850            }
20851            var second = this.timePickerSeconds ? parseInt(cal.find('.secondselect').val(), 10) : 0;
20852
20853            if (!this.timePicker24Hour) {
20854                var ampm = cal.find('.ampmselect').val();
20855                if (ampm === 'PM' && hour < 12)
20856                    hour += 12;
20857                if (ampm === 'AM' && hour === 12)
20858                    hour = 0;
20859            }
20860
20861            if (isLeft) {
20862                var start = this.startDate.clone();
20863                start.hour(hour);
20864                start.minute(minute);
20865                start.second(second);
20866                this.setStartDate(start);
20867                if (this.singleDatePicker) {
20868                    this.endDate = this.startDate.clone();
20869                } else if (this.endDate && this.endDate.format('YYYY-MM-DD') == start.format('YYYY-MM-DD') && this.endDate.isBefore(start)) {
20870                    this.setEndDate(start.clone());
20871                }
20872            } else if (this.endDate) {
20873                var end = this.endDate.clone();
20874                end.hour(hour);
20875                end.minute(minute);
20876                end.second(second);
20877                this.setEndDate(end);
20878            }
20879
20880            //update the calendars so all clickable dates reflect the new time component
20881            this.updateCalendars();
20882
20883            //update the form inputs above the calendars with the new time
20884            this.updateFormInputs();
20885
20886            //re-render the time pickers because changing one selection can affect what's enabled in another
20887            this.renderTimePicker('left');
20888            this.renderTimePicker('right');
20889
20890        },
20891
20892        elementChanged: function() {
20893            if (!this.element.is('input')) return;
20894            if (!this.element.val().length) return;
20895
20896            var dateString = this.element.val().split(this.locale.separator),
20897                start = null,
20898                end = null;
20899
20900            if (dateString.length === 2) {
20901                start = moment(dateString[0], this.locale.format);
20902                end = moment(dateString[1], this.locale.format);
20903            }
20904
20905            if (this.singleDatePicker || start === null || end === null) {
20906                start = moment(this.element.val(), this.locale.format);
20907                end = start;
20908            }
20909
20910            if (!start.isValid() || !end.isValid()) return;
20911
20912            this.setStartDate(start);
20913            this.setEndDate(end);
20914            this.updateView();
20915        },
20916
20917        keydown: function(e) {
20918            //hide on tab or enter
20919            if ((e.keyCode === 9) || (e.keyCode === 13)) {
20920                this.hide();
20921            }
20922
20923            //hide on esc and prevent propagation
20924            if (e.keyCode === 27) {
20925                e.preventDefault();
20926                e.stopPropagation();
20927
20928                this.hide();
20929            }
20930        },
20931
20932        updateElement: function() {
20933            if (this.element.is('input') && this.autoUpdateInput) {
20934                var newValue = this.startDate.format(this.locale.format);
20935                if (!this.singleDatePicker) {
20936                    newValue += this.locale.separator + this.endDate.format(this.locale.format);
20937                }
20938                if (newValue !== this.element.val()) {
20939                    this.element.val(newValue).trigger('change');
20940                }
20941            }
20942        },
20943
20944        remove: function() {
20945            this.container.remove();
20946            this.element.off('.daterangepicker');
20947            this.element.removeData();
20948        }
20949
20950    };
20951
20952    $.fn.daterangepicker = function(options, callback) {
20953        var implementOptions = $.extend(true, {}, $.fn.daterangepicker.defaultOptions, options);
20954        this.each(function() {
20955            var el = $(this);
20956            if (el.data('daterangepicker'))
20957                el.data('daterangepicker').remove();
20958            el.data('daterangepicker', new DateRangePicker(el, implementOptions, callback));
20959        });
20960        return this;
20961    };
20962
20963    return DateRangePicker;
20964
20965}));
20966
20967},{"jquery":13,"moment":14}],13:[function(require,module,exports){
20968/*!
20969 * jQuery JavaScript Library v3.4.1
20970 * https://jquery.com/
20971 *
20972 * Includes Sizzle.js
20973 * https://sizzlejs.com/
20974 *
20975 * Copyright JS Foundation and other contributors
20976 * Released under the MIT license
20977 * https://jquery.org/license
20978 *
20979 * Date: 2019-05-01T21:04Z
20980 */
20981( function( global, factory ) {
20982
20983	"use strict";
20984
20985	if ( typeof module === "object" && typeof module.exports === "object" ) {
20986
20987		// For CommonJS and CommonJS-like environments where a proper `window`
20988		// is present, execute the factory and get jQuery.
20989		// For environments that do not have a `window` with a `document`
20990		// (such as Node.js), expose a factory as module.exports.
20991		// This accentuates the need for the creation of a real `window`.
20992		// e.g. var jQuery = require("jquery")(window);
20993		// See ticket #14549 for more info.
20994		module.exports = global.document ?
20995			factory( global, true ) :
20996			function( w ) {
20997				if ( !w.document ) {
20998					throw new Error( "jQuery requires a window with a document" );
20999				}
21000				return factory( w );
21001			};
21002	} else {
21003		factory( global );
21004	}
21005
21006// Pass this if window is not defined yet
21007} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
21008
21009// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
21010// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
21011// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), str
vendor: 4,911 bytes, lines 21011-21212
21011ict mode should be common
21012// enough that all such attempts are guarded in a try block.
21013"use strict";
21014
21015var arr = [];
21016
21017var document = window.document;
21018
21019var getProto = Object.getPrototypeOf;
21020
21021var slice = arr.slice;
21022
21023var concat = arr.concat;
21024
21025var push = arr.push;
21026
21027var indexOf = arr.indexOf;
21028
21029var class2type = {};
21030
21031var toString = class2type.toString;
21032
21033var hasOwn = class2type.hasOwnProperty;
21034
21035var fnToString = hasOwn.toString;
21036
21037var ObjectFunctionString = fnToString.call( Object );
21038
21039var support = {};
21040
21041var isFunction = function isFunction( obj ) {
21042
21043      // Support: Chrome <=57, Firefox <=52
21044      // In some browsers, typeof returns "function" for HTML <object> elements
21045      // (i.e., `typeof document.createElement( "object" ) === "function"`).
21046      // We don't want to classify *any* DOM node as a function.
21047      return typeof obj === "function" && typeof obj.nodeType !== "number";
21048  };
21049
21050
21051var isWindow = function isWindow( obj ) {
21052		return obj != null && obj === obj.window;
21053	};
21054
21055
21056
21057
21058	var preservedScriptAttributes = {
21059		type: true,
21060		src: true,
21061		nonce: true,
21062		noModule: true
21063	};
21064
21065	function DOMEval( code, node, doc ) {
21066		doc = doc || document;
21067
21068		var i, val,
21069			script = doc.createElement( "script" );
21070
21071		script.text = code;
21072		if ( node ) {
21073			for ( i in preservedScriptAttributes ) {
21074
21075				// Support: Firefox 64+, Edge 18+
21076				// Some browsers don't support the "nonce" property on scripts.
21077				// On the other hand, just using `getAttribute` is not enough as
21078				// the `nonce` attribute is reset to an empty string whenever it
21079				// becomes browsing-context connected.
21080				// See https://github.com/whatwg/html/issues/2369
21081				// See https://html.spec.whatwg.org/#nonce-attributes
21082				// The `node.getAttribute` check was added for the sake of
21083				// `jQuery.globalEval` so that it can fake a nonce-containing node
21084				// via an object.
21085				val = node[ i ] || node.getAttribute && node.getAttribute( i );
21086				if ( val ) {
21087					script.setAttribute( i, val );
21088				}
21089			}
21090		}
21091		doc.head.appendChild( script ).parentNode.removeChild( script );
21092	}
21093
21094
21095function toType( obj ) {
21096	if ( obj == null ) {
21097		return obj + "";
21098	}
21099
21100	// Support: Android <=2.3 only (functionish RegExp)
21101	return typeof obj === "object" || typeof obj === "function" ?
21102		class2type[ toString.call( obj ) ] || "object" :
21103		typeof obj;
21104}
21105/* global Symbol */
21106// Defining this global in .eslintrc.json would create a danger of using the global
21107// unguarded in another place, it seems safer to define global only for this module
21108
21109
21110
21111var
21112	version = "3.4.1",
21113
21114	// Define a local copy of jQuery
21115	jQuery = function( selector, context ) {
21116
21117		// The jQuery object is actually just the init constructor 'enhanced'
21118		// Need init if jQuery is called (just allow error to be thrown if not included)
21119		return new jQuery.fn.init( selector, context );
21120	},
21121
21122	// Support: Android <=4.0 only
21123	// Make sure we trim BOM and NBSP
21124	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
21125
21126jQuery.fn = jQuery.prototype = {
21127
21128	// The current version of jQuery being used
21129	jquery: version,
21130
21131	constructor: jQuery,
21132
21133	// The default length of a jQuery object is 0
21134	length: 0,
21135
21136	toArray: function() {
21137		return slice.call( this );
21138	},
21139
21140	// Get the Nth element in the matched element set OR
21141	// Get the whole matched element set as a clean array
21142	get: function( num ) {
21143
21144		// Return all the elements in a clean array
21145		if ( num == null ) {
21146			return slice.call( this );
21147		}
21148
21149		// Return just the one element from the set
21150		return num < 0 ? this[ num + this.length ] : this[ num ];
21151	},
21152
21153	// Take an array of elements and push it onto the stack
21154	// (returning the new matched element set)
21155	pushStack: function( elems ) {
21156
21157		// Build a new jQuery matched element set
21158		var ret = jQuery.merge( this.constructor(), elems );
21159
21160		// Add the old object onto the stack (as a reference)
21161		ret.prevObject = this;
21162
21163		// Return the newly-formed element set
21164		return ret;
21165	},
21166
21167	// Execute a callback for every element in the matched set.
21168	each: function( callback ) {
21169		return jQuery.each( this, callback );
21170	},
21171
21172	map: function( callback ) {
21173		return this.pushStack( jQuery.map( this, function( elem, i ) {
21174			return callback.call( elem, i, elem );
21175		} ) );
21176	},
21177
21178	slice: function() {
21179		return this.pushStack( slice.apply( this, arguments ) );
21180	},
21181
21182	first: function() {
21183		return this.eq( 0 );
21184	},
21185
21186	last: function() {
21187		return this.eq( -1 );
21188	},
21189
21190	eq: function( i ) {
21191		var len = this.length,
21192			j = +i + ( i < 0 ? len : 0 );
21193		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
21194	},
21195
21196	end: function() {
21197		return this.prevObject || this.constructor();
21198	},
21199
21200	// For internal use only.
21201	// Behaves like an Array's method, not like a jQuery method.
21202	push: push,
21203	sort: arr.sort,
21204	splice: arr.splice
21205};
21206
21207jQuery.extend = jQuery.fn.extend = function() {
21208	var options, name, src, copy, copyIsArray, clone,
21209		target = arguments[ 0 ] || {},
21210		i = 1,
21211		length = arguments.length,
21212		deep = false;
vendor: 4,724 bytes, lines 21213-21425
21213
21214	// Handle a deep copy situation
21215	if ( typeof target === "boolean" ) {
21216		deep = target;
21217
21218		// Skip the boolean and the target
21219		target = arguments[ i ] || {};
21220		i++;
21221	}
21222
21223	// Handle case when target is a string or something (possible in deep copy)
21224	if ( typeof target !== "object" && !isFunction( target ) ) {
21225		target = {};
21226	}
21227
21228	// Extend jQuery itself if only one argument is passed
21229	if ( i === length ) {
21230		target = this;
21231		i--;
21232	}
21233
21234	for ( ; i < length; i++ ) {
21235
21236		// Only deal with non-null/undefined values
21237		if ( ( options = arguments[ i ] ) != null ) {
21238
21239			// Extend the base object
21240			for ( name in options ) {
21241				copy = options[ name ];
21242
21243				// Prevent Object.prototype pollution
21244				// Prevent never-ending loop
21245				if ( name === "__proto__" || target === copy ) {
21246					continue;
21247				}
21248
21249				// Recurse if we're merging plain objects or arrays
21250				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
21251					( copyIsArray = Array.isArray( copy ) ) ) ) {
21252					src = target[ name ];
21253
21254					// Ensure proper type for the source value
21255					if ( copyIsArray && !Array.isArray( src ) ) {
21256						clone = [];
21257					} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
21258						clone = {};
21259					} else {
21260						clone = src;
21261					}
21262					copyIsArray = false;
21263
21264					// Never move original objects, clone them
21265					target[ name ] = jQuery.extend( deep, clone, copy );
21266
21267				// Don't bring in undefined values
21268				} else if ( copy !== undefined ) {
21269					target[ name ] = copy;
21270				}
21271			}
21272		}
21273	}
21274
21275	// Return the modified object
21276	return target;
21277};
21278
21279jQuery.extend( {
21280
21281	// Unique for each copy of jQuery on the page
21282	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
21283
21284	// Assume jQuery is ready without the ready module
21285	isReady: true,
21286
21287	error: function( msg ) {
21288		throw new Error( msg );
21289	},
21290
21291	noop: function() {},
21292
21293	isPlainObject: function( obj ) {
21294		var proto, Ctor;
21295
21296		// Detect obvious negatives
21297		// Use toString instead of jQuery.type to catch host objects
21298		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
21299			return false;
21300		}
21301
21302		proto = getProto( obj );
21303
21304		// Objects with no prototype (e.g., `Object.create( null )`) are plain
21305		if ( !proto ) {
21306			return true;
21307		}
21308
21309		// Objects with prototype are plain iff they were constructed by a global Object function
21310		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
21311		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
21312	},
21313
21314	isEmptyObject: function( obj ) {
21315		var name;
21316
21317		for ( name in obj ) {
21318			return false;
21319		}
21320		return true;
21321	},
21322
21323	// Evaluates a script in a global context
21324	globalEval: function( code, options ) {
21325		DOMEval( code, { nonce: options && options.nonce } );
21326	},
21327
21328	each: function( obj, callback ) {
21329		var length, i = 0;
21330
21331		if ( isArrayLike( obj ) ) {
21332			length = obj.length;
21333			for ( ; i < length; i++ ) {
21334				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
21335					break;
21336				}
21337			}
21338		} else {
21339			for ( i in obj ) {
21340				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
21341					break;
21342				}
21343			}
21344		}
21345
21346		return obj;
21347	},
21348
21349	// Support: Android <=4.0 only
21350	trim: function( text ) {
21351		return text == null ?
21352			"" :
21353			( text + "" ).replace( rtrim, "" );
21354	},
21355
21356	// results is for internal usage only
21357	makeArray: function( arr, results ) {
21358		var ret = results || [];
21359
21360		if ( arr != null ) {
21361			if ( isArrayLike( Object( arr ) ) ) {
21362				jQuery.merge( ret,
21363					typeof arr === "string" ?
21364					[ arr ] : arr
21365				);
21366			} else {
21367				push.call( ret, arr );
21368			}
21369		}
21370
21371		return ret;
21372	},
21373
21374	inArray: function( elem, arr, i ) {
21375		return arr == null ? -1 : indexOf.call( arr, elem, i );
21376	},
21377
21378	// Support: Android <=4.0 only, PhantomJS 1 only
21379	// push.apply(_, arraylike) throws on ancient WebKit
21380	merge: function( first, second ) {
21381		var len = +second.length,
21382			j = 0,
21383			i = first.length;
21384
21385		for ( ; j < len; j++ ) {
21386			first[ i++ ] = second[ j ];
21387		}
21388
21389		first.length = i;
21390
21391		return first;
21392	},
21393
21394	grep: function( elems, callback, invert ) {
21395		var callbackInverse,
21396			matches = [],
21397			i = 0,
21398			length = elems.length,
21399			callbackExpect = !invert;
21400
21401		// Go through the array, only saving the items
21402		// that pass the validator function
21403		for ( ; i < length; i++ ) {
21404			callbackInverse = !callback( elems[ i ], i );
21405			if ( callbackInverse !== callbackExpect ) {
21406				matches.push( elems[ i ] );
21407			}
21408		}
21409
21410		return matches;
21411	},
21412
21413	// arg is for internal usage only
21414	map: function( elems, callback, arg ) {
21415		var length, value,
21416			i = 0,
21417			ret = [];
21418
21419		// Go through the array, translating each of the items to their new values
21420		if ( isArrayLike( elems ) ) {
21421			length = elems.length;
21422			for ( ; i < length; i++ ) {
21423				value = callback( elems[ i ], i, arg );
21424
21425				if ( value != null ) {
vendor: 4,136 bytes, lines 21426-21583
21426					ret.push( value );
21427				}
21428			}
21429
21430		// Go through every key on the object,
21431		} else {
21432			for ( i in elems ) {
21433				value = callback( elems[ i ], i, arg );
21434
21435				if ( value != null ) {
21436					ret.push( value );
21437				}
21438			}
21439		}
21440
21441		// Flatten any nested arrays
21442		return concat.apply( [], ret );
21443	},
21444
21445	// A global GUID counter for objects
21446	guid: 1,
21447
21448	// jQuery.support is not used in Core but other projects attach their
21449	// properties to it so it needs to exist.
21450	support: support
21451} );
21452
21453if ( typeof Symbol === "function" ) {
21454	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
21455}
21456
21457// Populate the class2type map
21458jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
21459function( i, name ) {
21460	class2type[ "[object " + name + "]" ] = name.toLowerCase();
21461} );
21462
21463function isArrayLike( obj ) {
21464
21465	// Support: real iOS 8.2 only (not reproducible in simulator)
21466	// `in` check used to prevent JIT error (gh-2145)
21467	// hasOwn isn't used here due to false negatives
21468	// regarding Nodelist length in IE
21469	var length = !!obj && "length" in obj && obj.length,
21470		type = toType( obj );
21471
21472	if ( isFunction( obj ) || isWindow( obj ) ) {
21473		return false;
21474	}
21475
21476	return type === "array" || length === 0 ||
21477		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
21478}
21479var Sizzle =
21480/*!
21481 * Sizzle CSS Selector Engine v2.3.4
21482 * https://sizzlejs.com/
21483 *
21484 * Copyright JS Foundation and other contributors
21485 * Released under the MIT license
21486 * https://js.foundation/
21487 *
21488 * Date: 2019-04-08
21489 */
21490(function( window ) {
21491
21492var i,
21493	support,
21494	Expr,
21495	getText,
21496	isXML,
21497	tokenize,
21498	compile,
21499	select,
21500	outermostContext,
21501	sortInput,
21502	hasDuplicate,
21503
21504	// Local document vars
21505	setDocument,
21506	document,
21507	docElem,
21508	documentIsHTML,
21509	rbuggyQSA,
21510	rbuggyMatches,
21511	matches,
21512	contains,
21513
21514	// Instance-specific data
21515	expando = "sizzle" + 1 * new Date(),
21516	preferredDoc = window.document,
21517	dirruns = 0,
21518	done = 0,
21519	classCache = createCache(),
21520	tokenCache = createCache(),
21521	compilerCache = createCache(),
21522	nonnativeSelectorCache = createCache(),
21523	sortOrder = function( a, b ) {
21524		if ( a === b ) {
21525			hasDuplicate = true;
21526		}
21527		return 0;
21528	},
21529
21530	// Instance methods
21531	hasOwn = ({}).hasOwnProperty,
21532	arr = [],
21533	pop = arr.pop,
21534	push_native = arr.push,
21535	push = arr.push,
21536	slice = arr.slice,
21537	// Use a stripped-down indexOf as it's faster than native
21538	// https://jsperf.com/thor-indexof-vs-for/5
21539	indexOf = function( list, elem ) {
21540		var i = 0,
21541			len = list.length;
21542		for ( ; i < len; i++ ) {
21543			if ( list[i] === elem ) {
21544				return i;
21545			}
21546		}
21547		return -1;
21548	},
21549
21550	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
21551
21552	// Regular expressions
21553
21554	// http://www.w3.org/TR/css3-selectors/#whitespace
21555	whitespace = "[\\x20\\t\\r\\n\\f]",
21556
21557	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
21558	identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
21559
21560	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
21561	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
21562		// Operator (capture 2)
21563		"*([*^$|!~]?=)" + whitespace +
21564		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
21565		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
21566		"*\\]",
21567
21568	pseudos = ":(" + identifier + ")(?:\\((" +
21569		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
21570		// 1. quoted (capture 3; capture 4 or capture 5)
21571		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
21572		// 2. simple (capture 6)
21573		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
21574		// 3. anything else (capture 2)
21575		".*" +
21576		")\\)|)",
21577
21578	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
21579	rwhitespace = new RegExp( whitespace + "+", "g" ),
21580	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
21581
21582	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
21583	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
vendor: 4,615 bytes, lines 21584-21732
21584	rdescend = new RegExp( whitespace + "|>" ),
21585
21586	rpseudo = new RegExp( pseudos ),
21587	ridentifier = new RegExp( "^" + identifier + "$" ),
21588
21589	matchExpr = {
21590		"ID": new RegExp( "^#(" + identifier + ")" ),
21591		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
21592		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
21593		"ATTR": new RegExp( "^" + attributes ),
21594		"PSEUDO": new RegExp( "^" + pseudos ),
21595		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
21596			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
21597			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
21598		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
21599		// For use in libraries implementing .is()
21600		// We use this for POS matching in `select`
21601		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
21602			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
21603	},
21604
21605	rhtml = /HTML$/i,
21606	rinputs = /^(?:input|select|textarea|button)$/i,
21607	rheader = /^h\d$/i,
21608
21609	rnative = /^[^{]+\{\s*\[native \w/,
21610
21611	// Easily-parseable/retrievable ID or TAG or CLASS selectors
21612	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
21613
21614	rsibling = /[+~]/,
21615
21616	// CSS escapes
21617	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
21618	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
21619	funescape = function( _, escaped, escapedWhitespace ) {
21620		var high = "0x" + escaped - 0x10000;
21621		// NaN means non-codepoint
21622		// Support: Firefox<24
21623		// Workaround erroneous numeric interpretation of +"0x"
21624		return high !== high || escapedWhitespace ?
21625			escaped :
21626			high < 0 ?
21627				// BMP codepoint
21628				String.fromCharCode( high + 0x10000 ) :
21629				// Supplemental Plane codepoint (surrogate pair)
21630				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
21631	},
21632
21633	// CSS string/identifier serialization
21634	// https://drafts.csswg.org/cssom/#common-serializing-idioms
21635	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
21636	fcssescape = function( ch, asCodePoint ) {
21637		if ( asCodePoint ) {
21638
21639			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
21640			if ( ch === "\0" ) {
21641				return "\uFFFD";
21642			}
21643
21644			// Control characters and (dependent upon position) numbers get escaped as code points
21645			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
21646		}
21647
21648		// Other potentially-special ASCII characters get backslash-escaped
21649		return "\\" + ch;
21650	},
21651
21652	// Used for iframes
21653	// See setDocument()
21654	// Removing the function wrapper causes a "Permission Denied"
21655	// error in IE
21656	unloadHandler = function() {
21657		setDocument();
21658	},
21659
21660	inDisabledFieldset = addCombinator(
21661		function( elem ) {
21662			return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
21663		},
21664		{ dir: "parentNode", next: "legend" }
21665	);
21666
21667// Optimize for push.apply( _, NodeList )
21668try {
21669	push.apply(
21670		(arr = slice.call( preferredDoc.childNodes )),
21671		preferredDoc.childNodes
21672	);
21673	// Support: Android<4.0
21674	// Detect silently failing push.apply
21675	arr[ preferredDoc.childNodes.length ].nodeType;
21676} catch ( e ) {
21677	push = { apply: arr.length ?
21678
21679		// Leverage slice if possible
21680		function( target, els ) {
21681			push_native.apply( target, slice.call(els) );
21682		} :
21683
21684		// Support: IE<9
21685		// Otherwise append directly
21686		function( target, els ) {
21687			var j = target.length,
21688				i = 0;
21689			// Can't trust NodeList.length
21690			while ( (target[j++] = els[i++]) ) {}
21691			target.length = j - 1;
21692		}
21693	};
21694}
21695
21696function Sizzle( selector, context, results, seed ) {
21697	var m, i, elem, nid, match, groups, newSelector,
21698		newContext = context && context.ownerDocument,
21699
21700		// nodeType defaults to 9, since context defaults to document
21701		nodeType = context ? context.nodeType : 9;
21702
21703	results = results || [];
21704
21705	// Return early from calls with invalid selector or context
21706	if ( typeof selector !== "string" || !selector ||
21707		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
21708
21709		return results;
21710	}
21711
21712	// Try to shortcut find operations (as opposed to filters) in HTML documents
21713	if ( !seed ) {
21714
21715		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
21716			setDocument( context );
21717		}
21718		context = context || document;
21719
21720		if ( documentIsHTML ) {
21721
21722			// If the selector is sufficiently simple, try using a "get*By*" DOM method
21723			// (excepting DocumentFragment context, where the methods don't exist)
21724			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
21725
21726				// ID selector
21727				if ( (m = match[1]) ) {
21728
21729					// Document context
21730					if ( nodeType === 9 ) {
21731						if ( (elem = context.getElementById( m )) ) {
21732
vendor: 11,833 bytes, lines 21733-22140
21733							// Support: IE, Opera, Webkit
21734							// TODO: identify versions
21735							// getElementById can match elements by name instead of ID
21736							if ( elem.id === m ) {
21737								results.push( elem );
21738								return results;
21739							}
21740						} else {
21741							return results;
21742						}
21743
21744					// Element context
21745					} else {
21746
21747						// Support: IE, Opera, Webkit
21748						// TODO: identify versions
21749						// getElementById can match elements by name instead of ID
21750						if ( newContext && (elem = newContext.getElementById( m )) &&
21751							contains( context, elem ) &&
21752							elem.id === m ) {
21753
21754							results.push( elem );
21755							return results;
21756						}
21757					}
21758
21759				// Type selector
21760				} else if ( match[2] ) {
21761					push.apply( results, context.getElementsByTagName( selector ) );
21762					return results;
21763
21764				// Class selector
21765				} else if ( (m = match[3]) && support.getElementsByClassName &&
21766					context.getElementsByClassName ) {
21767
21768					push.apply( results, context.getElementsByClassName( m ) );
21769					return results;
21770				}
21771			}
21772
21773			// Take advantage of querySelectorAll
21774			if ( support.qsa &&
21775				!nonnativeSelectorCache[ selector + " " ] &&
21776				(!rbuggyQSA || !rbuggyQSA.test( selector )) &&
21777
21778				// Support: IE 8 only
21779				// Exclude object elements
21780				(nodeType !== 1 || context.nodeName.toLowerCase() !== "object") ) {
21781
21782				newSelector = selector;
21783				newContext = context;
21784
21785				// qSA considers elements outside a scoping root when evaluating child or
21786				// descendant combinators, which is not what we want.
21787				// In such cases, we work around the behavior by prefixing every selector in the
21788				// list with an ID selector referencing the scope context.
21789				// Thanks to Andrew Dupont for this technique.
21790				if ( nodeType === 1 && rdescend.test( selector ) ) {
21791
21792					// Capture the context ID, setting it first if necessary
21793					if ( (nid = context.getAttribute( "id" )) ) {
21794						nid = nid.replace( rcssescape, fcssescape );
21795					} else {
21796						context.setAttribute( "id", (nid = expando) );
21797					}
21798
21799					// Prefix every selector in the list
21800					groups = tokenize( selector );
21801					i = groups.length;
21802					while ( i-- ) {
21803						groups[i] = "#" + nid + " " + toSelector( groups[i] );
21804					}
21805					newSelector = groups.join( "," );
21806
21807					// Expand context for sibling selectors
21808					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
21809						context;
21810				}
21811
21812				try {
21813					push.apply( results,
21814						newContext.querySelectorAll( newSelector )
21815					);
21816					return results;
21817				} catch ( qsaError ) {
21818					nonnativeSelectorCache( selector, true );
21819				} finally {
21820					if ( nid === expando ) {
21821						context.removeAttribute( "id" );
21822					}
21823				}
21824			}
21825		}
21826	}
21827
21828	// All others
21829	return select( selector.replace( rtrim, "$1" ), context, results, seed );
21830}
21831
21832/**
21833 * Create key-value caches of limited size
21834 * @returns {function(string, object)} Returns the Object data after storing it on itself with
21835 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
21836 *	deleting the oldest entry
21837 */
21838function createCache() {
21839	var keys = [];
21840
21841	function cache( key, value ) {
21842		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
21843		if ( keys.push( key + " " ) > Expr.cacheLength ) {
21844			// Only keep the most recent entries
21845			delete cache[ keys.shift() ];
21846		}
21847		return (cache[ key + " " ] = value);
21848	}
21849	return cache;
21850}
21851
21852/**
21853 * Mark a function for special use by Sizzle
21854 * @param {Function} fn The function to mark
21855 */
21856function markFunction( fn ) {
21857	fn[ expando ] = true;
21858	return fn;
21859}
21860
21861/**
21862 * Support testing using an element
21863 * @param {Function} fn Passed the created element and returns a boolean result
21864 */
21865function assert( fn ) {
21866	var el = document.createElement("fieldset");
21867
21868	try {
21869		return !!fn( el );
21870	} catch (e) {
21871		return false;
21872	} finally {
21873		// Remove from its parent by default
21874		if ( el.parentNode ) {
21875			el.parentNode.removeChild( el );
21876		}
21877		// release memory in IE
21878		el = null;
21879	}
21880}
21881
21882/**
21883 * Adds the same handler for all of the specified attrs
21884 * @param {String} attrs Pipe-separated list of attributes
21885 * @param {Function} handler The method that will be applied
21886 */
21887function addHandle( attrs, handler ) {
21888	var arr = attrs.split("|"),
21889		i = arr.length;
21890
21891	while ( i-- ) {
21892		Expr.attrHandle[ arr[i] ] = handler;
21893	}
21894}
21895
21896/**
21897 * Checks document order of two siblings
21898 * @param {Element} a
21899 * @param {Element} b
21900 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
21901 */
21902function siblingCheck( a, b ) {
21903	var cur = b && a,
21904		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
21905			a.sourceIndex - b.sourceIndex;
21906
21907	// Use IE sourceIndex if available on both nodes
21908	if ( diff ) {
21909		return diff;
21910	}
21911
21912	// Check if b follows a
21913	if ( cur ) {
21914		while ( (cur = cur.nextSibling) ) {
21915			if ( cur === b ) {
21916				return -1;
21917			}
21918		}
21919	}
21920
21921	return a ? 1 : -1;
21922}
21923
21924/**
21925 * Returns a function to use in pseudos for input types
21926 * @param {String} type
21927 */
21928function createInputPseudo( type ) {
21929	return function( elem ) {
21930		var name = elem.nodeName.toLowerCase();
21931		return name === "input" && elem.type === type;
21932	};
21933}
21934
21935/**
21936 * Returns a function to use in pseudos for buttons
21937 * @param {String} type
21938 */
21939function createButtonPseudo( type ) {
21940	return function( elem ) {
21941		var name = elem.nodeName.toLowerCase();
21942		return (name === "input" || name === "button") && elem.type === type;
21943	};
21944}
21945
21946/**
21947 * Returns a function to use in pseudos for :enabled/:disabled
21948 * @param {Boolean} disabled true for :disabled; false for :enabled
21949 */
21950function createDisabledPseudo( disabled ) {
21951
21952	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
21953	return function( elem ) {
21954
21955		// Only certain elements can match :enabled or :disabled
21956		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
21957		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
21958		if ( "form" in elem ) {
21959
21960			// Check for inherited disabledness on relevant non-disabled elements:
21961			// * listed form-associated elements in a disabled fieldset
21962			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
21963			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
21964			// * option elements in a disabled optgroup
21965			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
21966			// All such elements have a "form" property.
21967			if ( elem.parentNode && elem.disabled === false ) {
21968
21969				// Option elements defer to a parent optgroup if present
21970				if ( "label" in elem ) {
21971					if ( "label" in elem.parentNode ) {
21972						return elem.parentNode.disabled === disabled;
21973					} else {
21974						return elem.disabled === disabled;
21975					}
21976				}
21977
21978				// Support: IE 6 - 11
21979				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
21980				return elem.isDisabled === disabled ||
21981
21982					// Where there is no isDisabled, check manually
21983					/* jshint -W018 */
21984					elem.isDisabled !== !disabled &&
21985						inDisabledFieldset( elem ) === disabled;
21986			}
21987
21988			return elem.disabled === disabled;
21989
21990		// Try to winnow out elements that can't be disabled before trusting the disabled property.
21991		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
21992		// even exist on them, let alone have a boolean value.
21993		} else if ( "label" in elem ) {
21994			return elem.disabled === disabled;
21995		}
21996
21997		// Remaining elements are neither :enabled nor :disabled
21998		return false;
21999	};
22000}
22001
22002/**
22003 * Returns a function to use in pseudos for positionals
22004 * @param {Function} fn
22005 */
22006function createPositionalPseudo( fn ) {
22007	return markFunction(function( argument ) {
22008		argument = +argument;
22009		return markFunction(function( seed, matches ) {
22010			var j,
22011				matchIndexes = fn( [], seed.length, argument ),
22012				i = matchIndexes.length;
22013
22014			// Match elements found at the specified indexes
22015			while ( i-- ) {
22016				if ( seed[ (j = matchIndexes[i]) ] ) {
22017					seed[j] = !(matches[j] = seed[j]);
22018				}
22019			}
22020		});
22021	});
22022}
22023
22024/**
22025 * Checks a node for validity as a Sizzle context
22026 * @param {Element|Object=} context
22027 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
22028 */
22029function testContext( context ) {
22030	return context && typeof context.getElementsByTagName !== "undefined" && context;
22031}
22032
22033// Expose support vars for convenience
22034support = Sizzle.support = {};
22035
22036/**
22037 * Detects XML nodes
22038 * @param {Element|Object} elem An element or a document
22039 * @returns {Boolean} True iff elem is a non-HTML XML node
22040 */
22041isXML = Sizzle.isXML = function( elem ) {
22042	var namespace = elem.namespaceURI,
22043		docElem = (elem.ownerDocument || elem).documentElement;
22044
22045	// Support: IE <=8
22046	// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
22047	// https://bugs.jquery.com/ticket/4833
22048	return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
22049};
22050
22051/**
22052 * Sets document-related variables once based on the current document
22053 * @param {Element|Object} [doc] An element or document object to use to set the document
22054 * @returns {Object} Returns the current document
22055 */
22056setDocument = Sizzle.setDocument = function( node ) {
22057	var hasCompare, subWindow,
22058		doc = node ? node.ownerDocument || node : preferredDoc;
22059
22060	// Return early if doc is invalid or already selected
22061	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
22062		return document;
22063	}
22064
22065	// Update global variables
22066	document = doc;
22067	docElem = document.documentElement;
22068	documentIsHTML = !isXML( document );
22069
22070	// Support: IE 9-11, Edge
22071	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
22072	if ( preferredDoc !== document &&
22073		(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
22074
22075		// Support: IE 11, Edge
22076		if ( subWindow.addEventListener ) {
22077			subWindow.addEventListener( "unload", unloadHandler, false );
22078
22079		// Support: IE 9 - 10 only
22080		} else if ( subWindow.attachEvent ) {
22081			subWindow.attachEvent( "onunload", unloadHandler );
22082		}
22083	}
22084
22085	/* Attributes
22086	---------------------------------------------------------------------- */
22087
22088	// Support: IE<8
22089	// Verify that getAttribute really returns attributes and not properties
22090	// (excepting IE8 booleans)
22091	support.attributes = assert(function( el ) {
22092		el.className = "i";
22093		return !el.getAttribute("className");
22094	});
22095
22096	/* getElement(s)By*
22097	---------------------------------------------------------------------- */
22098
22099	// Check if getElementsByTagName("*") returns only elements
22100	support.getElementsByTagName = assert(function( el ) {
22101		el.appendChild( document.createComment("") );
22102		return !el.getElementsByTagName("*").length;
22103	});
22104
22105	// Support: IE<9
22106	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
22107
22108	// Support: IE<10
22109	// Check if getElementById returns elements by name
22110	// The broken getElementById methods don't pick up programmatically-set names,
22111	// so use a roundabout getElementsByName test
22112	support.getById = assert(function( el ) {
22113		docElem.appendChild( el ).id = expando;
22114		return !document.getElementsByName || !document.getElementsByName( expando ).length;
22115	});
22116
22117	// ID filter and find
22118	if ( support.getById ) {
22119		Expr.filter["ID"] = function( id ) {
22120			var attrId = id.replace( runescape, funescape );
22121			return function( elem ) {
22122				return elem.getAttribute("id") === attrId;
22123			};
22124		};
22125		Expr.find["ID"] = function( id, context ) {
22126			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
22127				var elem = context.getElementById( id );
22128				return elem ? [ elem ] : [];
22129			}
22130		};
22131	} else {
22132		Expr.filter["ID"] =  function( id ) {
22133			var attrId = id.replace( runescape, funescape );
22134			return function( elem ) {
22135				var node = typeof elem.getAttributeNode !== "undefined" &&
22136					elem.getAttributeNode("id");
22137				return node && node.value === attrId;
22138			};
22139		};
22140
vendor: 4,318 bytes, lines 22141-22276
22141		// Support: IE 6 - 7 only
22142		// getElementById is not reliable as a find shortcut
22143		Expr.find["ID"] = function( id, context ) {
22144			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
22145				var node, i, elems,
22146					elem = context.getElementById( id );
22147
22148				if ( elem ) {
22149
22150					// Verify the id attribute
22151					node = elem.getAttributeNode("id");
22152					if ( node && node.value === id ) {
22153						return [ elem ];
22154					}
22155
22156					// Fall back on getElementsByName
22157					elems = context.getElementsByName( id );
22158					i = 0;
22159					while ( (elem = elems[i++]) ) {
22160						node = elem.getAttributeNode("id");
22161						if ( node && node.value === id ) {
22162							return [ elem ];
22163						}
22164					}
22165				}
22166
22167				return [];
22168			}
22169		};
22170	}
22171
22172	// Tag
22173	Expr.find["TAG"] = support.getElementsByTagName ?
22174		function( tag, context ) {
22175			if ( typeof context.getElementsByTagName !== "undefined" ) {
22176				return context.getElementsByTagName( tag );
22177
22178			// DocumentFragment nodes don't have gEBTN
22179			} else if ( support.qsa ) {
22180				return context.querySelectorAll( tag );
22181			}
22182		} :
22183
22184		function( tag, context ) {
22185			var elem,
22186				tmp = [],
22187				i = 0,
22188				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
22189				results = context.getElementsByTagName( tag );
22190
22191			// Filter out possible comments
22192			if ( tag === "*" ) {
22193				while ( (elem = results[i++]) ) {
22194					if ( elem.nodeType === 1 ) {
22195						tmp.push( elem );
22196					}
22197				}
22198
22199				return tmp;
22200			}
22201			return results;
22202		};
22203
22204	// Class
22205	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
22206		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
22207			return context.getElementsByClassName( className );
22208		}
22209	};
22210
22211	/* QSA/matchesSelector
22212	---------------------------------------------------------------------- */
22213
22214	// QSA and matchesSelector support
22215
22216	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
22217	rbuggyMatches = [];
22218
22219	// qSa(:focus) reports false when true (Chrome 21)
22220	// We allow this because of a bug in IE8/9 that throws an error
22221	// whenever `document.activeElement` is accessed on an iframe
22222	// So, we allow :focus to pass through QSA all the time to avoid the IE error
22223	// See https://bugs.jquery.com/ticket/13378
22224	rbuggyQSA = [];
22225
22226	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
22227		// Build QSA regex
22228		// Regex strategy adopted from Diego Perini
22229		assert(function( el ) {
22230			// Select is set to empty string on purpose
22231			// This is to test IE's treatment of not explicitly
22232			// setting a boolean content attribute,
22233			// since its presence should be enough
22234			// https://bugs.jquery.com/ticket/12359
22235			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
22236				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
22237				"<option selected=''></option></select>";
22238
22239			// Support: IE8, Opera 11-12.16
22240			// Nothing should be selected when empty strings follow ^= or $= or *=
22241			// The test attribute must be unknown in Opera but "safe" for WinRT
22242			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
22243			if ( el.querySelectorAll("[msallowcapture^='']").length ) {
22244				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
22245			}
22246
22247			// Support: IE8
22248			// Boolean attributes and "value" are not treated correctly
22249			if ( !el.querySelectorAll("[selected]").length ) {
22250				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
22251			}
22252
22253			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
22254			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
22255				rbuggyQSA.push("~=");
22256			}
22257
22258			// Webkit/Opera - :checked should return selected option elements
22259			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
22260			// IE8 throws error here and will not see later tests
22261			if ( !el.querySelectorAll(":checked").length ) {
22262				rbuggyQSA.push(":checked");
22263			}
22264
22265			// Support: Safari 8+, iOS 8+
22266			// https://bugs.webkit.org/show_bug.cgi?id=136851
22267			// In-page `selector#id sibling-combinator selector` fails
22268			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
22269				rbuggyQSA.push(".#.+[+~]");
22270			}
22271		});
22272
22273		assert(function( el ) {
22274			el.innerHTML = "<a href='' disabled='disabled'></a>" +
22275				"<select disabled='disabled'><option/></select>";
22276
vendor: 6,799 bytes, lines 22277-22523
22277			// Support: Windows 8 Native Apps
22278			// The type and name attributes are restricted during .innerHTML assignment
22279			var input = document.createElement("input");
22280			input.setAttribute( "type", "hidden" );
22281			el.appendChild( input ).setAttribute( "name", "D" );
22282
22283			// Support: IE8
22284			// Enforce case-sensitivity of name attribute
22285			if ( el.querySelectorAll("[name=d]").length ) {
22286				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
22287			}
22288
22289			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
22290			// IE8 throws error here and will not see later tests
22291			if ( el.querySelectorAll(":enabled").length !== 2 ) {
22292				rbuggyQSA.push( ":enabled", ":disabled" );
22293			}
22294
22295			// Support: IE9-11+
22296			// IE's :disabled selector does not pick up the children of disabled fieldsets
22297			docElem.appendChild( el ).disabled = true;
22298			if ( el.querySelectorAll(":disabled").length !== 2 ) {
22299				rbuggyQSA.push( ":enabled", ":disabled" );
22300			}
22301
22302			// Opera 10-11 does not throw on post-comma invalid pseudos
22303			el.querySelectorAll("*,:x");
22304			rbuggyQSA.push(",.*:");
22305		});
22306	}
22307
22308	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
22309		docElem.webkitMatchesSelector ||
22310		docElem.mozMatchesSelector ||
22311		docElem.oMatchesSelector ||
22312		docElem.msMatchesSelector) )) ) {
22313
22314		assert(function( el ) {
22315			// Check to see if it's possible to do matchesSelector
22316			// on a disconnected node (IE 9)
22317			support.disconnectedMatch = matches.call( el, "*" );
22318
22319			// This should fail with an exception
22320			// Gecko does not error, returns false instead
22321			matches.call( el, "[s!='']:x" );
22322			rbuggyMatches.push( "!=", pseudos );
22323		});
22324	}
22325
22326	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
22327	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
22328
22329	/* Contains
22330	---------------------------------------------------------------------- */
22331	hasCompare = rnative.test( docElem.compareDocumentPosition );
22332
22333	// Element contains another
22334	// Purposefully self-exclusive
22335	// As in, an element does not contain itself
22336	contains = hasCompare || rnative.test( docElem.contains ) ?
22337		function( a, b ) {
22338			var adown = a.nodeType === 9 ? a.documentElement : a,
22339				bup = b && b.parentNode;
22340			return a === bup || !!( bup && bup.nodeType === 1 && (
22341				adown.contains ?
22342					adown.contains( bup ) :
22343					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
22344			));
22345		} :
22346		function( a, b ) {
22347			if ( b ) {
22348				while ( (b = b.parentNode) ) {
22349					if ( b === a ) {
22350						return true;
22351					}
22352				}
22353			}
22354			return false;
22355		};
22356
22357	/* Sorting
22358	---------------------------------------------------------------------- */
22359
22360	// Document order sorting
22361	sortOrder = hasCompare ?
22362	function( a, b ) {
22363
22364		// Flag for duplicate removal
22365		if ( a === b ) {
22366			hasDuplicate = true;
22367			return 0;
22368		}
22369
22370		// Sort on method existence if only one input has compareDocumentPosition
22371		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
22372		if ( compare ) {
22373			return compare;
22374		}
22375
22376		// Calculate position if both inputs belong to the same document
22377		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
22378			a.compareDocumentPosition( b ) :
22379
22380			// Otherwise we know they are disconnected
22381			1;
22382
22383		// Disconnected nodes
22384		if ( compare & 1 ||
22385			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
22386
22387			// Choose the first element that is related to our preferred document
22388			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
22389				return -1;
22390			}
22391			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
22392				return 1;
22393			}
22394
22395			// Maintain original order
22396			return sortInput ?
22397				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
22398				0;
22399		}
22400
22401		return compare & 4 ? -1 : 1;
22402	} :
22403	function( a, b ) {
22404		// Exit early if the nodes are identical
22405		if ( a === b ) {
22406			hasDuplicate = true;
22407			return 0;
22408		}
22409
22410		var cur,
22411			i = 0,
22412			aup = a.parentNode,
22413			bup = b.parentNode,
22414			ap = [ a ],
22415			bp = [ b ];
22416
22417		// Parentless nodes are either documents or disconnected
22418		if ( !aup || !bup ) {
22419			return a === document ? -1 :
22420				b === document ? 1 :
22421				aup ? -1 :
22422				bup ? 1 :
22423				sortInput ?
22424				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
22425				0;
22426
22427		// If the nodes are siblings, we can do a quick check
22428		} else if ( aup === bup ) {
22429			return siblingCheck( a, b );
22430		}
22431
22432		// Otherwise we need full lists of their ancestors for comparison
22433		cur = a;
22434		while ( (cur = cur.parentNode) ) {
22435			ap.unshift( cur );
22436		}
22437		cur = b;
22438		while ( (cur = cur.parentNode) ) {
22439			bp.unshift( cur );
22440		}
22441
22442		// Walk down the tree looking for a discrepancy
22443		while ( ap[i] === bp[i] ) {
22444			i++;
22445		}
22446
22447		return i ?
22448			// Do a sibling check if the nodes have a common ancestor
22449			siblingCheck( ap[i], bp[i] ) :
22450
22451			// Otherwise nodes in our document sort first
22452			ap[i] === preferredDoc ? -1 :
22453			bp[i] === preferredDoc ? 1 :
22454			0;
22455	};
22456
22457	return document;
22458};
22459
22460Sizzle.matches = function( expr, elements ) {
22461	return Sizzle( expr, null, null, elements );
22462};
22463
22464Sizzle.matchesSelector = function( elem, expr ) {
22465	// Set document vars if needed
22466	if ( ( elem.ownerDocument || elem ) !== document ) {
22467		setDocument( elem );
22468	}
22469
22470	if ( support.matchesSelector && documentIsHTML &&
22471		!nonnativeSelectorCache[ expr + " " ] &&
22472		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
22473		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
22474
22475		try {
22476			var ret = matches.call( elem, expr );
22477
22478			// IE 9's matchesSelector returns false on disconnected nodes
22479			if ( ret || support.disconnectedMatch ||
22480					// As well, disconnected nodes are said to be in a document
22481					// fragment in IE 9
22482					elem.document && elem.document.nodeType !== 11 ) {
22483				return ret;
22484			}
22485		} catch (e) {
22486			nonnativeSelectorCache( expr, true );
22487		}
22488	}
22489
22490	return Sizzle( expr, document, null, [ elem ] ).length > 0;
22491};
22492
22493Sizzle.contains = function( context, elem ) {
22494	// Set document vars if needed
22495	if ( ( context.ownerDocument || context ) !== document ) {
22496		setDocument( context );
22497	}
22498	return contains( context, elem );
22499};
22500
22501Sizzle.attr = function( elem, name ) {
22502	// Set document vars if needed
22503	if ( ( elem.ownerDocument || elem ) !== document ) {
22504		setDocument( elem );
22505	}
22506
22507	var fn = Expr.attrHandle[ name.toLowerCase() ],
22508		// Don't get fooled by Object.prototype properties (jQuery #13807)
22509		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
22510			fn( elem, name, !documentIsHTML ) :
22511			undefined;
22512
22513	return val !== undefined ?
22514		val :
22515		support.attributes || !documentIsHTML ?
22516			elem.getAttribute( name ) :
22517			(val = elem.getAttributeNode(name)) && val.specified ?
22518				val.value :
22519				null;
22520};
22521
22522Sizzle.escape = function( sel ) {
22523	return (sel + "").replace( rcssescape, fcssescape )
vendor: 11,991 bytes, lines 22523-22946
22523;
22524};
22525
22526Sizzle.error = function( msg ) {
22527	throw new Error( "Syntax error, unrecognized expression: " + msg );
22528};
22529
22530/**
22531 * Document sorting and removing duplicates
22532 * @param {ArrayLike} results
22533 */
22534Sizzle.uniqueSort = function( results ) {
22535	var elem,
22536		duplicates = [],
22537		j = 0,
22538		i = 0;
22539
22540	// Unless we *know* we can detect duplicates, assume their presence
22541	hasDuplicate = !support.detectDuplicates;
22542	sortInput = !support.sortStable && results.slice( 0 );
22543	results.sort( sortOrder );
22544
22545	if ( hasDuplicate ) {
22546		while ( (elem = results[i++]) ) {
22547			if ( elem === results[ i ] ) {
22548				j = duplicates.push( i );
22549			}
22550		}
22551		while ( j-- ) {
22552			results.splice( duplicates[ j ], 1 );
22553		}
22554	}
22555
22556	// Clear input after sorting to release objects
22557	// See https://github.com/jquery/sizzle/pull/225
22558	sortInput = null;
22559
22560	return results;
22561};
22562
22563/**
22564 * Utility function for retrieving the text value of an array of DOM nodes
22565 * @param {Array|Element} elem
22566 */
22567getText = Sizzle.getText = function( elem ) {
22568	var node,
22569		ret = "",
22570		i = 0,
22571		nodeType = elem.nodeType;
22572
22573	if ( !nodeType ) {
22574		// If no nodeType, this is expected to be an array
22575		while ( (node = elem[i++]) ) {
22576			// Do not traverse comment nodes
22577			ret += getText( node );
22578		}
22579	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
22580		// Use textContent for elements
22581		// innerText usage removed for consistency of new lines (jQuery #11153)
22582		if ( typeof elem.textContent === "string" ) {
22583			return elem.textContent;
22584		} else {
22585			// Traverse its children
22586			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
22587				ret += getText( elem );
22588			}
22589		}
22590	} else if ( nodeType === 3 || nodeType === 4 ) {
22591		return elem.nodeValue;
22592	}
22593	// Do not include comment or processing instruction nodes
22594
22595	return ret;
22596};
22597
22598Expr = Sizzle.selectors = {
22599
22600	// Can be adjusted by the user
22601	cacheLength: 50,
22602
22603	createPseudo: markFunction,
22604
22605	match: matchExpr,
22606
22607	attrHandle: {},
22608
22609	find: {},
22610
22611	relative: {
22612		">": { dir: "parentNode", first: true },
22613		" ": { dir: "parentNode" },
22614		"+": { dir: "previousSibling", first: true },
22615		"~": { dir: "previousSibling" }
22616	},
22617
22618	preFilter: {
22619		"ATTR": function( match ) {
22620			match[1] = match[1].replace( runescape, funescape );
22621
22622			// Move the given value to match[3] whether quoted or unquoted
22623			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
22624
22625			if ( match[2] === "~=" ) {
22626				match[3] = " " + match[3] + " ";
22627			}
22628
22629			return match.slice( 0, 4 );
22630		},
22631
22632		"CHILD": function( match ) {
22633			/* matches from matchExpr["CHILD"]
22634				1 type (only|nth|...)
22635				2 what (child|of-type)
22636				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
22637				4 xn-component of xn+y argument ([+-]?\d*n|)
22638				5 sign of xn-component
22639				6 x of xn-component
22640				7 sign of y-component
22641				8 y of y-component
22642			*/
22643			match[1] = match[1].toLowerCase();
22644
22645			if ( match[1].slice( 0, 3 ) === "nth" ) {
22646				// nth-* requires argument
22647				if ( !match[3] ) {
22648					Sizzle.error( match[0] );
22649				}
22650
22651				// numeric x and y parameters for Expr.filter.CHILD
22652				// remember that false/true cast respectively to 0/1
22653				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
22654				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
22655
22656			// other types prohibit arguments
22657			} else if ( match[3] ) {
22658				Sizzle.error( match[0] );
22659			}
22660
22661			return match;
22662		},
22663
22664		"PSEUDO": function( match ) {
22665			var excess,
22666				unquoted = !match[6] && match[2];
22667
22668			if ( matchExpr["CHILD"].test( match[0] ) ) {
22669				return null;
22670			}
22671
22672			// Accept quoted arguments as-is
22673			if ( match[3] ) {
22674				match[2] = match[4] || match[5] || "";
22675
22676			// Strip excess characters from unquoted arguments
22677			} else if ( unquoted && rpseudo.test( unquoted ) &&
22678				// Get excess from tokenize (recursively)
22679				(excess = tokenize( unquoted, true )) &&
22680				// advance to the next closing parenthesis
22681				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
22682
22683				// excess is a negative index
22684				match[0] = match[0].slice( 0, excess );
22685				match[2] = unquoted.slice( 0, excess );
22686			}
22687
22688			// Return only captures needed by the pseudo filter method (type and argument)
22689			return match.slice( 0, 3 );
22690		}
22691	},
22692
22693	filter: {
22694
22695		"TAG": function( nodeNameSelector ) {
22696			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
22697			return nodeNameSelector === "*" ?
22698				function() { return true; } :
22699				function( elem ) {
22700					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
22701				};
22702		},
22703
22704		"CLASS": function( className ) {
22705			var pattern = classCache[ className + " " ];
22706
22707			return pattern ||
22708				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
22709				classCache( className, function( elem ) {
22710					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
22711				});
22712		},
22713
22714		"ATTR": function( name, operator, check ) {
22715			return function( elem ) {
22716				var result = Sizzle.attr( elem, name );
22717
22718				if ( result == null ) {
22719					return operator === "!=";
22720				}
22721				if ( !operator ) {
22722					return true;
22723				}
22724
22725				result += "";
22726
22727				return operator === "=" ? result === check :
22728					operator === "!=" ? result !== check :
22729					operator === "^=" ? check && result.indexOf( check ) === 0 :
22730					operator === "*=" ? check && result.indexOf( check ) > -1 :
22731					operator === "$=" ? check && result.slice( -check.length ) === check :
22732					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
22733					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
22734					false;
22735			};
22736		},
22737
22738		"CHILD": function( type, what, argument, first, last ) {
22739			var simple = type.slice( 0, 3 ) !== "nth",
22740				forward = type.slice( -4 ) !== "last",
22741				ofType = what === "of-type";
22742
22743			return first === 1 && last === 0 ?
22744
22745				// Shortcut for :nth-*(n)
22746				function( elem ) {
22747					return !!elem.parentNode;
22748				} :
22749
22750				function( elem, context, xml ) {
22751					var cache, uniqueCache, outerCache, node, nodeIndex, start,
22752						dir = simple !== forward ? "nextSibling" : "previousSibling",
22753						parent = elem.parentNode,
22754						name = ofType && elem.nodeName.toLowerCase(),
22755						useCache = !xml && !ofType,
22756						diff = false;
22757
22758					if ( parent ) {
22759
22760						// :(first|last|only)-(child|of-type)
22761						if ( simple ) {
22762							while ( dir ) {
22763								node = elem;
22764								while ( (node = node[ dir ]) ) {
22765									if ( ofType ?
22766										node.nodeName.toLowerCase() === name :
22767										node.nodeType === 1 ) {
22768
22769										return false;
22770									}
22771								}
22772								// Reverse direction for :only-* (if we haven't yet done so)
22773								start = dir = type === "only" && !start && "nextSibling";
22774							}
22775							return true;
22776						}
22777
22778						start = [ forward ? parent.firstChild : parent.lastChild ];
22779
22780						// non-xml :nth-child(...) stores cache data on `parent`
22781						if ( forward && useCache ) {
22782
22783							// Seek `elem` from a previously-cached index
22784
22785							// ...in a gzip-friendly way
22786							node = parent;
22787							outerCache = node[ expando ] || (node[ expando ] = {});
22788
22789							// Support: IE <9 only
22790							// Defend against cloned attroperties (jQuery gh-1709)
22791							uniqueCache = outerCache[ node.uniqueID ] ||
22792								(outerCache[ node.uniqueID ] = {});
22793
22794							cache = uniqueCache[ type ] || [];
22795							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
22796							diff = nodeIndex && cache[ 2 ];
22797							node = nodeIndex && parent.childNodes[ nodeIndex ];
22798
22799							while ( (node = ++nodeIndex && node && node[ dir ] ||
22800
22801								// Fallback to seeking `elem` from the start
22802								(diff = nodeIndex = 0) || start.pop()) ) {
22803
22804								// When found, cache indexes on `parent` and break
22805								if ( node.nodeType === 1 && ++diff && node === elem ) {
22806									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
22807									break;
22808								}
22809							}
22810
22811						} else {
22812							// Use previously-cached element index if available
22813							if ( useCache ) {
22814								// ...in a gzip-friendly way
22815								node = elem;
22816								outerCache = node[ expando ] || (node[ expando ] = {});
22817
22818								// Support: IE <9 only
22819								// Defend against cloned attroperties (jQuery gh-1709)
22820								uniqueCache = outerCache[ node.uniqueID ] ||
22821									(outerCache[ node.uniqueID ] = {});
22822
22823								cache = uniqueCache[ type ] || [];
22824								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
22825								diff = nodeIndex;
22826							}
22827
22828							// xml :nth-child(...)
22829							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
22830							if ( diff === false ) {
22831								// Use the same loop as above to seek `elem` from the start
22832								while ( (node = ++nodeIndex && node && node[ dir ] ||
22833									(diff = nodeIndex = 0) || start.pop()) ) {
22834
22835									if ( ( ofType ?
22836										node.nodeName.toLowerCase() === name :
22837										node.nodeType === 1 ) &&
22838										++diff ) {
22839
22840										// Cache the index of each encountered element
22841										if ( useCache ) {
22842											outerCache = node[ expando ] || (node[ expando ] = {});
22843
22844											// Support: IE <9 only
22845											// Defend against cloned attroperties (jQuery gh-1709)
22846											uniqueCache = outerCache[ node.uniqueID ] ||
22847												(outerCache[ node.uniqueID ] = {});
22848
22849											uniqueCache[ type ] = [ dirruns, diff ];
22850										}
22851
22852										if ( node === elem ) {
22853											break;
22854										}
22855									}
22856								}
22857							}
22858						}
22859
22860						// Incorporate the offset, then check against cycle size
22861						diff -= last;
22862						return diff === first || ( diff % first === 0 && diff / first >= 0 );
22863					}
22864				};
22865		},
22866
22867		"PSEUDO": function( pseudo, argument ) {
22868			// pseudo-class names are case-insensitive
22869			// http://www.w3.org/TR/selectors/#pseudo-classes
22870			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
22871			// Remember that setFilters inherits from pseudos
22872			var args,
22873				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
22874					Sizzle.error( "unsupported pseudo: " + pseudo );
22875
22876			// The user may use createPseudo to indicate that
22877			// arguments are needed to create the filter function
22878			// just as Sizzle does
22879			if ( fn[ expando ] ) {
22880				return fn( argument );
22881			}
22882
22883			// But maintain support for old signatures
22884			if ( fn.length > 1 ) {
22885				args = [ pseudo, pseudo, "", argument ];
22886				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
22887					markFunction(function( seed, matches ) {
22888						var idx,
22889							matched = fn( seed, argument ),
22890							i = matched.length;
22891						while ( i-- ) {
22892							idx = indexOf( seed, matched[i] );
22893							seed[ idx ] = !( matches[ idx ] = matched[i] );
22894						}
22895					}) :
22896					function( elem ) {
22897						return fn( elem, 0, args );
22898					};
22899			}
22900
22901			return fn;
22902		}
22903	},
22904
22905	pseudos: {
22906		// Potentially complex pseudos
22907		"not": markFunction(function( selector ) {
22908			// Trim the selector passed to compile
22909			// to avoid treating leading and trailing
22910			// spaces as combinators
22911			var input = [],
22912				results = [],
22913				matcher = compile( selector.replace( rtrim, "$1" ) );
22914
22915			return matcher[ expando ] ?
22916				markFunction(function( seed, matches, context, xml ) {
22917					var elem,
22918						unmatched = matcher( seed, null, xml, [] ),
22919						i = seed.length;
22920
22921					// Match elements unmatched by `matcher`
22922					while ( i-- ) {
22923						if ( (elem = unmatched[i]) ) {
22924							seed[i] = !(matches[i] = elem);
22925						}
22926					}
22927				}) :
22928				function( elem, context, xml ) {
22929					input[0] = elem;
22930					matcher( input, null, xml, results );
22931					// Don't keep the element (issue #299)
22932					input[0] = null;
22933					return !results.pop();
22934				};
22935		}),
22936
22937		"has": markFunction(function( selector ) {
22938			return function( elem ) {
22939				return Sizzle( selector, elem ).length > 0;
22940			};
22941		}),
22942
22943		"contains": markFunction(function( text ) {
22944			text = text.replace( runescape, funescape );
22945			return function( elem ) {
22946				return ( elem.textContent || 
vendor: 1,115 bytes, lines 22946-22974
22946getText( elem ) ).indexOf( text ) > -1;
22947			};
22948		}),
22949
22950		// "Whether an element is represented by a :lang() selector
22951		// is based solely on the element's language value
22952		// being equal to the identifier C,
22953		// or beginning with the identifier C immediately followed by "-".
22954		// The matching of C against the element's language value is performed case-insensitively.
22955		// The identifier C does not have to be a valid language name."
22956		// http://www.w3.org/TR/selectors/#lang-pseudo
22957		"lang": markFunction( function( lang ) {
22958			// lang value must be a valid identifier
22959			if ( !ridentifier.test(lang || "") ) {
22960				Sizzle.error( "unsupported lang: " + lang );
22961			}
22962			lang = lang.replace( runescape, funescape ).toLowerCase();
22963			return function( elem ) {
22964				var elemLang;
22965				do {
22966					if ( (elemLang = documentIsHTML ?
22967						elem.lang :
22968						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
22969
22970						elemLang = elemLang.toLowerCase();
22971						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
22972					}
22973				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
22974				return false;
vendor: 3,169 bytes, lines 22975-23089
22975			};
22976		}),
22977
22978		// Miscellaneous
22979		"target": function( elem ) {
22980			var hash = window.location && window.location.hash;
22981			return hash && hash.slice( 1 ) === elem.id;
22982		},
22983
22984		"root": function( elem ) {
22985			return elem === docElem;
22986		},
22987
22988		"focus": function( elem ) {
22989			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
22990		},
22991
22992		// Boolean properties
22993		"enabled": createDisabledPseudo( false ),
22994		"disabled": createDisabledPseudo( true ),
22995
22996		"checked": function( elem ) {
22997			// In CSS3, :checked should return both checked and selected elements
22998			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
22999			var nodeName = elem.nodeName.toLowerCase();
23000			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
23001		},
23002
23003		"selected": function( elem ) {
23004			// Accessing this property makes selected-by-default
23005			// options in Safari work properly
23006			if ( elem.parentNode ) {
23007				elem.parentNode.selectedIndex;
23008			}
23009
23010			return elem.selected === true;
23011		},
23012
23013		// Contents
23014		"empty": function( elem ) {
23015			// http://www.w3.org/TR/selectors/#empty-pseudo
23016			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
23017			//   but not by others (comment: 8; processing instruction: 7; etc.)
23018			// nodeType < 6 works because attributes (2) do not appear as children
23019			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
23020				if ( elem.nodeType < 6 ) {
23021					return false;
23022				}
23023			}
23024			return true;
23025		},
23026
23027		"parent": function( elem ) {
23028			return !Expr.pseudos["empty"]( elem );
23029		},
23030
23031		// Element/input types
23032		"header": function( elem ) {
23033			return rheader.test( elem.nodeName );
23034		},
23035
23036		"input": function( elem ) {
23037			return rinputs.test( elem.nodeName );
23038		},
23039
23040		"button": function( elem ) {
23041			var name = elem.nodeName.toLowerCase();
23042			return name === "input" && elem.type === "button" || name === "button";
23043		},
23044
23045		"text": function( elem ) {
23046			var attr;
23047			return elem.nodeName.toLowerCase() === "input" &&
23048				elem.type === "text" &&
23049
23050				// Support: IE<8
23051				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
23052				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
23053		},
23054
23055		// Position-in-collection
23056		"first": createPositionalPseudo(function() {
23057			return [ 0 ];
23058		}),
23059
23060		"last": createPositionalPseudo(function( matchIndexes, length ) {
23061			return [ length - 1 ];
23062		}),
23063
23064		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
23065			return [ argument < 0 ? argument + length : argument ];
23066		}),
23067
23068		"even": createPositionalPseudo(function( matchIndexes, length ) {
23069			var i = 0;
23070			for ( ; i < length; i += 2 ) {
23071				matchIndexes.push( i );
23072			}
23073			return matchIndexes;
23074		}),
23075
23076		"odd": createPositionalPseudo(function( matchIndexes, length ) {
23077			var i = 1;
23078			for ( ; i < length; i += 2 ) {
23079				matchIndexes.push( i );
23080			}
23081			return matchIndexes;
23082		}),
23083
23084		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
23085			var i = argument < 0 ?
23086				argument + length :
23087				argument > length ?
23088					length :
23089					
vendor: 20,845 bytes, lines 23089-23850
23089argument;
23090			for ( ; --i >= 0; ) {
23091				matchIndexes.push( i );
23092			}
23093			return matchIndexes;
23094		}),
23095
23096		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
23097			var i = argument < 0 ? argument + length : argument;
23098			for ( ; ++i < length; ) {
23099				matchIndexes.push( i );
23100			}
23101			return matchIndexes;
23102		})
23103	}
23104};
23105
23106Expr.pseudos["nth"] = Expr.pseudos["eq"];
23107
23108// Add button/input type pseudos
23109for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
23110	Expr.pseudos[ i ] = createInputPseudo( i );
23111}
23112for ( i in { submit: true, reset: true } ) {
23113	Expr.pseudos[ i ] = createButtonPseudo( i );
23114}
23115
23116// Easy API for creating new setFilters
23117function setFilters() {}
23118setFilters.prototype = Expr.filters = Expr.pseudos;
23119Expr.setFilters = new setFilters();
23120
23121tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
23122	var matched, match, tokens, type,
23123		soFar, groups, preFilters,
23124		cached = tokenCache[ selector + " " ];
23125
23126	if ( cached ) {
23127		return parseOnly ? 0 : cached.slice( 0 );
23128	}
23129
23130	soFar = selector;
23131	groups = [];
23132	preFilters = Expr.preFilter;
23133
23134	while ( soFar ) {
23135
23136		// Comma and first run
23137		if ( !matched || (match = rcomma.exec( soFar )) ) {
23138			if ( match ) {
23139				// Don't consume trailing commas as valid
23140				soFar = soFar.slice( match[0].length ) || soFar;
23141			}
23142			groups.push( (tokens = []) );
23143		}
23144
23145		matched = false;
23146
23147		// Combinators
23148		if ( (match = rcombinators.exec( soFar )) ) {
23149			matched = match.shift();
23150			tokens.push({
23151				value: matched,
23152				// Cast descendant combinators to space
23153				type: match[0].replace( rtrim, " " )
23154			});
23155			soFar = soFar.slice( matched.length );
23156		}
23157
23158		// Filters
23159		for ( type in Expr.filter ) {
23160			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
23161				(match = preFilters[ type ]( match ))) ) {
23162				matched = match.shift();
23163				tokens.push({
23164					value: matched,
23165					type: type,
23166					matches: match
23167				});
23168				soFar = soFar.slice( matched.length );
23169			}
23170		}
23171
23172		if ( !matched ) {
23173			break;
23174		}
23175	}
23176
23177	// Return the length of the invalid excess
23178	// if we're just parsing
23179	// Otherwise, throw an error or return tokens
23180	return parseOnly ?
23181		soFar.length :
23182		soFar ?
23183			Sizzle.error( selector ) :
23184			// Cache the tokens
23185			tokenCache( selector, groups ).slice( 0 );
23186};
23187
23188function toSelector( tokens ) {
23189	var i = 0,
23190		len = tokens.length,
23191		selector = "";
23192	for ( ; i < len; i++ ) {
23193		selector += tokens[i].value;
23194	}
23195	return selector;
23196}
23197
23198function addCombinator( matcher, combinator, base ) {
23199	var dir = combinator.dir,
23200		skip = combinator.next,
23201		key = skip || dir,
23202		checkNonElements = base && key === "parentNode",
23203		doneName = done++;
23204
23205	return combinator.first ?
23206		// Check against closest ancestor/preceding element
23207		function( elem, context, xml ) {
23208			while ( (elem = elem[ dir ]) ) {
23209				if ( elem.nodeType === 1 || checkNonElements ) {
23210					return matcher( elem, context, xml );
23211				}
23212			}
23213			return false;
23214		} :
23215
23216		// Check against all ancestor/preceding elements
23217		function( elem, context, xml ) {
23218			var oldCache, uniqueCache, outerCache,
23219				newCache = [ dirruns, doneName ];
23220
23221			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
23222			if ( xml ) {
23223				while ( (elem = elem[ dir ]) ) {
23224					if ( elem.nodeType === 1 || checkNonElements ) {
23225						if ( matcher( elem, context, xml ) ) {
23226							return true;
23227						}
23228					}
23229				}
23230			} else {
23231				while ( (elem = elem[ dir ]) ) {
23232					if ( elem.nodeType === 1 || checkNonElements ) {
23233						outerCache = elem[ expando ] || (elem[ expando ] = {});
23234
23235						// Support: IE <9 only
23236						// Defend against cloned attroperties (jQuery gh-1709)
23237						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
23238
23239						if ( skip && skip === elem.nodeName.toLowerCase() ) {
23240							elem = elem[ dir ] || elem;
23241						} else if ( (oldCache = uniqueCache[ key ]) &&
23242							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
23243
23244							// Assign to newCache so results back-propagate to previous elements
23245							return (newCache[ 2 ] = oldCache[ 2 ]);
23246						} else {
23247							// Reuse newcache so results back-propagate to previous elements
23248							uniqueCache[ key ] = newCache;
23249
23250							// A match means we're done; a fail means we have to keep checking
23251							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
23252								return true;
23253							}
23254						}
23255					}
23256				}
23257			}
23258			return false;
23259		};
23260}
23261
23262function elementMatcher( matchers ) {
23263	return matchers.length > 1 ?
23264		function( elem, context, xml ) {
23265			var i = matchers.length;
23266			while ( i-- ) {
23267				if ( !matchers[i]( elem, context, xml ) ) {
23268					return false;
23269				}
23270			}
23271			return true;
23272		} :
23273		matchers[0];
23274}
23275
23276function multipleContexts( selector, contexts, results ) {
23277	var i = 0,
23278		len = contexts.length;
23279	for ( ; i < len; i++ ) {
23280		Sizzle( selector, contexts[i], results );
23281	}
23282	return results;
23283}
23284
23285function condense( unmatched, map, filter, context, xml ) {
23286	var elem,
23287		newUnmatched = [],
23288		i = 0,
23289		len = unmatched.length,
23290		mapped = map != null;
23291
23292	for ( ; i < len; i++ ) {
23293		if ( (elem = unmatched[i]) ) {
23294			if ( !filter || filter( elem, context, xml ) ) {
23295				newUnmatched.push( elem );
23296				if ( mapped ) {
23297					map.push( i );
23298				}
23299			}
23300		}
23301	}
23302
23303	return newUnmatched;
23304}
23305
23306function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
23307	if ( postFilter && !postFilter[ expando ] ) {
23308		postFilter = setMatcher( postFilter );
23309	}
23310	if ( postFinder && !postFinder[ expando ] ) {
23311		postFinder = setMatcher( postFinder, postSelector );
23312	}
23313	return markFunction(function( seed, results, context, xml ) {
23314		var temp, i, elem,
23315			preMap = [],
23316			postMap = [],
23317			preexisting = results.length,
23318
23319			// Get initial elements from seed or context
23320			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
23321
23322			// Prefilter to get matcher input, preserving a map for seed-results synchronization
23323			matcherIn = preFilter && ( seed || !selector ) ?
23324				condense( elems, preMap, preFilter, context, xml ) :
23325				elems,
23326
23327			matcherOut = matcher ?
23328				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
23329				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
23330
23331					// ...intermediate processing is necessary
23332					[] :
23333
23334					// ...otherwise use results directly
23335					results :
23336				matcherIn;
23337
23338		// Find primary matches
23339		if ( matcher ) {
23340			matcher( matcherIn, matcherOut, context, xml );
23341		}
23342
23343		// Apply postFilter
23344		if ( postFilter ) {
23345			temp = condense( matcherOut, postMap );
23346			postFilter( temp, [], context, xml );
23347
23348			// Un-match failing elements by moving them back to matcherIn
23349			i = temp.length;
23350			while ( i-- ) {
23351				if ( (elem = temp[i]) ) {
23352					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
23353				}
23354			}
23355		}
23356
23357		if ( seed ) {
23358			if ( postFinder || preFilter ) {
23359				if ( postFinder ) {
23360					// Get the final matcherOut by condensing this intermediate into postFinder contexts
23361					temp = [];
23362					i = matcherOut.length;
23363					while ( i-- ) {
23364						if ( (elem = matcherOut[i]) ) {
23365							// Restore matcherIn since elem is not yet a final match
23366							temp.push( (matcherIn[i] = elem) );
23367						}
23368					}
23369					postFinder( null, (matcherOut = []), temp, xml );
23370				}
23371
23372				// Move matched elements from seed to results to keep them synchronized
23373				i = matcherOut.length;
23374				while ( i-- ) {
23375					if ( (elem = matcherOut[i]) &&
23376						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
23377
23378						seed[temp] = !(results[temp] = elem);
23379					}
23380				}
23381			}
23382
23383		// Add elements to results, through postFinder if defined
23384		} else {
23385			matcherOut = condense(
23386				matcherOut === results ?
23387					matcherOut.splice( preexisting, matcherOut.length ) :
23388					matcherOut
23389			);
23390			if ( postFinder ) {
23391				postFinder( null, results, matcherOut, xml );
23392			} else {
23393				push.apply( results, matcherOut );
23394			}
23395		}
23396	});
23397}
23398
23399function matcherFromTokens( tokens ) {
23400	var checkContext, matcher, j,
23401		len = tokens.length,
23402		leadingRelative = Expr.relative[ tokens[0].type ],
23403		implicitRelative = leadingRelative || Expr.relative[" "],
23404		i = leadingRelative ? 1 : 0,
23405
23406		// The foundational matcher ensures that elements are reachable from top-level context(s)
23407		matchContext = addCombinator( function( elem ) {
23408			return elem === checkContext;
23409		}, implicitRelative, true ),
23410		matchAnyContext = addCombinator( function( elem ) {
23411			return indexOf( checkContext, elem ) > -1;
23412		}, implicitRelative, true ),
23413		matchers = [ function( elem, context, xml ) {
23414			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
23415				(checkContext = context).nodeType ?
23416					matchContext( elem, context, xml ) :
23417					matchAnyContext( elem, context, xml ) );
23418			// Avoid hanging onto element (issue #299)
23419			checkContext = null;
23420			return ret;
23421		} ];
23422
23423	for ( ; i < len; i++ ) {
23424		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
23425			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
23426		} else {
23427			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
23428
23429			// Return special upon seeing a positional matcher
23430			if ( matcher[ expando ] ) {
23431				// Find the next relative operator (if any) for proper handling
23432				j = ++i;
23433				for ( ; j < len; j++ ) {
23434					if ( Expr.relative[ tokens[j].type ] ) {
23435						break;
23436					}
23437				}
23438				return setMatcher(
23439					i > 1 && elementMatcher( matchers ),
23440					i > 1 && toSelector(
23441						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
23442						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
23443					).replace( rtrim, "$1" ),
23444					matcher,
23445					i < j && matcherFromTokens( tokens.slice( i, j ) ),
23446					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
23447					j < len && toSelector( tokens )
23448				);
23449			}
23450			matchers.push( matcher );
23451		}
23452	}
23453
23454	return elementMatcher( matchers );
23455}
23456
23457function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
23458	var bySet = setMatchers.length > 0,
23459		byElement = elementMatchers.length > 0,
23460		superMatcher = function( seed, context, xml, results, outermost ) {
23461			var elem, j, matcher,
23462				matchedCount = 0,
23463				i = "0",
23464				unmatched = seed && [],
23465				setMatched = [],
23466				contextBackup = outermostContext,
23467				// We must always have either seed elements or outermost context
23468				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
23469				// Use integer dirruns iff this is the outermost matcher
23470				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
23471				len = elems.length;
23472
23473			if ( outermost ) {
23474				outermostContext = context === document || context || outermost;
23475			}
23476
23477			// Add elements passing elementMatchers directly to results
23478			// Support: IE<9, Safari
23479			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
23480			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
23481				if ( byElement && elem ) {
23482					j = 0;
23483					if ( !context && elem.ownerDocument !== document ) {
23484						setDocument( elem );
23485						xml = !documentIsHTML;
23486					}
23487					while ( (matcher = elementMatchers[j++]) ) {
23488						if ( matcher( elem, context || document, xml) ) {
23489							results.push( elem );
23490							break;
23491						}
23492					}
23493					if ( outermost ) {
23494						dirruns = dirrunsUnique;
23495					}
23496				}
23497
23498				// Track unmatched elements for set filters
23499				if ( bySet ) {
23500					// They will have gone through all possible matchers
23501					if ( (elem = !matcher && elem) ) {
23502						matchedCount--;
23503					}
23504
23505					// Lengthen the array for every element, matched or not
23506					if ( seed ) {
23507						unmatched.push( elem );
23508					}
23509				}
23510			}
23511
23512			// `i` is now the count of elements visited above, and adding it to `matchedCount`
23513			// makes the latter nonnegative.
23514			matchedCount += i;
23515
23516			// Apply set filters to unmatched elements
23517			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
23518			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
23519			// no element matchers and no seed.
23520			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
23521			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
23522			// numerically zero.
23523			if ( bySet && i !== matchedCount ) {
23524				j = 0;
23525				while ( (matcher = setMatchers[j++]) ) {
23526					matcher( unmatched, setMatched, context, xml );
23527				}
23528
23529				if ( seed ) {
23530					// Reintegrate element matches to eliminate the need for sorting
23531					if ( matchedCount > 0 ) {
23532						while ( i-- ) {
23533							if ( !(unmatched[i] || setMatched[i]) ) {
23534								setMatched[i] = pop.call( results );
23535							}
23536						}
23537					}
23538
23539					// Discard index placeholder values to get only actual matches
23540					setMatched = condense( setMatched );
23541				}
23542
23543				// Add matches to results
23544				push.apply( results, setMatched );
23545
23546				// Seedless set matches succeeding multiple successful matchers stipulate sorting
23547				if ( outermost && !seed && setMatched.length > 0 &&
23548					( matchedCount + setMatchers.length ) > 1 ) {
23549
23550					Sizzle.uniqueSort( results );
23551				}
23552			}
23553
23554			// Override manipulation of globals by nested matchers
23555			if ( outermost ) {
23556				dirruns = dirrunsUnique;
23557				outermostContext = contextBackup;
23558			}
23559
23560			return unmatched;
23561		};
23562
23563	return bySet ?
23564		markFunction( superMatcher ) :
23565		superMatcher;
23566}
23567
23568compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
23569	var i,
23570		setMatchers = [],
23571		elementMatchers = [],
23572		cached = compilerCache[ selector + " " ];
23573
23574	if ( !cached ) {
23575		// Generate a function of recursive functions that can be used to check each element
23576		if ( !match ) {
23577			match = tokenize( selector );
23578		}
23579		i = match.length;
23580		while ( i-- ) {
23581			cached = matcherFromTokens( match[i] );
23582			if ( cached[ expando ] ) {
23583				setMatchers.push( cached );
23584			} else {
23585				elementMatchers.push( cached );
23586			}
23587		}
23588
23589		// Cache the compiled function
23590		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
23591
23592		// Save selector and tokenization
23593		cached.selector = selector;
23594	}
23595	return cached;
23596};
23597
23598/**
23599 * A low-level selection function that works with Sizzle's compiled
23600 *  selector functions
23601 * @param {String|Function} selector A selector or a pre-compiled
23602 *  selector function built with Sizzle.compile
23603 * @param {Element} context
23604 * @param {Array} [results]
23605 * @param {Array} [seed] A set of elements to match against
23606 */
23607select = Sizzle.select = function( selector, context, results, seed ) {
23608	var i, tokens, token, type, find,
23609		compiled = typeof selector === "function" && selector,
23610		match = !seed && tokenize( (selector = compiled.selector || selector) );
23611
23612	results = results || [];
23613
23614	// Try to minimize operations if there is only one selector in the list and no seed
23615	// (the latter of which guarantees us context)
23616	if ( match.length === 1 ) {
23617
23618		// Reduce context if the leading compound selector is an ID
23619		tokens = match[0] = match[0].slice( 0 );
23620		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
23621				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
23622
23623			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
23624			if ( !context ) {
23625				return results;
23626
23627			// Precompiled matchers will still verify ancestry, so step up a level
23628			} else if ( compiled ) {
23629				context = context.parentNode;
23630			}
23631
23632			selector = selector.slice( tokens.shift().value.length );
23633		}
23634
23635		// Fetch a seed set for right-to-left matching
23636		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
23637		while ( i-- ) {
23638			token = tokens[i];
23639
23640			// Abort if we hit a combinator
23641			if ( Expr.relative[ (type = token.type) ] ) {
23642				break;
23643			}
23644			if ( (find = Expr.find[ type ]) ) {
23645				// Search, expanding context for leading sibling combinators
23646				if ( (seed = find(
23647					token.matches[0].replace( runescape, funescape ),
23648					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
23649				)) ) {
23650
23651					// If seed is empty or no tokens remain, we can return early
23652					tokens.splice( i, 1 );
23653					selector = seed.length && toSelector( tokens );
23654					if ( !selector ) {
23655						push.apply( results, seed );
23656						return results;
23657					}
23658
23659					break;
23660				}
23661			}
23662		}
23663	}
23664
23665	// Compile and execute a filtering function if one is not provided
23666	// Provide `match` to avoid retokenization if we modified the selector above
23667	( compiled || compile( selector, match ) )(
23668		seed,
23669		context,
23670		!documentIsHTML,
23671		results,
23672		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
23673	);
23674	return results;
23675};
23676
23677// One-time assignments
23678
23679// Sort stability
23680support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
23681
23682// Support: Chrome 14-35+
23683// Always assume duplicates if they aren't passed to the comparison function
23684support.detectDuplicates = !!hasDuplicate;
23685
23686// Initialize against the default document
23687setDocument();
23688
23689// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
23690// Detached nodes confoundingly follow *each other*
23691support.sortDetached = assert(function( el ) {
23692	// Should return 1, but returns 4 (following)
23693	return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
23694});
23695
23696// Support: IE<8
23697// Prevent attribute/property "interpolation"
23698// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
23699if ( !assert(function( el ) {
23700	el.innerHTML = "<a href='#'></a>";
23701	return el.firstChild.getAttribute("href") === "#" ;
23702}) ) {
23703	addHandle( "type|href|height|width", function( elem, name, isXML ) {
23704		if ( !isXML ) {
23705			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
23706		}
23707	});
23708}
23709
23710// Support: IE<9
23711// Use defaultValue in place of getAttribute("value")
23712if ( !support.attributes || !assert(function( el ) {
23713	el.innerHTML = "<input/>";
23714	el.firstChild.setAttribute( "value", "" );
23715	return el.firstChild.getAttribute( "value" ) === "";
23716}) ) {
23717	addHandle( "value", function( elem, name, isXML ) {
23718		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
23719			return elem.defaultValue;
23720		}
23721	});
23722}
23723
23724// Support: IE<9
23725// Use getAttributeNode to fetch booleans when getAttribute lies
23726if ( !assert(function( el ) {
23727	return el.getAttribute("disabled") == null;
23728}) ) {
23729	addHandle( booleans, function( elem, name, isXML ) {
23730		var val;
23731		if ( !isXML ) {
23732			return elem[ name ] === true ? name.toLowerCase() :
23733					(val = elem.getAttributeNode( name )) && val.specified ?
23734					val.value :
23735				null;
23736		}
23737	});
23738}
23739
23740return Sizzle;
23741
23742})( window );
23743
23744
23745
23746jQuery.find = Sizzle;
23747jQuery.expr = Sizzle.selectors;
23748
23749// Deprecated
23750jQuery.expr[ ":" ] = jQuery.expr.pseudos;
23751jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
23752jQuery.text = Sizzle.getText;
23753jQuery.isXMLDoc = Sizzle.isXML;
23754jQuery.contains = Sizzle.contains;
23755jQuery.escapeSelector = Sizzle.escape;
23756
23757
23758
23759
23760var dir = function( elem, dir, until ) {
23761	var matched = [],
23762		truncate = until !== undefined;
23763
23764	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
23765		if ( elem.nodeType === 1 ) {
23766			if ( truncate && jQuery( elem ).is( until ) ) {
23767				break;
23768			}
23769			matched.push( elem );
23770		}
23771	}
23772	return matched;
23773};
23774
23775
23776var siblings = function( n, elem ) {
23777	var matched = [];
23778
23779	for ( ; n; n = n.nextSibling ) {
23780		if ( n.nodeType === 1 && n !== elem ) {
23781			matched.push( n );
23782		}
23783	}
23784
23785	return matched;
23786};
23787
23788
23789var rneedsContext = jQuery.expr.match.needsContext;
23790
23791
23792
23793function nodeName( elem, name ) {
23794
23795  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
23796
23797};
23798var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
23799
23800
23801
23802// Implement the identical functionality for filter and not
23803function winnow( elements, qualifier, not ) {
23804	if ( isFunction( qualifier ) ) {
23805		return jQuery.grep( elements, function( elem, i ) {
23806			return !!qualifier.call( elem, i, elem ) !== not;
23807		} );
23808	}
23809
23810	// Single element
23811	if ( qualifier.nodeType ) {
23812		return jQuery.grep( elements, function( elem ) {
23813			return ( elem === qualifier ) !== not;
23814		} );
23815	}
23816
23817	// Arraylike of elements (jQuery, arguments, Array)
23818	if ( typeof qualifier !== "string" ) {
23819		return jQuery.grep( elements, function( elem ) {
23820			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
23821		} );
23822	}
23823
23824	// Filtered directly for both simple and complex selectors
23825	return jQuery.filter( qualifier, elements, not );
23826}
23827
23828jQuery.filter = function( expr, elems, not ) {
23829	var elem = elems[ 0 ];
23830
23831	if ( not ) {
23832		expr = ":not(" + expr + ")";
23833	}
23834
23835	if ( elems.length === 1 && elem.nodeType === 1 ) {
23836		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
23837	}
23838
23839	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
23840		return elem.nodeType === 1;
23841	} ) );
23842};
23843
23844jQuery.fn.extend( {
23845	find: function( selector ) {
23846		var i, ret,
23847			len = this.length,
23848			self = this;
23849
23850		if ( typeof selector !== "string" ) {
vendor: 6,536 bytes, lines 23851-24111
23851			return this.pushStack( jQuery( selector ).filter( function() {
23852				for ( i = 0; i < len; i++ ) {
23853					if ( jQuery.contains( self[ i ], this ) ) {
23854						return true;
23855					}
23856				}
23857			} ) );
23858		}
23859
23860		ret = this.pushStack( [] );
23861
23862		for ( i = 0; i < len; i++ ) {
23863			jQuery.find( selector, self[ i ], ret );
23864		}
23865
23866		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
23867	},
23868	filter: function( selector ) {
23869		return this.pushStack( winnow( this, selector || [], false ) );
23870	},
23871	not: function( selector ) {
23872		return this.pushStack( winnow( this, selector || [], true ) );
23873	},
23874	is: function( selector ) {
23875		return !!winnow(
23876			this,
23877
23878			// If this is a positional/relative selector, check membership in the returned set
23879			// so $("p:first").is("p:last") won't return true for a doc with two "p".
23880			typeof selector === "string" && rneedsContext.test( selector ) ?
23881				jQuery( selector ) :
23882				selector || [],
23883			false
23884		).length;
23885	}
23886} );
23887
23888
23889// Initialize a jQuery object
23890
23891
23892// A central reference to the root jQuery(document)
23893var rootjQuery,
23894
23895	// A simple way to check for HTML strings
23896	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
23897	// Strict HTML recognition (#11290: must start with <)
23898	// Shortcut simple #id case for speed
23899	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
23900
23901	init = jQuery.fn.init = function( selector, context, root ) {
23902		var match, elem;
23903
23904		// HANDLE: $(""), $(null), $(undefined), $(false)
23905		if ( !selector ) {
23906			return this;
23907		}
23908
23909		// Method init() accepts an alternate rootjQuery
23910		// so migrate can support jQuery.sub (gh-2101)
23911		root = root || rootjQuery;
23912
23913		// Handle HTML strings
23914		if ( typeof selector === "string" ) {
23915			if ( selector[ 0 ] === "<" &&
23916				selector[ selector.length - 1 ] === ">" &&
23917				selector.length >= 3 ) {
23918
23919				// Assume that strings that start and end with <> are HTML and skip the regex check
23920				match = [ null, selector, null ];
23921
23922			} else {
23923				match = rquickExpr.exec( selector );
23924			}
23925
23926			// Match html or make sure no context is specified for #id
23927			if ( match && ( match[ 1 ] || !context ) ) {
23928
23929				// HANDLE: $(html) -> $(array)
23930				if ( match[ 1 ] ) {
23931					context = context instanceof jQuery ? context[ 0 ] : context;
23932
23933					// Option to run scripts is true for back-compat
23934					// Intentionally let the error be thrown if parseHTML is not present
23935					jQuery.merge( this, jQuery.parseHTML(
23936						match[ 1 ],
23937						context && context.nodeType ? context.ownerDocument || context : document,
23938						true
23939					) );
23940
23941					// HANDLE: $(html, props)
23942					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
23943						for ( match in context ) {
23944
23945							// Properties of context are called as methods if possible
23946							if ( isFunction( this[ match ] ) ) {
23947								this[ match ]( context[ match ] );
23948
23949							// ...and otherwise set as attributes
23950							} else {
23951								this.attr( match, context[ match ] );
23952							}
23953						}
23954					}
23955
23956					return this;
23957
23958				// HANDLE: $(#id)
23959				} else {
23960					elem = document.getElementById( match[ 2 ] );
23961
23962					if ( elem ) {
23963
23964						// Inject the element directly into the jQuery object
23965						this[ 0 ] = elem;
23966						this.length = 1;
23967					}
23968					return this;
23969				}
23970
23971			// HANDLE: $(expr, $(...))
23972			} else if ( !context || context.jquery ) {
23973				return ( context || root ).find( selector );
23974
23975			// HANDLE: $(expr, context)
23976			// (which is just equivalent to: $(context).find(expr)
23977			} else {
23978				return this.constructor( context ).find( selector );
23979			}
23980
23981		// HANDLE: $(DOMElement)
23982		} else if ( selector.nodeType ) {
23983			this[ 0 ] = selector;
23984			this.length = 1;
23985			return this;
23986
23987		// HANDLE: $(function)
23988		// Shortcut for document ready
23989		} else if ( isFunction( selector ) ) {
23990			return root.ready !== undefined ?
23991				root.ready( selector ) :
23992
23993				// Execute immediately if ready is not present
23994				selector( jQuery );
23995		}
23996
23997		return jQuery.makeArray( selector, this );
23998	};
23999
24000// Give the init function the jQuery prototype for later instantiation
24001init.prototype = jQuery.fn;
24002
24003// Initialize central reference
24004rootjQuery = jQuery( document );
24005
24006
24007var rparentsprev = /^(?:parents|prev(?:Until|All))/,
24008
24009	// Methods guaranteed to produce a unique set when starting from a unique set
24010	guaranteedUnique = {
24011		children: true,
24012		contents: true,
24013		next: true,
24014		prev: true
24015	};
24016
24017jQuery.fn.extend( {
24018	has: function( target ) {
24019		var targets = jQuery( target, this ),
24020			l = targets.length;
24021
24022		return this.filter( function() {
24023			var i = 0;
24024			for ( ; i < l; i++ ) {
24025				if ( jQuery.contains( this, targets[ i ] ) ) {
24026					return true;
24027				}
24028			}
24029		} );
24030	},
24031
24032	closest: function( selectors, context ) {
24033		var cur,
24034			i = 0,
24035			l = this.length,
24036			matched = [],
24037			targets = typeof selectors !== "string" && jQuery( selectors );
24038
24039		// Positional selectors never match, since there's no _selection_ context
24040		if ( !rneedsContext.test( selectors ) ) {
24041			for ( ; i < l; i++ ) {
24042				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
24043
24044					// Always skip document fragments
24045					if ( cur.nodeType < 11 && ( targets ?
24046						targets.index( cur ) > -1 :
24047
24048						// Don't pass non-elements to Sizzle
24049						cur.nodeType === 1 &&
24050							jQuery.find.matchesSelector( cur, selectors ) ) ) {
24051
24052						matched.push( cur );
24053						break;
24054					}
24055				}
24056			}
24057		}
24058
24059		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
24060	},
24061
24062	// Determine the position of an element within the set
24063	index: function( elem ) {
24064
24065		// No argument, return index in parent
24066		if ( !elem ) {
24067			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
24068		}
24069
24070		// Index in selector
24071		if ( typeof elem === "string" ) {
24072			return indexOf.call( jQuery( elem ), this[ 0 ] );
24073		}
24074
24075		// Locate the position of the desired element
24076		return indexOf.call( this,
24077
24078			// If it receives a jQuery object, the first element is used
24079			elem.jquery ? elem[ 0 ] : elem
24080		);
24081	},
24082
24083	add: function( selector, context ) {
24084		return this.pushStack(
24085			jQuery.uniqueSort(
24086				jQuery.merge( this.get(), jQuery( selector, context ) )
24087			)
24088		);
24089	},
24090
24091	addBack: function( selector ) {
24092		return this.add( selector == null ?
24093			this.prevObject : this.prevObject.filter( selector )
24094		);
24095	}
24096} );
24097
24098function sibling( cur, dir ) {
24099	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
24100	return cur;
24101}
24102
24103jQuery.each( {
24104	parent: function( elem ) {
24105		var parent = elem.parentNode;
24106		return parent && parent.nodeType !== 11 ? parent : null;
24107	},
24108	parents: function( elem ) {
24109		return dir( elem, "parentNode" );
24110	},
24111	parentsUntil: function( elem, 
24111i, until ) {
24112		return dir( elem, "parentNode", until );
24113	},
24114	next: function( elem ) {
24115		return sibling( elem, "nextSibling" );
24116	},
24117	prev: function( elem ) {
24118		return sibling( elem, "previousSibling" );
24119	},
24120	nextAll: function( elem ) {
24121		return dir( elem, "nextSibling" );
24122	},
24123	prevAll: function( elem ) {
24124		return dir( elem, "previousSibling" );
24125	},
24126	nextUntil: function( elem, i, until ) {
24127		return dir( elem, "nextSibling", until );
24128	},
24129	prevUntil: function( elem, i, until ) {
24130		return dir( elem, "previousSibling", until );
24131	},
24132	siblings: function( elem ) {
24133		return siblings( ( elem.parentNode || {} ).firstChild, elem );
24134	},
24135	children: function( elem ) {
24136		return siblings( elem.firstChild );
24137	},
24138	contents: function( elem ) {
24139		if ( typeof elem.contentDocument !== "undefined" ) {
vendor: 8,211 bytes, lines 24139-24473
24139
24140			return elem.contentDocument;
24141		}
24142
24143		// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
24144		// Treat the template element as a regular one in browsers that
24145		// don't support it.
24146		if ( nodeName( elem, "template" ) ) {
24147			elem = elem.content || elem;
24148		}
24149
24150		return jQuery.merge( [], elem.childNodes );
24151	}
24152}, function( name, fn ) {
24153	jQuery.fn[ name ] = function( until, selector ) {
24154		var matched = jQuery.map( this, fn, until );
24155
24156		if ( name.slice( -5 ) !== "Until" ) {
24157			selector = until;
24158		}
24159
24160		if ( selector && typeof selector === "string" ) {
24161			matched = jQuery.filter( selector, matched );
24162		}
24163
24164		if ( this.length > 1 ) {
24165
24166			// Remove duplicates
24167			if ( !guaranteedUnique[ name ] ) {
24168				jQuery.uniqueSort( matched );
24169			}
24170
24171			// Reverse order for parents* and prev-derivatives
24172			if ( rparentsprev.test( name ) ) {
24173				matched.reverse();
24174			}
24175		}
24176
24177		return this.pushStack( matched );
24178	};
24179} );
24180var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
24181
24182
24183
24184// Convert String-formatted options into Object-formatted ones
24185function createOptions( options ) {
24186	var object = {};
24187	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
24188		object[ flag ] = true;
24189	} );
24190	return object;
24191}
24192
24193/*
24194 * Create a callback list using the following parameters:
24195 *
24196 *	options: an optional list of space-separated options that will change how
24197 *			the callback list behaves or a more traditional option object
24198 *
24199 * By default a callback list will act like an event callback list and can be
24200 * "fired" multiple times.
24201 *
24202 * Possible options:
24203 *
24204 *	once:			will ensure the callback list can only be fired once (like a Deferred)
24205 *
24206 *	memory:			will keep track of previous values and will call any callback added
24207 *					after the list has been fired right away with the latest "memorized"
24208 *					values (like a Deferred)
24209 *
24210 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
24211 *
24212 *	stopOnFalse:	interrupt callings when a callback returns false
24213 *
24214 */
24215jQuery.Callbacks = function( options ) {
24216
24217	// Convert options from String-formatted to Object-formatted if needed
24218	// (we check in cache first)
24219	options = typeof options === "string" ?
24220		createOptions( options ) :
24221		jQuery.extend( {}, options );
24222
24223	var // Flag to know if list is currently firing
24224		firing,
24225
24226		// Last fire value for non-forgettable lists
24227		memory,
24228
24229		// Flag to know if list was already fired
24230		fired,
24231
24232		// Flag to prevent firing
24233		locked,
24234
24235		// Actual callback list
24236		list = [],
24237
24238		// Queue of execution data for repeatable lists
24239		queue = [],
24240
24241		// Index of currently firing callback (modified by add/remove as needed)
24242		firingIndex = -1,
24243
24244		// Fire callbacks
24245		fire = function() {
24246
24247			// Enforce single-firing
24248			locked = locked || options.once;
24249
24250			// Execute callbacks for all pending executions,
24251			// respecting firingIndex overrides and runtime changes
24252			fired = firing = true;
24253			for ( ; queue.length; firingIndex = -1 ) {
24254				memory = queue.shift();
24255				while ( ++firingIndex < list.length ) {
24256
24257					// Run callback and check for early termination
24258					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
24259						options.stopOnFalse ) {
24260
24261						// Jump to end and forget the data so .add doesn't re-fire
24262						firingIndex = list.length;
24263						memory = false;
24264					}
24265				}
24266			}
24267
24268			// Forget the data if we're done with it
24269			if ( !options.memory ) {
24270				memory = false;
24271			}
24272
24273			firing = false;
24274
24275			// Clean up if we're done firing for good
24276			if ( locked ) {
24277
24278				// Keep an empty list if we have data for future add calls
24279				if ( memory ) {
24280					list = [];
24281
24282				// Otherwise, this object is spent
24283				} else {
24284					list = "";
24285				}
24286			}
24287		},
24288
24289		// Actual Callbacks object
24290		self = {
24291
24292			// Add a callback or a collection of callbacks to the list
24293			add: function() {
24294				if ( list ) {
24295
24296					// If we have memory from a past run, we should fire after adding
24297					if ( memory && !firing ) {
24298						firingIndex = list.length - 1;
24299						queue.push( memory );
24300					}
24301
24302					( function add( args ) {
24303						jQuery.each( args, function( _, arg ) {
24304							if ( isFunction( arg ) ) {
24305								if ( !options.unique || !self.has( arg ) ) {
24306									list.push( arg );
24307								}
24308							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
24309
24310								// Inspect recursively
24311								add( arg );
24312							}
24313						} );
24314					} )( arguments );
24315
24316					if ( memory && !firing ) {
24317						fire();
24318					}
24319				}
24320				return this;
24321			},
24322
24323			// Remove a callback from the list
24324			remove: function() {
24325				jQuery.each( arguments, function( _, arg ) {
24326					var index;
24327					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
24328						list.splice( index, 1 );
24329
24330						// Handle firing indexes
24331						if ( index <= firingIndex ) {
24332							firingIndex--;
24333						}
24334					}
24335				} );
24336				return this;
24337			},
24338
24339			// Check if a given callback is in the list.
24340			// If no argument is given, return whether or not list has callbacks attached.
24341			has: function( fn ) {
24342				return fn ?
24343					jQuery.inArray( fn, list ) > -1 :
24344					list.length > 0;
24345			},
24346
24347			// Remove all callbacks from the list
24348			empty: function() {
24349				if ( list ) {
24350					list = [];
24351				}
24352				return this;
24353			},
24354
24355			// Disable .fire and .add
24356			// Abort any current/pending executions
24357			// Clear all callbacks and values
24358			disable: function() {
24359				locked = queue = [];
24360				list = memory = "";
24361				return this;
24362			},
24363			disabled: function() {
24364				return !list;
24365			},
24366
24367			// Disable .fire
24368			// Also disable .add unless we have memory (since it would have no effect)
24369			// Abort any pending executions
24370			lock: function() {
24371				locked = queue = [];
24372				if ( !memory && !firing ) {
24373					list = memory = "";
24374				}
24375				return this;
24376			},
24377			locked: function() {
24378				return !!locked;
24379			},
24380
24381			// Call all callbacks with the given context and arguments
24382			fireWith: function( context, args ) {
24383				if ( !locked ) {
24384					args = args || [];
24385					args = [ context, args.slice ? args.slice() : args ];
24386					queue.push( args );
24387					if ( !firing ) {
24388						fire();
24389					}
24390				}
24391				return this;
24392			},
24393
24394			// Call all the callbacks with the given arguments
24395			fire: function() {
24396				self.fireWith( this, arguments );
24397				return this;
24398			},
24399
24400			// To know if the callbacks have already been called at least once
24401			fired: function() {
24402				return !!fired;
24403			}
24404		};
24405
24406	return self;
24407};
24408
24409
24410function Identity( v ) {
24411	return v;
24412}
24413function Thrower( ex ) {
24414	throw ex;
24415}
24416
24417function adoptValue( value, resolve, reject, noValue ) {
24418	var method;
24419
24420	try {
24421
24422		// Check for promise aspect first to privilege synchronous behavior
24423		if ( value && isFunction( ( method = value.promise ) ) ) {
24424			method.call( value ).done( resolve ).fail( reject );
24425
24426		// Other thenables
24427		} else if ( value && isFunction( ( method = value.then ) ) ) {
24428			method.call( value, resolve, reject );
24429
24430		// Other non-thenables
24431		} else {
24432
24433			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
24434			// * false: [ value ].slice( 0 ) => resolve( value )
24435			// * true: [ value ].slice( 1 ) => resolve()
24436			resolve.apply( undefined, [ value ].slice( noValue ) );
24437		}
24438
24439	// For Promises/A+, convert exceptions into rejections
24440	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
24441	// Deferred#then to conditionally suppress rejection.
24442	} catch ( value ) {
24443
24444		// Support: Android 4.0 only
24445		// Strict mode functions invoked without .call/.apply get global-object context
24446		reject.apply( undefined, [ value ] );
24447	}
24448}
24449
24450jQuery.extend( {
24451
24452	Deferred: function( func ) {
24453		var tuples = [
24454
24455				// action, add listener, callbacks,
24456				// ... .then handlers, argument index, [final state]
24457				[ "notify", "progress", jQuery.Callbacks( "memory" ),
24458					jQuery.Callbacks( "memory" ), 2 ],
24459				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
24460					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
24461				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
24462					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
24463			],
24464			state = "pending",
24465			promise = {
24466				state: function() {
24467					return state;
24468				},
24469				always: function() {
24470					deferred.done( arguments ).fail( arguments );
24471					return this;
24472				},
24473				"catch": function( fn ) {
vendor: 15,167 bytes, lines 24474-25065
24474					return promise.then( null, fn );
24475				},
24476
24477				// Keep pipe for back-compat
24478				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
24479					var fns = arguments;
24480
24481					return jQuery.Deferred( function( newDefer ) {
24482						jQuery.each( tuples, function( i, tuple ) {
24483
24484							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
24485							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
24486
24487							// deferred.progress(function() { bind to newDefer or newDefer.notify })
24488							// deferred.done(function() { bind to newDefer or newDefer.resolve })
24489							// deferred.fail(function() { bind to newDefer or newDefer.reject })
24490							deferred[ tuple[ 1 ] ]( function() {
24491								var returned = fn && fn.apply( this, arguments );
24492								if ( returned && isFunction( returned.promise ) ) {
24493									returned.promise()
24494										.progress( newDefer.notify )
24495										.done( newDefer.resolve )
24496										.fail( newDefer.reject );
24497								} else {
24498									newDefer[ tuple[ 0 ] + "With" ](
24499										this,
24500										fn ? [ returned ] : arguments
24501									);
24502								}
24503							} );
24504						} );
24505						fns = null;
24506					} ).promise();
24507				},
24508				then: function( onFulfilled, onRejected, onProgress ) {
24509					var maxDepth = 0;
24510					function resolve( depth, deferred, handler, special ) {
24511						return function() {
24512							var that = this,
24513								args = arguments,
24514								mightThrow = function() {
24515									var returned, then;
24516
24517									// Support: Promises/A+ section 2.3.3.3.3
24518									// https://promisesaplus.com/#point-59
24519									// Ignore double-resolution attempts
24520									if ( depth < maxDepth ) {
24521										return;
24522									}
24523
24524									returned = handler.apply( that, args );
24525
24526									// Support: Promises/A+ section 2.3.1
24527									// https://promisesaplus.com/#point-48
24528									if ( returned === deferred.promise() ) {
24529										throw new TypeError( "Thenable self-resolution" );
24530									}
24531
24532									// Support: Promises/A+ sections 2.3.3.1, 3.5
24533									// https://promisesaplus.com/#point-54
24534									// https://promisesaplus.com/#point-75
24535									// Retrieve `then` only once
24536									then = returned &&
24537
24538										// Support: Promises/A+ section 2.3.4
24539										// https://promisesaplus.com/#point-64
24540										// Only check objects and functions for thenability
24541										( typeof returned === "object" ||
24542											typeof returned === "function" ) &&
24543										returned.then;
24544
24545									// Handle a returned thenable
24546									if ( isFunction( then ) ) {
24547
24548										// Special processors (notify) just wait for resolution
24549										if ( special ) {
24550											then.call(
24551												returned,
24552												resolve( maxDepth, deferred, Identity, special ),
24553												resolve( maxDepth, deferred, Thrower, special )
24554											);
24555
24556										// Normal processors (resolve) also hook into progress
24557										} else {
24558
24559											// ...and disregard older resolution values
24560											maxDepth++;
24561
24562											then.call(
24563												returned,
24564												resolve( maxDepth, deferred, Identity, special ),
24565												resolve( maxDepth, deferred, Thrower, special ),
24566												resolve( maxDepth, deferred, Identity,
24567													deferred.notifyWith )
24568											);
24569										}
24570
24571									// Handle all other returned values
24572									} else {
24573
24574										// Only substitute handlers pass on context
24575										// and multiple values (non-spec behavior)
24576										if ( handler !== Identity ) {
24577											that = undefined;
24578											args = [ returned ];
24579										}
24580
24581										// Process the value(s)
24582										// Default process is resolve
24583										( special || deferred.resolveWith )( that, args );
24584									}
24585								},
24586
24587								// Only normal processors (resolve) catch and reject exceptions
24588								process = special ?
24589									mightThrow :
24590									function() {
24591										try {
24592											mightThrow();
24593										} catch ( e ) {
24594
24595											if ( jQuery.Deferred.exceptionHook ) {
24596												jQuery.Deferred.exceptionHook( e,
24597													process.stackTrace );
24598											}
24599
24600											// Support: Promises/A+ section 2.3.3.3.4.1
24601											// https://promisesaplus.com/#point-61
24602											// Ignore post-resolution exceptions
24603											if ( depth + 1 >= maxDepth ) {
24604
24605												// Only substitute handlers pass on context
24606												// and multiple values (non-spec behavior)
24607												if ( handler !== Thrower ) {
24608													that = undefined;
24609													args = [ e ];
24610												}
24611
24612												deferred.rejectWith( that, args );
24613											}
24614										}
24615									};
24616
24617							// Support: Promises/A+ section 2.3.3.3.1
24618							// https://promisesaplus.com/#point-57
24619							// Re-resolve promises immediately to dodge false rejection from
24620							// subsequent errors
24621							if ( depth ) {
24622								process();
24623							} else {
24624
24625								// Call an optional hook to record the stack, in case of exception
24626								// since it's otherwise lost when execution goes async
24627								if ( jQuery.Deferred.getStackHook ) {
24628									process.stackTrace = jQuery.Deferred.getStackHook();
24629								}
24630								window.setTimeout( process );
24631							}
24632						};
24633					}
24634
24635					return jQuery.Deferred( function( newDefer ) {
24636
24637						// progress_handlers.add( ... )
24638						tuples[ 0 ][ 3 ].add(
24639							resolve(
24640								0,
24641								newDefer,
24642								isFunction( onProgress ) ?
24643									onProgress :
24644									Identity,
24645								newDefer.notifyWith
24646							)
24647						);
24648
24649						// fulfilled_handlers.add( ... )
24650						tuples[ 1 ][ 3 ].add(
24651							resolve(
24652								0,
24653								newDefer,
24654								isFunction( onFulfilled ) ?
24655									onFulfilled :
24656									Identity
24657							)
24658						);
24659
24660						// rejected_handlers.add( ... )
24661						tuples[ 2 ][ 3 ].add(
24662							resolve(
24663								0,
24664								newDefer,
24665								isFunction( onRejected ) ?
24666									onRejected :
24667									Thrower
24668							)
24669						);
24670					} ).promise();
24671				},
24672
24673				// Get a promise for this deferred
24674				// If obj is provided, the promise aspect is added to the object
24675				promise: function( obj ) {
24676					return obj != null ? jQuery.extend( obj, promise ) : promise;
24677				}
24678			},
24679			deferred = {};
24680
24681		// Add list-specific methods
24682		jQuery.each( tuples, function( i, tuple ) {
24683			var list = tuple[ 2 ],
24684				stateString = tuple[ 5 ];
24685
24686			// promise.progress = list.add
24687			// promise.done = list.add
24688			// promise.fail = list.add
24689			promise[ tuple[ 1 ] ] = list.add;
24690
24691			// Handle state
24692			if ( stateString ) {
24693				list.add(
24694					function() {
24695
24696						// state = "resolved" (i.e., fulfilled)
24697						// state = "rejected"
24698						state = stateString;
24699					},
24700
24701					// rejected_callbacks.disable
24702					// fulfilled_callbacks.disable
24703					tuples[ 3 - i ][ 2 ].disable,
24704
24705					// rejected_handlers.disable
24706					// fulfilled_handlers.disable
24707					tuples[ 3 - i ][ 3 ].disable,
24708
24709					// progress_callbacks.lock
24710					tuples[ 0 ][ 2 ].lock,
24711
24712					// progress_handlers.lock
24713					tuples[ 0 ][ 3 ].lock
24714				);
24715			}
24716
24717			// progress_handlers.fire
24718			// fulfilled_handlers.fire
24719			// rejected_handlers.fire
24720			list.add( tuple[ 3 ].fire );
24721
24722			// deferred.notify = function() { deferred.notifyWith(...) }
24723			// deferred.resolve = function() { deferred.resolveWith(...) }
24724			// deferred.reject = function() { deferred.rejectWith(...) }
24725			deferred[ tuple[ 0 ] ] = function() {
24726				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
24727				return this;
24728			};
24729
24730			// deferred.notifyWith = list.fireWith
24731			// deferred.resolveWith = list.fireWith
24732			// deferred.rejectWith = list.fireWith
24733			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
24734		} );
24735
24736		// Make the deferred a promise
24737		promise.promise( deferred );
24738
24739		// Call given func if any
24740		if ( func ) {
24741			func.call( deferred, deferred );
24742		}
24743
24744		// All done!
24745		return deferred;
24746	},
24747
24748	// Deferred helper
24749	when: function( singleValue ) {
24750		var
24751
24752			// count of uncompleted subordinates
24753			remaining = arguments.length,
24754
24755			// count of unprocessed arguments
24756			i = remaining,
24757
24758			// subordinate fulfillment data
24759			resolveContexts = Array( i ),
24760			resolveValues = slice.call( arguments ),
24761
24762			// the master Deferred
24763			master = jQuery.Deferred(),
24764
24765			// subordinate callback factory
24766			updateFunc = function( i ) {
24767				return function( value ) {
24768					resolveContexts[ i ] = this;
24769					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
24770					if ( !( --remaining ) ) {
24771						master.resolveWith( resolveContexts, resolveValues );
24772					}
24773				};
24774			};
24775
24776		// Single- and empty arguments are adopted like Promise.resolve
24777		if ( remaining <= 1 ) {
24778			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
24779				!remaining );
24780
24781			// Use .then() to unwrap secondary thenables (cf. gh-3000)
24782			if ( master.state() === "pending" ||
24783				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
24784
24785				return master.then();
24786			}
24787		}
24788
24789		// Multiple arguments are aggregated like Promise.all array elements
24790		while ( i-- ) {
24791			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
24792		}
24793
24794		return master.promise();
24795	}
24796} );
24797
24798
24799// These usually indicate a programmer mistake during development,
24800// warn about them ASAP rather than swallowing them by default.
24801var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
24802
24803jQuery.Deferred.exceptionHook = function( error, stack ) {
24804
24805	// Support: IE 8 - 9 only
24806	// Console exists when dev tools are open, which can happen at any time
24807	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
24808		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
24809	}
24810};
24811
24812
24813
24814
24815jQuery.readyException = function( error ) {
24816	window.setTimeout( function() {
24817		throw error;
24818	} );
24819};
24820
24821
24822
24823
24824// The deferred used on DOM ready
24825var readyList = jQuery.Deferred();
24826
24827jQuery.fn.ready = function( fn ) {
24828
24829	readyList
24830		.then( fn )
24831
24832		// Wrap jQuery.readyException in a function so that the lookup
24833		// happens at the time of error handling instead of callback
24834		// registration.
24835		.catch( function( error ) {
24836			jQuery.readyException( error );
24837		} );
24838
24839	return this;
24840};
24841
24842jQuery.extend( {
24843
24844	// Is the DOM ready to be used? Set to true once it occurs.
24845	isReady: false,
24846
24847	// A counter to track how many items to wait for before
24848	// the ready event fires. See #6781
24849	readyWait: 1,
24850
24851	// Handle when the DOM is ready
24852	ready: function( wait ) {
24853
24854		// Abort if there are pending holds or we're already ready
24855		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
24856			return;
24857		}
24858
24859		// Remember that the DOM is ready
24860		jQuery.isReady = true;
24861
24862		// If a normal DOM Ready event fired, decrement, and wait if need be
24863		if ( wait !== true && --jQuery.readyWait > 0 ) {
24864			return;
24865		}
24866
24867		// If there are functions bound, to execute
24868		readyList.resolveWith( document, [ jQuery ] );
24869	}
24870} );
24871
24872jQuery.ready.then = readyList.then;
24873
24874// The ready event handler and self cleanup method
24875function completed() {
24876	document.removeEventListener( "DOMContentLoaded", completed );
24877	window.removeEventListener( "load", completed );
24878	jQuery.ready();
24879}
24880
24881// Catch cases where $(document).ready() is called
24882// after the browser event has already occurred.
24883// Support: IE <=9 - 10 only
24884// Older IE sometimes signals "interactive" too soon
24885if ( document.readyState === "complete" ||
24886	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
24887
24888	// Handle it asynchronously to allow scripts the opportunity to delay ready
24889	window.setTimeout( jQuery.ready );
24890
24891} else {
24892
24893	// Use the handy event callback
24894	document.addEventListener( "DOMContentLoaded", completed );
24895
24896	// A fallback to window.onload, that will always work
24897	window.addEventListener( "load", completed );
24898}
24899
24900
24901
24902
24903// Multifunctional method to get and set values of a collection
24904// The value/s can optionally be executed if it's a function
24905var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
24906	var i = 0,
24907		len = elems.length,
24908		bulk = key == null;
24909
24910	// Sets many values
24911	if ( toType( key ) === "object" ) {
24912		chainable = true;
24913		for ( i in key ) {
24914			access( elems, fn, i, key[ i ], true, emptyGet, raw );
24915		}
24916
24917	// Sets one value
24918	} else if ( value !== undefined ) {
24919		chainable = true;
24920
24921		if ( !isFunction( value ) ) {
24922			raw = true;
24923		}
24924
24925		if ( bulk ) {
24926
24927			// Bulk operations run against the entire set
24928			if ( raw ) {
24929				fn.call( elems, value );
24930				fn = null;
24931
24932			// ...except when executing function values
24933			} else {
24934				bulk = fn;
24935				fn = function( elem, key, value ) {
24936					return bulk.call( jQuery( elem ), value );
24937				};
24938			}
24939		}
24940
24941		if ( fn ) {
24942			for ( ; i < len; i++ ) {
24943				fn(
24944					elems[ i ], key, raw ?
24945					value :
24946					value.call( elems[ i ], i, fn( elems[ i ], key ) )
24947				);
24948			}
24949		}
24950	}
24951
24952	if ( chainable ) {
24953		return elems;
24954	}
24955
24956	// Gets
24957	if ( bulk ) {
24958		return fn.call( elems );
24959	}
24960
24961	return len ? fn( elems[ 0 ], key ) : emptyGet;
24962};
24963
24964
24965// Matches dashed string for camelizing
24966var rmsPrefix = /^-ms-/,
24967	rdashAlpha = /-([a-z])/g;
24968
24969// Used by camelCase as callback to replace()
24970function fcamelCase( all, letter ) {
24971	return letter.toUpperCase();
24972}
24973
24974// Convert dashed to camelCase; used by the css and data modules
24975// Support: IE <=9 - 11, Edge 12 - 15
24976// Microsoft forgot to hump their vendor prefix (#9572)
24977function camelCase( string ) {
24978	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
24979}
24980var acceptData = function( owner ) {
24981
24982	// Accepts only:
24983	//  - Node
24984	//    - Node.ELEMENT_NODE
24985	//    - Node.DOCUMENT_NODE
24986	//  - Object
24987	//    - Any
24988	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
24989};
24990
24991
24992
24993
24994function Data() {
24995	this.expando = jQuery.expando + Data.uid++;
24996}
24997
24998Data.uid = 1;
24999
25000Data.prototype = {
25001
25002	cache: function( owner ) {
25003
25004		// Check if the owner object already has a cache
25005		var value = owner[ this.expando ];
25006
25007		// If not, create one
25008		if ( !value ) {
25009			value = {};
25010
25011			// We can accept data for non-element nodes in modern browsers,
25012			// but we should not, see #8335.
25013			// Always return an empty object.
25014			if ( acceptData( owner ) ) {
25015
25016				// If it is a node unlikely to be stringify-ed or looped over
25017				// use plain assignment
25018				if ( owner.nodeType ) {
25019					owner[ this.expando ] = value;
25020
25021				// Otherwise secure it in a non-enumerable property
25022				// configurable must be true to allow the property to be
25023				// deleted when data is removed
25024				} else {
25025					Object.defineProperty( owner, this.expando, {
25026						value: value,
25027						configurable: true
25028					} );
25029				}
25030			}
25031		}
25032
25033		return value;
25034	},
25035	set: function( owner, data, value ) {
25036		var prop,
25037			cache = this.cache( owner );
25038
25039		// Handle: [ owner, key, value ] args
25040		// Always use camelCase key (gh-2257)
25041		if ( typeof data === "string" ) {
25042			cache[ camelCase( data ) ] = value;
25043
25044		// Handle: [ owner, { properties } ] args
25045		} else {
25046
25047			// Copy the properties one-by-one to the cache object
25048			for ( prop in data ) {
25049				cache[ camelCase( prop ) ] = data[ prop ];
25050			}
25051		}
25052		return cache;
25053	},
25054	get: function( owner, key ) {
25055		return key === undefined ?
25056			this.cache( owner ) :
25057
25058			// Always use camelCase key (gh-2257)
25059			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
25060	},
25061	access: function( owner, key, value ) {
25062
25063		// In cases where either:
25064		//
25065		//   1. No key was specified
vendor: 10,628 bytes, lines 25066-25497
25066		//   2. A string key was specified, but no value provided
25067		//
25068		// Take the "read" path and allow the get method to determine
25069		// which value to return, respectively either:
25070		//
25071		//   1. The entire cache object
25072		//   2. The data stored at the key
25073		//
25074		if ( key === undefined ||
25075				( ( key && typeof key === "string" ) && value === undefined ) ) {
25076
25077			return this.get( owner, key );
25078		}
25079
25080		// When the key is not a string, or both a key and value
25081		// are specified, set or extend (existing objects) with either:
25082		//
25083		//   1. An object of properties
25084		//   2. A key and value
25085		//
25086		this.set( owner, key, value );
25087
25088		// Since the "set" path can have two possible entry points
25089		// return the expected data based on which path was taken[*]
25090		return value !== undefined ? value : key;
25091	},
25092	remove: function( owner, key ) {
25093		var i,
25094			cache = owner[ this.expando ];
25095
25096		if ( cache === undefined ) {
25097			return;
25098		}
25099
25100		if ( key !== undefined ) {
25101
25102			// Support array or space separated string of keys
25103			if ( Array.isArray( key ) ) {
25104
25105				// If key is an array of keys...
25106				// We always set camelCase keys, so remove that.
25107				key = key.map( camelCase );
25108			} else {
25109				key = camelCase( key );
25110
25111				// If a key with the spaces exists, use it.
25112				// Otherwise, create an array by matching non-whitespace
25113				key = key in cache ?
25114					[ key ] :
25115					( key.match( rnothtmlwhite ) || [] );
25116			}
25117
25118			i = key.length;
25119
25120			while ( i-- ) {
25121				delete cache[ key[ i ] ];
25122			}
25123		}
25124
25125		// Remove the expando if there's no more data
25126		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
25127
25128			// Support: Chrome <=35 - 45
25129			// Webkit & Blink performance suffers when deleting properties
25130			// from DOM nodes, so set to undefined instead
25131			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
25132			if ( owner.nodeType ) {
25133				owner[ this.expando ] = undefined;
25134			} else {
25135				delete owner[ this.expando ];
25136			}
25137		}
25138	},
25139	hasData: function( owner ) {
25140		var cache = owner[ this.expando ];
25141		return cache !== undefined && !jQuery.isEmptyObject( cache );
25142	}
25143};
25144var dataPriv = new Data();
25145
25146var dataUser = new Data();
25147
25148
25149
25150//	Implementation Summary
25151//
25152//	1. Enforce API surface and semantic compatibility with 1.9.x branch
25153//	2. Improve the module's maintainability by reducing the storage
25154//		paths to a single mechanism.
25155//	3. Use the same single mechanism to support "private" and "user" data.
25156//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
25157//	5. Avoid exposing implementation details on user objects (eg. expando properties)
25158//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
25159
25160var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
25161	rmultiDash = /[A-Z]/g;
25162
25163function getData( data ) {
25164	if ( data === "true" ) {
25165		return true;
25166	}
25167
25168	if ( data === "false" ) {
25169		return false;
25170	}
25171
25172	if ( data === "null" ) {
25173		return null;
25174	}
25175
25176	// Only convert to a number if it doesn't change the string
25177	if ( data === +data + "" ) {
25178		return +data;
25179	}
25180
25181	if ( rbrace.test( data ) ) {
25182		return JSON.parse( data );
25183	}
25184
25185	return data;
25186}
25187
25188function dataAttr( elem, key, data ) {
25189	var name;
25190
25191	// If nothing was found internally, try to fetch any
25192	// data from the HTML5 data-* attribute
25193	if ( data === undefined && elem.nodeType === 1 ) {
25194		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
25195		data = elem.getAttribute( name );
25196
25197		if ( typeof data === "string" ) {
25198			try {
25199				data = getData( data );
25200			} catch ( e ) {}
25201
25202			// Make sure we set the data so it isn't changed later
25203			dataUser.set( elem, key, data );
25204		} else {
25205			data = undefined;
25206		}
25207	}
25208	return data;
25209}
25210
25211jQuery.extend( {
25212	hasData: function( elem ) {
25213		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
25214	},
25215
25216	data: function( elem, name, data ) {
25217		return dataUser.access( elem, name, data );
25218	},
25219
25220	removeData: function( elem, name ) {
25221		dataUser.remove( elem, name );
25222	},
25223
25224	// TODO: Now that all calls to _data and _removeData have been replaced
25225	// with direct calls to dataPriv methods, these can be deprecated.
25226	_data: function( elem, name, data ) {
25227		return dataPriv.access( elem, name, data );
25228	},
25229
25230	_removeData: function( elem, name ) {
25231		dataPriv.remove( elem, name );
25232	}
25233} );
25234
25235jQuery.fn.extend( {
25236	data: function( key, value ) {
25237		var i, name, data,
25238			elem = this[ 0 ],
25239			attrs = elem && elem.attributes;
25240
25241		// Gets all values
25242		if ( key === undefined ) {
25243			if ( this.length ) {
25244				data = dataUser.get( elem );
25245
25246				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
25247					i = attrs.length;
25248					while ( i-- ) {
25249
25250						// Support: IE 11 only
25251						// The attrs elements can be null (#14894)
25252						if ( attrs[ i ] ) {
25253							name = attrs[ i ].name;
25254							if ( name.indexOf( "data-" ) === 0 ) {
25255								name = camelCase( name.slice( 5 ) );
25256								dataAttr( elem, name, data[ name ] );
25257							}
25258						}
25259					}
25260					dataPriv.set( elem, "hasDataAttrs", true );
25261				}
25262			}
25263
25264			return data;
25265		}
25266
25267		// Sets multiple values
25268		if ( typeof key === "object" ) {
25269			return this.each( function() {
25270				dataUser.set( this, key );
25271			} );
25272		}
25273
25274		return access( this, function( value ) {
25275			var data;
25276
25277			// The calling jQuery object (element matches) is not empty
25278			// (and therefore has an element appears at this[ 0 ]) and the
25279			// `value` parameter was not undefined. An empty jQuery object
25280			// will result in `undefined` for elem = this[ 0 ] which will
25281			// throw an exception if an attempt to read a data cache is made.
25282			if ( elem && value === undefined ) {
25283
25284				// Attempt to get data from the cache
25285				// The key will always be camelCased in Data
25286				data = dataUser.get( elem, key );
25287				if ( data !== undefined ) {
25288					return data;
25289				}
25290
25291				// Attempt to "discover" the data in
25292				// HTML5 custom data-* attrs
25293				data = dataAttr( elem, key );
25294				if ( data !== undefined ) {
25295					return data;
25296				}
25297
25298				// We tried really hard, but the data doesn't exist.
25299				return;
25300			}
25301
25302			// Set the data...
25303			this.each( function() {
25304
25305				// We always store the camelCased key
25306				dataUser.set( this, key, value );
25307			} );
25308		}, null, value, arguments.length > 1, null, true );
25309	},
25310
25311	removeData: function( key ) {
25312		return this.each( function() {
25313			dataUser.remove( this, key );
25314		} );
25315	}
25316} );
25317
25318
25319jQuery.extend( {
25320	queue: function( elem, type, data ) {
25321		var queue;
25322
25323		if ( elem ) {
25324			type = ( type || "fx" ) + "queue";
25325			queue = dataPriv.get( elem, type );
25326
25327			// Speed up dequeue by getting out quickly if this is just a lookup
25328			if ( data ) {
25329				if ( !queue || Array.isArray( data ) ) {
25330					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
25331				} else {
25332					queue.push( data );
25333				}
25334			}
25335			return queue || [];
25336		}
25337	},
25338
25339	dequeue: function( elem, type ) {
25340		type = type || "fx";
25341
25342		var queue = jQuery.queue( elem, type ),
25343			startLength = queue.length,
25344			fn = queue.shift(),
25345			hooks = jQuery._queueHooks( elem, type ),
25346			next = function() {
25347				jQuery.dequeue( elem, type );
25348			};
25349
25350		// If the fx queue is dequeued, always remove the progress sentinel
25351		if ( fn === "inprogress" ) {
25352			fn = queue.shift();
25353			startLength--;
25354		}
25355
25356		if ( fn ) {
25357
25358			// Add a progress sentinel to prevent the fx queue from being
25359			// automatically dequeued
25360			if ( type === "fx" ) {
25361				queue.unshift( "inprogress" );
25362			}
25363
25364			// Clear up the last queue stop function
25365			delete hooks.stop;
25366			fn.call( elem, next, hooks );
25367		}
25368
25369		if ( !startLength && hooks ) {
25370			hooks.empty.fire();
25371		}
25372	},
25373
25374	// Not public - generate a queueHooks object, or return the current one
25375	_queueHooks: function( elem, type ) {
25376		var key = type + "queueHooks";
25377		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
25378			empty: jQuery.Callbacks( "once memory" ).add( function() {
25379				dataPriv.remove( elem, [ type + "queue", key ] );
25380			} )
25381		} );
25382	}
25383} );
25384
25385jQuery.fn.extend( {
25386	queue: function( type, data ) {
25387		var setter = 2;
25388
25389		if ( typeof type !== "string" ) {
25390			data = type;
25391			type = "fx";
25392			setter--;
25393		}
25394
25395		if ( arguments.length < setter ) {
25396			return jQuery.queue( this[ 0 ], type );
25397		}
25398
25399		return data === undefined ?
25400			this :
25401			this.each( function() {
25402				var queue = jQuery.queue( this, type, data );
25403
25404				// Ensure a hooks for this queue
25405				jQuery._queueHooks( this, type );
25406
25407				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
25408					jQuery.dequeue( this, type );
25409				}
25410			} );
25411	},
25412	dequeue: function( type ) {
25413		return this.each( function() {
25414			jQuery.dequeue( this, type );
25415		} );
25416	},
25417	clearQueue: function( type ) {
25418		return this.queue( type || "fx", [] );
25419	},
25420
25421	// Get a promise resolved when queues of a certain type
25422	// are emptied (fx is the type by default)
25423	promise: function( type, obj ) {
25424		var tmp,
25425			count = 1,
25426			defer = jQuery.Deferred(),
25427			elements = this,
25428			i = this.length,
25429			resolve = function() {
25430				if ( !( --count ) ) {
25431					defer.resolveWith( elements, [ elements ] );
25432				}
25433			};
25434
25435		if ( typeof type !== "string" ) {
25436			obj = type;
25437			type = undefined;
25438		}
25439		type = type || "fx";
25440
25441		while ( i-- ) {
25442			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
25443			if ( tmp && tmp.empty ) {
25444				count++;
25445				tmp.empty.add( resolve );
25446			}
25447		}
25448		resolve();
25449		return defer.promise( obj );
25450	}
25451} );
25452var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
25453
25454var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
25455
25456
25457var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
25458
25459var documentElement = document.documentElement;
25460
25461
25462
25463	var isAttached = function( elem ) {
25464			return jQuery.contains( elem.ownerDocument, elem );
25465		},
25466		composed = { composed: true };
25467
25468	// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
25469	// Check attachment across shadow DOM boundaries when possible (gh-3504)
25470	// Support: iOS 10.0-10.2 only
25471	// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
25472	// leading to errors. We need to check for `getRootNode`.
25473	if ( documentElement.getRootNode ) {
25474		isAttached = function( elem ) {
25475			return jQuery.contains( elem.ownerDocument, elem ) ||
25476				elem.getRootNode( composed ) === elem.ownerDocument;
25477		};
25478	}
25479var isHiddenWithinTree = function( elem, el ) {
25480
25481		// isHiddenWithinTree might be called from jQuery#filter function;
25482		// in that case, element will be second argument
25483		elem = el || elem;
25484
25485		// Inline style trumps all
25486		return elem.style.display === "none" ||
25487			elem.style.display === "" &&
25488
25489			// Otherwise, check computed style
25490			// Support: Firefox <=43 - 45
25491			// Disconnected elements can have computed display: none, so first confirm that elem is
25492			// in the document.
25493			isAttached( elem ) &&
25494
25495			jQuery.css( elem, "display" ) === "none";
25496	};
25497
vendor: 2,487 bytes, lines 25498-25595
25498var swap = function( elem, options, callback, args ) {
25499	var ret, name,
25500		old = {};
25501
25502	// Remember the old values, and insert the new ones
25503	for ( name in options ) {
25504		old[ name ] = elem.style[ name ];
25505		elem.style[ name ] = options[ name ];
25506	}
25507
25508	ret = callback.apply( elem, args || [] );
25509
25510	// Revert the old values
25511	for ( name in options ) {
25512		elem.style[ name ] = old[ name ];
25513	}
25514
25515	return ret;
25516};
25517
25518
25519
25520
25521function adjustCSS( elem, prop, valueParts, tween ) {
25522	var adjusted, scale,
25523		maxIterations = 20,
25524		currentValue = tween ?
25525			function() {
25526				return tween.cur();
25527			} :
25528			function() {
25529				return jQuery.css( elem, prop, "" );
25530			},
25531		initial = currentValue(),
25532		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
25533
25534		// Starting value computation is required for potential unit mismatches
25535		initialInUnit = elem.nodeType &&
25536			( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
25537			rcssNum.exec( jQuery.css( elem, prop ) );
25538
25539	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
25540
25541		// Support: Firefox <=54
25542		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
25543		initial = initial / 2;
25544
25545		// Trust units reported by jQuery.css
25546		unit = unit || initialInUnit[ 3 ];
25547
25548		// Iteratively approximate from a nonzero starting point
25549		initialInUnit = +initial || 1;
25550
25551		while ( maxIterations-- ) {
25552
25553			// Evaluate and update our best guess (doubling guesses that zero out).
25554			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
25555			jQuery.style( elem, prop, initialInUnit + unit );
25556			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
25557				maxIterations = 0;
25558			}
25559			initialInUnit = initialInUnit / scale;
25560
25561		}
25562
25563		initialInUnit = initialInUnit * 2;
25564		jQuery.style( elem, prop, initialInUnit + unit );
25565
25566		// Make sure we update the tween properties later on
25567		valueParts = valueParts || [];
25568	}
25569
25570	if ( valueParts ) {
25571		initialInUnit = +initialInUnit || +initial || 0;
25572
25573		// Apply relative offset (+=/-=) if specified
25574		adjusted = valueParts[ 1 ] ?
25575			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
25576			+valueParts[ 2 ];
25577		if ( tween ) {
25578			tween.unit = unit;
25579			tween.start = initialInUnit;
25580			tween.end = adjusted;
25581		}
25582	}
25583	return adjusted;
25584}
25585
25586
25587var defaultDisplayMap = {};
25588
25589function getDefaultDisplay( elem ) {
25590	var temp,
25591		doc = elem.ownerDocument,
25592		nodeName = elem.nodeName,
25593		display = defaultDisplayMap[ nodeName ];
25594
25595	if ( display ) {
vendor: 4,818 bytes, lines 25596-25791
25596		return display;
25597	}
25598
25599	temp = doc.body.appendChild( doc.createElement( nodeName ) );
25600	display = jQuery.css( temp, "display" );
25601
25602	temp.parentNode.removeChild( temp );
25603
25604	if ( display === "none" ) {
25605		display = "block";
25606	}
25607	defaultDisplayMap[ nodeName ] = display;
25608
25609	return display;
25610}
25611
25612function showHide( elements, show ) {
25613	var display, elem,
25614		values = [],
25615		index = 0,
25616		length = elements.length;
25617
25618	// Determine new display value for elements that need to change
25619	for ( ; index < length; index++ ) {
25620		elem = elements[ index ];
25621		if ( !elem.style ) {
25622			continue;
25623		}
25624
25625		display = elem.style.display;
25626		if ( show ) {
25627
25628			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
25629			// check is required in this first loop unless we have a nonempty display value (either
25630			// inline or about-to-be-restored)
25631			if ( display === "none" ) {
25632				values[ index ] = dataPriv.get( elem, "display" ) || null;
25633				if ( !values[ index ] ) {
25634					elem.style.display = "";
25635				}
25636			}
25637			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
25638				values[ index ] = getDefaultDisplay( elem );
25639			}
25640		} else {
25641			if ( display !== "none" ) {
25642				values[ index ] = "none";
25643
25644				// Remember what we're overwriting
25645				dataPriv.set( elem, "display", display );
25646			}
25647		}
25648	}
25649
25650	// Set the display of the elements in a second loop to avoid constant reflow
25651	for ( index = 0; index < length; index++ ) {
25652		if ( values[ index ] != null ) {
25653			elements[ index ].style.display = values[ index ];
25654		}
25655	}
25656
25657	return elements;
25658}
25659
25660jQuery.fn.extend( {
25661	show: function() {
25662		return showHide( this, true );
25663	},
25664	hide: function() {
25665		return showHide( this );
25666	},
25667	toggle: function( state ) {
25668		if ( typeof state === "boolean" ) {
25669			return state ? this.show() : this.hide();
25670		}
25671
25672		return this.each( function() {
25673			if ( isHiddenWithinTree( this ) ) {
25674				jQuery( this ).show();
25675			} else {
25676				jQuery( this ).hide();
25677			}
25678		} );
25679	}
25680} );
25681var rcheckableType = ( /^(?:checkbox|radio)$/i );
25682
25683var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
25684
25685var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
25686
25687
25688
25689// We have to close these tags to support XHTML (#13200)
25690var wrapMap = {
25691
25692	// Support: IE <=9 only
25693	option: [ 1, "<select multiple='multiple'>", "</select>" ],
25694
25695	// XHTML parsers do not magically insert elements in the
25696	// same way that tag soup parsers do. So we cannot shorten
25697	// this by omitting <tbody> or other required elements.
25698	thead: [ 1, "<table>", "</table>" ],
25699	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
25700	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
25701	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
25702
25703	_default: [ 0, "", "" ]
25704};
25705
25706// Support: IE <=9 only
25707wrapMap.optgroup = wrapMap.option;
25708
25709wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
25710wrapMap.th = wrapMap.td;
25711
25712
25713function getAll( context, tag ) {
25714
25715	// Support: IE <=9 - 11 only
25716	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
25717	var ret;
25718
25719	if ( typeof context.getElementsByTagName !== "undefined" ) {
25720		ret = context.getElementsByTagName( tag || "*" );
25721
25722	} else if ( typeof context.querySelectorAll !== "undefined" ) {
25723		ret = context.querySelectorAll( tag || "*" );
25724
25725	} else {
25726		ret = [];
25727	}
25728
25729	if ( tag === undefined || tag && nodeName( context, tag ) ) {
25730		return jQuery.merge( [ context ], ret );
25731	}
25732
25733	return ret;
25734}
25735
25736
25737// Mark scripts as having already been evaluated
25738function setGlobalEval( elems, refElements ) {
25739	var i = 0,
25740		l = elems.length;
25741
25742	for ( ; i < l; i++ ) {
25743		dataPriv.set(
25744			elems[ i ],
25745			"globalEval",
25746			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
25747		);
25748	}
25749}
25750
25751
25752var rhtml = /<|&#?\w+;/;
25753
25754function buildFragment( elems, context, scripts, selection, ignored ) {
25755	var elem, tmp, tag, wrap, attached, j,
25756		fragment = context.createDocumentFragment(),
25757		nodes = [],
25758		i = 0,
25759		l = elems.length;
25760
25761	for ( ; i < l; i++ ) {
25762		elem = elems[ i ];
25763
25764		if ( elem || elem === 0 ) {
25765
25766			// Add nodes directly
25767			if ( toType( elem ) === "object" ) {
25768
25769				// Support: Android <=4.0 only, PhantomJS 1 only
25770				// push.apply(_, arraylike) throws on ancient WebKit
25771				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
25772
25773			// Convert non-html into a text node
25774			} else if ( !rhtml.test( elem ) ) {
25775				nodes.push( context.createTextNode( elem ) );
25776
25777			// Convert html into DOM nodes
25778			} else {
25779				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
25780
25781				// Deserialize a standard representation
25782				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
25783				wrap = wrapMap[ tag ] || wrapMap._default;
25784				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
25785
25786				// Descend through wrappers to the right content
25787				j = wrap[ 0 ];
25788				while ( j-- ) {
25789					tmp = tmp.lastChild;
25790				}
25791
vendor: 1,252 bytes, lines 25792-25849
25792				// Support: Android <=4.0 only, PhantomJS 1 only
25793				// push.apply(_, arraylike) throws on ancient WebKit
25794				jQuery.merge( nodes, tmp.childNodes );
25795
25796				// Remember the top-level container
25797				tmp = fragment.firstChild;
25798
25799				// Ensure the created nodes are orphaned (#12392)
25800				tmp.textContent = "";
25801			}
25802		}
25803	}
25804
25805	// Remove wrapper from fragment
25806	fragment.textContent = "";
25807
25808	i = 0;
25809	while ( ( elem = nodes[ i++ ] ) ) {
25810
25811		// Skip elements already in the context collection (trac-4087)
25812		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
25813			if ( ignored ) {
25814				ignored.push( elem );
25815			}
25816			continue;
25817		}
25818
25819		attached = isAttached( elem );
25820
25821		// Append to fragment
25822		tmp = getAll( fragment.appendChild( elem ), "script" );
25823
25824		// Preserve script evaluation history
25825		if ( attached ) {
25826			setGlobalEval( tmp );
25827		}
25828
25829		// Capture executables
25830		if ( scripts ) {
25831			j = 0;
25832			while ( ( elem = tmp[ j++ ] ) ) {
25833				if ( rscriptType.test( elem.type || "" ) ) {
25834					scripts.push( elem );
25835				}
25836			}
25837		}
25838	}
25839
25840	return fragment;
25841}
25842
25843
25844( function() {
25845	var fragment = document.createDocumentFragment(),
25846		div = fragment.appendChild( document.createElement( "div" ) ),
25847		input = document.createElement( "input" );
25848
25849	// Support: Android 4.0 - 4.3 only
vendor: 6,890 bytes, lines 25850-26096
25850	// Check state lost if the name is set (#11217)
25851	// Support: Windows Web Apps (WWA)
25852	// `name` and `type` must use .setAttribute for WWA (#14901)
25853	input.setAttribute( "type", "radio" );
25854	input.setAttribute( "checked", "checked" );
25855	input.setAttribute( "name", "t" );
25856
25857	div.appendChild( input );
25858
25859	// Support: Android <=4.1 only
25860	// Older WebKit doesn't clone checked state correctly in fragments
25861	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
25862
25863	// Support: IE <=11 only
25864	// Make sure textarea (and checkbox) defaultValue is properly cloned
25865	div.innerHTML = "<textarea>x</textarea>";
25866	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
25867} )();
25868
25869
25870var
25871	rkeyEvent = /^key/,
25872	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
25873	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
25874
25875function returnTrue() {
25876	return true;
25877}
25878
25879function returnFalse() {
25880	return false;
25881}
25882
25883// Support: IE <=9 - 11+
25884// focus() and blur() are asynchronous, except when they are no-op.
25885// So expect focus to be synchronous when the element is already active,
25886// and blur to be synchronous when the element is not already active.
25887// (focus and blur are always synchronous in other supported browsers,
25888// this just defines when we can count on it).
25889function expectSync( elem, type ) {
25890	return ( elem === safeActiveElement() ) === ( type === "focus" );
25891}
25892
25893// Support: IE <=9 only
25894// Accessing document.activeElement can throw unexpectedly
25895// https://bugs.jquery.com/ticket/13393
25896function safeActiveElement() {
25897	try {
25898		return document.activeElement;
25899	} catch ( err ) { }
25900}
25901
25902function on( elem, types, selector, data, fn, one ) {
25903	var origFn, type;
25904
25905	// Types can be a map of types/handlers
25906	if ( typeof types === "object" ) {
25907
25908		// ( types-Object, selector, data )
25909		if ( typeof selector !== "string" ) {
25910
25911			// ( types-Object, data )
25912			data = data || selector;
25913			selector = undefined;
25914		}
25915		for ( type in types ) {
25916			on( elem, type, selector, data, types[ type ], one );
25917		}
25918		return elem;
25919	}
25920
25921	if ( data == null && fn == null ) {
25922
25923		// ( types, fn )
25924		fn = selector;
25925		data = selector = undefined;
25926	} else if ( fn == null ) {
25927		if ( typeof selector === "string" ) {
25928
25929			// ( types, selector, fn )
25930			fn = data;
25931			data = undefined;
25932		} else {
25933
25934			// ( types, data, fn )
25935			fn = data;
25936			data = selector;
25937			selector = undefined;
25938		}
25939	}
25940	if ( fn === false ) {
25941		fn = returnFalse;
25942	} else if ( !fn ) {
25943		return elem;
25944	}
25945
25946	if ( one === 1 ) {
25947		origFn = fn;
25948		fn = function( event ) {
25949
25950			// Can use an empty set, since event contains the info
25951			jQuery().off( event );
25952			return origFn.apply( this, arguments );
25953		};
25954
25955		// Use same guid so caller can remove using origFn
25956		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
25957	}
25958	return elem.each( function() {
25959		jQuery.event.add( this, types, fn, data, selector );
25960	} );
25961}
25962
25963/*
25964 * Helper functions for managing events -- not part of the public interface.
25965 * Props to Dean Edwards' addEvent library for many of the ideas.
25966 */
25967jQuery.event = {
25968
25969	global: {},
25970
25971	add: function( elem, types, handler, data, selector ) {
25972
25973		var handleObjIn, eventHandle, tmp,
25974			events, t, handleObj,
25975			special, handlers, type, namespaces, origType,
25976			elemData = dataPriv.get( elem );
25977
25978		// Don't attach events to noData or text/comment nodes (but allow plain objects)
25979		if ( !elemData ) {
25980			return;
25981		}
25982
25983		// Caller can pass in an object of custom data in lieu of the handler
25984		if ( handler.handler ) {
25985			handleObjIn = handler;
25986			handler = handleObjIn.handler;
25987			selector = handleObjIn.selector;
25988		}
25989
25990		// Ensure that invalid selectors throw exceptions at attach time
25991		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
25992		if ( selector ) {
25993			jQuery.find.matchesSelector( documentElement, selector );
25994		}
25995
25996		// Make sure that the handler has a unique ID, used to find/remove it later
25997		if ( !handler.guid ) {
25998			handler.guid = jQuery.guid++;
25999		}
26000
26001		// Init the element's event structure and main handler, if this is the first
26002		if ( !( events = elemData.events ) ) {
26003			events = elemData.events = {};
26004		}
26005		if ( !( eventHandle = elemData.handle ) ) {
26006			eventHandle = elemData.handle = function( e ) {
26007
26008				// Discard the second event of a jQuery.event.trigger() and
26009				// when an event is called after a page has unloaded
26010				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
26011					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
26012			};
26013		}
26014
26015		// Handle multiple events separated by a space
26016		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
26017		t = types.length;
26018		while ( t-- ) {
26019			tmp = rtypenamespace.exec( types[ t ] ) || [];
26020			type = origType = tmp[ 1 ];
26021			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
26022
26023			// There *must* be a type, no attaching namespace-only handlers
26024			if ( !type ) {
26025				continue;
26026			}
26027
26028			// If event changes its type, use the special event handlers for the changed type
26029			special = jQuery.event.special[ type ] || {};
26030
26031			// If selector defined, determine special event api type, otherwise given type
26032			type = ( selector ? special.delegateType : special.bindType ) || type;
26033
26034			// Update special based on newly reset type
26035			special = jQuery.event.special[ type ] || {};
26036
26037			// handleObj is passed to all event handlers
26038			handleObj = jQuery.extend( {
26039				type: type,
26040				origType: origType,
26041				data: data,
26042				handler: handler,
26043				guid: handler.guid,
26044				selector: selector,
26045				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
26046				namespace: namespaces.join( "." )
26047			}, handleObjIn );
26048
26049			// Init the event handler queue if we're the first
26050			if ( !( handlers = events[ type ] ) ) {
26051				handlers = events[ type ] = [];
26052				handlers.delegateCount = 0;
26053
26054				// Only use addEventListener if the special events handler returns false
26055				if ( !special.setup ||
26056					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
26057
26058					if ( elem.addEventListener ) {
26059						elem.addEventListener( type, eventHandle );
26060					}
26061				}
26062			}
26063
26064			if ( special.add ) {
26065				special.add.call( elem, handleObj );
26066
26067				if ( !handleObj.handler.guid ) {
26068					handleObj.handler.guid = handler.guid;
26069				}
26070			}
26071
26072			// Add to the element's handler list, delegates in front
26073			if ( selector ) {
26074				handlers.splice( handlers.delegateCount++, 0, handleObj );
26075			} else {
26076				handlers.push( handleObj );
26077			}
26078
26079			// Keep track of which events have ever been used, for event optimization
26080			jQuery.event.global[ type ] = true;
26081		}
26082
26083	},
26084
26085	// Detach an event or set of events from an element
26086	remove: function( elem, types, handler, selector, mappedTypes ) {
26087
26088		var j, origCount, tmp,
26089			events, t, handleObj,
26090			special, handlers, type, namespaces, origType,
26091			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
26092
26093		if ( !elemData || !( events = elemData.events ) ) {
26094			return;
26095		}
26096
vendor: 4,172 bytes, lines 26097-26232
26097		// Once for each type.namespace in types; type may be omitted
26098		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
26099		t = types.length;
26100		while ( t-- ) {
26101			tmp = rtypenamespace.exec( types[ t ] ) || [];
26102			type = origType = tmp[ 1 ];
26103			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
26104
26105			// Unbind all events (on this namespace, if provided) for the element
26106			if ( !type ) {
26107				for ( type in events ) {
26108					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
26109				}
26110				continue;
26111			}
26112
26113			special = jQuery.event.special[ type ] || {};
26114			type = ( selector ? special.delegateType : special.bindType ) || type;
26115			handlers = events[ type ] || [];
26116			tmp = tmp[ 2 ] &&
26117				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
26118
26119			// Remove matching events
26120			origCount = j = handlers.length;
26121			while ( j-- ) {
26122				handleObj = handlers[ j ];
26123
26124				if ( ( mappedTypes || origType === handleObj.origType ) &&
26125					( !handler || handler.guid === handleObj.guid ) &&
26126					( !tmp || tmp.test( handleObj.namespace ) ) &&
26127					( !selector || selector === handleObj.selector ||
26128						selector === "**" && handleObj.selector ) ) {
26129					handlers.splice( j, 1 );
26130
26131					if ( handleObj.selector ) {
26132						handlers.delegateCount--;
26133					}
26134					if ( special.remove ) {
26135						special.remove.call( elem, handleObj );
26136					}
26137				}
26138			}
26139
26140			// Remove generic event handler if we removed something and no more handlers exist
26141			// (avoids potential for endless recursion during removal of special event handlers)
26142			if ( origCount && !handlers.length ) {
26143				if ( !special.teardown ||
26144					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
26145
26146					jQuery.removeEvent( elem, type, elemData.handle );
26147				}
26148
26149				delete events[ type ];
26150			}
26151		}
26152
26153		// Remove data and the expando if it's no longer used
26154		if ( jQuery.isEmptyObject( events ) ) {
26155			dataPriv.remove( elem, "handle events" );
26156		}
26157	},
26158
26159	dispatch: function( nativeEvent ) {
26160
26161		// Make a writable jQuery.Event from the native event object
26162		var event = jQuery.event.fix( nativeEvent );
26163
26164		var i, j, ret, matched, handleObj, handlerQueue,
26165			args = new Array( arguments.length ),
26166			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
26167			special = jQuery.event.special[ event.type ] || {};
26168
26169		// Use the fix-ed jQuery.Event rather than the (read-only) native event
26170		args[ 0 ] = event;
26171
26172		for ( i = 1; i < arguments.length; i++ ) {
26173			args[ i ] = arguments[ i ];
26174		}
26175
26176		event.delegateTarget = this;
26177
26178		// Call the preDispatch hook for the mapped type, and let it bail if desired
26179		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
26180			return;
26181		}
26182
26183		// Determine handlers
26184		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
26185
26186		// Run delegates first; they may want to stop propagation beneath us
26187		i = 0;
26188		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
26189			event.currentTarget = matched.elem;
26190
26191			j = 0;
26192			while ( ( handleObj = matched.handlers[ j++ ] ) &&
26193				!event.isImmediatePropagationStopped() ) {
26194
26195				// If the event is namespaced, then each handler is only invoked if it is
26196				// specially universal or its namespaces are a superset of the event's.
26197				if ( !event.rnamespace || handleObj.namespace === false ||
26198					event.rnamespace.test( handleObj.namespace ) ) {
26199
26200					event.handleObj = handleObj;
26201					event.data = handleObj.data;
26202
26203					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
26204						handleObj.handler ).apply( matched.elem, args );
26205
26206					if ( ret !== undefined ) {
26207						if ( ( event.result = ret ) === false ) {
26208							event.preventDefault();
26209							event.stopPropagation();
26210						}
26211					}
26212				}
26213			}
26214		}
26215
26216		// Call the postDispatch hook for the mapped type
26217		if ( special.postDispatch ) {
26218			special.postDispatch.call( this, event );
26219		}
26220
26221		return event.result;
26222	},
26223
26224	handlers: function( event, handlers ) {
26225		var i, handleObj, sel, matchedHandlers, matchedSelectors,
26226			handlerQueue = [],
26227			delegateCount = handlers.delegateCount,
26228			cur = event.target;
26229
26230		// Find delegate handlers
26231		if ( delegateCount &&
26232
vendor: 5,718 bytes, lines 26233-26418
26233			// Support: IE <=9
26234			// Black-hole SVG <use> instance trees (trac-13180)
26235			cur.nodeType &&
26236
26237			// Support: Firefox <=42
26238			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
26239			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
26240			// Support: IE 11 only
26241			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
26242			!( event.type === "click" && event.button >= 1 ) ) {
26243
26244			for ( ; cur !== this; cur = cur.parentNode || this ) {
26245
26246				// Don't check non-elements (#13208)
26247				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
26248				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
26249					matchedHandlers = [];
26250					matchedSelectors = {};
26251					for ( i = 0; i < delegateCount; i++ ) {
26252						handleObj = handlers[ i ];
26253
26254						// Don't conflict with Object.prototype properties (#13203)
26255						sel = handleObj.selector + " ";
26256
26257						if ( matchedSelectors[ sel ] === undefined ) {
26258							matchedSelectors[ sel ] = handleObj.needsContext ?
26259								jQuery( sel, this ).index( cur ) > -1 :
26260								jQuery.find( sel, this, null, [ cur ] ).length;
26261						}
26262						if ( matchedSelectors[ sel ] ) {
26263							matchedHandlers.push( handleObj );
26264						}
26265					}
26266					if ( matchedHandlers.length ) {
26267						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
26268					}
26269				}
26270			}
26271		}
26272
26273		// Add the remaining (directly-bound) handlers
26274		cur = this;
26275		if ( delegateCount < handlers.length ) {
26276			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
26277		}
26278
26279		return handlerQueue;
26280	},
26281
26282	addProp: function( name, hook ) {
26283		Object.defineProperty( jQuery.Event.prototype, name, {
26284			enumerable: true,
26285			configurable: true,
26286
26287			get: isFunction( hook ) ?
26288				function() {
26289					if ( this.originalEvent ) {
26290							return hook( this.originalEvent );
26291					}
26292				} :
26293				function() {
26294					if ( this.originalEvent ) {
26295							return this.originalEvent[ name ];
26296					}
26297				},
26298
26299			set: function( value ) {
26300				Object.defineProperty( this, name, {
26301					enumerable: true,
26302					configurable: true,
26303					writable: true,
26304					value: value
26305				} );
26306			}
26307		} );
26308	},
26309
26310	fix: function( originalEvent ) {
26311		return originalEvent[ jQuery.expando ] ?
26312			originalEvent :
26313			new jQuery.Event( originalEvent );
26314	},
26315
26316	special: {
26317		load: {
26318
26319			// Prevent triggered image.load events from bubbling to window.load
26320			noBubble: true
26321		},
26322		click: {
26323
26324			// Utilize native event to ensure correct state for checkable inputs
26325			setup: function( data ) {
26326
26327				// For mutual compressibility with _default, replace `this` access with a local var.
26328				// `|| data` is dead code meant only to preserve the variable through minification.
26329				var el = this || data;
26330
26331				// Claim the first handler
26332				if ( rcheckableType.test( el.type ) &&
26333					el.click && nodeName( el, "input" ) ) {
26334
26335					// dataPriv.set( el, "click", ... )
26336					leverageNative( el, "click", returnTrue );
26337				}
26338
26339				// Return false to allow normal processing in the caller
26340				return false;
26341			},
26342			trigger: function( data ) {
26343
26344				// For mutual compressibility with _default, replace `this` access with a local var.
26345				// `|| data` is dead code meant only to preserve the variable through minification.
26346				var el = this || data;
26347
26348				// Force setup before triggering a click
26349				if ( rcheckableType.test( el.type ) &&
26350					el.click && nodeName( el, "input" ) ) {
26351
26352					leverageNative( el, "click" );
26353				}
26354
26355				// Return non-false to allow normal event-path propagation
26356				return true;
26357			},
26358
26359			// For cross-browser consistency, suppress native .click() on links
26360			// Also prevent it if we're currently inside a leveraged native-event stack
26361			_default: function( event ) {
26362				var target = event.target;
26363				return rcheckableType.test( target.type ) &&
26364					target.click && nodeName( target, "input" ) &&
26365					dataPriv.get( target, "click" ) ||
26366					nodeName( target, "a" );
26367			}
26368		},
26369
26370		beforeunload: {
26371			postDispatch: function( event ) {
26372
26373				// Support: Firefox 20+
26374				// Firefox doesn't alert if the returnValue field is not set.
26375				if ( event.result !== undefined && event.originalEvent ) {
26376					event.originalEvent.returnValue = event.result;
26377				}
26378			}
26379		}
26380	}
26381};
26382
26383// Ensure the presence of an event listener that handles manually-triggered
26384// synthetic events by interrupting progress until reinvoked in response to
26385// *native* events that it fires directly, ensuring that state changes have
26386// already occurred before other listeners are invoked.
26387function leverageNative( el, type, expectSync ) {
26388
26389	// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
26390	if ( !expectSync ) {
26391		if ( dataPriv.get( el, type ) === undefined ) {
26392			jQuery.event.add( el, type, returnTrue );
26393		}
26394		return;
26395	}
26396
26397	// Register the controller as a special universal handler for all event namespaces
26398	dataPriv.set( el, type, false );
26399	jQuery.event.add( el, type, {
26400		namespace: false,
26401		handler: function( event ) {
26402			var notAsync, result,
26403				saved = dataPriv.get( this, type );
26404
26405			if ( ( event.isTrigger & 1 ) && this[ type ] ) {
26406
26407				// Interrupt processing of the outer synthetic .trigger()ed event
26408				// Saved data should be false in such cases, but might be a leftover capture object
26409				// from an async native handler (gh-4350)
26410				if ( !saved.length ) {
26411
26412					// Store arguments for use when handling the inner native event
26413					// There will always be at least one argument (an event object), so this array
26414					// will not be confused with a leftover capture object.
26415					saved = slice.call( arguments );
26416					dataPriv.set( this, type, saved );
26417
26418					// Trigger the native event and capture its result
26419					// Support: IE <=9 - 11+
26420					// focus() and blur() are asynchronous
26421					notAsync = expectSync( this, type );
26422					this[ type ]();
26423					result = dataPriv.get( this, type );
26424					if ( saved !== result || notAsync ) {
26425						dataPriv.set( this, type, false );
26426					} else {
26427						result = {};
26428					}
26429					if ( saved !== result ) {
26430
26431						// Cancel the outer synthetic event
26432						event.stopImmediatePropagation();
26433						event.preventDefault();
26434						return result.value;
26435					}
26436
26437				// If this is an inner synthetic event for an event with a bubbling surrogate
26438				// (focus or blur), assume that the surrogate already propagated from triggering the
26439				// native event and prevent that from happening again here.
26440				// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
26441				// bubbling surrogate propagates *after* the non-bubbling base), but that seems
26442				// less bad than duplication.
26443				} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
26444					event.stopPropagation();
26445				}
26446
26447			// If this is a native event triggered above, everything is now in order
26448			// Fire an inner synthetic event with the original arguments
26449			} else if ( saved.length ) {
26450
26451				// ...and capture the result
26452				dataPriv.set( this, type, {
26453					value: jQuery.event.trigger(
26454
26455						// Support: IE <=9 - 11+
26456						// Extend with the prototype to reset the above stopImmediatePropagation()
26457						jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
26458						saved.slice( 1 ),
26459						this
26460					)
26461				} );
26462
26463				// Abort handling of the native event
26464				event.stopImmediatePropagation();
26465			}
26466		}
26467	} );
26468}
26469
26470jQuery.removeEvent = function( elem, type, handle ) {
26471
26472	// This "if" is needed for plain objects
26473	if ( elem.removeEventListener ) {
26474		elem.removeEventListener( type, handle );
26475	}
26476};
26477
26478jQuery.Event = function( src, props ) {
26479
26480	// Allow instantiation without the 'new' keyword
26481	if ( !( this instanceof jQuery.Event ) ) {
26482		return new jQuery.Event( src, props );
26483	}
26484
26485	// Event object
26486	if ( src && src.type ) {
26487		this.originalEvent = src;
26488		this.type = src.type;
26489
26490		// Events bubbling up the document may have been marked as prevented
26491		// by a handler lower down the tree; reflect the correct value.
26492		this.isDefaultPrevented = src.defaultPrevented ||
26493				src.defaultPrevented === undefined &&
26494
26495				// Support: Android <=2.3 only
26496				src.returnValue === false ?
26497			returnTrue :
26498			returnFalse;
26499
26500		// Create target properties
26501		// Support: Safari <=6 - 7 only
26502		// Target should not be a text node (#504, #13143)
26503		this.target = ( src.target && src.target.nodeType === 3 ) ?
26504			src.target.parentNode :
26505			src.target;
26506
26507		this.currentTarget = src.currentTarget;
26508		this.relatedTarget = src.relatedTarget;
26509
26510	// Event type
26511	} else {
26512		this.type = src;
26513	}
26514
26515	// Put explicitly provided properties onto the event object
26516	if ( props ) {
26517		jQuery.extend( this, props );
26518	}
26519
26520	// Create a timestamp if incoming event doesn't have one
26521	this.timeStamp = src && src.timeStamp || Date.now();
26522
26523	// Mark it as fixed
26524	this[ jQuery.expando ] = true;
26525};
26526
26527// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
26528// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
26529jQuery.Event.prototype = {
26530	constructor: jQuery.Event,
26531	isDefaultPrevented: returnFalse,
26532	isPropagationStopped: returnFalse,
26533	isImmediatePropagationStopped: returnFalse,
26534	isSimulated: false,
26535
26536	preventDefault: function() {
26537		var e = this.originalEvent;
26538
26539		this.isDefaultPrevented = returnTrue;
26540
26541		if ( e && !this.isSimulated ) {
26542			e.preventDefault();
26543		}
26544	},
26545	stopPropagation: function() {
26546		var e = this.originalEvent;
26547
26548		this.isPropagationStopped = returnTrue;
26549
26550		if ( e && !this.isSimulated ) {
26551			e.stopPropagation();
26552		}
26553	},
26554	stopImmediatePropagation: function() {
26555		var e = this.originalEvent;
26556
26557		this.isImmediatePropagationStopped = returnTrue;
26558
26559		if ( e && !this.isSimulated ) {
26560			e.stopImmediatePropagation();
26561		}
26562
26563		this.stopPropagation();
26564	}
26565};
26566
26567// Includes all common event props including KeyEvent and MouseEvent specific props
26568jQuery.each( {
26569	altKey: true,
26570	bubbles: true,
26571	cancelable: true,
26572	changedTouches: true,
26573	ctrlKey: true,
26574	detail: true,
26575	eventPhase: true,
26576	metaKey: true,
26577	pageX: true,
26578	pageY: true,
26579	shiftKey: true,
26580	view: true,
26581	"char": true,
26582	code: true,
26583	charCode: true,
26584	key: true,
26585	keyCode: true,
26586	button: true,
26587	buttons: true,
26588	clientX: true,
26589	clientY: true,
26590	offsetX: true,
26591	offsetY: true,
26592	pointerId: true,
26593	pointerType: true,
26594	screenX: true,
26595	screenY: true,
26596	targetTouches: true,
26597	toElement: true,
26598	touches: true,
26599
26600	which: function( event ) {
26601		var button = event.button;
26602
26603		// Add which for key events
26604		if ( event.which == null && rkeyEvent.test( event.type ) ) {
26605			return event.charCode != null ? event.charCode : event.keyCode;
26606		}
26607
26608		// Add which for click: 1 === left; 2 === middle; 3 === right
26609		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
26610			if ( button & 1 ) {
26611				return 1;
26612			}
26613
26614			if ( button & 2 ) {
26615				return 3;
26616			}
26617
26618			if ( button & 4 ) {
26619				return 2;
26620			}
26621
26622			return 0;
26623		}
26624
26625		return event.which;
26626	}
26627}, jQuery.event.addProp );
26628
26629jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
26630	jQuery.event.special[ type ] = {
26631
26632		// Utilize native event if possible so blur/focus sequence is correct
26633		setup: function() {
26634
26635			// Claim the first handler
26636			// dataPriv.set( this, "focus", ... )
26637			// dataPriv.set( this, "blur", ... )
26638			leverageNative( this, type, expectSync );
26639
26640			// Return false to allow normal processing in the caller
26641			return false;
vendor: 4,563 bytes, lines 26642-26818
26642		},
26643		trigger: function() {
26644
26645			// Force setup before trigger
26646			leverageNative( this, type );
26647
26648			// Return non-false to allow normal event-path propagation
26649			return true;
26650		},
26651
26652		delegateType: delegateType
26653	};
26654} );
26655
26656// Create mouseenter/leave events using mouseover/out and event-time checks
26657// so that event delegation works in jQuery.
26658// Do the same for pointerenter/pointerleave and pointerover/pointerout
26659//
26660// Support: Safari 7 only
26661// Safari sends mouseenter too often; see:
26662// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
26663// for the description of the bug (it existed in older Chrome versions as well).
26664jQuery.each( {
26665	mouseenter: "mouseover",
26666	mouseleave: "mouseout",
26667	pointerenter: "pointerover",
26668	pointerleave: "pointerout"
26669}, function( orig, fix ) {
26670	jQuery.event.special[ orig ] = {
26671		delegateType: fix,
26672		bindType: fix,
26673
26674		handle: function( event ) {
26675			var ret,
26676				target = this,
26677				related = event.relatedTarget,
26678				handleObj = event.handleObj;
26679
26680			// For mouseenter/leave call the handler if related is outside the target.
26681			// NB: No relatedTarget if the mouse left/entered the browser window
26682			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
26683				event.type = handleObj.origType;
26684				ret = handleObj.handler.apply( this, arguments );
26685				event.type = fix;
26686			}
26687			return ret;
26688		}
26689	};
26690} );
26691
26692jQuery.fn.extend( {
26693
26694	on: function( types, selector, data, fn ) {
26695		return on( this, types, selector, data, fn );
26696	},
26697	one: function( types, selector, data, fn ) {
26698		return on( this, types, selector, data, fn, 1 );
26699	},
26700	off: function( types, selector, fn ) {
26701		var handleObj, type;
26702		if ( types && types.preventDefault && types.handleObj ) {
26703
26704			// ( event )  dispatched jQuery.Event
26705			handleObj = types.handleObj;
26706			jQuery( types.delegateTarget ).off(
26707				handleObj.namespace ?
26708					handleObj.origType + "." + handleObj.namespace :
26709					handleObj.origType,
26710				handleObj.selector,
26711				handleObj.handler
26712			);
26713			return this;
26714		}
26715		if ( typeof types === "object" ) {
26716
26717			// ( types-object [, selector] )
26718			for ( type in types ) {
26719				this.off( type, selector, types[ type ] );
26720			}
26721			return this;
26722		}
26723		if ( selector === false || typeof selector === "function" ) {
26724
26725			// ( types [, fn] )
26726			fn = selector;
26727			selector = undefined;
26728		}
26729		if ( fn === false ) {
26730			fn = returnFalse;
26731		}
26732		return this.each( function() {
26733			jQuery.event.remove( this, types, fn, selector );
26734		} );
26735	}
26736} );
26737
26738
26739var
26740
26741	/* eslint-disable max-len */
26742
26743	// See https://github.com/eslint/eslint/issues/3229
26744	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
26745
26746	/* eslint-enable */
26747
26748	// Support: IE <=10 - 11, Edge 12 - 13 only
26749	// In IE/Edge using regex groups here causes severe slowdowns.
26750	// See https://connect.microsoft.com/IE/feedback/details/1736512/
26751	rnoInnerhtml = /<script|<style|<link/i,
26752
26753	// checked="checked" or checked
26754	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
26755	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
26756
26757// Prefer a tbody over its parent table for containing new rows
26758function manipulationTarget( elem, content ) {
26759	if ( nodeName( elem, "table" ) &&
26760		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
26761
26762		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
26763	}
26764
26765	return elem;
26766}
26767
26768// Replace/restore the type attribute of script elements for safe DOM manipulation
26769function disableScript( elem ) {
26770	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
26771	return elem;
26772}
26773function restoreScript( elem ) {
26774	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
26775		elem.type = elem.type.slice( 5 );
26776	} else {
26777		elem.removeAttribute( "type" );
26778	}
26779
26780	return elem;
26781}
26782
26783function cloneCopyEvent( src, dest ) {
26784	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
26785
26786	if ( dest.nodeType !== 1 ) {
26787		return;
26788	}
26789
26790	// 1. Copy private data: events, handlers, etc.
26791	if ( dataPriv.hasData( src ) ) {
26792		pdataOld = dataPriv.access( src );
26793		pdataCur = dataPriv.set( dest, pdataOld );
26794		events = pdataOld.events;
26795
26796		if ( events ) {
26797			delete pdataCur.handle;
26798			pdataCur.events = {};
26799
26800			for ( type in events ) {
26801				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
26802					jQuery.event.add( dest, type, events[ type ][ i ] );
26803				}
26804			}
26805		}
26806	}
26807
26808	// 2. Copy user data
26809	if ( dataUser.hasData( src ) ) {
26810		udataOld = dataUser.access( src );
26811		udataCur = jQuery.extend( {}, udataOld );
26812
26813		dataUser.set( dest, udataCur );
26814	}
26815}
26816
26817// Fix IE bugs, see support tests
26818function fixInput( src, dest ) {
vendor: 3,609 bytes, lines 26819-26946
26819	var nodeName = dest.nodeName.toLowerCase();
26820
26821	// Fails to persist the checked state of a cloned checkbox or radio button.
26822	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
26823		dest.checked = src.checked;
26824
26825	// Fails to return the selected option to the default selected state when cloning options
26826	} else if ( nodeName === "input" || nodeName === "textarea" ) {
26827		dest.defaultValue = src.defaultValue;
26828	}
26829}
26830
26831function domManip( collection, args, callback, ignored ) {
26832
26833	// Flatten any nested arrays
26834	args = concat.apply( [], args );
26835
26836	var fragment, first, scripts, hasScripts, node, doc,
26837		i = 0,
26838		l = collection.length,
26839		iNoClone = l - 1,
26840		value = args[ 0 ],
26841		valueIsFunction = isFunction( value );
26842
26843	// We can't cloneNode fragments that contain checked, in WebKit
26844	if ( valueIsFunction ||
26845			( l > 1 && typeof value === "string" &&
26846				!support.checkClone && rchecked.test( value ) ) ) {
26847		return collection.each( function( index ) {
26848			var self = collection.eq( index );
26849			if ( valueIsFunction ) {
26850				args[ 0 ] = value.call( this, index, self.html() );
26851			}
26852			domManip( self, args, callback, ignored );
26853		} );
26854	}
26855
26856	if ( l ) {
26857		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
26858		first = fragment.firstChild;
26859
26860		if ( fragment.childNodes.length === 1 ) {
26861			fragment = first;
26862		}
26863
26864		// Require either new content or an interest in ignored elements to invoke the callback
26865		if ( first || ignored ) {
26866			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
26867			hasScripts = scripts.length;
26868
26869			// Use the original fragment for the last item
26870			// instead of the first because it can end up
26871			// being emptied incorrectly in certain situations (#8070).
26872			for ( ; i < l; i++ ) {
26873				node = fragment;
26874
26875				if ( i !== iNoClone ) {
26876					node = jQuery.clone( node, true, true );
26877
26878					// Keep references to cloned scripts for later restoration
26879					if ( hasScripts ) {
26880
26881						// Support: Android <=4.0 only, PhantomJS 1 only
26882						// push.apply(_, arraylike) throws on ancient WebKit
26883						jQuery.merge( scripts, getAll( node, "script" ) );
26884					}
26885				}
26886
26887				callback.call( collection[ i ], node, i );
26888			}
26889
26890			if ( hasScripts ) {
26891				doc = scripts[ scripts.length - 1 ].ownerDocument;
26892
26893				// Reenable scripts
26894				jQuery.map( scripts, restoreScript );
26895
26896				// Evaluate executable scripts on first document insertion
26897				for ( i = 0; i < hasScripts; i++ ) {
26898					node = scripts[ i ];
26899					if ( rscriptType.test( node.type || "" ) &&
26900						!dataPriv.access( node, "globalEval" ) &&
26901						jQuery.contains( doc, node ) ) {
26902
26903						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
26904
26905							// Optional AJAX dependency, but won't run scripts if not present
26906							if ( jQuery._evalUrl && !node.noModule ) {
26907								jQuery._evalUrl( node.src, {
26908									nonce: node.nonce || node.getAttribute( "nonce" )
26909								} );
26910							}
26911						} else {
26912							DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
26913						}
26914					}
26915				}
26916			}
26917		}
26918	}
26919
26920	return collection;
26921}
26922
26923function remove( elem, selector, keepData ) {
26924	var node,
26925		nodes = selector ? jQuery.filter( selector, elem ) : elem,
26926		i = 0;
26927
26928	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
26929		if ( !keepData && node.nodeType === 1 ) {
26930			jQuery.cleanData( getAll( node ) );
26931		}
26932
26933		if ( node.parentNode ) {
26934			if ( keepData && isAttached( node ) ) {
26935				setGlobalEval( getAll( node, "script" ) );
26936			}
26937			node.parentNode.removeChild( node );
26938		}
26939	}
26940
26941	return elem;
26942}
26943
26944jQuery.extend( {
26945	htmlPrefilter: function( html ) {
26946		return html.replace( rxhtmlTag, "<$1></$2>" )
vendor: 2,889 bytes, lines 26946-27055
26946;
26947	},
26948
26949	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
26950		var i, l, srcElements, destElements,
26951			clone = elem.cloneNode( true ),
26952			inPage = isAttached( elem );
26953
26954		// Fix IE cloning issues
26955		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
26956				!jQuery.isXMLDoc( elem ) ) {
26957
26958			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
26959			destElements = getAll( clone );
26960			srcElements = getAll( elem );
26961
26962			for ( i = 0, l = srcElements.length; i < l; i++ ) {
26963				fixInput( srcElements[ i ], destElements[ i ] );
26964			}
26965		}
26966
26967		// Copy the events from the original to the clone
26968		if ( dataAndEvents ) {
26969			if ( deepDataAndEvents ) {
26970				srcElements = srcElements || getAll( elem );
26971				destElements = destElements || getAll( clone );
26972
26973				for ( i = 0, l = srcElements.length; i < l; i++ ) {
26974					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
26975				}
26976			} else {
26977				cloneCopyEvent( elem, clone );
26978			}
26979		}
26980
26981		// Preserve script evaluation history
26982		destElements = getAll( clone, "script" );
26983		if ( destElements.length > 0 ) {
26984			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
26985		}
26986
26987		// Return the cloned set
26988		return clone;
26989	},
26990
26991	cleanData: function( elems ) {
26992		var data, elem, type,
26993			special = jQuery.event.special,
26994			i = 0;
26995
26996		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
26997			if ( acceptData( elem ) ) {
26998				if ( ( data = elem[ dataPriv.expando ] ) ) {
26999					if ( data.events ) {
27000						for ( type in data.events ) {
27001							if ( special[ type ] ) {
27002								jQuery.event.remove( elem, type );
27003
27004							// This is a shortcut to avoid jQuery.event.remove's overhead
27005							} else {
27006								jQuery.removeEvent( elem, type, data.handle );
27007							}
27008						}
27009					}
27010
27011					// Support: Chrome <=35 - 45+
27012					// Assign undefined instead of using delete, see Data#remove
27013					elem[ dataPriv.expando ] = undefined;
27014				}
27015				if ( elem[ dataUser.expando ] ) {
27016
27017					// Support: Chrome <=35 - 45+
27018					// Assign undefined instead of using delete, see Data#remove
27019					elem[ dataUser.expando ] = undefined;
27020				}
27021			}
27022		}
27023	}
27024} );
27025
27026jQuery.fn.extend( {
27027	detach: function( selector ) {
27028		return remove( this, selector, true );
27029	},
27030
27031	remove: function( selector ) {
27032		return remove( this, selector );
27033	},
27034
27035	text: function( value ) {
27036		return access( this, function( value ) {
27037			return value === undefined ?
27038				jQuery.text( this ) :
27039				this.empty().each( function() {
27040					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
27041						this.textContent = value;
27042					}
27043				} );
27044		}, null, value, arguments.length );
27045	},
27046
27047	append: function() {
27048		return domManip( this, arguments, function( elem ) {
27049			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
27050				var target = manipulationTarget( this, elem );
27051				target.appendChild( elem );
27052			}
27053		} );
27054	},
27055
vendor: 5,129 bytes, lines 27056-27248
27056	prepend: function() {
27057		return domManip( this, arguments, function( elem ) {
27058			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
27059				var target = manipulationTarget( this, elem );
27060				target.insertBefore( elem, target.firstChild );
27061			}
27062		} );
27063	},
27064
27065	before: function() {
27066		return domManip( this, arguments, function( elem ) {
27067			if ( this.parentNode ) {
27068				this.parentNode.insertBefore( elem, this );
27069			}
27070		} );
27071	},
27072
27073	after: function() {
27074		return domManip( this, arguments, function( elem ) {
27075			if ( this.parentNode ) {
27076				this.parentNode.insertBefore( elem, this.nextSibling );
27077			}
27078		} );
27079	},
27080
27081	empty: function() {
27082		var elem,
27083			i = 0;
27084
27085		for ( ; ( elem = this[ i ] ) != null; i++ ) {
27086			if ( elem.nodeType === 1 ) {
27087
27088				// Prevent memory leaks
27089				jQuery.cleanData( getAll( elem, false ) );
27090
27091				// Remove any remaining nodes
27092				elem.textContent = "";
27093			}
27094		}
27095
27096		return this;
27097	},
27098
27099	clone: function( dataAndEvents, deepDataAndEvents ) {
27100		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
27101		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
27102
27103		return this.map( function() {
27104			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
27105		} );
27106	},
27107
27108	html: function( value ) {
27109		return access( this, function( value ) {
27110			var elem = this[ 0 ] || {},
27111				i = 0,
27112				l = this.length;
27113
27114			if ( value === undefined && elem.nodeType === 1 ) {
27115				return elem.innerHTML;
27116			}
27117
27118			// See if we can take a shortcut and just use innerHTML
27119			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
27120				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
27121
27122				value = jQuery.htmlPrefilter( value );
27123
27124				try {
27125					for ( ; i < l; i++ ) {
27126						elem = this[ i ] || {};
27127
27128						// Remove element nodes and prevent memory leaks
27129						if ( elem.nodeType === 1 ) {
27130							jQuery.cleanData( getAll( elem, false ) );
27131							elem.innerHTML = value;
27132						}
27133					}
27134
27135					elem = 0;
27136
27137				// If using innerHTML throws an exception, use the fallback method
27138				} catch ( e ) {}
27139			}
27140
27141			if ( elem ) {
27142				this.empty().append( value );
27143			}
27144		}, null, value, arguments.length );
27145	},
27146
27147	replaceWith: function() {
27148		var ignored = [];
27149
27150		// Make the changes, replacing each non-ignored context element with the new content
27151		return domManip( this, arguments, function( elem ) {
27152			var parent = this.parentNode;
27153
27154			if ( jQuery.inArray( this, ignored ) < 0 ) {
27155				jQuery.cleanData( getAll( this ) );
27156				if ( parent ) {
27157					parent.replaceChild( elem, this );
27158				}
27159			}
27160
27161		// Force callback invocation
27162		}, ignored );
27163	}
27164} );
27165
27166jQuery.each( {
27167	appendTo: "append",
27168	prependTo: "prepend",
27169	insertBefore: "before",
27170	insertAfter: "after",
27171	replaceAll: "replaceWith"
27172}, function( name, original ) {
27173	jQuery.fn[ name ] = function( selector ) {
27174		var elems,
27175			ret = [],
27176			insert = jQuery( selector ),
27177			last = insert.length - 1,
27178			i = 0;
27179
27180		for ( ; i <= last; i++ ) {
27181			elems = i === last ? this : this.clone( true );
27182			jQuery( insert[ i ] )[ original ]( elems );
27183
27184			// Support: Android <=4.0 only, PhantomJS 1 only
27185			// .get() because push.apply(_, arraylike) throws on ancient WebKit
27186			push.apply( ret, elems.get() );
27187		}
27188
27189		return this.pushStack( ret );
27190	};
27191} );
27192var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
27193
27194var getStyles = function( elem ) {
27195
27196		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
27197		// IE throws on elements created in popups
27198		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
27199		var view = elem.ownerDocument.defaultView;
27200
27201		if ( !view || !view.opener ) {
27202			view = window;
27203		}
27204
27205		return view.getComputedStyle( elem );
27206	};
27207
27208var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
27209
27210
27211
27212( function() {
27213
27214	// Executing both pixelPosition & boxSizingReliable tests require only one layout
27215	// so they're executed at the same time to save the second computation.
27216	function computeStyleTests() {
27217
27218		// This is a singleton, we need to execute it only once
27219		if ( !div ) {
27220			return;
27221		}
27222
27223		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
27224			"margin-top:1px;padding:0;border:0";
27225		div.style.cssText =
27226			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
27227			"margin:auto;border:1px;padding:1px;" +
27228			"width:60%;top:1%";
27229		documentElement.appendChild( container ).appendChild( div );
27230
27231		var divStyle = window.getComputedStyle( div );
27232		pixelPositionVal = divStyle.top !== "1%";
27233
27234		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
27235		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
27236
27237		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
27238		// Some styles come back with percentage values, even though they shouldn't
27239		div.style.right = "60%";
27240		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
27241
27242		// Support: IE 9 - 11 only
27243		// Detect misreporting of content dimensions for box-sizing:border-box elements
27244		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
27245
27246		// Support: IE 9 only
27247		// Detect overflow:scroll screwiness (gh-3699)
27248		
vendor: 8,298 bytes, lines 27248-27538
27248// Support: Chrome <=64
27249		// Don't get tricked when zoom affects offsetWidth (gh-4029)
27250		div.style.position = "absolute";
27251		scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
27252
27253		documentElement.removeChild( container );
27254
27255		// Nullify the div so it wouldn't be stored in the memory and
27256		// it will also be a sign that checks already performed
27257		div = null;
27258	}
27259
27260	function roundPixelMeasures( measure ) {
27261		return Math.round( parseFloat( measure ) );
27262	}
27263
27264	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
27265		reliableMarginLeftVal,
27266		container = document.createElement( "div" ),
27267		div = document.createElement( "div" );
27268
27269	// Finish early in limited (non-browser) environments
27270	if ( !div.style ) {
27271		return;
27272	}
27273
27274	// Support: IE <=9 - 11 only
27275	// Style of cloned element affects source element cloned (#8908)
27276	div.style.backgroundClip = "content-box";
27277	div.cloneNode( true ).style.backgroundClip = "";
27278	support.clearCloneStyle = div.style.backgroundClip === "content-box";
27279
27280	jQuery.extend( support, {
27281		boxSizingReliable: function() {
27282			computeStyleTests();
27283			return boxSizingReliableVal;
27284		},
27285		pixelBoxStyles: function() {
27286			computeStyleTests();
27287			return pixelBoxStylesVal;
27288		},
27289		pixelPosition: function() {
27290			computeStyleTests();
27291			return pixelPositionVal;
27292		},
27293		reliableMarginLeft: function() {
27294			computeStyleTests();
27295			return reliableMarginLeftVal;
27296		},
27297		scrollboxSize: function() {
27298			computeStyleTests();
27299			return scrollboxSizeVal;
27300		}
27301	} );
27302} )();
27303
27304
27305function curCSS( elem, name, computed ) {
27306	var width, minWidth, maxWidth, ret,
27307
27308		// Support: Firefox 51+
27309		// Retrieving style before computed somehow
27310		// fixes an issue with getting wrong values
27311		// on detached elements
27312		style = elem.style;
27313
27314	computed = computed || getStyles( elem );
27315
27316	// getPropertyValue is needed for:
27317	//   .css('filter') (IE 9 only, #12537)
27318	//   .css('--customProperty) (#3144)
27319	if ( computed ) {
27320		ret = computed.getPropertyValue( name ) || computed[ name ];
27321
27322		if ( ret === "" && !isAttached( elem ) ) {
27323			ret = jQuery.style( elem, name );
27324		}
27325
27326		// A tribute to the "awesome hack by Dean Edwards"
27327		// Android Browser returns percentage for some values,
27328		// but width seems to be reliably pixels.
27329		// This is against the CSSOM draft spec:
27330		// https://drafts.csswg.org/cssom/#resolved-values
27331		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
27332
27333			// Remember the original values
27334			width = style.width;
27335			minWidth = style.minWidth;
27336			maxWidth = style.maxWidth;
27337
27338			// Put in the new values to get a computed value out
27339			style.minWidth = style.maxWidth = style.width = ret;
27340			ret = computed.width;
27341
27342			// Revert the changed values
27343			style.width = width;
27344			style.minWidth = minWidth;
27345			style.maxWidth = maxWidth;
27346		}
27347	}
27348
27349	return ret !== undefined ?
27350
27351		// Support: IE <=9 - 11 only
27352		// IE returns zIndex value as an integer.
27353		ret + "" :
27354		ret;
27355}
27356
27357
27358function addGetHookIf( conditionFn, hookFn ) {
27359
27360	// Define the hook, we'll check on the first run if it's really needed.
27361	return {
27362		get: function() {
27363			if ( conditionFn() ) {
27364
27365				// Hook not needed (or it's not possible to use it due
27366				// to missing dependency), remove it.
27367				delete this.get;
27368				return;
27369			}
27370
27371			// Hook needed; redefine it so that the support test is not executed again.
27372			return ( this.get = hookFn ).apply( this, arguments );
27373		}
27374	};
27375}
27376
27377
27378var cssPrefixes = [ "Webkit", "Moz", "ms" ],
27379	emptyStyle = document.createElement( "div" ).style,
27380	vendorProps = {};
27381
27382// Return a vendor-prefixed property or undefined
27383function vendorPropName( name ) {
27384
27385	// Check for vendor prefixed names
27386	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
27387		i = cssPrefixes.length;
27388
27389	while ( i-- ) {
27390		name = cssPrefixes[ i ] + capName;
27391		if ( name in emptyStyle ) {
27392			return name;
27393		}
27394	}
27395}
27396
27397// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
27398function finalPropName( name ) {
27399	var final = jQuery.cssProps[ name ] || vendorProps[ name ];
27400
27401	if ( final ) {
27402		return final;
27403	}
27404	if ( name in emptyStyle ) {
27405		return name;
27406	}
27407	return vendorProps[ name ] = vendorPropName( name ) || name;
27408}
27409
27410
27411var
27412
27413	// Swappable if display is none or starts with table
27414	// except "table", "table-cell", or "table-caption"
27415	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
27416	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
27417	rcustomProp = /^--/,
27418	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
27419	cssNormalTransform = {
27420		letterSpacing: "0",
27421		fontWeight: "400"
27422	};
27423
27424function setPositiveNumber( elem, value, subtract ) {
27425
27426	// Any relative (+/-) values have already been
27427	// normalized at this point
27428	var matches = rcssNum.exec( value );
27429	return matches ?
27430
27431		// Guard against undefined "subtract", e.g., when used as in cssHooks
27432		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
27433		value;
27434}
27435
27436function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
27437	var i = dimension === "width" ? 1 : 0,
27438		extra = 0,
27439		delta = 0;
27440
27441	// Adjustment may not be necessary
27442	if ( box === ( isBorderBox ? "border" : "content" ) ) {
27443		return 0;
27444	}
27445
27446	for ( ; i < 4; i += 2 ) {
27447
27448		// Both box models exclude margin
27449		if ( box === "margin" ) {
27450			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
27451		}
27452
27453		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
27454		if ( !isBorderBox ) {
27455
27456			// Add padding
27457			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
27458
27459			// For "border" or "margin", add border
27460			if ( box !== "padding" ) {
27461				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
27462
27463			// But still keep track of it otherwise
27464			} else {
27465				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
27466			}
27467
27468		// If we get here with a border-box (content + padding + border), we're seeking "content" or
27469		// "padding" or "margin"
27470		} else {
27471
27472			// For "content", subtract padding
27473			if ( box === "content" ) {
27474				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
27475			}
27476
27477			// For "content" or "padding", subtract border
27478			if ( box !== "margin" ) {
27479				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
27480			}
27481		}
27482	}
27483
27484	// Account for positive content-box scroll gutter when requested by providing computedVal
27485	if ( !isBorderBox && computedVal >= 0 ) {
27486
27487		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
27488		// Assuming integer scroll gutter, subtract the rest and round down
27489		delta += Math.max( 0, Math.ceil(
27490			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
27491			computedVal -
27492			delta -
27493			extra -
27494			0.5
27495
27496		// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
27497		// Use an explicit zero to avoid NaN (gh-3964)
27498		) ) || 0;
27499	}
27500
27501	return delta;
27502}
27503
27504function getWidthOrHeight( elem, dimension, extra ) {
27505
27506	// Start with computed style
27507	var styles = getStyles( elem ),
27508
27509		// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
27510		// Fake content-box until we know it's needed to know the true value.
27511		boxSizingNeeded = !support.boxSizingReliable() || extra,
27512		isBorderBox = boxSizingNeeded &&
27513			jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
27514		valueIsBorderBox = isBorderBox,
27515
27516		val = curCSS( elem, dimension, styles ),
27517		offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
27518
27519	// Support: Firefox <=54
27520	// Return a confounding non-pixel value or feign ignorance, as appropriate.
27521	if ( rnumnonpx.test( val ) ) {
27522		if ( !extra ) {
27523			return val;
27524		}
27525		val = "auto";
27526	}
27527
27528
27529	// Fall back to offsetWidth/offsetHeight when value is "auto"
27530	// This happens for inline elements with no explicit setting (gh-3571)
27531	// Support: Android <=4.1 - 4.3 only
27532	// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
27533	// Support: IE 9-11 only
27534	// Also use offsetWidth/offsetHeight for when box sizing is unreliable
27535	// We use getClientRects() to check for hidden/disconnected.
27536	// In those cases, the computed value can be trusted to be border-box
27537	if ( ( !support.boxSizingReliable() && isBorderBox ||
27538		val === "auto" ||
vendor: 3,698 bytes, lines 27539-27669
27539		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
27540		elem.getClientRects().length ) {
27541
27542		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
27543
27544		// Where available, offsetWidth/offsetHeight approximate border box dimensions.
27545		// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
27546		// retrieved value as a content box dimension.
27547		valueIsBorderBox = offsetProp in elem;
27548		if ( valueIsBorderBox ) {
27549			val = elem[ offsetProp ];
27550		}
27551	}
27552
27553	// Normalize "" and auto
27554	val = parseFloat( val ) || 0;
27555
27556	// Adjust for the element's box model
27557	return ( val +
27558		boxModelAdjustment(
27559			elem,
27560			dimension,
27561			extra || ( isBorderBox ? "border" : "content" ),
27562			valueIsBorderBox,
27563			styles,
27564
27565			// Provide the current computed size to request scroll gutter calculation (gh-3589)
27566			val
27567		)
27568	) + "px";
27569}
27570
27571jQuery.extend( {
27572
27573	// Add in style property hooks for overriding the default
27574	// behavior of getting and setting a style property
27575	cssHooks: {
27576		opacity: {
27577			get: function( elem, computed ) {
27578				if ( computed ) {
27579
27580					// We should always get a number back from opacity
27581					var ret = curCSS( elem, "opacity" );
27582					return ret === "" ? "1" : ret;
27583				}
27584			}
27585		}
27586	},
27587
27588	// Don't automatically add "px" to these possibly-unitless properties
27589	cssNumber: {
27590		"animationIterationCount": true,
27591		"columnCount": true,
27592		"fillOpacity": true,
27593		"flexGrow": true,
27594		"flexShrink": true,
27595		"fontWeight": true,
27596		"gridArea": true,
27597		"gridColumn": true,
27598		"gridColumnEnd": true,
27599		"gridColumnStart": true,
27600		"gridRow": true,
27601		"gridRowEnd": true,
27602		"gridRowStart": true,
27603		"lineHeight": true,
27604		"opacity": true,
27605		"order": true,
27606		"orphans": true,
27607		"widows": true,
27608		"zIndex": true,
27609		"zoom": true
27610	},
27611
27612	// Add in properties whose names you wish to fix before
27613	// setting or getting the value
27614	cssProps: {},
27615
27616	// Get and set the style property on a DOM Node
27617	style: function( elem, name, value, extra ) {
27618
27619		// Don't set styles on text and comment nodes
27620		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
27621			return;
27622		}
27623
27624		// Make sure that we're working with the right name
27625		var ret, type, hooks,
27626			origName = camelCase( name ),
27627			isCustomProp = rcustomProp.test( name ),
27628			style = elem.style;
27629
27630		// Make sure that we're working with the right name. We don't
27631		// want to query the value if it is a CSS custom property
27632		// since they are user-defined.
27633		if ( !isCustomProp ) {
27634			name = finalPropName( origName );
27635		}
27636
27637		// Gets hook for the prefixed version, then unprefixed version
27638		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
27639
27640		// Check if we're setting a value
27641		if ( value !== undefined ) {
27642			type = typeof value;
27643
27644			// Convert "+=" or "-=" to relative numbers (#7345)
27645			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
27646				value = adjustCSS( elem, name, ret );
27647
27648				// Fixes bug #9237
27649				type = "number";
27650			}
27651
27652			// Make sure that null and NaN values aren't set (#7116)
27653			if ( value == null || value !== value ) {
27654				return;
27655			}
27656
27657			// If a number was passed in, add the unit (except for certain CSS properties)
27658			// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
27659			// "px" to a few hardcoded values.
27660			if ( type === "number" && !isCustomProp ) {
27661				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
27662			}
27663
27664			// background-* props affect original clone's values
27665			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
27666				style[ name ] = "inherit";
27667			}
27668
27669			// If a hook was provided, use that value, otherwise just set the specified value
vendor: 7,976 bytes, lines 27670-27952
27670			if ( !hooks || !( "set" in hooks ) ||
27671				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
27672
27673				if ( isCustomProp ) {
27674					style.setProperty( name, value );
27675				} else {
27676					style[ name ] = value;
27677				}
27678			}
27679
27680		} else {
27681
27682			// If a hook was provided get the non-computed value from there
27683			if ( hooks && "get" in hooks &&
27684				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
27685
27686				return ret;
27687			}
27688
27689			// Otherwise just get the value from the style object
27690			return style[ name ];
27691		}
27692	},
27693
27694	css: function( elem, name, extra, styles ) {
27695		var val, num, hooks,
27696			origName = camelCase( name ),
27697			isCustomProp = rcustomProp.test( name );
27698
27699		// Make sure that we're working with the right name. We don't
27700		// want to modify the value if it is a CSS custom property
27701		// since they are user-defined.
27702		if ( !isCustomProp ) {
27703			name = finalPropName( origName );
27704		}
27705
27706		// Try prefixed name followed by the unprefixed name
27707		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
27708
27709		// If a hook was provided get the computed value from there
27710		if ( hooks && "get" in hooks ) {
27711			val = hooks.get( elem, true, extra );
27712		}
27713
27714		// Otherwise, if a way to get the computed value exists, use that
27715		if ( val === undefined ) {
27716			val = curCSS( elem, name, styles );
27717		}
27718
27719		// Convert "normal" to computed value
27720		if ( val === "normal" && name in cssNormalTransform ) {
27721			val = cssNormalTransform[ name ];
27722		}
27723
27724		// Make numeric if forced or a qualifier was provided and val looks numeric
27725		if ( extra === "" || extra ) {
27726			num = parseFloat( val );
27727			return extra === true || isFinite( num ) ? num || 0 : val;
27728		}
27729
27730		return val;
27731	}
27732} );
27733
27734jQuery.each( [ "height", "width" ], function( i, dimension ) {
27735	jQuery.cssHooks[ dimension ] = {
27736		get: function( elem, computed, extra ) {
27737			if ( computed ) {
27738
27739				// Certain elements can have dimension info if we invisibly show them
27740				// but it must have a current display style that would benefit
27741				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
27742
27743					// Support: Safari 8+
27744					// Table columns in Safari have non-zero offsetWidth & zero
27745					// getBoundingClientRect().width unless display is changed.
27746					// Support: IE <=11 only
27747					// Running getBoundingClientRect on a disconnected node
27748					// in IE throws an error.
27749					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
27750						swap( elem, cssShow, function() {
27751							return getWidthOrHeight( elem, dimension, extra );
27752						} ) :
27753						getWidthOrHeight( elem, dimension, extra );
27754			}
27755		},
27756
27757		set: function( elem, value, extra ) {
27758			var matches,
27759				styles = getStyles( elem ),
27760
27761				// Only read styles.position if the test has a chance to fail
27762				// to avoid forcing a reflow.
27763				scrollboxSizeBuggy = !support.scrollboxSize() &&
27764					styles.position === "absolute",
27765
27766				// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
27767				boxSizingNeeded = scrollboxSizeBuggy || extra,
27768				isBorderBox = boxSizingNeeded &&
27769					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
27770				subtract = extra ?
27771					boxModelAdjustment(
27772						elem,
27773						dimension,
27774						extra,
27775						isBorderBox,
27776						styles
27777					) :
27778					0;
27779
27780			// Account for unreliable border-box dimensions by comparing offset* to computed and
27781			// faking a content-box to get border and padding (gh-3699)
27782			if ( isBorderBox && scrollboxSizeBuggy ) {
27783				subtract -= Math.ceil(
27784					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
27785					parseFloat( styles[ dimension ] ) -
27786					boxModelAdjustment( elem, dimension, "border", false, styles ) -
27787					0.5
27788				);
27789			}
27790
27791			// Convert to pixels if value adjustment is needed
27792			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
27793				( matches[ 3 ] || "px" ) !== "px" ) {
27794
27795				elem.style[ dimension ] = value;
27796				value = jQuery.css( elem, dimension );
27797			}
27798
27799			return setPositiveNumber( elem, value, subtract );
27800		}
27801	};
27802} );
27803
27804jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
27805	function( elem, computed ) {
27806		if ( computed ) {
27807			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
27808				elem.getBoundingClientRect().left -
27809					swap( elem, { marginLeft: 0 }, function() {
27810						return elem.getBoundingClientRect().left;
27811					} )
27812				) + "px";
27813		}
27814	}
27815);
27816
27817// These hooks are used by animate to expand properties
27818jQuery.each( {
27819	margin: "",
27820	padding: "",
27821	border: "Width"
27822}, function( prefix, suffix ) {
27823	jQuery.cssHooks[ prefix + suffix ] = {
27824		expand: function( value ) {
27825			var i = 0,
27826				expanded = {},
27827
27828				// Assumes a single number if not a string
27829				parts = typeof value === "string" ? value.split( " " ) : [ value ];
27830
27831			for ( ; i < 4; i++ ) {
27832				expanded[ prefix + cssExpand[ i ] + suffix ] =
27833					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
27834			}
27835
27836			return expanded;
27837		}
27838	};
27839
27840	if ( prefix !== "margin" ) {
27841		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
27842	}
27843} );
27844
27845jQuery.fn.extend( {
27846	css: function( name, value ) {
27847		return access( this, function( elem, name, value ) {
27848			var styles, len,
27849				map = {},
27850				i = 0;
27851
27852			if ( Array.isArray( name ) ) {
27853				styles = getStyles( elem );
27854				len = name.length;
27855
27856				for ( ; i < len; i++ ) {
27857					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
27858				}
27859
27860				return map;
27861			}
27862
27863			return value !== undefined ?
27864				jQuery.style( elem, name, value ) :
27865				jQuery.css( elem, name );
27866		}, name, value, arguments.length > 1 );
27867	}
27868} );
27869
27870
27871function Tween( elem, options, prop, end, easing ) {
27872	return new Tween.prototype.init( elem, options, prop, end, easing );
27873}
27874jQuery.Tween = Tween;
27875
27876Tween.prototype = {
27877	constructor: Tween,
27878	init: function( elem, options, prop, end, easing, unit ) {
27879		this.elem = elem;
27880		this.prop = prop;
27881		this.easing = easing || jQuery.easing._default;
27882		this.options = options;
27883		this.start = this.now = this.cur();
27884		this.end = end;
27885		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
27886	},
27887	cur: function() {
27888		var hooks = Tween.propHooks[ this.prop ];
27889
27890		return hooks && hooks.get ?
27891			hooks.get( this ) :
27892			Tween.propHooks._default.get( this );
27893	},
27894	run: function( percent ) {
27895		var eased,
27896			hooks = Tween.propHooks[ this.prop ];
27897
27898		if ( this.options.duration ) {
27899			this.pos = eased = jQuery.easing[ this.easing ](
27900				percent, this.options.duration * percent, 0, 1, this.options.duration
27901			);
27902		} else {
27903			this.pos = eased = percent;
27904		}
27905		this.now = ( this.end - this.start ) * eased + this.start;
27906
27907		if ( this.options.step ) {
27908			this.options.step.call( this.elem, this.now, this );
27909		}
27910
27911		if ( hooks && hooks.set ) {
27912			hooks.set( this );
27913		} else {
27914			Tween.propHooks._default.set( this );
27915		}
27916		return this;
27917	}
27918};
27919
27920Tween.prototype.init.prototype = Tween.prototype;
27921
27922Tween.propHooks = {
27923	_default: {
27924		get: function( tween ) {
27925			var result;
27926
27927			// Use a property on the element directly when it is not a DOM element,
27928			// or when there is no matching style property that exists.
27929			if ( tween.elem.nodeType !== 1 ||
27930				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
27931				return tween.elem[ tween.prop ];
27932			}
27933
27934			// Passing an empty string as a 3rd parameter to .css will automatically
27935			// attempt a parseFloat and fallback to a string if the parse fails.
27936			// Simple values such as "10px" are parsed to Float;
27937			// complex values such as "rotate(1rad)" are returned as-is.
27938			result = jQuery.css( tween.elem, tween.prop, "" );
27939
27940			// Empty strings, null, undefined and "auto" are converted to 0.
27941			return !result || result === "auto" ? 0 : result;
27942		},
27943		set: function( tween ) {
27944
27945			// Use step hook for back compat.
27946			// Use cssHook if its there.
27947			// Use .style if available and use plain properties where available.
27948			if ( jQuery.fx.step[ tween.prop ] ) {
27949				jQuery.fx.step[ tween.prop ]( tween );
27950			} else if ( tween.elem.nodeType === 1 && (
27951					jQuery.cssHooks[ tween.prop ] ||
27952					tween.elem.style[ finalPropName( tween.prop ) ] != null
vendor: 29,107 bytes, lines 27952-29149
27952 ) ) {
27953				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
27954			} else {
27955				tween.elem[ tween.prop ] = tween.now;
27956			}
27957		}
27958	}
27959};
27960
27961// Support: IE <=9 only
27962// Panic based approach to setting things on disconnected nodes
27963Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
27964	set: function( tween ) {
27965		if ( tween.elem.nodeType && tween.elem.parentNode ) {
27966			tween.elem[ tween.prop ] = tween.now;
27967		}
27968	}
27969};
27970
27971jQuery.easing = {
27972	linear: function( p ) {
27973		return p;
27974	},
27975	swing: function( p ) {
27976		return 0.5 - Math.cos( p * Math.PI ) / 2;
27977	},
27978	_default: "swing"
27979};
27980
27981jQuery.fx = Tween.prototype.init;
27982
27983// Back compat <1.8 extension point
27984jQuery.fx.step = {};
27985
27986
27987
27988
27989var
27990	fxNow, inProgress,
27991	rfxtypes = /^(?:toggle|show|hide)$/,
27992	rrun = /queueHooks$/;
27993
27994function schedule() {
27995	if ( inProgress ) {
27996		if ( document.hidden === false && window.requestAnimationFrame ) {
27997			window.requestAnimationFrame( schedule );
27998		} else {
27999			window.setTimeout( schedule, jQuery.fx.interval );
28000		}
28001
28002		jQuery.fx.tick();
28003	}
28004}
28005
28006// Animations created synchronously will run synchronously
28007function createFxNow() {
28008	window.setTimeout( function() {
28009		fxNow = undefined;
28010	} );
28011	return ( fxNow = Date.now() );
28012}
28013
28014// Generate parameters to create a standard animation
28015function genFx( type, includeWidth ) {
28016	var which,
28017		i = 0,
28018		attrs = { height: type };
28019
28020	// If we include width, step value is 1 to do all cssExpand values,
28021	// otherwise step value is 2 to skip over Left and Right
28022	includeWidth = includeWidth ? 1 : 0;
28023	for ( ; i < 4; i += 2 - includeWidth ) {
28024		which = cssExpand[ i ];
28025		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
28026	}
28027
28028	if ( includeWidth ) {
28029		attrs.opacity = attrs.width = type;
28030	}
28031
28032	return attrs;
28033}
28034
28035function createTween( value, prop, animation ) {
28036	var tween,
28037		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
28038		index = 0,
28039		length = collection.length;
28040	for ( ; index < length; index++ ) {
28041		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
28042
28043			// We're done with this property
28044			return tween;
28045		}
28046	}
28047}
28048
28049function defaultPrefilter( elem, props, opts ) {
28050	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
28051		isBox = "width" in props || "height" in props,
28052		anim = this,
28053		orig = {},
28054		style = elem.style,
28055		hidden = elem.nodeType && isHiddenWithinTree( elem ),
28056		dataShow = dataPriv.get( elem, "fxshow" );
28057
28058	// Queue-skipping animations hijack the fx hooks
28059	if ( !opts.queue ) {
28060		hooks = jQuery._queueHooks( elem, "fx" );
28061		if ( hooks.unqueued == null ) {
28062			hooks.unqueued = 0;
28063			oldfire = hooks.empty.fire;
28064			hooks.empty.fire = function() {
28065				if ( !hooks.unqueued ) {
28066					oldfire();
28067				}
28068			};
28069		}
28070		hooks.unqueued++;
28071
28072		anim.always( function() {
28073
28074			// Ensure the complete handler is called before this completes
28075			anim.always( function() {
28076				hooks.unqueued--;
28077				if ( !jQuery.queue( elem, "fx" ).length ) {
28078					hooks.empty.fire();
28079				}
28080			} );
28081		} );
28082	}
28083
28084	// Detect show/hide animations
28085	for ( prop in props ) {
28086		value = props[ prop ];
28087		if ( rfxtypes.test( value ) ) {
28088			delete props[ prop ];
28089			toggle = toggle || value === "toggle";
28090			if ( value === ( hidden ? "hide" : "show" ) ) {
28091
28092				// Pretend to be hidden if this is a "show" and
28093				// there is still data from a stopped show/hide
28094				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
28095					hidden = true;
28096
28097				// Ignore all other no-op show/hide data
28098				} else {
28099					continue;
28100				}
28101			}
28102			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
28103		}
28104	}
28105
28106	// Bail out if this is a no-op like .hide().hide()
28107	propTween = !jQuery.isEmptyObject( props );
28108	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
28109		return;
28110	}
28111
28112	// Restrict "overflow" and "display" styles during box animations
28113	if ( isBox && elem.nodeType === 1 ) {
28114
28115		// Support: IE <=9 - 11, Edge 12 - 15
28116		// Record all 3 overflow attributes because IE does not infer the shorthand
28117		// from identically-valued overflowX and overflowY and Edge just mirrors
28118		// the overflowX value there.
28119		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
28120
28121		// Identify a display type, preferring old show/hide data over the CSS cascade
28122		restoreDisplay = dataShow && dataShow.display;
28123		if ( restoreDisplay == null ) {
28124			restoreDisplay = dataPriv.get( elem, "display" );
28125		}
28126		display = jQuery.css( elem, "display" );
28127		if ( display === "none" ) {
28128			if ( restoreDisplay ) {
28129				display = restoreDisplay;
28130			} else {
28131
28132				// Get nonempty value(s) by temporarily forcing visibility
28133				showHide( [ elem ], true );
28134				restoreDisplay = elem.style.display || restoreDisplay;
28135				display = jQuery.css( elem, "display" );
28136				showHide( [ elem ] );
28137			}
28138		}
28139
28140		// Animate inline elements as inline-block
28141		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
28142			if ( jQuery.css( elem, "float" ) === "none" ) {
28143
28144				// Restore the original display value at the end of pure show/hide animations
28145				if ( !propTween ) {
28146					anim.done( function() {
28147						style.display = restoreDisplay;
28148					} );
28149					if ( restoreDisplay == null ) {
28150						display = style.display;
28151						restoreDisplay = display === "none" ? "" : display;
28152					}
28153				}
28154				style.display = "inline-block";
28155			}
28156		}
28157	}
28158
28159	if ( opts.overflow ) {
28160		style.overflow = "hidden";
28161		anim.always( function() {
28162			style.overflow = opts.overflow[ 0 ];
28163			style.overflowX = opts.overflow[ 1 ];
28164			style.overflowY = opts.overflow[ 2 ];
28165		} );
28166	}
28167
28168	// Implement show/hide animations
28169	propTween = false;
28170	for ( prop in orig ) {
28171
28172		// General show/hide setup for this element animation
28173		if ( !propTween ) {
28174			if ( dataShow ) {
28175				if ( "hidden" in dataShow ) {
28176					hidden = dataShow.hidden;
28177				}
28178			} else {
28179				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
28180			}
28181
28182			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
28183			if ( toggle ) {
28184				dataShow.hidden = !hidden;
28185			}
28186
28187			// Show elements before animating them
28188			if ( hidden ) {
28189				showHide( [ elem ], true );
28190			}
28191
28192			/* eslint-disable no-loop-func */
28193
28194			anim.done( function() {
28195
28196			/* eslint-enable no-loop-func */
28197
28198				// The final step of a "hide" animation is actually hiding the element
28199				if ( !hidden ) {
28200					showHide( [ elem ] );
28201				}
28202				dataPriv.remove( elem, "fxshow" );
28203				for ( prop in orig ) {
28204					jQuery.style( elem, prop, orig[ prop ] );
28205				}
28206			} );
28207		}
28208
28209		// Per-property setup
28210		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
28211		if ( !( prop in dataShow ) ) {
28212			dataShow[ prop ] = propTween.start;
28213			if ( hidden ) {
28214				propTween.end = propTween.start;
28215				propTween.start = 0;
28216			}
28217		}
28218	}
28219}
28220
28221function propFilter( props, specialEasing ) {
28222	var index, name, easing, value, hooks;
28223
28224	// camelCase, specialEasing and expand cssHook pass
28225	for ( index in props ) {
28226		name = camelCase( index );
28227		easing = specialEasing[ name ];
28228		value = props[ index ];
28229		if ( Array.isArray( value ) ) {
28230			easing = value[ 1 ];
28231			value = props[ index ] = value[ 0 ];
28232		}
28233
28234		if ( index !== name ) {
28235			props[ name ] = value;
28236			delete props[ index ];
28237		}
28238
28239		hooks = jQuery.cssHooks[ name ];
28240		if ( hooks && "expand" in hooks ) {
28241			value = hooks.expand( value );
28242			delete props[ name ];
28243
28244			// Not quite $.extend, this won't overwrite existing keys.
28245			// Reusing 'index' because we have the correct "name"
28246			for ( index in value ) {
28247				if ( !( index in props ) ) {
28248					props[ index ] = value[ index ];
28249					specialEasing[ index ] = easing;
28250				}
28251			}
28252		} else {
28253			specialEasing[ name ] = easing;
28254		}
28255	}
28256}
28257
28258function Animation( elem, properties, options ) {
28259	var result,
28260		stopped,
28261		index = 0,
28262		length = Animation.prefilters.length,
28263		deferred = jQuery.Deferred().always( function() {
28264
28265			// Don't match elem in the :animated selector
28266			delete tick.elem;
28267		} ),
28268		tick = function() {
28269			if ( stopped ) {
28270				return false;
28271			}
28272			var currentTime = fxNow || createFxNow(),
28273				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
28274
28275				// Support: Android 2.3 only
28276				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
28277				temp = remaining / animation.duration || 0,
28278				percent = 1 - temp,
28279				index = 0,
28280				length = animation.tweens.length;
28281
28282			for ( ; index < length; index++ ) {
28283				animation.tweens[ index ].run( percent );
28284			}
28285
28286			deferred.notifyWith( elem, [ animation, percent, remaining ] );
28287
28288			// If there's more to do, yield
28289			if ( percent < 1 && length ) {
28290				return remaining;
28291			}
28292
28293			// If this was an empty animation, synthesize a final progress notification
28294			if ( !length ) {
28295				deferred.notifyWith( elem, [ animation, 1, 0 ] );
28296			}
28297
28298			// Resolve the animation and report its conclusion
28299			deferred.resolveWith( elem, [ animation ] );
28300			return false;
28301		},
28302		animation = deferred.promise( {
28303			elem: elem,
28304			props: jQuery.extend( {}, properties ),
28305			opts: jQuery.extend( true, {
28306				specialEasing: {},
28307				easing: jQuery.easing._default
28308			}, options ),
28309			originalProperties: properties,
28310			originalOptions: options,
28311			startTime: fxNow || createFxNow(),
28312			duration: options.duration,
28313			tweens: [],
28314			createTween: function( prop, end ) {
28315				var tween = jQuery.Tween( elem, animation.opts, prop, end,
28316						animation.opts.specialEasing[ prop ] || animation.opts.easing );
28317				animation.tweens.push( tween );
28318				return tween;
28319			},
28320			stop: function( gotoEnd ) {
28321				var index = 0,
28322
28323					// If we are going to the end, we want to run all the tweens
28324					// otherwise we skip this part
28325					length = gotoEnd ? animation.tweens.length : 0;
28326				if ( stopped ) {
28327					return this;
28328				}
28329				stopped = true;
28330				for ( ; index < length; index++ ) {
28331					animation.tweens[ index ].run( 1 );
28332				}
28333
28334				// Resolve when we played the last frame; otherwise, reject
28335				if ( gotoEnd ) {
28336					deferred.notifyWith( elem, [ animation, 1, 0 ] );
28337					deferred.resolveWith( elem, [ animation, gotoEnd ] );
28338				} else {
28339					deferred.rejectWith( elem, [ animation, gotoEnd ] );
28340				}
28341				return this;
28342			}
28343		} ),
28344		props = animation.props;
28345
28346	propFilter( props, animation.opts.specialEasing );
28347
28348	for ( ; index < length; index++ ) {
28349		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
28350		if ( result ) {
28351			if ( isFunction( result.stop ) ) {
28352				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
28353					result.stop.bind( result );
28354			}
28355			return result;
28356		}
28357	}
28358
28359	jQuery.map( props, createTween, animation );
28360
28361	if ( isFunction( animation.opts.start ) ) {
28362		animation.opts.start.call( elem, animation );
28363	}
28364
28365	// Attach callbacks from options
28366	animation
28367		.progress( animation.opts.progress )
28368		.done( animation.opts.done, animation.opts.complete )
28369		.fail( animation.opts.fail )
28370		.always( animation.opts.always );
28371
28372	jQuery.fx.timer(
28373		jQuery.extend( tick, {
28374			elem: elem,
28375			anim: animation,
28376			queue: animation.opts.queue
28377		} )
28378	);
28379
28380	return animation;
28381}
28382
28383jQuery.Animation = jQuery.extend( Animation, {
28384
28385	tweeners: {
28386		"*": [ function( prop, value ) {
28387			var tween = this.createTween( prop, value );
28388			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
28389			return tween;
28390		} ]
28391	},
28392
28393	tweener: function( props, callback ) {
28394		if ( isFunction( props ) ) {
28395			callback = props;
28396			props = [ "*" ];
28397		} else {
28398			props = props.match( rnothtmlwhite );
28399		}
28400
28401		var prop,
28402			index = 0,
28403			length = props.length;
28404
28405		for ( ; index < length; index++ ) {
28406			prop = props[ index ];
28407			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
28408			Animation.tweeners[ prop ].unshift( callback );
28409		}
28410	},
28411
28412	prefilters: [ defaultPrefilter ],
28413
28414	prefilter: function( callback, prepend ) {
28415		if ( prepend ) {
28416			Animation.prefilters.unshift( callback );
28417		} else {
28418			Animation.prefilters.push( callback );
28419		}
28420	}
28421} );
28422
28423jQuery.speed = function( speed, easing, fn ) {
28424	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
28425		complete: fn || !fn && easing ||
28426			isFunction( speed ) && speed,
28427		duration: speed,
28428		easing: fn && easing || easing && !isFunction( easing ) && easing
28429	};
28430
28431	// Go to the end state if fx are off
28432	if ( jQuery.fx.off ) {
28433		opt.duration = 0;
28434
28435	} else {
28436		if ( typeof opt.duration !== "number" ) {
28437			if ( opt.duration in jQuery.fx.speeds ) {
28438				opt.duration = jQuery.fx.speeds[ opt.duration ];
28439
28440			} else {
28441				opt.duration = jQuery.fx.speeds._default;
28442			}
28443		}
28444	}
28445
28446	// Normalize opt.queue - true/undefined/null -> "fx"
28447	if ( opt.queue == null || opt.queue === true ) {
28448		opt.queue = "fx";
28449	}
28450
28451	// Queueing
28452	opt.old = opt.complete;
28453
28454	opt.complete = function() {
28455		if ( isFunction( opt.old ) ) {
28456			opt.old.call( this );
28457		}
28458
28459		if ( opt.queue ) {
28460			jQuery.dequeue( this, opt.queue );
28461		}
28462	};
28463
28464	return opt;
28465};
28466
28467jQuery.fn.extend( {
28468	fadeTo: function( speed, to, easing, callback ) {
28469
28470		// Show any hidden elements after setting opacity to 0
28471		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
28472
28473			// Animate to the value specified
28474			.end().animate( { opacity: to }, speed, easing, callback );
28475	},
28476	animate: function( prop, speed, easing, callback ) {
28477		var empty = jQuery.isEmptyObject( prop ),
28478			optall = jQuery.speed( speed, easing, callback ),
28479			doAnimation = function() {
28480
28481				// Operate on a copy of prop so per-property easing won't be lost
28482				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
28483
28484				// Empty animations, or finishing resolves immediately
28485				if ( empty || dataPriv.get( this, "finish" ) ) {
28486					anim.stop( true );
28487				}
28488			};
28489			doAnimation.finish = doAnimation;
28490
28491		return empty || optall.queue === false ?
28492			this.each( doAnimation ) :
28493			this.queue( optall.queue, doAnimation );
28494	},
28495	stop: function( type, clearQueue, gotoEnd ) {
28496		var stopQueue = function( hooks ) {
28497			var stop = hooks.stop;
28498			delete hooks.stop;
28499			stop( gotoEnd );
28500		};
28501
28502		if ( typeof type !== "string" ) {
28503			gotoEnd = clearQueue;
28504			clearQueue = type;
28505			type = undefined;
28506		}
28507		if ( clearQueue && type !== false ) {
28508			this.queue( type || "fx", [] );
28509		}
28510
28511		return this.each( function() {
28512			var dequeue = true,
28513				index = type != null && type + "queueHooks",
28514				timers = jQuery.timers,
28515				data = dataPriv.get( this );
28516
28517			if ( index ) {
28518				if ( data[ index ] && data[ index ].stop ) {
28519					stopQueue( data[ index ] );
28520				}
28521			} else {
28522				for ( index in data ) {
28523					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
28524						stopQueue( data[ index ] );
28525					}
28526				}
28527			}
28528
28529			for ( index = timers.length; index--; ) {
28530				if ( timers[ index ].elem === this &&
28531					( type == null || timers[ index ].queue === type ) ) {
28532
28533					timers[ index ].anim.stop( gotoEnd );
28534					dequeue = false;
28535					timers.splice( index, 1 );
28536				}
28537			}
28538
28539			// Start the next in the queue if the last step wasn't forced.
28540			// Timers currently will call their complete callbacks, which
28541			// will dequeue but only if they were gotoEnd.
28542			if ( dequeue || !gotoEnd ) {
28543				jQuery.dequeue( this, type );
28544			}
28545		} );
28546	},
28547	finish: function( type ) {
28548		if ( type !== false ) {
28549			type = type || "fx";
28550		}
28551		return this.each( function() {
28552			var index,
28553				data = dataPriv.get( this ),
28554				queue = data[ type + "queue" ],
28555				hooks = data[ type + "queueHooks" ],
28556				timers = jQuery.timers,
28557				length = queue ? queue.length : 0;
28558
28559			// Enable finishing flag on private data
28560			data.finish = true;
28561
28562			// Empty the queue first
28563			jQuery.queue( this, type, [] );
28564
28565			if ( hooks && hooks.stop ) {
28566				hooks.stop.call( this, true );
28567			}
28568
28569			// Look for any active animations, and finish them
28570			for ( index = timers.length; index--; ) {
28571				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
28572					timers[ index ].anim.stop( true );
28573					timers.splice( index, 1 );
28574				}
28575			}
28576
28577			// Look for any animations in the old queue and finish them
28578			for ( index = 0; index < length; index++ ) {
28579				if ( queue[ index ] && queue[ index ].finish ) {
28580					queue[ index ].finish.call( this );
28581				}
28582			}
28583
28584			// Turn off finishing flag
28585			delete data.finish;
28586		} );
28587	}
28588} );
28589
28590jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
28591	var cssFn = jQuery.fn[ name ];
28592	jQuery.fn[ name ] = function( speed, easing, callback ) {
28593		return speed == null || typeof speed === "boolean" ?
28594			cssFn.apply( this, arguments ) :
28595			this.animate( genFx( name, true ), speed, easing, callback );
28596	};
28597} );
28598
28599// Generate shortcuts for custom animations
28600jQuery.each( {
28601	slideDown: genFx( "show" ),
28602	slideUp: genFx( "hide" ),
28603	slideToggle: genFx( "toggle" ),
28604	fadeIn: { opacity: "show" },
28605	fadeOut: { opacity: "hide" },
28606	fadeToggle: { opacity: "toggle" }
28607}, function( name, props ) {
28608	jQuery.fn[ name ] = function( speed, easing, callback ) {
28609		return this.animate( props, speed, easing, callback );
28610	};
28611} );
28612
28613jQuery.timers = [];
28614jQuery.fx.tick = function() {
28615	var timer,
28616		i = 0,
28617		timers = jQuery.timers;
28618
28619	fxNow = Date.now();
28620
28621	for ( ; i < timers.length; i++ ) {
28622		timer = timers[ i ];
28623
28624		// Run the timer and safely remove it when done (allowing for external removal)
28625		if ( !timer() && timers[ i ] === timer ) {
28626			timers.splice( i--, 1 );
28627		}
28628	}
28629
28630	if ( !timers.length ) {
28631		jQuery.fx.stop();
28632	}
28633	fxNow = undefined;
28634};
28635
28636jQuery.fx.timer = function( timer ) {
28637	jQuery.timers.push( timer );
28638	jQuery.fx.start();
28639};
28640
28641jQuery.fx.interval = 13;
28642jQuery.fx.start = function() {
28643	if ( inProgress ) {
28644		return;
28645	}
28646
28647	inProgress = true;
28648	schedule();
28649};
28650
28651jQuery.fx.stop = function() {
28652	inProgress = null;
28653};
28654
28655jQuery.fx.speeds = {
28656	slow: 600,
28657	fast: 200,
28658
28659	// Default speed
28660	_default: 400
28661};
28662
28663
28664// Based off of the plugin by Clint Helfers, with permission.
28665// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
28666jQuery.fn.delay = function( time, type ) {
28667	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
28668	type = type || "fx";
28669
28670	return this.queue( type, function( next, hooks ) {
28671		var timeout = window.setTimeout( next, time );
28672		hooks.stop = function() {
28673			window.clearTimeout( timeout );
28674		};
28675	} );
28676};
28677
28678
28679( function() {
28680	var input = document.createElement( "input" ),
28681		select = document.createElement( "select" ),
28682		opt = select.appendChild( document.createElement( "option" ) );
28683
28684	input.type = "checkbox";
28685
28686	// Support: Android <=4.3 only
28687	// Default value for a checkbox should be "on"
28688	support.checkOn = input.value !== "";
28689
28690	// Support: IE <=11 only
28691	// Must access selectedIndex to make default options select
28692	support.optSelected = opt.selected;
28693
28694	// Support: IE <=11 only
28695	// An input loses its value after becoming a radio
28696	input = document.createElement( "input" );
28697	input.value = "t";
28698	input.type = "radio";
28699	support.radioValue = input.value === "t";
28700} )();
28701
28702
28703var boolHook,
28704	attrHandle = jQuery.expr.attrHandle;
28705
28706jQuery.fn.extend( {
28707	attr: function( name, value ) {
28708		return access( this, jQuery.attr, name, value, arguments.length > 1 );
28709	},
28710
28711	removeAttr: function( name ) {
28712		return this.each( function() {
28713			jQuery.removeAttr( this, name );
28714		} );
28715	}
28716} );
28717
28718jQuery.extend( {
28719	attr: function( elem, name, value ) {
28720		var ret, hooks,
28721			nType = elem.nodeType;
28722
28723		// Don't get/set attributes on text, comment and attribute nodes
28724		if ( nType === 3 || nType === 8 || nType === 2 ) {
28725			return;
28726		}
28727
28728		// Fallback to prop when attributes are not supported
28729		if ( typeof elem.getAttribute === "undefined" ) {
28730			return jQuery.prop( elem, name, value );
28731		}
28732
28733		// Attribute hooks are determined by the lowercase version
28734		// Grab necessary hook if one is defined
28735		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
28736			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
28737				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
28738		}
28739
28740		if ( value !== undefined ) {
28741			if ( value === null ) {
28742				jQuery.removeAttr( elem, name );
28743				return;
28744			}
28745
28746			if ( hooks && "set" in hooks &&
28747				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
28748				return ret;
28749			}
28750
28751			elem.setAttribute( name, value + "" );
28752			return value;
28753		}
28754
28755		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
28756			return ret;
28757		}
28758
28759		ret = jQuery.find.attr( elem, name );
28760
28761		// Non-existent attributes return null, we normalize to undefined
28762		return ret == null ? undefined : ret;
28763	},
28764
28765	attrHooks: {
28766		type: {
28767			set: function( elem, value ) {
28768				if ( !support.radioValue && value === "radio" &&
28769					nodeName( elem, "input" ) ) {
28770					var val = elem.value;
28771					elem.setAttribute( "type", value );
28772					if ( val ) {
28773						elem.value = val;
28774					}
28775					return value;
28776				}
28777			}
28778		}
28779	},
28780
28781	removeAttr: function( elem, value ) {
28782		var name,
28783			i = 0,
28784
28785			// Attribute names can contain non-HTML whitespace characters
28786			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
28787			attrNames = value && value.match( rnothtmlwhite );
28788
28789		if ( attrNames && elem.nodeType === 1 ) {
28790			while ( ( name = attrNames[ i++ ] ) ) {
28791				elem.removeAttribute( name );
28792			}
28793		}
28794	}
28795} );
28796
28797// Hooks for boolean attributes
28798boolHook = {
28799	set: function( elem, value, name ) {
28800		if ( value === false ) {
28801
28802			// Remove boolean attributes when set to false
28803			jQuery.removeAttr( elem, name );
28804		} else {
28805			elem.setAttribute( name, name );
28806		}
28807		return name;
28808	}
28809};
28810
28811jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
28812	var getter = attrHandle[ name ] || jQuery.find.attr;
28813
28814	attrHandle[ name ] = function( elem, name, isXML ) {
28815		var ret, handle,
28816			lowercaseName = name.toLowerCase();
28817
28818		if ( !isXML ) {
28819
28820			// Avoid an infinite loop by temporarily removing this function from the getter
28821			handle = attrHandle[ lowercaseName ];
28822			attrHandle[ lowercaseName ] = ret;
28823			ret = getter( elem, name, isXML ) != null ?
28824				lowercaseName :
28825				null;
28826			attrHandle[ lowercaseName ] = handle;
28827		}
28828		return ret;
28829	};
28830} );
28831
28832
28833
28834
28835var rfocusable = /^(?:input|select|textarea|button)$/i,
28836	rclickable = /^(?:a|area)$/i;
28837
28838jQuery.fn.extend( {
28839	prop: function( name, value ) {
28840		return access( this, jQuery.prop, name, value, arguments.length > 1 );
28841	},
28842
28843	removeProp: function( name ) {
28844		return this.each( function() {
28845			delete this[ jQuery.propFix[ name ] || name ];
28846		} );
28847	}
28848} );
28849
28850jQuery.extend( {
28851	prop: function( elem, name, value ) {
28852		var ret, hooks,
28853			nType = elem.nodeType;
28854
28855		// Don't get/set properties on text, comment and attribute nodes
28856		if ( nType === 3 || nType === 8 || nType === 2 ) {
28857			return;
28858		}
28859
28860		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
28861
28862			// Fix name and attach hooks
28863			name = jQuery.propFix[ name ] || name;
28864			hooks = jQuery.propHooks[ name ];
28865		}
28866
28867		if ( value !== undefined ) {
28868			if ( hooks && "set" in hooks &&
28869				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
28870				return ret;
28871			}
28872
28873			return ( elem[ name ] = value );
28874		}
28875
28876		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
28877			return ret;
28878		}
28879
28880		return elem[ name ];
28881	},
28882
28883	propHooks: {
28884		tabIndex: {
28885			get: function( elem ) {
28886
28887				// Support: IE <=9 - 11 only
28888				// elem.tabIndex doesn't always return the
28889				// correct value when it hasn't been explicitly set
28890				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
28891				// Use proper attribute retrieval(#12072)
28892				var tabindex = jQuery.find.attr( elem, "tabindex" );
28893
28894				if ( tabindex ) {
28895					return parseInt( tabindex, 10 );
28896				}
28897
28898				if (
28899					rfocusable.test( elem.nodeName ) ||
28900					rclickable.test( elem.nodeName ) &&
28901					elem.href
28902				) {
28903					return 0;
28904				}
28905
28906				return -1;
28907			}
28908		}
28909	},
28910
28911	propFix: {
28912		"for": "htmlFor",
28913		"class": "className"
28914	}
28915} );
28916
28917// Support: IE <=11 only
28918// Accessing the selectedIndex property
28919// forces the browser to respect setting selected
28920// on the option
28921// The getter ensures a default option is selected
28922// when in an optgroup
28923// eslint rule "no-unused-expressions" is disabled for this code
28924// since it considers such accessions noop
28925if ( !support.optSelected ) {
28926	jQuery.propHooks.selected = {
28927		get: function( elem ) {
28928
28929			/* eslint no-unused-expressions: "off" */
28930
28931			var parent = elem.parentNode;
28932			if ( parent && parent.parentNode ) {
28933				parent.parentNode.selectedIndex;
28934			}
28935			return null;
28936		},
28937		set: function( elem ) {
28938
28939			/* eslint no-unused-expressions: "off" */
28940
28941			var parent = elem.parentNode;
28942			if ( parent ) {
28943				parent.selectedIndex;
28944
28945				if ( parent.parentNode ) {
28946					parent.parentNode.selectedIndex;
28947				}
28948			}
28949		}
28950	};
28951}
28952
28953jQuery.each( [
28954	"tabIndex",
28955	"readOnly",
28956	"maxLength",
28957	"cellSpacing",
28958	"cellPadding",
28959	"rowSpan",
28960	"colSpan",
28961	"useMap",
28962	"frameBorder",
28963	"contentEditable"
28964], function() {
28965	jQuery.propFix[ this.toLowerCase() ] = this;
28966} );
28967
28968
28969
28970
28971	// Strip and collapse whitespace according to HTML spec
28972	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
28973	function stripAndCollapse( value ) {
28974		var tokens = value.match( rnothtmlwhite ) || [];
28975		return tokens.join( " " );
28976	}
28977
28978
28979function getClass( elem ) {
28980	return elem.getAttribute && elem.getAttribute( "class" ) || "";
28981}
28982
28983function classesToArray( value ) {
28984	if ( Array.isArray( value ) ) {
28985		return value;
28986	}
28987	if ( typeof value === "string" ) {
28988		return value.match( rnothtmlwhite ) || [];
28989	}
28990	return [];
28991}
28992
28993jQuery.fn.extend( {
28994	addClass: function( value ) {
28995		var classes, elem, cur, curValue, clazz, j, finalValue,
28996			i = 0;
28997
28998		if ( isFunction( value ) ) {
28999			return this.each( function( j ) {
29000				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
29001			} );
29002		}
29003
29004		classes = classesToArray( value );
29005
29006		if ( classes.length ) {
29007			while ( ( elem = this[ i++ ] ) ) {
29008				curValue = getClass( elem );
29009				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
29010
29011				if ( cur ) {
29012					j = 0;
29013					while ( ( clazz = classes[ j++ ] ) ) {
29014						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
29015							cur += clazz + " ";
29016						}
29017					}
29018
29019					// Only assign if different to avoid unneeded rendering.
29020					finalValue = stripAndCollapse( cur );
29021					if ( curValue !== finalValue ) {
29022						elem.setAttribute( "class", finalValue );
29023					}
29024				}
29025			}
29026		}
29027
29028		return this;
29029	},
29030
29031	removeClass: function( value ) {
29032		var classes, elem, cur, curValue, clazz, j, finalValue,
29033			i = 0;
29034
29035		if ( isFunction( value ) ) {
29036			return this.each( function( j ) {
29037				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
29038			} );
29039		}
29040
29041		if ( !arguments.length ) {
29042			return this.attr( "class", "" );
29043		}
29044
29045		classes = classesToArray( value );
29046
29047		if ( classes.length ) {
29048			while ( ( elem = this[ i++ ] ) ) {
29049				curValue = getClass( elem );
29050
29051				// This expression is here for better compressibility (see addClass)
29052				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
29053
29054				if ( cur ) {
29055					j = 0;
29056					while ( ( clazz = classes[ j++ ] ) ) {
29057
29058						// Remove *all* instances
29059						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
29060							cur = cur.replace( " " + clazz + " ", " " );
29061						}
29062					}
29063
29064					// Only assign if different to avoid unneeded rendering.
29065					finalValue = stripAndCollapse( cur );
29066					if ( curValue !== finalValue ) {
29067						elem.setAttribute( "class", finalValue );
29068					}
29069				}
29070			}
29071		}
29072
29073		return this;
29074	},
29075
29076	toggleClass: function( value, stateVal ) {
29077		var type = typeof value,
29078			isValidValue = type === "string" || Array.isArray( value );
29079
29080		if ( typeof stateVal === "boolean" && isValidValue ) {
29081			return stateVal ? this.addClass( value ) : this.removeClass( value );
29082		}
29083
29084		if ( isFunction( value ) ) {
29085			return this.each( function( i ) {
29086				jQuery( this ).toggleClass(
29087					value.call( this, i, getClass( this ), stateVal ),
29088					stateVal
29089				);
29090			} );
29091		}
29092
29093		return this.each( function() {
29094			var className, i, self, classNames;
29095
29096			if ( isValidValue ) {
29097
29098				// Toggle individual class names
29099				i = 0;
29100				self = jQuery( this );
29101				classNames = classesToArray( value );
29102
29103				while ( ( className = classNames[ i++ ] ) ) {
29104
29105					// Check each className given, space separated list
29106					if ( self.hasClass( className ) ) {
29107						self.removeClass( className );
29108					} else {
29109						self.addClass( className );
29110					}
29111				}
29112
29113			// Toggle whole class name
29114			} else if ( value === undefined || type === "boolean" ) {
29115				className = getClass( this );
29116				if ( className ) {
29117
29118					// Store className if set
29119					dataPriv.set( this, "__className__", className );
29120				}
29121
29122				// If the element has a class name or if we're passed `false`,
29123				// then remove the whole classname (if there was one, the above saved it).
29124				// Otherwise bring back whatever was previously saved (if anything),
29125				// falling back to the empty string if nothing was stored.
29126				if ( this.setAttribute ) {
29127					this.setAttribute( "class",
29128						className || value === false ?
29129						"" :
29130						dataPriv.get( this, "__className__" ) || ""
29131					);
29132				}
29133			}
29134		} );
29135	},
29136
29137	hasClass: function( selector ) {
29138		var className, elem,
29139			i = 0;
29140
29141		className = " " + selector + " ";
29142		while ( ( elem = this[ i++ ] ) ) {
29143			if ( elem.nodeType === 1 &&
29144				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
29145					return true;
29146			}
29147		}
29148
29149		return false;
vendor: 5,544 bytes, lines 29150-29385
29150	}
29151} );
29152
29153
29154
29155
29156var rreturn = /\r/g;
29157
29158jQuery.fn.extend( {
29159	val: function( value ) {
29160		var hooks, ret, valueIsFunction,
29161			elem = this[ 0 ];
29162
29163		if ( !arguments.length ) {
29164			if ( elem ) {
29165				hooks = jQuery.valHooks[ elem.type ] ||
29166					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
29167
29168				if ( hooks &&
29169					"get" in hooks &&
29170					( ret = hooks.get( elem, "value" ) ) !== undefined
29171				) {
29172					return ret;
29173				}
29174
29175				ret = elem.value;
29176
29177				// Handle most common string cases
29178				if ( typeof ret === "string" ) {
29179					return ret.replace( rreturn, "" );
29180				}
29181
29182				// Handle cases where value is null/undef or number
29183				return ret == null ? "" : ret;
29184			}
29185
29186			return;
29187		}
29188
29189		valueIsFunction = isFunction( value );
29190
29191		return this.each( function( i ) {
29192			var val;
29193
29194			if ( this.nodeType !== 1 ) {
29195				return;
29196			}
29197
29198			if ( valueIsFunction ) {
29199				val = value.call( this, i, jQuery( this ).val() );
29200			} else {
29201				val = value;
29202			}
29203
29204			// Treat null/undefined as ""; convert numbers to string
29205			if ( val == null ) {
29206				val = "";
29207
29208			} else if ( typeof val === "number" ) {
29209				val += "";
29210
29211			} else if ( Array.isArray( val ) ) {
29212				val = jQuery.map( val, function( value ) {
29213					return value == null ? "" : value + "";
29214				} );
29215			}
29216
29217			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
29218
29219			// If set returns undefined, fall back to normal setting
29220			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
29221				this.value = val;
29222			}
29223		} );
29224	}
29225} );
29226
29227jQuery.extend( {
29228	valHooks: {
29229		option: {
29230			get: function( elem ) {
29231
29232				var val = jQuery.find.attr( elem, "value" );
29233				return val != null ?
29234					val :
29235
29236					// Support: IE <=10 - 11 only
29237					// option.text throws exceptions (#14686, #14858)
29238					// Strip and collapse whitespace
29239					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
29240					stripAndCollapse( jQuery.text( elem ) );
29241			}
29242		},
29243		select: {
29244			get: function( elem ) {
29245				var value, option, i,
29246					options = elem.options,
29247					index = elem.selectedIndex,
29248					one = elem.type === "select-one",
29249					values = one ? null : [],
29250					max = one ? index + 1 : options.length;
29251
29252				if ( index < 0 ) {
29253					i = max;
29254
29255				} else {
29256					i = one ? index : 0;
29257				}
29258
29259				// Loop through all the selected options
29260				for ( ; i < max; i++ ) {
29261					option = options[ i ];
29262
29263					// Support: IE <=9 only
29264					// IE8-9 doesn't update selected after form reset (#2551)
29265					if ( ( option.selected || i === index ) &&
29266
29267							// Don't return options that are disabled or in a disabled optgroup
29268							!option.disabled &&
29269							( !option.parentNode.disabled ||
29270								!nodeName( option.parentNode, "optgroup" ) ) ) {
29271
29272						// Get the specific value for the option
29273						value = jQuery( option ).val();
29274
29275						// We don't need an array for one selects
29276						if ( one ) {
29277							return value;
29278						}
29279
29280						// Multi-Selects return an array
29281						values.push( value );
29282					}
29283				}
29284
29285				return values;
29286			},
29287
29288			set: function( elem, value ) {
29289				var optionSet, option,
29290					options = elem.options,
29291					values = jQuery.makeArray( value ),
29292					i = options.length;
29293
29294				while ( i-- ) {
29295					option = options[ i ];
29296
29297					/* eslint-disable no-cond-assign */
29298
29299					if ( option.selected =
29300						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
29301					) {
29302						optionSet = true;
29303					}
29304
29305					/* eslint-enable no-cond-assign */
29306				}
29307
29308				// Force browsers to behave consistently when non-matching value is set
29309				if ( !optionSet ) {
29310					elem.selectedIndex = -1;
29311				}
29312				return values;
29313			}
29314		}
29315	}
29316} );
29317
29318// Radios and checkboxes getter/setter
29319jQuery.each( [ "radio", "checkbox" ], function() {
29320	jQuery.valHooks[ this ] = {
29321		set: function( elem, value ) {
29322			if ( Array.isArray( value ) ) {
29323				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
29324			}
29325		}
29326	};
29327	if ( !support.checkOn ) {
29328		jQuery.valHooks[ this ].get = function( elem ) {
29329			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
29330		};
29331	}
29332} );
29333
29334
29335
29336
29337// Return jQuery for attributes-only inclusion
29338
29339
29340support.focusin = "onfocusin" in window;
29341
29342
29343var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
29344	stopPropagationCallback = function( e ) {
29345		e.stopPropagation();
29346	};
29347
29348jQuery.extend( jQuery.event, {
29349
29350	trigger: function( event, data, elem, onlyHandlers ) {
29351
29352		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
29353			eventPath = [ elem || document ],
29354			type = hasOwn.call( event, "type" ) ? event.type : event,
29355			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
29356
29357		cur = lastElement = tmp = elem = elem || document;
29358
29359		// Don't do events on text and comment nodes
29360		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
29361			return;
29362		}
29363
29364		// focus/blur morphs to focusin/out; ensure we're not firing them right now
29365		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
29366			return;
29367		}
29368
29369		if ( type.indexOf( "." ) > -1 ) {
29370
29371			// Namespaced trigger; create a regexp to match event type in handle()
29372			namespaces = type.split( "." );
29373			type = namespaces.shift();
29374			namespaces.sort();
29375		}
29376		ontype = type.indexOf( ":" ) < 0 && "on" + type;
29377
29378		// Caller can pass in a jQuery.Event object, Object, or just an event type string
29379		event = event[ jQuery.expando ] ?
29380			event :
29381			new jQuery.Event( type, typeof event === "object" && event );
29382
29383		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
29384		event.isTrigger = onlyHandlers ? 2 : 3;
29385		event.namespace = namespaces.join( "." );
vendor: 7,012 bytes, lines 29386-29659
29386		event.rnamespace = event.namespace ?
29387			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
29388			null;
29389
29390		// Clean up the event in case it is being reused
29391		event.result = undefined;
29392		if ( !event.target ) {
29393			event.target = elem;
29394		}
29395
29396		// Clone any incoming data and prepend the event, creating the handler arg list
29397		data = data == null ?
29398			[ event ] :
29399			jQuery.makeArray( data, [ event ] );
29400
29401		// Allow special events to draw outside the lines
29402		special = jQuery.event.special[ type ] || {};
29403		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
29404			return;
29405		}
29406
29407		// Determine event propagation path in advance, per W3C events spec (#9951)
29408		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
29409		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
29410
29411			bubbleType = special.delegateType || type;
29412			if ( !rfocusMorph.test( bubbleType + type ) ) {
29413				cur = cur.parentNode;
29414			}
29415			for ( ; cur; cur = cur.parentNode ) {
29416				eventPath.push( cur );
29417				tmp = cur;
29418			}
29419
29420			// Only add window if we got to document (e.g., not plain obj or detached DOM)
29421			if ( tmp === ( elem.ownerDocument || document ) ) {
29422				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
29423			}
29424		}
29425
29426		// Fire handlers on the event path
29427		i = 0;
29428		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
29429			lastElement = cur;
29430			event.type = i > 1 ?
29431				bubbleType :
29432				special.bindType || type;
29433
29434			// jQuery handler
29435			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
29436				dataPriv.get( cur, "handle" );
29437			if ( handle ) {
29438				handle.apply( cur, data );
29439			}
29440
29441			// Native handler
29442			handle = ontype && cur[ ontype ];
29443			if ( handle && handle.apply && acceptData( cur ) ) {
29444				event.result = handle.apply( cur, data );
29445				if ( event.result === false ) {
29446					event.preventDefault();
29447				}
29448			}
29449		}
29450		event.type = type;
29451
29452		// If nobody prevented the default action, do it now
29453		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
29454
29455			if ( ( !special._default ||
29456				special._default.apply( eventPath.pop(), data ) === false ) &&
29457				acceptData( elem ) ) {
29458
29459				// Call a native DOM method on the target with the same name as the event.
29460				// Don't do default actions on window, that's where global variables be (#6170)
29461				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
29462
29463					// Don't re-trigger an onFOO event when we call its FOO() method
29464					tmp = elem[ ontype ];
29465
29466					if ( tmp ) {
29467						elem[ ontype ] = null;
29468					}
29469
29470					// Prevent re-triggering of the same event, since we already bubbled it above
29471					jQuery.event.triggered = type;
29472
29473					if ( event.isPropagationStopped() ) {
29474						lastElement.addEventListener( type, stopPropagationCallback );
29475					}
29476
29477					elem[ type ]();
29478
29479					if ( event.isPropagationStopped() ) {
29480						lastElement.removeEventListener( type, stopPropagationCallback );
29481					}
29482
29483					jQuery.event.triggered = undefined;
29484
29485					if ( tmp ) {
29486						elem[ ontype ] = tmp;
29487					}
29488				}
29489			}
29490		}
29491
29492		return event.result;
29493	},
29494
29495	// Piggyback on a donor event to simulate a different one
29496	// Used only for `focus(in | out)` events
29497	simulate: function( type, elem, event ) {
29498		var e = jQuery.extend(
29499			new jQuery.Event(),
29500			event,
29501			{
29502				type: type,
29503				isSimulated: true
29504			}
29505		);
29506
29507		jQuery.event.trigger( e, null, elem );
29508	}
29509
29510} );
29511
29512jQuery.fn.extend( {
29513
29514	trigger: function( type, data ) {
29515		return this.each( function() {
29516			jQuery.event.trigger( type, data, this );
29517		} );
29518	},
29519	triggerHandler: function( type, data ) {
29520		var elem = this[ 0 ];
29521		if ( elem ) {
29522			return jQuery.event.trigger( type, data, elem, true );
29523		}
29524	}
29525} );
29526
29527
29528// Support: Firefox <=44
29529// Firefox doesn't have focus(in | out) events
29530// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
29531//
29532// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
29533// focus(in | out) events fire after focus & blur events,
29534// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
29535// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
29536if ( !support.focusin ) {
29537	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
29538
29539		// Attach a single capturing handler on the document while someone wants focusin/focusout
29540		var handler = function( event ) {
29541			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
29542		};
29543
29544		jQuery.event.special[ fix ] = {
29545			setup: function() {
29546				var doc = this.ownerDocument || this,
29547					attaches = dataPriv.access( doc, fix );
29548
29549				if ( !attaches ) {
29550					doc.addEventListener( orig, handler, true );
29551				}
29552				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
29553			},
29554			teardown: function() {
29555				var doc = this.ownerDocument || this,
29556					attaches = dataPriv.access( doc, fix ) - 1;
29557
29558				if ( !attaches ) {
29559					doc.removeEventListener( orig, handler, true );
29560					dataPriv.remove( doc, fix );
29561
29562				} else {
29563					dataPriv.access( doc, fix, attaches );
29564				}
29565			}
29566		};
29567	} );
29568}
29569var location = window.location;
29570
29571var nonce = Date.now();
29572
29573var rquery = ( /\?/ );
29574
29575
29576
29577// Cross-browser xml parsing
29578jQuery.parseXML = function( data ) {
29579	var xml;
29580	if ( !data || typeof data !== "string" ) {
29581		return null;
29582	}
29583
29584	// Support: IE 9 - 11 only
29585	// IE throws on parseFromString with invalid input.
29586	try {
29587		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
29588	} catch ( e ) {
29589		xml = undefined;
29590	}
29591
29592	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
29593		jQuery.error( "Invalid XML: " + data );
29594	}
29595	return xml;
29596};
29597
29598
29599var
29600	rbracket = /\[\]$/,
29601	rCRLF = /\r?\n/g,
29602	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
29603	rsubmittable = /^(?:input|select|textarea|keygen)/i;
29604
29605function buildParams( prefix, obj, traditional, add ) {
29606	var name;
29607
29608	if ( Array.isArray( obj ) ) {
29609
29610		// Serialize array item.
29611		jQuery.each( obj, function( i, v ) {
29612			if ( traditional || rbracket.test( prefix ) ) {
29613
29614				// Treat each array item as a scalar.
29615				add( prefix, v );
29616
29617			} else {
29618
29619				// Item is non-scalar (array or object), encode its numeric index.
29620				buildParams(
29621					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
29622					v,
29623					traditional,
29624					add
29625				);
29626			}
29627		} );
29628
29629	} else if ( !traditional && toType( obj ) === "object" ) {
29630
29631		// Serialize object item.
29632		for ( name in obj ) {
29633			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
29634		}
29635
29636	} else {
29637
29638		// Serialize scalar item.
29639		add( prefix, obj );
29640	}
29641}
29642
29643// Serialize an array of form elements or a set of
29644// key/values into a query string
29645jQuery.param = function( a, traditional ) {
29646	var prefix,
29647		s = [],
29648		add = function( key, valueOrFunction ) {
29649
29650			// If value is a function, invoke it and use its return value
29651			var value = isFunction( valueOrFunction ) ?
29652				valueOrFunction() :
29653				valueOrFunction;
29654
29655			s[ s.length ] = encodeURIComponent( key ) + "=" +
29656				encodeURIComponent( value == null ? "" : value );
29657		};
29658
29659	
29659if ( a == null ) {
29660		return "";
29661	}
vendor: 12,730 bytes, lines 29661-30165
29661
29662
29663	// If an array was passed in, assume that it is an array of form elements.
29664	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
29665
29666		// Serialize the form elements
29667		jQuery.each( a, function() {
29668			add( this.name, this.value );
29669		} );
29670
29671	} else {
29672
29673		// If traditional, encode the "old" way (the way 1.3.2 or older
29674		// did it), otherwise encode params recursively.
29675		for ( prefix in a ) {
29676			buildParams( prefix, a[ prefix ], traditional, add );
29677		}
29678	}
29679
29680	// Return the resulting serialization
29681	return s.join( "&" );
29682};
29683
29684jQuery.fn.extend( {
29685	serialize: function() {
29686		return jQuery.param( this.serializeArray() );
29687	},
29688	serializeArray: function() {
29689		return this.map( function() {
29690
29691			// Can add propHook for "elements" to filter or add form elements
29692			var elements = jQuery.prop( this, "elements" );
29693			return elements ? jQuery.makeArray( elements ) : this;
29694		} )
29695		.filter( function() {
29696			var type = this.type;
29697
29698			// Use .is( ":disabled" ) so that fieldset[disabled] works
29699			return this.name && !jQuery( this ).is( ":disabled" ) &&
29700				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
29701				( this.checked || !rcheckableType.test( type ) );
29702		} )
29703		.map( function( i, elem ) {
29704			var val = jQuery( this ).val();
29705
29706			if ( val == null ) {
29707				return null;
29708			}
29709
29710			if ( Array.isArray( val ) ) {
29711				return jQuery.map( val, function( val ) {
29712					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
29713				} );
29714			}
29715
29716			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
29717		} ).get();
29718	}
29719} );
29720
29721
29722var
29723	r20 = /%20/g,
29724	rhash = /#.*$/,
29725	rantiCache = /([?&])_=[^&]*/,
29726	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
29727
29728	// #7653, #8125, #8152: local protocol detection
29729	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
29730	rnoContent = /^(?:GET|HEAD)$/,
29731	rprotocol = /^\/\//,
29732
29733	/* Prefilters
29734	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
29735	 * 2) These are called:
29736	 *    - BEFORE asking for a transport
29737	 *    - AFTER param serialization (s.data is a string if s.processData is true)
29738	 * 3) key is the dataType
29739	 * 4) the catchall symbol "*" can be used
29740	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
29741	 */
29742	prefilters = {},
29743
29744	/* Transports bindings
29745	 * 1) key is the dataType
29746	 * 2) the catchall symbol "*" can be used
29747	 * 3) selection will start with transport dataType and THEN go to "*" if needed
29748	 */
29749	transports = {},
29750
29751	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
29752	allTypes = "*/".concat( "*" ),
29753
29754	// Anchor tag for parsing the document origin
29755	originAnchor = document.createElement( "a" );
29756	originAnchor.href = location.href;
29757
29758// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
29759function addToPrefiltersOrTransports( structure ) {
29760
29761	// dataTypeExpression is optional and defaults to "*"
29762	return function( dataTypeExpression, func ) {
29763
29764		if ( typeof dataTypeExpression !== "string" ) {
29765			func = dataTypeExpression;
29766			dataTypeExpression = "*";
29767		}
29768
29769		var dataType,
29770			i = 0,
29771			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
29772
29773		if ( isFunction( func ) ) {
29774
29775			// For each dataType in the dataTypeExpression
29776			while ( ( dataType = dataTypes[ i++ ] ) ) {
29777
29778				// Prepend if requested
29779				if ( dataType[ 0 ] === "+" ) {
29780					dataType = dataType.slice( 1 ) || "*";
29781					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
29782
29783				// Otherwise append
29784				} else {
29785					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
29786				}
29787			}
29788		}
29789	};
29790}
29791
29792// Base inspection function for prefilters and transports
29793function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
29794
29795	var inspected = {},
29796		seekingTransport = ( structure === transports );
29797
29798	function inspect( dataType ) {
29799		var selected;
29800		inspected[ dataType ] = true;
29801		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
29802			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
29803			if ( typeof dataTypeOrTransport === "string" &&
29804				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
29805
29806				options.dataTypes.unshift( dataTypeOrTransport );
29807				inspect( dataTypeOrTransport );
29808				return false;
29809			} else if ( seekingTransport ) {
29810				return !( selected = dataTypeOrTransport );
29811			}
29812		} );
29813		return selected;
29814	}
29815
29816	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
29817}
29818
29819// A special extend for ajax options
29820// that takes "flat" options (not to be deep extended)
29821// Fixes #9887
29822function ajaxExtend( target, src ) {
29823	var key, deep,
29824		flatOptions = jQuery.ajaxSettings.flatOptions || {};
29825
29826	for ( key in src ) {
29827		if ( src[ key ] !== undefined ) {
29828			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
29829		}
29830	}
29831	if ( deep ) {
29832		jQuery.extend( true, target, deep );
29833	}
29834
29835	return target;
29836}
29837
29838/* Handles responses to an ajax request:
29839 * - finds the right dataType (mediates between content-type and expected dataType)
29840 * - returns the corresponding response
29841 */
29842function ajaxHandleResponses( s, jqXHR, responses ) {
29843
29844	var ct, type, finalDataType, firstDataType,
29845		contents = s.contents,
29846		dataTypes = s.dataTypes;
29847
29848	// Remove auto dataType and get content-type in the process
29849	while ( dataTypes[ 0 ] === "*" ) {
29850		dataTypes.shift();
29851		if ( ct === undefined ) {
29852			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
29853		}
29854	}
29855
29856	// Check if we're dealing with a known content-type
29857	if ( ct ) {
29858		for ( type in contents ) {
29859			if ( contents[ type ] && contents[ type ].test( ct ) ) {
29860				dataTypes.unshift( type );
29861				break;
29862			}
29863		}
29864	}
29865
29866	// Check to see if we have a response for the expected dataType
29867	if ( dataTypes[ 0 ] in responses ) {
29868		finalDataType = dataTypes[ 0 ];
29869	} else {
29870
29871		// Try convertible dataTypes
29872		for ( type in responses ) {
29873			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
29874				finalDataType = type;
29875				break;
29876			}
29877			if ( !firstDataType ) {
29878				firstDataType = type;
29879			}
29880		}
29881
29882		// Or just use first one
29883		finalDataType = finalDataType || firstDataType;
29884	}
29885
29886	// If we found a dataType
29887	// We add the dataType to the list if needed
29888	// and return the corresponding response
29889	if ( finalDataType ) {
29890		if ( finalDataType !== dataTypes[ 0 ] ) {
29891			dataTypes.unshift( finalDataType );
29892		}
29893		return responses[ finalDataType ];
29894	}
29895}
29896
29897/* Chain conversions given the request and the original response
29898 * Also sets the responseXXX fields on the jqXHR instance
29899 */
29900function ajaxConvert( s, response, jqXHR, isSuccess ) {
29901	var conv2, current, conv, tmp, prev,
29902		converters = {},
29903
29904		// Work with a copy of dataTypes in case we need to modify it for conversion
29905		dataTypes = s.dataTypes.slice();
29906
29907	// Create converters map with lowercased keys
29908	if ( dataTypes[ 1 ] ) {
29909		for ( conv in s.converters ) {
29910			converters[ conv.toLowerCase() ] = s.converters[ conv ];
29911		}
29912	}
29913
29914	current = dataTypes.shift();
29915
29916	// Convert to each sequential dataType
29917	while ( current ) {
29918
29919		if ( s.responseFields[ current ] ) {
29920			jqXHR[ s.responseFields[ current ] ] = response;
29921		}
29922
29923		// Apply the dataFilter if provided
29924		if ( !prev && isSuccess && s.dataFilter ) {
29925			response = s.dataFilter( response, s.dataType );
29926		}
29927
29928		prev = current;
29929		current = dataTypes.shift();
29930
29931		if ( current ) {
29932
29933			// There's only work to do if current dataType is non-auto
29934			if ( current === "*" ) {
29935
29936				current = prev;
29937
29938			// Convert response if prev dataType is non-auto and differs from current
29939			} else if ( prev !== "*" && prev !== current ) {
29940
29941				// Seek a direct converter
29942				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
29943
29944				// If none found, seek a pair
29945				if ( !conv ) {
29946					for ( conv2 in converters ) {
29947
29948						// If conv2 outputs current
29949						tmp = conv2.split( " " );
29950						if ( tmp[ 1 ] === current ) {
29951
29952							// If prev can be converted to accepted input
29953							conv = converters[ prev + " " + tmp[ 0 ] ] ||
29954								converters[ "* " + tmp[ 0 ] ];
29955							if ( conv ) {
29956
29957								// Condense equivalence converters
29958								if ( conv === true ) {
29959									conv = converters[ conv2 ];
29960
29961								// Otherwise, insert the intermediate dataType
29962								} else if ( converters[ conv2 ] !== true ) {
29963									current = tmp[ 0 ];
29964									dataTypes.unshift( tmp[ 1 ] );
29965								}
29966								break;
29967							}
29968						}
29969					}
29970				}
29971
29972				// Apply converter (if not an equivalence)
29973				if ( conv !== true ) {
29974
29975					// Unless errors are allowed to bubble, catch and return them
29976					if ( conv && s.throws ) {
29977						response = conv( response );
29978					} else {
29979						try {
29980							response = conv( response );
29981						} catch ( e ) {
29982							return {
29983								state: "parsererror",
29984								error: conv ? e : "No conversion from " + prev + " to " + current
29985							};
29986						}
29987					}
29988				}
29989			}
29990		}
29991	}
29992
29993	return { state: "success", data: response };
29994}
29995
29996jQuery.extend( {
29997
29998	// Counter for holding the number of active queries
29999	active: 0,
30000
30001	// Last-Modified header cache for next request
30002	lastModified: {},
30003	etag: {},
30004
30005	ajaxSettings: {
30006		url: location.href,
30007		type: "GET",
30008		isLocal: rlocalProtocol.test( location.protocol ),
30009		global: true,
30010		processData: true,
30011		async: true,
30012		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
30013
30014		/*
30015		timeout: 0,
30016		data: null,
30017		dataType: null,
30018		username: null,
30019		password: null,
30020		cache: null,
30021		throws: false,
30022		traditional: false,
30023		headers: {},
30024		*/
30025
30026		accepts: {
30027			"*": allTypes,
30028			text: "text/plain",
30029			html: "text/html",
30030			xml: "application/xml, text/xml",
30031			json: "application/json, text/javascript"
30032		},
30033
30034		contents: {
30035			xml: /\bxml\b/,
30036			html: /\bhtml/,
30037			json: /\bjson\b/
30038		},
30039
30040		responseFields: {
30041			xml: "responseXML",
30042			text: "responseText",
30043			json: "responseJSON"
30044		},
30045
30046		// Data converters
30047		// Keys separate source (or catchall "*") and destination types with a single space
30048		converters: {
30049
30050			// Convert anything to text
30051			"* text": String,
30052
30053			// Text to html (true = no transformation)
30054			"text html": true,
30055
30056			// Evaluate text as a json expression
30057			"text json": JSON.parse,
30058
30059			// Parse text as xml
30060			"text xml": jQuery.parseXML
30061		},
30062
30063		// For options that shouldn't be deep extended:
30064		// you can add your own custom options here if
30065		// and when you create one that shouldn't be
30066		// deep extended (see ajaxExtend)
30067		flatOptions: {
30068			url: true,
30069			context: true
30070		}
30071	},
30072
30073	// Creates a full fledged settings object into target
30074	// with both ajaxSettings and settings fields.
30075	// If target is omitted, writes into ajaxSettings.
30076	ajaxSetup: function( target, settings ) {
30077		return settings ?
30078
30079			// Building a settings object
30080			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
30081
30082			// Extending ajaxSettings
30083			ajaxExtend( jQuery.ajaxSettings, target );
30084	},
30085
30086	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
30087	ajaxTransport: addToPrefiltersOrTransports( transports ),
30088
30089	// Main method
30090	ajax: function( url, options ) {
30091
30092		// If url is an object, simulate pre-1.5 signature
30093		if ( typeof url === "object" ) {
30094			options = url;
30095			url = undefined;
30096		}
30097
30098		// Force options to be an object
30099		options = options || {};
30100
30101		var transport,
30102
30103			// URL without anti-cache param
30104			cacheURL,
30105
30106			// Response headers
30107			responseHeadersString,
30108			responseHeaders,
30109
30110			// timeout handle
30111			timeoutTimer,
30112
30113			// Url cleanup var
30114			urlAnchor,
30115
30116			// Request state (becomes false upon send and true upon completion)
30117			completed,
30118
30119			// To know if global events are to be dispatched
30120			fireGlobals,
30121
30122			// Loop variable
30123			i,
30124
30125			// uncached part of the url
30126			uncached,
30127
30128			// Create the final options object
30129			s = jQuery.ajaxSetup( {}, options ),
30130
30131			// Callbacks context
30132			callbackContext = s.context || s,
30133
30134			// Context for global events is callbackContext if it is a DOM node or jQuery collection
30135			globalEventContext = s.context &&
30136				( callbackContext.nodeType || callbackContext.jquery ) ?
30137					jQuery( callbackContext ) :
30138					jQuery.event,
30139
30140			// Deferreds
30141			deferred = jQuery.Deferred(),
30142			completeDeferred = jQuery.Callbacks( "once memory" ),
30143
30144			// Status-dependent callbacks
30145			statusCode = s.statusCode || {},
30146
30147			// Headers (they are sent all at once)
30148			requestHeaders = {},
30149			requestHeadersNames = {},
30150
30151			// Default abort message
30152			strAbort = "canceled",
30153
30154			// Fake xhr
30155			jqXHR = {
30156				readyState: 0,
30157
30158				// Builds headers hashtable if needed
30159				getResponseHeader: function( key ) {
30160					var match;
30161					if ( completed ) {
30162						if ( !responseHeaders ) {
30163							responseHeaders = {};
30164							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
30165								responseHeaders[ match[ 1 ].toLowerCase() 
30165+ " " ] =
30166									( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
30167										.concat( match[ 2 ] );
30168							}
30169						}
30170						match = responseHeaders[ key.toLowerCase() + " " ];
30171					}
30172					return match == null ? null : match.join( ", " )
vendor: 10,702 bytes, lines 30172-30561
30172;
30173				},
30174
30175				// Raw string
30176				getAllResponseHeaders: function() {
30177					return completed ? responseHeadersString : null;
30178				},
30179
30180				// Caches the header
30181				setRequestHeader: function( name, value ) {
30182					if ( completed == null ) {
30183						name = requestHeadersNames[ name.toLowerCase() ] =
30184							requestHeadersNames[ name.toLowerCase() ] || name;
30185						requestHeaders[ name ] = value;
30186					}
30187					return this;
30188				},
30189
30190				// Overrides response content-type header
30191				overrideMimeType: function( type ) {
30192					if ( completed == null ) {
30193						s.mimeType = type;
30194					}
30195					return this;
30196				},
30197
30198				// Status-dependent callbacks
30199				statusCode: function( map ) {
30200					var code;
30201					if ( map ) {
30202						if ( completed ) {
30203
30204							// Execute the appropriate callbacks
30205							jqXHR.always( map[ jqXHR.status ] );
30206						} else {
30207
30208							// Lazy-add the new callbacks in a way that preserves old ones
30209							for ( code in map ) {
30210								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
30211							}
30212						}
30213					}
30214					return this;
30215				},
30216
30217				// Cancel the request
30218				abort: function( statusText ) {
30219					var finalText = statusText || strAbort;
30220					if ( transport ) {
30221						transport.abort( finalText );
30222					}
30223					done( 0, finalText );
30224					return this;
30225				}
30226			};
30227
30228		// Attach deferreds
30229		deferred.promise( jqXHR );
30230
30231		// Add protocol if not provided (prefilters might expect it)
30232		// Handle falsy url in the settings object (#10093: consistency with old signature)
30233		// We also use the url parameter if available
30234		s.url = ( ( url || s.url || location.href ) + "" )
30235			.replace( rprotocol, location.protocol + "//" );
30236
30237		// Alias method option to type as per ticket #12004
30238		s.type = options.method || options.type || s.method || s.type;
30239
30240		// Extract dataTypes list
30241		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
30242
30243		// A cross-domain request is in order when the origin doesn't match the current origin.
30244		if ( s.crossDomain == null ) {
30245			urlAnchor = document.createElement( "a" );
30246
30247			// Support: IE <=8 - 11, Edge 12 - 15
30248			// IE throws exception on accessing the href property if url is malformed,
30249			// e.g. http://example.com:80x/
30250			try {
30251				urlAnchor.href = s.url;
30252
30253				// Support: IE <=8 - 11 only
30254				// Anchor's host property isn't correctly set when s.url is relative
30255				urlAnchor.href = urlAnchor.href;
30256				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
30257					urlAnchor.protocol + "//" + urlAnchor.host;
30258			} catch ( e ) {
30259
30260				// If there is an error parsing the URL, assume it is crossDomain,
30261				// it can be rejected by the transport if it is invalid
30262				s.crossDomain = true;
30263			}
30264		}
30265
30266		// Convert data if not already a string
30267		if ( s.data && s.processData && typeof s.data !== "string" ) {
30268			s.data = jQuery.param( s.data, s.traditional );
30269		}
30270
30271		// Apply prefilters
30272		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
30273
30274		// If request was aborted inside a prefilter, stop there
30275		if ( completed ) {
30276			return jqXHR;
30277		}
30278
30279		// We can fire global events as of now if asked to
30280		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
30281		fireGlobals = jQuery.event && s.global;
30282
30283		// Watch for a new set of requests
30284		if ( fireGlobals && jQuery.active++ === 0 ) {
30285			jQuery.event.trigger( "ajaxStart" );
30286		}
30287
30288		// Uppercase the type
30289		s.type = s.type.toUpperCase();
30290
30291		// Determine if request has content
30292		s.hasContent = !rnoContent.test( s.type );
30293
30294		// Save the URL in case we're toying with the If-Modified-Since
30295		// and/or If-None-Match header later on
30296		// Remove hash to simplify url manipulation
30297		cacheURL = s.url.replace( rhash, "" );
30298
30299		// More options handling for requests with no content
30300		if ( !s.hasContent ) {
30301
30302			// Remember the hash so we can put it back
30303			uncached = s.url.slice( cacheURL.length );
30304
30305			// If data is available and should be processed, append data to url
30306			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
30307				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
30308
30309				// #9682: remove data so that it's not used in an eventual retry
30310				delete s.data;
30311			}
30312
30313			// Add or update anti-cache param if needed
30314			if ( s.cache === false ) {
30315				cacheURL = cacheURL.replace( rantiCache, "$1" );
30316				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
30317			}
30318
30319			// Put hash and anti-cache on the URL that will be requested (gh-1732)
30320			s.url = cacheURL + uncached;
30321
30322		// Change '%20' to '+' if this is encoded form body content (gh-2658)
30323		} else if ( s.data && s.processData &&
30324			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
30325			s.data = s.data.replace( r20, "+" );
30326		}
30327
30328		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
30329		if ( s.ifModified ) {
30330			if ( jQuery.lastModified[ cacheURL ] ) {
30331				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
30332			}
30333			if ( jQuery.etag[ cacheURL ] ) {
30334				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
30335			}
30336		}
30337
30338		// Set the correct header, if data is being sent
30339		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
30340			jqXHR.setRequestHeader( "Content-Type", s.contentType );
30341		}
30342
30343		// Set the Accepts header for the server, depending on the dataType
30344		jqXHR.setRequestHeader(
30345			"Accept",
30346			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
30347				s.accepts[ s.dataTypes[ 0 ] ] +
30348					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
30349				s.accepts[ "*" ]
30350		);
30351
30352		// Check for headers option
30353		for ( i in s.headers ) {
30354			jqXHR.setRequestHeader( i, s.headers[ i ] );
30355		}
30356
30357		// Allow custom headers/mimetypes and early abort
30358		if ( s.beforeSend &&
30359			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
30360
30361			// Abort if not done already and return
30362			return jqXHR.abort();
30363		}
30364
30365		// Aborting is no longer a cancellation
30366		strAbort = "abort";
30367
30368		// Install callbacks on deferreds
30369		completeDeferred.add( s.complete );
30370		jqXHR.done( s.success );
30371		jqXHR.fail( s.error );
30372
30373		// Get transport
30374		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
30375
30376		// If no transport, we auto-abort
30377		if ( !transport ) {
30378			done( -1, "No Transport" );
30379		} else {
30380			jqXHR.readyState = 1;
30381
30382			// Send global event
30383			if ( fireGlobals ) {
30384				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
30385			}
30386
30387			// If request was aborted inside ajaxSend, stop there
30388			if ( completed ) {
30389				return jqXHR;
30390			}
30391
30392			// Timeout
30393			if ( s.async && s.timeout > 0 ) {
30394				timeoutTimer = window.setTimeout( function() {
30395					jqXHR.abort( "timeout" );
30396				}, s.timeout );
30397			}
30398
30399			try {
30400				completed = false;
30401				transport.send( requestHeaders, done );
30402			} catch ( e ) {
30403
30404				// Rethrow post-completion exceptions
30405				if ( completed ) {
30406					throw e;
30407				}
30408
30409				// Propagate others as results
30410				done( -1, e );
30411			}
30412		}
30413
30414		// Callback for when everything is done
30415		function done( status, nativeStatusText, responses, headers ) {
30416			var isSuccess, success, error, response, modified,
30417				statusText = nativeStatusText;
30418
30419			// Ignore repeat invocations
30420			if ( completed ) {
30421				return;
30422			}
30423
30424			completed = true;
30425
30426			// Clear timeout if it exists
30427			if ( timeoutTimer ) {
30428				window.clearTimeout( timeoutTimer );
30429			}
30430
30431			// Dereference transport for early garbage collection
30432			// (no matter how long the jqXHR object will be used)
30433			transport = undefined;
30434
30435			// Cache response headers
30436			responseHeadersString = headers || "";
30437
30438			// Set readyState
30439			jqXHR.readyState = status > 0 ? 4 : 0;
30440
30441			// Determine if successful
30442			isSuccess = status >= 200 && status < 300 || status === 304;
30443
30444			// Get response data
30445			if ( responses ) {
30446				response = ajaxHandleResponses( s, jqXHR, responses );
30447			}
30448
30449			// Convert no matter what (that way responseXXX fields are always set)
30450			response = ajaxConvert( s, response, jqXHR, isSuccess );
30451
30452			// If successful, handle type chaining
30453			if ( isSuccess ) {
30454
30455				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
30456				if ( s.ifModified ) {
30457					modified = jqXHR.getResponseHeader( "Last-Modified" );
30458					if ( modified ) {
30459						jQuery.lastModified[ cacheURL ] = modified;
30460					}
30461					modified = jqXHR.getResponseHeader( "etag" );
30462					if ( modified ) {
30463						jQuery.etag[ cacheURL ] = modified;
30464					}
30465				}
30466
30467				// if no content
30468				if ( status === 204 || s.type === "HEAD" ) {
30469					statusText = "nocontent";
30470
30471				// if not modified
30472				} else if ( status === 304 ) {
30473					statusText = "notmodified";
30474
30475				// If we have data, let's convert it
30476				} else {
30477					statusText = response.state;
30478					success = response.data;
30479					error = response.error;
30480					isSuccess = !error;
30481				}
30482			} else {
30483
30484				// Extract error from statusText and normalize for non-aborts
30485				error = statusText;
30486				if ( status || !statusText ) {
30487					statusText = "error";
30488					if ( status < 0 ) {
30489						status = 0;
30490					}
30491				}
30492			}
30493
30494			// Set data for the fake xhr object
30495			jqXHR.status = status;
30496			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
30497
30498			// Success/Error
30499			if ( isSuccess ) {
30500				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
30501			} else {
30502				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
30503			}
30504
30505			// Status-dependent callbacks
30506			jqXHR.statusCode( statusCode );
30507			statusCode = undefined;
30508
30509			if ( fireGlobals ) {
30510				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
30511					[ jqXHR, s, isSuccess ? success : error ] );
30512			}
30513
30514			// Complete
30515			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
30516
30517			if ( fireGlobals ) {
30518				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
30519
30520				// Handle the global AJAX counter
30521				if ( !( --jQuery.active ) ) {
30522					jQuery.event.trigger( "ajaxStop" );
30523				}
30524			}
30525		}
30526
30527		return jqXHR;
30528	},
30529
30530	getJSON: function( url, data, callback ) {
30531		return jQuery.get( url, data, callback, "json" );
30532	},
30533
30534	getScript: function( url, callback ) {
30535		return jQuery.get( url, undefined, callback, "script" );
30536	}
30537} );
30538
30539jQuery.each( [ "get", "post" ], function( i, method ) {
30540	jQuery[ method ] = function( url, data, callback, type ) {
30541
30542		// Shift arguments if data argument was omitted
30543		if ( isFunction( data ) ) {
30544			type = type || callback;
30545			callback = data;
30546			data = undefined;
30547		}
30548
30549		// The url can be an options object (which then must have .url)
30550		return jQuery.ajax( jQuery.extend( {
30551			url: url,
30552			type: method,
30553			dataType: type,
30554			data: data,
30555			success: callback
30556		}, jQuery.isPlainObject( url ) && url ) );
30557	};
30558} );
30559
30560
30561jQuery._evalUrl = function( url
30561, options ) {
30562	return jQuery.ajax( {
30563		url: url,
30564
30565		// Make this explicit, since user can override this through ajaxSetup (#11264)
30566		type: "GET",
30567		dataType: "script",
30568		cache: true,
30569		async: false,
30570		global: false,
30571
30572		// Only evaluate the response if it is successful (gh-4126)
30573		// dataFilter is not invoked for failure responses, so using it instead
30574		// of the default converter is kludgy but it works.
30575		converters: {
30576			"text script": function() {}
30577		},
30578		dataFilter: function( response ) {
30579			jQuery.globalEval( response, options
vendor: 11,651 bytes, lines 30579-31044
30579 );
30580		}
30581	} );
30582};
30583
30584
30585jQuery.fn.extend( {
30586	wrapAll: function( html ) {
30587		var wrap;
30588
30589		if ( this[ 0 ] ) {
30590			if ( isFunction( html ) ) {
30591				html = html.call( this[ 0 ] );
30592			}
30593
30594			// The elements to wrap the target around
30595			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
30596
30597			if ( this[ 0 ].parentNode ) {
30598				wrap.insertBefore( this[ 0 ] );
30599			}
30600
30601			wrap.map( function() {
30602				var elem = this;
30603
30604				while ( elem.firstElementChild ) {
30605					elem = elem.firstElementChild;
30606				}
30607
30608				return elem;
30609			} ).append( this );
30610		}
30611
30612		return this;
30613	},
30614
30615	wrapInner: function( html ) {
30616		if ( isFunction( html ) ) {
30617			return this.each( function( i ) {
30618				jQuery( this ).wrapInner( html.call( this, i ) );
30619			} );
30620		}
30621
30622		return this.each( function() {
30623			var self = jQuery( this ),
30624				contents = self.contents();
30625
30626			if ( contents.length ) {
30627				contents.wrapAll( html );
30628
30629			} else {
30630				self.append( html );
30631			}
30632		} );
30633	},
30634
30635	wrap: function( html ) {
30636		var htmlIsFunction = isFunction( html );
30637
30638		return this.each( function( i ) {
30639			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
30640		} );
30641	},
30642
30643	unwrap: function( selector ) {
30644		this.parent( selector ).not( "body" ).each( function() {
30645			jQuery( this ).replaceWith( this.childNodes );
30646		} );
30647		return this;
30648	}
30649} );
30650
30651
30652jQuery.expr.pseudos.hidden = function( elem ) {
30653	return !jQuery.expr.pseudos.visible( elem );
30654};
30655jQuery.expr.pseudos.visible = function( elem ) {
30656	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
30657};
30658
30659
30660
30661
30662jQuery.ajaxSettings.xhr = function() {
30663	try {
30664		return new window.XMLHttpRequest();
30665	} catch ( e ) {}
30666};
30667
30668var xhrSuccessStatus = {
30669
30670		// File protocol always yields status code 0, assume 200
30671		0: 200,
30672
30673		// Support: IE <=9 only
30674		// #1450: sometimes IE returns 1223 when it should be 204
30675		1223: 204
30676	},
30677	xhrSupported = jQuery.ajaxSettings.xhr();
30678
30679support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
30680support.ajax = xhrSupported = !!xhrSupported;
30681
30682jQuery.ajaxTransport( function( options ) {
30683	var callback, errorCallback;
30684
30685	// Cross domain only allowed if supported through XMLHttpRequest
30686	if ( support.cors || xhrSupported && !options.crossDomain ) {
30687		return {
30688			send: function( headers, complete ) {
30689				var i,
30690					xhr = options.xhr();
30691
30692				xhr.open(
30693					options.type,
30694					options.url,
30695					options.async,
30696					options.username,
30697					options.password
30698				);
30699
30700				// Apply custom fields if provided
30701				if ( options.xhrFields ) {
30702					for ( i in options.xhrFields ) {
30703						xhr[ i ] = options.xhrFields[ i ];
30704					}
30705				}
30706
30707				// Override mime type if needed
30708				if ( options.mimeType && xhr.overrideMimeType ) {
30709					xhr.overrideMimeType( options.mimeType );
30710				}
30711
30712				// X-Requested-With header
30713				// For cross-domain requests, seeing as conditions for a preflight are
30714				// akin to a jigsaw puzzle, we simply never set it to be sure.
30715				// (it can always be set on a per-request basis or even using ajaxSetup)
30716				// For same-domain requests, won't change header if already provided.
30717				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
30718					headers[ "X-Requested-With" ] = "XMLHttpRequest";
30719				}
30720
30721				// Set headers
30722				for ( i in headers ) {
30723					xhr.setRequestHeader( i, headers[ i ] );
30724				}
30725
30726				// Callback
30727				callback = function( type ) {
30728					return function() {
30729						if ( callback ) {
30730							callback = errorCallback = xhr.onload =
30731								xhr.onerror = xhr.onabort = xhr.ontimeout =
30732									xhr.onreadystatechange = null;
30733
30734							if ( type === "abort" ) {
30735								xhr.abort();
30736							} else if ( type === "error" ) {
30737
30738								// Support: IE <=9 only
30739								// On a manual native abort, IE9 throws
30740								// errors on any property access that is not readyState
30741								if ( typeof xhr.status !== "number" ) {
30742									complete( 0, "error" );
30743								} else {
30744									complete(
30745
30746										// File: protocol always yields status 0; see #8605, #14207
30747										xhr.status,
30748										xhr.statusText
30749									);
30750								}
30751							} else {
30752								complete(
30753									xhrSuccessStatus[ xhr.status ] || xhr.status,
30754									xhr.statusText,
30755
30756									// Support: IE <=9 only
30757									// IE9 has no XHR2 but throws on binary (trac-11426)
30758									// For XHR2 non-text, let the caller handle it (gh-2498)
30759									( xhr.responseType || "text" ) !== "text"  ||
30760									typeof xhr.responseText !== "string" ?
30761										{ binary: xhr.response } :
30762										{ text: xhr.responseText },
30763									xhr.getAllResponseHeaders()
30764								);
30765							}
30766						}
30767					};
30768				};
30769
30770				// Listen to events
30771				xhr.onload = callback();
30772				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
30773
30774				// Support: IE 9 only
30775				// Use onreadystatechange to replace onabort
30776				// to handle uncaught aborts
30777				if ( xhr.onabort !== undefined ) {
30778					xhr.onabort = errorCallback;
30779				} else {
30780					xhr.onreadystatechange = function() {
30781
30782						// Check readyState before timeout as it changes
30783						if ( xhr.readyState === 4 ) {
30784
30785							// Allow onerror to be called first,
30786							// but that will not handle a native abort
30787							// Also, save errorCallback to a variable
30788							// as xhr.onerror cannot be accessed
30789							window.setTimeout( function() {
30790								if ( callback ) {
30791									errorCallback();
30792								}
30793							} );
30794						}
30795					};
30796				}
30797
30798				// Create the abort callback
30799				callback = callback( "abort" );
30800
30801				try {
30802
30803					// Do send the request (this may raise an exception)
30804					xhr.send( options.hasContent && options.data || null );
30805				} catch ( e ) {
30806
30807					// #14683: Only rethrow if this hasn't been notified as an error yet
30808					if ( callback ) {
30809						throw e;
30810					}
30811				}
30812			},
30813
30814			abort: function() {
30815				if ( callback ) {
30816					callback();
30817				}
30818			}
30819		};
30820	}
30821} );
30822
30823
30824
30825
30826// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
30827jQuery.ajaxPrefilter( function( s ) {
30828	if ( s.crossDomain ) {
30829		s.contents.script = false;
30830	}
30831} );
30832
30833// Install script dataType
30834jQuery.ajaxSetup( {
30835	accepts: {
30836		script: "text/javascript, application/javascript, " +
30837			"application/ecmascript, application/x-ecmascript"
30838	},
30839	contents: {
30840		script: /\b(?:java|ecma)script\b/
30841	},
30842	converters: {
30843		"text script": function( text ) {
30844			jQuery.globalEval( text );
30845			return text;
30846		}
30847	}
30848} );
30849
30850// Handle cache's special case and crossDomain
30851jQuery.ajaxPrefilter( "script", function( s ) {
30852	if ( s.cache === undefined ) {
30853		s.cache = false;
30854	}
30855	if ( s.crossDomain ) {
30856		s.type = "GET";
30857	}
30858} );
30859
30860// Bind script tag hack transport
30861jQuery.ajaxTransport( "script", function( s ) {
30862
30863	// This transport only deals with cross domain or forced-by-attrs requests
30864	if ( s.crossDomain || s.scriptAttrs ) {
30865		var script, callback;
30866		return {
30867			send: function( _, complete ) {
30868				script = jQuery( "<script>" )
30869					.attr( s.scriptAttrs || {} )
30870					.prop( { charset: s.scriptCharset, src: s.url } )
30871					.on( "load error", callback = function( evt ) {
30872						script.remove();
30873						callback = null;
30874						if ( evt ) {
30875							complete( evt.type === "error" ? 404 : 200, evt.type );
30876						}
30877					} );
30878
30879				// Use native DOM manipulation to avoid our domManip AJAX trickery
30880				document.head.appendChild( script[ 0 ] );
30881			},
30882			abort: function() {
30883				if ( callback ) {
30884					callback();
30885				}
30886			}
30887		};
30888	}
30889} );
30890
30891
30892
30893
30894var oldCallbacks = [],
30895	rjsonp = /(=)\?(?=&|$)|\?\?/;
30896
30897// Default jsonp settings
30898jQuery.ajaxSetup( {
30899	jsonp: "callback",
30900	jsonpCallback: function() {
30901		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
30902		this[ callback ] = true;
30903		return callback;
30904	}
30905} );
30906
30907// Detect, normalize options and install callbacks for jsonp requests
30908jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
30909
30910	var callbackName, overwritten, responseContainer,
30911		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
30912			"url" :
30913			typeof s.data === "string" &&
30914				( s.contentType || "" )
30915					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
30916				rjsonp.test( s.data ) && "data"
30917		);
30918
30919	// Handle iff the expected data type is "jsonp" or we have a parameter to set
30920	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
30921
30922		// Get callback name, remembering preexisting value associated with it
30923		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
30924			s.jsonpCallback() :
30925			s.jsonpCallback;
30926
30927		// Insert callback into url or form data
30928		if ( jsonProp ) {
30929			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
30930		} else if ( s.jsonp !== false ) {
30931			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
30932		}
30933
30934		// Use data converter to retrieve json after script execution
30935		s.converters[ "script json" ] = function() {
30936			if ( !responseContainer ) {
30937				jQuery.error( callbackName + " was not called" );
30938			}
30939			return responseContainer[ 0 ];
30940		};
30941
30942		// Force json dataType
30943		s.dataTypes[ 0 ] = "json";
30944
30945		// Install callback
30946		overwritten = window[ callbackName ];
30947		window[ callbackName ] = function() {
30948			responseContainer = arguments;
30949		};
30950
30951		// Clean-up function (fires after converters)
30952		jqXHR.always( function() {
30953
30954			// If previous value didn't exist - remove it
30955			if ( overwritten === undefined ) {
30956				jQuery( window ).removeProp( callbackName );
30957
30958			// Otherwise restore preexisting value
30959			} else {
30960				window[ callbackName ] = overwritten;
30961			}
30962
30963			// Save back as free
30964			if ( s[ callbackName ] ) {
30965
30966				// Make sure that re-using the options doesn't screw things around
30967				s.jsonpCallback = originalSettings.jsonpCallback;
30968
30969				// Save the callback name for future use
30970				oldCallbacks.push( callbackName );
30971			}
30972
30973			// Call if it was a function and we have a response
30974			if ( responseContainer && isFunction( overwritten ) ) {
30975				overwritten( responseContainer[ 0 ] );
30976			}
30977
30978			responseContainer = overwritten = undefined;
30979		} );
30980
30981		// Delegate to script
30982		return "script";
30983	}
30984} );
30985
30986
30987
30988
30989// Support: Safari 8 only
30990// In Safari 8 documents created via document.implementation.createHTMLDocument
30991// collapse sibling forms: the second one becomes a child of the first one.
30992// Because of that, this security measure has to be disabled in Safari 8.
30993// https://bugs.webkit.org/show_bug.cgi?id=137337
30994support.createHTMLDocument = ( function() {
30995	var body = document.implementation.createHTMLDocument( "" ).body;
30996	body.innerHTML = "<form></form><form></form>";
30997	return body.childNodes.length === 2;
30998} )();
30999
31000
31001// Argument "data" should be string of html
31002// context (optional): If specified, the fragment will be created in this context,
31003// defaults to document
31004// keepScripts (optional): If true, will include scripts passed in the html string
31005jQuery.parseHTML = function( data, context, keepScripts ) {
31006	if ( typeof data !== "string" ) {
31007		return [];
31008	}
31009	if ( typeof context === "boolean" ) {
31010		keepScripts = context;
31011		context = false;
31012	}
31013
31014	var base, parsed, scripts;
31015
31016	if ( !context ) {
31017
31018		// Stop scripts or inline event handlers from being executed immediately
31019		// by using document.implementation
31020		if ( support.createHTMLDocument ) {
31021			context = document.implementation.createHTMLDocument( "" );
31022
31023			// Set the base href for the created document
31024			// so any parsed elements with URLs
31025			// are based on the document's URL (gh-2965)
31026			base = context.createElement( "base" );
31027			base.href = document.location.href;
31028			context.head.appendChild( base );
31029		} else {
31030			context = document;
31031		}
31032	}
31033
31034	parsed = rsingleTag.exec( data );
31035	scripts = !keepScripts && [];
31036
31037	// Single tag
31038	if ( parsed ) {
31039		return [ context.createElement( parsed[ 1 ] ) ];
31040	}
31041
31042	parsed = buildFragment( [ data ], context, scripts );
31043
31044	if ( scripts && scripts.length ) {
vendor: 14,511 bytes, lines 31045-31565
31045		jQuery( scripts ).remove();
31046	}
31047
31048	return jQuery.merge( [], parsed.childNodes );
31049};
31050
31051
31052/**
31053 * Load a url into a page
31054 */
31055jQuery.fn.load = function( url, params, callback ) {
31056	var selector, type, response,
31057		self = this,
31058		off = url.indexOf( " " );
31059
31060	if ( off > -1 ) {
31061		selector = stripAndCollapse( url.slice( off ) );
31062		url = url.slice( 0, off );
31063	}
31064
31065	// If it's a function
31066	if ( isFunction( params ) ) {
31067
31068		// We assume that it's the callback
31069		callback = params;
31070		params = undefined;
31071
31072	// Otherwise, build a param string
31073	} else if ( params && typeof params === "object" ) {
31074		type = "POST";
31075	}
31076
31077	// If we have elements to modify, make the request
31078	if ( self.length > 0 ) {
31079		jQuery.ajax( {
31080			url: url,
31081
31082			// If "type" variable is undefined, then "GET" method will be used.
31083			// Make value of this field explicit since
31084			// user can override it through ajaxSetup method
31085			type: type || "GET",
31086			dataType: "html",
31087			data: params
31088		} ).done( function( responseText ) {
31089
31090			// Save response for use in complete callback
31091			response = arguments;
31092
31093			self.html( selector ?
31094
31095				// If a selector was specified, locate the right elements in a dummy div
31096				// Exclude scripts to avoid IE 'Permission Denied' errors
31097				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
31098
31099				// Otherwise use the full result
31100				responseText );
31101
31102		// If the request succeeds, this function gets "data", "status", "jqXHR"
31103		// but they are ignored because response was set above.
31104		// If it fails, this function gets "jqXHR", "status", "error"
31105		} ).always( callback && function( jqXHR, status ) {
31106			self.each( function() {
31107				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
31108			} );
31109		} );
31110	}
31111
31112	return this;
31113};
31114
31115
31116
31117
31118// Attach a bunch of functions for handling common AJAX events
31119jQuery.each( [
31120	"ajaxStart",
31121	"ajaxStop",
31122	"ajaxComplete",
31123	"ajaxError",
31124	"ajaxSuccess",
31125	"ajaxSend"
31126], function( i, type ) {
31127	jQuery.fn[ type ] = function( fn ) {
31128		return this.on( type, fn );
31129	};
31130} );
31131
31132
31133
31134
31135jQuery.expr.pseudos.animated = function( elem ) {
31136	return jQuery.grep( jQuery.timers, function( fn ) {
31137		return elem === fn.elem;
31138	} ).length;
31139};
31140
31141
31142
31143
31144jQuery.offset = {
31145	setOffset: function( elem, options, i ) {
31146		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
31147			position = jQuery.css( elem, "position" ),
31148			curElem = jQuery( elem ),
31149			props = {};
31150
31151		// Set position first, in-case top/left are set even on static elem
31152		if ( position === "static" ) {
31153			elem.style.position = "relative";
31154		}
31155
31156		curOffset = curElem.offset();
31157		curCSSTop = jQuery.css( elem, "top" );
31158		curCSSLeft = jQuery.css( elem, "left" );
31159		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
31160			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
31161
31162		// Need to be able to calculate position if either
31163		// top or left is auto and position is either absolute or fixed
31164		if ( calculatePosition ) {
31165			curPosition = curElem.position();
31166			curTop = curPosition.top;
31167			curLeft = curPosition.left;
31168
31169		} else {
31170			curTop = parseFloat( curCSSTop ) || 0;
31171			curLeft = parseFloat( curCSSLeft ) || 0;
31172		}
31173
31174		if ( isFunction( options ) ) {
31175
31176			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
31177			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
31178		}
31179
31180		if ( options.top != null ) {
31181			props.top = ( options.top - curOffset.top ) + curTop;
31182		}
31183		if ( options.left != null ) {
31184			props.left = ( options.left - curOffset.left ) + curLeft;
31185		}
31186
31187		if ( "using" in options ) {
31188			options.using.call( elem, props );
31189
31190		} else {
31191			curElem.css( props );
31192		}
31193	}
31194};
31195
31196jQuery.fn.extend( {
31197
31198	// offset() relates an element's border box to the document origin
31199	offset: function( options ) {
31200
31201		// Preserve chaining for setter
31202		if ( arguments.length ) {
31203			return options === undefined ?
31204				this :
31205				this.each( function( i ) {
31206					jQuery.offset.setOffset( this, options, i );
31207				} );
31208		}
31209
31210		var rect, win,
31211			elem = this[ 0 ];
31212
31213		if ( !elem ) {
31214			return;
31215		}
31216
31217		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
31218		// Support: IE <=11 only
31219		// Running getBoundingClientRect on a
31220		// disconnected node in IE throws an error
31221		if ( !elem.getClientRects().length ) {
31222			return { top: 0, left: 0 };
31223		}
31224
31225		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
31226		rect = elem.getBoundingClientRect();
31227		win = elem.ownerDocument.defaultView;
31228		return {
31229			top: rect.top + win.pageYOffset,
31230			left: rect.left + win.pageXOffset
31231		};
31232	},
31233
31234	// position() relates an element's margin box to its offset parent's padding box
31235	// This corresponds to the behavior of CSS absolute positioning
31236	position: function() {
31237		if ( !this[ 0 ] ) {
31238			return;
31239		}
31240
31241		var offsetParent, offset, doc,
31242			elem = this[ 0 ],
31243			parentOffset = { top: 0, left: 0 };
31244
31245		// position:fixed elements are offset from the viewport, which itself always has zero offset
31246		if ( jQuery.css( elem, "position" ) === "fixed" ) {
31247
31248			// Assume position:fixed implies availability of getBoundingClientRect
31249			offset = elem.getBoundingClientRect();
31250
31251		} else {
31252			offset = this.offset();
31253
31254			// Account for the *real* offset parent, which can be the document or its root element
31255			// when a statically positioned element is identified
31256			doc = elem.ownerDocument;
31257			offsetParent = elem.offsetParent || doc.documentElement;
31258			while ( offsetParent &&
31259				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
31260				jQuery.css( offsetParent, "position" ) === "static" ) {
31261
31262				offsetParent = offsetParent.parentNode;
31263			}
31264			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
31265
31266				// Incorporate borders into its offset, since they are outside its content origin
31267				parentOffset = jQuery( offsetParent ).offset();
31268				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
31269				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
31270			}
31271		}
31272
31273		// Subtract parent offsets and element margins
31274		return {
31275			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
31276			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
31277		};
31278	},
31279
31280	// This method will return documentElement in the following cases:
31281	// 1) For the element inside the iframe without offsetParent, this method will return
31282	//    documentElement of the parent window
31283	// 2) For the hidden or detached element
31284	// 3) For body or html element, i.e. in case of the html node - it will return itself
31285	//
31286	// but those exceptions were never presented as a real life use-cases
31287	// and might be considered as more preferable results.
31288	//
31289	// This logic, however, is not guaranteed and can change at any point in the future
31290	offsetParent: function() {
31291		return this.map( function() {
31292			var offsetParent = this.offsetParent;
31293
31294			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
31295				offsetParent = offsetParent.offsetParent;
31296			}
31297
31298			return offsetParent || documentElement;
31299		} );
31300	}
31301} );
31302
31303// Create scrollLeft and scrollTop methods
31304jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
31305	var top = "pageYOffset" === prop;
31306
31307	jQuery.fn[ method ] = function( val ) {
31308		return access( this, function( elem, method, val ) {
31309
31310			// Coalesce documents and windows
31311			var win;
31312			if ( isWindow( elem ) ) {
31313				win = elem;
31314			} else if ( elem.nodeType === 9 ) {
31315				win = elem.defaultView;
31316			}
31317
31318			if ( val === undefined ) {
31319				return win ? win[ prop ] : elem[ method ];
31320			}
31321
31322			if ( win ) {
31323				win.scrollTo(
31324					!top ? val : win.pageXOffset,
31325					top ? val : win.pageYOffset
31326				);
31327
31328			} else {
31329				elem[ method ] = val;
31330			}
31331		}, method, val, arguments.length );
31332	};
31333} );
31334
31335// Support: Safari <=7 - 9.1, Chrome <=37 - 49
31336// Add the top/left cssHooks using jQuery.fn.position
31337// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
31338// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
31339// getComputedStyle returns percent when specified for top/left/bottom/right;
31340// rather than make the css module depend on the offset module, just check for it here
31341jQuery.each( [ "top", "left" ], function( i, prop ) {
31342	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
31343		function( elem, computed ) {
31344			if ( computed ) {
31345				computed = curCSS( elem, prop );
31346
31347				// If curCSS returns percentage, fallback to offset
31348				return rnumnonpx.test( computed ) ?
31349					jQuery( elem ).position()[ prop ] + "px" :
31350					computed;
31351			}
31352		}
31353	);
31354} );
31355
31356
31357// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
31358jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
31359	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
31360		function( defaultExtra, funcName ) {
31361
31362		// Margin is only for outerHeight, outerWidth
31363		jQuery.fn[ funcName ] = function( margin, value ) {
31364			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
31365				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
31366
31367			return access( this, function( elem, type, value ) {
31368				var doc;
31369
31370				if ( isWindow( elem ) ) {
31371
31372					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
31373					return funcName.indexOf( "outer" ) === 0 ?
31374						elem[ "inner" + name ] :
31375						elem.document.documentElement[ "client" + name ];
31376				}
31377
31378				// Get document width or height
31379				if ( elem.nodeType === 9 ) {
31380					doc = elem.documentElement;
31381
31382					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
31383					// whichever is greatest
31384					return Math.max(
31385						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
31386						elem.body[ "offset" + name ], doc[ "offset" + name ],
31387						doc[ "client" + name ]
31388					);
31389				}
31390
31391				return value === undefined ?
31392
31393					// Get width or height on the element, requesting but not forcing parseFloat
31394					jQuery.css( elem, type, extra ) :
31395
31396					// Set width or height on the element
31397					jQuery.style( elem, type, value, extra );
31398			}, type, chainable ? margin : undefined, chainable );
31399		};
31400	} );
31401} );
31402
31403
31404jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
31405	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
31406	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
31407	function( i, name ) {
31408
31409	// Handle event binding
31410	jQuery.fn[ name ] = function( data, fn ) {
31411		return arguments.length > 0 ?
31412			this.on( name, null, data, fn ) :
31413			this.trigger( name );
31414	};
31415} );
31416
31417jQuery.fn.extend( {
31418	hover: function( fnOver, fnOut ) {
31419		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
31420	}
31421} );
31422
31423
31424
31425
31426jQuery.fn.extend( {
31427
31428	bind: function( types, data, fn ) {
31429		return this.on( types, null, data, fn );
31430	},
31431	unbind: function( types, fn ) {
31432		return this.off( types, null, fn );
31433	},
31434
31435	delegate: function( selector, types, data, fn ) {
31436		return this.on( types, selector, data, fn );
31437	},
31438	undelegate: function( selector, types, fn ) {
31439
31440		// ( namespace ) or ( selector, types [, fn] )
31441		return arguments.length === 1 ?
31442			this.off( selector, "**" ) :
31443			this.off( types, selector || "**", fn );
31444	}
31445} );
31446
31447// Bind a function to a context, optionally partially applying any
31448// arguments.
31449// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
31450// However, it is not slated for removal any time soon
31451jQuery.proxy = function( fn, context ) {
31452	var tmp, args, proxy;
31453
31454	if ( typeof context === "string" ) {
31455		tmp = fn[ context ];
31456		context = fn;
31457		fn = tmp;
31458	}
31459
31460	// Quick check to determine if target is callable, in the spec
31461	// this throws a TypeError, but we will just return undefined.
31462	if ( !isFunction( fn ) ) {
31463		return undefined;
31464	}
31465
31466	// Simulated bind
31467	args = slice.call( arguments, 2 );
31468	proxy = function() {
31469		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
31470	};
31471
31472	// Set the guid of unique handler to the same of original handler, so it can be removed
31473	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
31474
31475	return proxy;
31476};
31477
31478jQuery.holdReady = function( hold ) {
31479	if ( hold ) {
31480		jQuery.readyWait++;
31481	} else {
31482		jQuery.ready( true );
31483	}
31484};
31485jQuery.isArray = Array.isArray;
31486jQuery.parseJSON = JSON.parse;
31487jQuery.nodeName = nodeName;
31488jQuery.isFunction = isFunction;
31489jQuery.isWindow = isWindow;
31490jQuery.camelCase = camelCase;
31491jQuery.type = toType;
31492
31493jQuery.now = Date.now;
31494
31495jQuery.isNumeric = function( obj ) {
31496
31497	// As of jQuery 3.0, isNumeric is limited to
31498	// strings and numbers (primitives or objects)
31499	// that can be coerced to finite numbers (gh-2662)
31500	var type = jQuery.type( obj );
31501	return ( type === "number" || type === "string" ) &&
31502
31503		// parseFloat NaNs numeric-cast false positives ("")
31504		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
31505		// subtraction forces infinities to NaN
31506		!isNaN( obj - parseFloat( obj ) );
31507};
31508
31509
31510
31511
31512// Register as a named AMD module, since jQuery can be concatenated with other
31513// files that may use define, but not via a proper concatenation script that
31514// understands anonymous AMD modules. A named AMD is safest and most robust
31515// way to register. Lowercase jquery is used because AMD module names are
31516// derived from file names, and jQuery is normally delivered in a lowercase
31517// file name. Do this after creating the global so that if an AMD module wants
31518// to call noConflict to hide this version of jQuery, it will work.
31519
31520// Note that for maximum portability, libraries that are not jQuery should
31521// declare themselves as anonymous modules, and avoid setting a global if an
31522// AMD loader is present. jQuery is a special case. For more information, see
31523// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
31524
31525if ( typeof define === "function" && define.amd ) {
31526	define( "jquery", [], function() {
31527		return jQuery;
31528	} );
31529}
31530
31531
31532
31533
31534var
31535
31536	// Map over jQuery in case of overwrite
31537	_jQuery = window.jQuery,
31538
31539	// Map over the $ in case of overwrite
31540	_$ = window.$;
31541
31542jQuery.noConflict = function( deep ) {
31543	if ( window.$ === jQuery ) {
31544		window.$ = _$;
31545	}
31546
31547	if ( deep && window.jQuery === jQuery ) {
31548		window.jQuery = _jQuery;
31549	}
31550
31551	return jQuery;
31552};
31553
31554// Expose jQuery and $ identifiers, even in AMD
31555// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
31556// and CommonJS for browser emulators (#13566)
31557if ( !noGlobal ) {
31558	window.jQuery = window.$ = jQuery;
31559}
31560
31561
31562
31563
31564return jQuery;
31565} );
31566
31567},{}],14:[function(require,module,exports){
31568//! moment.js
31569
31570;(function (global, factory) {
31571    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
31572    typeof define === 'function' && define.amd ? define(factory) :
31573    global.moment = factory()
vendor: 56,293 bytes, lines 31573-33333
31573
31574}(this, (function () { 'use strict';
31575
31576    var hookCallback;
31577
31578    function hooks () {
31579        return hookCallback.apply(null, arguments);
31580    }
31581
31582    // This is done to register the method called with moment()
31583    // without creating circular dependencies.
31584    function setHookCallback (callback) {
31585        hookCallback = callback;
31586    }
31587
31588    function isArray(input) {
31589        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
31590    }
31591
31592    function isObject(input) {
31593        // IE8 will treat undefined and null as object if it wasn't for
31594        // input != null
31595        return input != null && Object.prototype.toString.call(input) === '[object Object]';
31596    }
31597
31598    function isObjectEmpty(obj) {
31599        if (Object.getOwnPropertyNames) {
31600            return (Object.getOwnPropertyNames(obj).length === 0);
31601        } else {
31602            var k;
31603            for (k in obj) {
31604                if (obj.hasOwnProperty(k)) {
31605                    return false;
31606                }
31607            }
31608            return true;
31609        }
31610    }
31611
31612    function isUndefined(input) {
31613        return input === void 0;
31614    }
31615
31616    function isNumber(input) {
31617        return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
31618    }
31619
31620    function isDate(input) {
31621        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
31622    }
31623
31624    function map(arr, fn) {
31625        var res = [], i;
31626        for (i = 0; i < arr.length; ++i) {
31627            res.push(fn(arr[i], i));
31628        }
31629        return res;
31630    }
31631
31632    function hasOwnProp(a, b) {
31633        return Object.prototype.hasOwnProperty.call(a, b);
31634    }
31635
31636    function extend(a, b) {
31637        for (var i in b) {
31638            if (hasOwnProp(b, i)) {
31639                a[i] = b[i];
31640            }
31641        }
31642
31643        if (hasOwnProp(b, 'toString')) {
31644            a.toString = b.toString;
31645        }
31646
31647        if (hasOwnProp(b, 'valueOf')) {
31648            a.valueOf = b.valueOf;
31649        }
31650
31651        return a;
31652    }
31653
31654    function createUTC (input, format, locale, strict) {
31655        return createLocalOrUTC(input, format, locale, strict, true).utc();
31656    }
31657
31658    function defaultParsingFlags() {
31659        // We need to deep clone this object.
31660        return {
31661            empty           : false,
31662            unusedTokens    : [],
31663            unusedInput     : [],
31664            overflow        : -2,
31665            charsLeftOver   : 0,
31666            nullInput       : false,
31667            invalidMonth    : null,
31668            invalidFormat   : false,
31669            userInvalidated : false,
31670            iso             : false,
31671            parsedDateParts : [],
31672            meridiem        : null,
31673            rfc2822         : false,
31674            weekdayMismatch : false
31675        };
31676    }
31677
31678    function getParsingFlags(m) {
31679        if (m._pf == null) {
31680            m._pf = defaultParsingFlags();
31681        }
31682        return m._pf;
31683    }
31684
31685    var some;
31686    if (Array.prototype.some) {
31687        some = Array.prototype.some;
31688    } else {
31689        some = function (fun) {
31690            var t = Object(this);
31691            var len = t.length >>> 0;
31692
31693            for (var i = 0; i < len; i++) {
31694                if (i in t && fun.call(this, t[i], i, t)) {
31695                    return true;
31696                }
31697            }
31698
31699            return false;
31700        };
31701    }
31702
31703    function isValid(m) {
31704        if (m._isValid == null) {
31705            var flags = getParsingFlags(m);
31706            var parsedParts = some.call(flags.parsedDateParts, function (i) {
31707                return i != null;
31708            });
31709            var isNowValid = !isNaN(m._d.getTime()) &&
31710                flags.overflow < 0 &&
31711                !flags.empty &&
31712                !flags.invalidMonth &&
31713                !flags.invalidWeekday &&
31714                !flags.weekdayMismatch &&
31715                !flags.nullInput &&
31716                !flags.invalidFormat &&
31717                !flags.userInvalidated &&
31718                (!flags.meridiem || (flags.meridiem && parsedParts));
31719
31720            if (m._strict) {
31721                isNowValid = isNowValid &&
31722                    flags.charsLeftOver === 0 &&
31723                    flags.unusedTokens.length === 0 &&
31724                    flags.bigHour === undefined;
31725            }
31726
31727            if (Object.isFrozen == null || !Object.isFrozen(m)) {
31728                m._isValid = isNowValid;
31729            }
31730            else {
31731                return isNowValid;
31732            }
31733        }
31734        return m._isValid;
31735    }
31736
31737    function createInvalid (flags) {
31738        var m = createUTC(NaN);
31739        if (flags != null) {
31740            extend(getParsingFlags(m), flags);
31741        }
31742        else {
31743            getParsingFlags(m).userInvalidated = true;
31744        }
31745
31746        return m;
31747    }
31748
31749    // Plugins that add properties should also add the key here (null value),
31750    // so we can properly clone ourselves.
31751    var momentProperties = hooks.momentProperties = [];
31752
31753    function copyConfig(to, from) {
31754        var i, prop, val;
31755
31756        if (!isUndefined(from._isAMomentObject)) {
31757            to._isAMomentObject = from._isAMomentObject;
31758        }
31759        if (!isUndefined(from._i)) {
31760            to._i = from._i;
31761        }
31762        if (!isUndefined(from._f)) {
31763            to._f = from._f;
31764        }
31765        if (!isUndefined(from._l)) {
31766            to._l = from._l;
31767        }
31768        if (!isUndefined(from._strict)) {
31769            to._strict = from._strict;
31770        }
31771        if (!isUndefined(from._tzm)) {
31772            to._tzm = from._tzm;
31773        }
31774        if (!isUndefined(from._isUTC)) {
31775            to._isUTC = from._isUTC;
31776        }
31777        if (!isUndefined(from._offset)) {
31778            to._offset = from._offset;
31779        }
31780        if (!isUndefined(from._pf)) {
31781            to._pf = getParsingFlags(from);
31782        }
31783        if (!isUndefined(from._locale)) {
31784            to._locale = from._locale;
31785        }
31786
31787        if (momentProperties.length > 0) {
31788            for (i = 0; i < momentProperties.length; i++) {
31789                prop = momentProperties[i];
31790                val = from[prop];
31791                if (!isUndefined(val)) {
31792                    to[prop] = val;
31793                }
31794            }
31795        }
31796
31797        return to;
31798    }
31799
31800    var updateInProgress = false;
31801
31802    // Moment prototype object
31803    function Moment(config) {
31804        copyConfig(this, config);
31805        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
31806        if (!this.isValid()) {
31807            this._d = new Date(NaN);
31808        }
31809        // Prevent infinite loop in case updateOffset creates new moment
31810        // objects.
31811        if (updateInProgress === false) {
31812            updateInProgress = true;
31813            hooks.updateOffset(this);
31814            updateInProgress = false;
31815        }
31816    }
31817
31818    function isMoment (obj) {
31819        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
31820    }
31821
31822    function absFloor (number) {
31823        if (number < 0) {
31824            // -0 -> 0
31825            return Math.ceil(number) || 0;
31826        } else {
31827            return Math.floor(number);
31828        }
31829    }
31830
31831    function toInt(argumentForCoercion) {
31832        var coercedNumber = +argumentForCoercion,
31833            value = 0;
31834
31835        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
31836            value = absFloor(coercedNumber);
31837        }
31838
31839        return value;
31840    }
31841
31842    // compare two arrays, return the number of differences
31843    function compareArrays(array1, array2, dontConvert) {
31844        var len = Math.min(array1.length, array2.length),
31845            lengthDiff = Math.abs(array1.length - array2.length),
31846            diffs = 0,
31847            i;
31848        for (i = 0; i < len; i++) {
31849            if ((dontConvert && array1[i] !== array2[i]) ||
31850                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
31851                diffs++;
31852            }
31853        }
31854        return diffs + lengthDiff;
31855    }
31856
31857    function warn(msg) {
31858        if (hooks.suppressDeprecationWarnings === false &&
31859                (typeof console !==  'undefined') && console.warn) {
31860            console.warn('Deprecation warning: ' + msg);
31861        }
31862    }
31863
31864    function deprecate(msg, fn) {
31865        var firstTime = true;
31866
31867        return extend(function () {
31868            if (hooks.deprecationHandler != null) {
31869                hooks.deprecationHandler(null, msg);
31870            }
31871            if (firstTime) {
31872                var args = [];
31873                var arg;
31874                for (var i = 0; i < arguments.length; i++) {
31875                    arg = '';
31876                    if (typeof arguments[i] === 'object') {
31877                        arg += '\n[' + i + '] ';
31878                        for (var key in arguments[0]) {
31879                            arg += key + ': ' + arguments[0][key] + ', ';
31880                        }
31881                        arg = arg.slice(0, -2); // Remove trailing comma and space
31882                    } else {
31883                        arg = arguments[i];
31884                    }
31885                    args.push(arg);
31886                }
31887                warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
31888                firstTime = false;
31889            }
31890            return fn.apply(this, arguments);
31891        }, fn);
31892    }
31893
31894    var deprecations = {};
31895
31896    function deprecateSimple(name, msg) {
31897        if (hooks.deprecationHandler != null) {
31898            hooks.deprecationHandler(name, msg);
31899        }
31900        if (!deprecations[name]) {
31901            warn(msg);
31902            deprecations[name] = true;
31903        }
31904    }
31905
31906    hooks.suppressDeprecationWarnings = false;
31907    hooks.deprecationHandler = null;
31908
31909    function isFunction(input) {
31910        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
31911    }
31912
31913    function set (config) {
31914        var prop, i;
31915        for (i in config) {
31916            prop = config[i];
31917            if (isFunction(prop)) {
31918                this[i] = prop;
31919            } else {
31920                this['_' + i] = prop;
31921            }
31922        }
31923        this._config = config;
31924        // Lenient ordinal parsing accepts just a number in addition to
31925        // number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
31926        // TODO: Remove "ordinalParse" fallback in next major release.
31927        this._dayOfMonthOrdinalParseLenient = new RegExp(
31928            (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
31929                '|' + (/\d{1,2}/).source);
31930    }
31931
31932    function mergeConfigs(parentConfig, childConfig) {
31933        var res = extend({}, parentConfig), prop;
31934        for (prop in childConfig) {
31935            if (hasOwnProp(childConfig, prop)) {
31936                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
31937                    res[prop] = {};
31938                    extend(res[prop], parentConfig[prop]);
31939                    extend(res[prop], childConfig[prop]);
31940                } else if (childConfig[prop] != null) {
31941                    res[prop] = childConfig[prop];
31942                } else {
31943                    delete res[prop];
31944                }
31945            }
31946        }
31947        for (prop in parentConfig) {
31948            if (hasOwnProp(parentConfig, prop) &&
31949                    !hasOwnProp(childConfig, prop) &&
31950                    isObject(parentConfig[prop])) {
31951                // make sure changes to properties don't modify parent config
31952                res[prop] = extend({}, res[prop]);
31953            }
31954        }
31955        return res;
31956    }
31957
31958    function Locale(config) {
31959        if (config != null) {
31960            this.set(config);
31961        }
31962    }
31963
31964    var keys;
31965
31966    if (Object.keys) {
31967        keys = Object.keys;
31968    } else {
31969        keys = function (obj) {
31970            var i, res = [];
31971            for (i in obj) {
31972                if (hasOwnProp(obj, i)) {
31973                    res.push(i);
31974                }
31975            }
31976            return res;
31977        };
31978    }
31979
31980    var defaultCalendar = {
31981        sameDay : '[Today at] LT',
31982        nextDay : '[Tomorrow at] LT',
31983        nextWeek : 'dddd [at] LT',
31984        lastDay : '[Yesterday at] LT',
31985        lastWeek : '[Last] dddd [at] LT',
31986        sameElse : 'L'
31987    };
31988
31989    function calendar (key, mom, now) {
31990        var output = this._calendar[key] || this._calendar['sameElse'];
31991        return isFunction(output) ? output.call(mom, now) : output;
31992    }
31993
31994    var defaultLongDateFormat = {
31995        LTS  : 'h:mm:ss A',
31996        LT   : 'h:mm A',
31997        L    : 'MM/DD/YYYY',
31998        LL   : 'MMMM D, YYYY',
31999        LLL  : 'MMMM D, YYYY h:mm A',
32000        LLLL : 'dddd, MMMM D, YYYY h:mm A'
32001    };
32002
32003    function longDateFormat (key) {
32004        var format = this._longDateFormat[key],
32005            formatUpper = this._longDateFormat[key.toUpperCase()];
32006
32007        if (format || !formatUpper) {
32008            return format;
32009        }
32010
32011        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
32012            return val.slice(1);
32013        });
32014
32015        return this._longDateFormat[key];
32016    }
32017
32018    var defaultInvalidDate = 'Invalid date';
32019
32020    function invalidDate () {
32021        return this._invalidDate;
32022    }
32023
32024    var defaultOrdinal = '%d';
32025    var defaultDayOfMonthOrdinalParse = /\d{1,2}/;
32026
32027    function ordinal (number) {
32028        return this._ordinal.replace('%d', number);
32029    }
32030
32031    var defaultRelativeTime = {
32032        future : 'in %s',
32033        past   : '%s ago',
32034        s  : 'a few seconds',
32035        ss : '%d seconds',
32036        m  : 'a minute',
32037        mm : '%d minutes',
32038        h  : 'an hour',
32039        hh : '%d hours',
32040        d  : 'a day',
32041        dd : '%d days',
32042        M  : 'a month',
32043        MM : '%d months',
32044        y  : 'a year',
32045        yy : '%d years'
32046    };
32047
32048    function relativeTime (number, withoutSuffix, string, isFuture) {
32049        var output = this._relativeTime[string];
32050        return (isFunction(output)) ?
32051            output(number, withoutSuffix, string, isFuture) :
32052            output.replace(/%d/i, number);
32053    }
32054
32055    function pastFuture (diff, output) {
32056        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
32057        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
32058    }
32059
32060    var aliases = {};
32061
32062    function addUnitAlias (unit, shorthand) {
32063        var lowerCase = unit.toLowerCase();
32064        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
32065    }
32066
32067    function normalizeUnits(units) {
32068        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
32069    }
32070
32071    function normalizeObjectUnits(inputObject) {
32072        var normalizedInput = {},
32073            normalizedProp,
32074            prop;
32075
32076        for (prop in inputObject) {
32077            if (hasOwnProp(inputObject, prop)) {
32078                normalizedProp = normalizeUnits(prop);
32079                if (normalizedProp) {
32080                    normalizedInput[normalizedProp] = inputObject[prop];
32081                }
32082            }
32083        }
32084
32085        return normalizedInput;
32086    }
32087
32088    var priorities = {};
32089
32090    function addUnitPriority(unit, priority) {
32091        priorities[unit] = priority;
32092    }
32093
32094    function getPrioritizedUnits(unitsObj) {
32095        var units = [];
32096        for (var u in unitsObj) {
32097            units.push({unit: u, priority: priorities[u]});
32098        }
32099        units.sort(function (a, b) {
32100            return a.priority - b.priority;
32101        });
32102        return units;
32103    }
32104
32105    function zeroFill(number, targetLength, forceSign) {
32106        var absNumber = '' + Math.abs(number),
32107            zerosToFill = targetLength - absNumber.length,
32108            sign = number >= 0;
32109        return (sign ? (forceSign ? '+' : '') : '-') +
32110            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
32111    }
32112
32113    var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
32114
32115    var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
32116
32117    var formatFunctions = {};
32118
32119    var formatTokenFunctions = {};
32120
32121    // token:    'M'
32122    // padded:   ['MM', 2]
32123    // ordinal:  'Mo'
32124    // callback: function () { this.month() + 1 }
32125    function addFormatToken (token, padded, ordinal, callback) {
32126        var func = callback;
32127        if (typeof callback === 'string') {
32128            func = function () {
32129                return this[callback]();
32130            };
32131        }
32132        if (token) {
32133            formatTokenFunctions[token] = func;
32134        }
32135        if (padded) {
32136            formatTokenFunctions[padded[0]] = function () {
32137                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
32138            };
32139        }
32140        if (ordinal) {
32141            formatTokenFunctions[ordinal] = function () {
32142                return this.localeData().ordinal(func.apply(this, arguments), token);
32143            };
32144        }
32145    }
32146
32147    function removeFormattingTokens(input) {
32148        if (input.match(/\[[\s\S]/)) {
32149            return input.replace(/^\[|\]$/g, '');
32150        }
32151        return input.replace(/\\/g, '');
32152    }
32153
32154    function makeFormatFunction(format) {
32155        var array = format.match(formattingTokens), i, length;
32156
32157        for (i = 0, length = array.length; i < length; i++) {
32158            if (formatTokenFunctions[array[i]]) {
32159                array[i] = formatTokenFunctions[array[i]];
32160            } else {
32161                array[i] = removeFormattingTokens(array[i]);
32162            }
32163        }
32164
32165        return function (mom) {
32166            var output = '', i;
32167            for (i = 0; i < length; i++) {
32168                output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
32169            }
32170            return output;
32171        };
32172    }
32173
32174    // format date using native date object
32175    function formatMoment(m, format) {
32176        if (!m.isValid()) {
32177            return m.localeData().invalidDate();
32178        }
32179
32180        format = expandFormat(format, m.localeData());
32181        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);
32182
32183        return formatFunctions[format](m);
32184    }
32185
32186    function expandFormat(format, locale) {
32187        var i = 5;
32188
32189        function replaceLongDateFormatTokens(input) {
32190            return locale.longDateFormat(input) || input;
32191        }
32192
32193        localFormattingTokens.lastIndex = 0;
32194        while (i >= 0 && localFormattingTokens.test(format)) {
32195            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
32196            localFormattingTokens.lastIndex = 0;
32197            i -= 1;
32198        }
32199
32200        return format;
32201    }
32202
32203    var match1         = /\d/;            //       0 - 9
32204    var match2         = /\d\d/;          //      00 - 99
32205    var match3         = /\d{3}/;         //     000 - 999
32206    var match4         = /\d{4}/;         //    0000 - 9999
32207    var match6         = /[+-]?\d{6}/;    // -999999 - 999999
32208    var match1to2      = /\d\d?/;         //       0 - 99
32209    var match3to4      = /\d\d\d\d?/;     //     999 - 9999
32210    var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
32211    var match1to3      = /\d{1,3}/;       //       0 - 999
32212    var match1to4      = /\d{1,4}/;       //       0 - 9999
32213    var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999
32214
32215    var matchUnsigned  = /\d+/;           //       0 - inf
32216    var matchSigned    = /[+-]?\d+/;      //    -inf - inf
32217
32218    var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
32219    var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z
32220
32221    var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
32222
32223    // any word (or two) characters or numbers including two/three word month in arabic.
32224    // includes scottish gaelic two word and hyphenated months
32225    var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;
32226
32227    var regexes = {};
32228
32229    function addRegexToken (token, regex, strictRegex) {
32230        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
32231            return (isStrict && strictRegex) ? strictRegex : regex;
32232        };
32233    }
32234
32235    function getParseRegexForToken (token, config) {
32236        if (!hasOwnProp(regexes, token)) {
32237            return new RegExp(unescapeFormat(token));
32238        }
32239
32240        return regexes[token](config._strict, config._locale);
32241    }
32242
32243    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
32244    function unescapeFormat(s) {
32245        return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
32246            return p1 || p2 || p3 || p4;
32247        }));
32248    }
32249
32250    function regexEscape(s) {
32251        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
32252    }
32253
32254    var tokens = {};
32255
32256    function addParseToken (token, callback) {
32257        var i, func = callback;
32258        if (typeof token === 'string') {
32259            token = [token];
32260        }
32261        if (isNumber(callback)) {
32262            func = function (input, array) {
32263                array[callback] = toInt(input);
32264            };
32265        }
32266        for (i = 0; i < token.length; i++) {
32267            tokens[token[i]] = func;
32268        }
32269    }
32270
32271    function addWeekParseToken (token, callback) {
32272        addParseToken(token, function (input, array, config, token) {
32273            config._w = config._w || {};
32274            callback(input, config._w, config, token);
32275        });
32276    }
32277
32278    function addTimeToArrayFromToken(token, input, config) {
32279        if (input != null && hasOwnProp(tokens, token)) {
32280            tokens[token](input, config._a, config, token);
32281        }
32282    }
32283
32284    var YEAR = 0;
32285    var MONTH = 1;
32286    var DATE = 2;
32287    var HOUR = 3;
32288    var MINUTE = 4;
32289    var SECOND = 5;
32290    var MILLISECOND = 6;
32291    var WEEK = 7;
32292    var WEEKDAY = 8;
32293
32294    // FORMATTING
32295
32296    addFormatToken('Y', 0, 0, function () {
32297        var y = this.year();
32298        return y <= 9999 ? '' + y : '+' + y;
32299    });
32300
32301    addFormatToken(0, ['YY', 2], 0, function () {
32302        return this.year() % 100;
32303    });
32304
32305    addFormatToken(0, ['YYYY',   4],       0, 'year');
32306    addFormatToken(0, ['YYYYY',  5],       0, 'year');
32307    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
32308
32309    // ALIASES
32310
32311    addUnitAlias('year', 'y');
32312
32313    // PRIORITIES
32314
32315    addUnitPriority('year', 1);
32316
32317    // PARSING
32318
32319    addRegexToken('Y',      matchSigned);
32320    addRegexToken('YY',     match1to2, match2);
32321    addRegexToken('YYYY',   match1to4, match4);
32322    addRegexToken('YYYYY',  match1to6, match6);
32323    addRegexToken('YYYYYY', match1to6, match6);
32324
32325    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
32326    addParseToken('YYYY', function (input, array) {
32327        array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
32328    });
32329    addParseToken('YY', function (input, array) {
32330        array[YEAR] = hooks.parseTwoDigitYear(input);
32331    });
32332    addParseToken('Y', function (input, array) {
32333        array[YEAR] = parseInt(input, 10);
32334    });
32335
32336    // HELPERS
32337
32338    function daysInYear(year) {
32339        return isLeapYear(year) ? 366 : 365;
32340    }
32341
32342    function isLeapYear(year) {
32343        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
32344    }
32345
32346    // HOOKS
32347
32348    hooks.parseTwoDigitYear = function (input) {
32349        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
32350    };
32351
32352    // MOMENTS
32353
32354    var getSetYear = makeGetSet('FullYear', true);
32355
32356    function getIsLeapYear () {
32357        return isLeapYear(this.year());
32358    }
32359
32360    function makeGetSet (unit, keepTime) {
32361        return function (value) {
32362            if (value != null) {
32363                set$1(this, unit, value);
32364                hooks.updateOffset(this, keepTime);
32365                return this;
32366            } else {
32367                return get(this, unit);
32368            }
32369        };
32370    }
32371
32372    function get (mom, unit) {
32373        return mom.isValid() ?
32374            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
32375    }
32376
32377    function set$1 (mom, unit, value) {
32378        if (mom.isValid() && !isNaN(value)) {
32379            if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
32380                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
32381            }
32382            else {
32383                mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
32384            }
32385        }
32386    }
32387
32388    // MOMENTS
32389
32390    function stringGet (units) {
32391        units = normalizeUnits(units);
32392        if (isFunction(this[units])) {
32393            return this[units]();
32394        }
32395        return this;
32396    }
32397
32398
32399    function stringSet (units, value) {
32400        if (typeof units === 'object') {
32401            units = normalizeObjectUnits(units);
32402            var prioritized = getPrioritizedUnits(units);
32403            for (var i = 0; i < prioritized.length; i++) {
32404                this[prioritized[i].unit](units[prioritized[i].unit]);
32405            }
32406        } else {
32407            units = normalizeUnits(units);
32408            if (isFunction(this[units])) {
32409                return this[units](value);
32410            }
32411        }
32412        return this;
32413    }
32414
32415    function mod(n, x) {
32416        return ((n % x) + x) % x;
32417    }
32418
32419    var indexOf;
32420
32421    if (Array.prototype.indexOf) {
32422        indexOf = Array.prototype.indexOf;
32423    } else {
32424        indexOf = function (o) {
32425            // I know
32426            var i;
32427            for (i = 0; i < this.length; ++i) {
32428                if (this[i] === o) {
32429                    return i;
32430                }
32431            }
32432            return -1;
32433        };
32434    }
32435
32436    function daysInMonth(year, month) {
32437        if (isNaN(year) || isNaN(month)) {
32438            return NaN;
32439        }
32440        var modMonth = mod(month, 12);
32441        year += (month - modMonth) / 12;
32442        return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);
32443    }
32444
32445    // FORMATTING
32446
32447    addFormatToken('M', ['MM', 2], 'Mo', function () {
32448        return this.month() + 1;
32449    });
32450
32451    addFormatToken('MMM', 0, 0, function (format) {
32452        return this.localeData().monthsShort(this, format);
32453    });
32454
32455    addFormatToken('MMMM', 0, 0, function (format) {
32456        return this.localeData().months(this, format);
32457    });
32458
32459    // ALIASES
32460
32461    addUnitAlias('month', 'M');
32462
32463    // PRIORITY
32464
32465    addUnitPriority('month', 8);
32466
32467    // PARSING
32468
32469    addRegexToken('M',    match1to2);
32470    addRegexToken('MM',   match1to2, match2);
32471    addRegexToken('MMM',  function (isStrict, locale) {
32472        return locale.monthsShortRegex(isStrict);
32473    });
32474    addRegexToken('MMMM', function (isStrict, locale) {
32475        return locale.monthsRegex(isStrict);
32476    });
32477
32478    addParseToken(['M', 'MM'], function (input, array) {
32479        array[MONTH] = toInt(input) - 1;
32480    });
32481
32482    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
32483        var month = config._locale.monthsParse(input, token, config._strict);
32484        // if we didn't find a month name, mark the date as invalid.
32485        if (month != null) {
32486            array[MONTH] = month;
32487        } else {
32488            getParsingFlags(config).invalidMonth = input;
32489        }
32490    });
32491
32492    // LOCALES
32493
32494    var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
32495    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
32496    function localeMonths (m, format) {
32497        if (!m) {
32498            return isArray(this._months) ? this._months :
32499                this._months['standalone'];
32500        }
32501        return isArray(this._months) ? this._months[m.month()] :
32502            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
32503    }
32504
32505    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
32506    function localeMonthsShort (m, format) {
32507        if (!m) {
32508            return isArray(this._monthsShort) ? this._monthsShort :
32509                this._monthsShort['standalone'];
32510        }
32511        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
32512            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
32513    }
32514
32515    function handleStrictParse(monthName, format, strict) {
32516        var i, ii, mom, llc = monthName.toLocaleLowerCase();
32517        if (!this._monthsParse) {
32518            // this is not used
32519            this._monthsParse = [];
32520            this._longMonthsParse = [];
32521            this._shortMonthsParse = [];
32522            for (i = 0; i < 12; ++i) {
32523                mom = createUTC([2000, i]);
32524                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
32525                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
32526            }
32527        }
32528
32529        if (strict) {
32530            if (format === 'MMM') {
32531                ii = indexOf.call(this._shortMonthsParse, llc);
32532                return ii !== -1 ? ii : null;
32533            } else {
32534                ii = indexOf.call(this._longMonthsParse, llc);
32535                return ii !== -1 ? ii : null;
32536            }
32537        } else {
32538            if (format === 'MMM') {
32539                ii = indexOf.call(this._shortMonthsParse, llc);
32540                if (ii !== -1) {
32541                    return ii;
32542                }
32543                ii = indexOf.call(this._longMonthsParse, llc);
32544                return ii !== -1 ? ii : null;
32545            } else {
32546                ii = indexOf.call(this._longMonthsParse, llc);
32547                if (ii !== -1) {
32548                    return ii;
32549                }
32550                ii = indexOf.call(this._shortMonthsParse, llc);
32551                return ii !== -1 ? ii : null;
32552            }
32553        }
32554    }
32555
32556    function localeMonthsParse (monthName, format, strict) {
32557        var i, mom, regex;
32558
32559        if (this._monthsParseExact) {
32560            return handleStrictParse.call(this, monthName, format, strict);
32561        }
32562
32563        if (!this._monthsParse) {
32564            this._monthsParse = [];
32565            this._longMonthsParse = [];
32566            this._shortMonthsParse = [];
32567        }
32568
32569        // TODO: add sorting
32570        // Sorting makes sure if one month (or abbr) is a prefix of another
32571        // see sorting in computeMonthsParse
32572        for (i = 0; i < 12; i++) {
32573            // make the regex if we don't have it already
32574            mom = createUTC([2000, i]);
32575            if (strict && !this._longMonthsParse[i]) {
32576                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
32577                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
32578            }
32579            if (!strict && !this._monthsParse[i]) {
32580                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
32581                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
32582            }
32583            // test the regex
32584            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
32585                return i;
32586            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
32587                return i;
32588            } else if (!strict && this._monthsParse[i].test(monthName)) {
32589                return i;
32590            }
32591        }
32592    }
32593
32594    // MOMENTS
32595
32596    function setMonth (mom, value) {
32597        var dayOfMonth;
32598
32599        if (!mom.isValid()) {
32600            // No op
32601            return mom;
32602        }
32603
32604        if (typeof value === 'string') {
32605            if (/^\d+$/.test(value)) {
32606                value = toInt(value);
32607            } else {
32608                value = mom.localeData().monthsParse(value);
32609                // TODO: Another silent failure?
32610                if (!isNumber(value)) {
32611                    return mom;
32612                }
32613            }
32614        }
32615
32616        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
32617        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
32618        return mom;
32619    }
32620
32621    function getSetMonth (value) {
32622        if (value != null) {
32623            setMonth(this, value);
32624            hooks.updateOffset(this, true);
32625            return this;
32626        } else {
32627            return get(this, 'Month');
32628        }
32629    }
32630
32631    function getDaysInMonth () {
32632        return daysInMonth(this.year(), this.month());
32633    }
32634
32635    var defaultMonthsShortRegex = matchWord;
32636    function monthsShortRegex (isStrict) {
32637        if (this._monthsParseExact) {
32638            if (!hasOwnProp(this, '_monthsRegex')) {
32639                computeMonthsParse.call(this);
32640            }
32641            if (isStrict) {
32642                return this._monthsShortStrictRegex;
32643            } else {
32644                return this._monthsShortRegex;
32645            }
32646        } else {
32647            if (!hasOwnProp(this, '_monthsShortRegex')) {
32648                this._monthsShortRegex = defaultMonthsShortRegex;
32649            }
32650            return this._monthsShortStrictRegex && isStrict ?
32651                this._monthsShortStrictRegex : this._monthsShortRegex;
32652        }
32653    }
32654
32655    var defaultMonthsRegex = matchWord;
32656    function monthsRegex (isStrict) {
32657        if (this._monthsParseExact) {
32658            if (!hasOwnProp(this, '_monthsRegex')) {
32659                computeMonthsParse.call(this);
32660            }
32661            if (isStrict) {
32662                return this._monthsStrictRegex;
32663            } else {
32664                return this._monthsRegex;
32665            }
32666        } else {
32667            if (!hasOwnProp(this, '_monthsRegex')) {
32668                this._monthsRegex = defaultMonthsRegex;
32669            }
32670            return this._monthsStrictRegex && isStrict ?
32671                this._monthsStrictRegex : this._monthsRegex;
32672        }
32673    }
32674
32675    function computeMonthsParse () {
32676        function cmpLenRev(a, b) {
32677            return b.length - a.length;
32678        }
32679
32680        var shortPieces = [], longPieces = [], mixedPieces = [],
32681            i, mom;
32682        for (i = 0; i < 12; i++) {
32683            // make the regex if we don't have it already
32684            mom = createUTC([2000, i]);
32685            shortPieces.push(this.monthsShort(mom, ''));
32686            longPieces.push(this.months(mom, ''));
32687            mixedPieces.push(this.months(mom, ''));
32688            mixedPieces.push(this.monthsShort(mom, ''));
32689        }
32690        // Sorting makes sure if one month (or abbr) is a prefix of another it
32691        // will match the longer piece.
32692        shortPieces.sort(cmpLenRev);
32693        longPieces.sort(cmpLenRev);
32694        mixedPieces.sort(cmpLenRev);
32695        for (i = 0; i < 12; i++) {
32696            shortPieces[i] = regexEscape(shortPieces[i]);
32697            longPieces[i] = regexEscape(longPieces[i]);
32698        }
32699        for (i = 0; i < 24; i++) {
32700            mixedPieces[i] = regexEscape(mixedPieces[i]);
32701        }
32702
32703        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
32704        this._monthsShortRegex = this._monthsRegex;
32705        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
32706        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
32707    }
32708
32709    function createDate (y, m, d, h, M, s, ms) {
32710        // can't just apply() to create a date:
32711        // https://stackoverflow.com/q/181348
32712        var date;
32713        // the date constructor remaps years 0-99 to 1900-1999
32714        if (y < 100 && y >= 0) {
32715            // preserve leap years using a full 400 year cycle, then reset
32716            date = new Date(y + 400, m, d, h, M, s, ms);
32717            if (isFinite(date.getFullYear())) {
32718                date.setFullYear(y);
32719            }
32720        } else {
32721            date = new Date(y, m, d, h, M, s, ms);
32722        }
32723
32724        return date;
32725    }
32726
32727    function createUTCDate (y) {
32728        var date;
32729        // the Date.UTC function remaps years 0-99 to 1900-1999
32730        if (y < 100 && y >= 0) {
32731            var args = Array.prototype.slice.call(arguments);
32732            // preserve leap years using a full 400 year cycle, then reset
32733            args[0] = y + 400;
32734            date = new Date(Date.UTC.apply(null, args));
32735            if (isFinite(date.getUTCFullYear())) {
32736                date.setUTCFullYear(y);
32737            }
32738        } else {
32739            date = new Date(Date.UTC.apply(null, arguments));
32740        }
32741
32742        return date;
32743    }
32744
32745    // start-of-first-week - start-of-year
32746    function firstWeekOffset(year, dow, doy) {
32747        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
32748            fwd = 7 + dow - doy,
32749            // first-week day local weekday -- which local weekday is fwd
32750            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
32751
32752        return -fwdlw + fwd - 1;
32753    }
32754
32755    // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
32756    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
32757        var localWeekday = (7 + weekday - dow) % 7,
32758            weekOffset = firstWeekOffset(year, dow, doy),
32759            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
32760            resYear, resDayOfYear;
32761
32762        if (dayOfYear <= 0) {
32763            resYear = year - 1;
32764            resDayOfYear = daysInYear(resYear) + dayOfYear;
32765        } else if (dayOfYear > daysInYear(year)) {
32766            resYear = year + 1;
32767            resDayOfYear = dayOfYear - daysInYear(year);
32768        } else {
32769            resYear = year;
32770            resDayOfYear = dayOfYear;
32771        }
32772
32773        return {
32774            year: resYear,
32775            dayOfYear: resDayOfYear
32776        };
32777    }
32778
32779    function weekOfYear(mom, dow, doy) {
32780        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
32781            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
32782            resWeek, resYear;
32783
32784        if (week < 1) {
32785            resYear = mom.year() - 1;
32786            resWeek = week + weeksInYear(resYear, dow, doy);
32787        } else if (week > weeksInYear(mom.year(), dow, doy)) {
32788            resWeek = week - weeksInYear(mom.year(), dow, doy);
32789            resYear = mom.year() + 1;
32790        } else {
32791            resYear = mom.year();
32792            resWeek = week;
32793        }
32794
32795        return {
32796            week: resWeek,
32797            year: resYear
32798        };
32799    }
32800
32801    function weeksInYear(year, dow, doy) {
32802        var weekOffset = firstWeekOffset(year, dow, doy),
32803            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
32804        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
32805    }
32806
32807    // FORMATTING
32808
32809    addFormatToken('w', ['ww', 2], 'wo', 'week');
32810    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
32811
32812    // ALIASES
32813
32814    addUnitAlias('week', 'w');
32815    addUnitAlias('isoWeek', 'W');
32816
32817    // PRIORITIES
32818
32819    addUnitPriority('week', 5);
32820    addUnitPriority('isoWeek', 5);
32821
32822    // PARSING
32823
32824    addRegexToken('w',  match1to2);
32825    addRegexToken('ww', match1to2, match2);
32826    addRegexToken('W',  match1to2);
32827    addRegexToken('WW', match1to2, match2);
32828
32829    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
32830        week[token.substr(0, 1)] = toInt(input);
32831    });
32832
32833    // HELPERS
32834
32835    // LOCALES
32836
32837    function localeWeek (mom) {
32838        return weekOfYear(mom, this._week.dow, this._week.doy).week;
32839    }
32840
32841    var defaultLocaleWeek = {
32842        dow : 0, // Sunday is the first day of the week.
32843        doy : 6  // The week that contains Jan 6th is the first week of the year.
32844    };
32845
32846    function localeFirstDayOfWeek () {
32847        return this._week.dow;
32848    }
32849
32850    function localeFirstDayOfYear () {
32851        return this._week.doy;
32852    }
32853
32854    // MOMENTS
32855
32856    function getSetWeek (input) {
32857        var week = this.localeData().week(this);
32858        return input == null ? week : this.add((input - week) * 7, 'd');
32859    }
32860
32861    function getSetISOWeek (input) {
32862        var week = weekOfYear(this, 1, 4).week;
32863        return input == null ? week : this.add((input - week) * 7, 'd');
32864    }
32865
32866    // FORMATTING
32867
32868    addFormatToken('d', 0, 'do', 'day');
32869
32870    addFormatToken('dd', 0, 0, function (format) {
32871        return this.localeData().weekdaysMin(this, format);
32872    });
32873
32874    addFormatToken('ddd', 0, 0, function (format) {
32875        return this.localeData().weekdaysShort(this, format);
32876    });
32877
32878    addFormatToken('dddd', 0, 0, function (format) {
32879        return this.localeData().weekdays(this, format);
32880    });
32881
32882    addFormatToken('e', 0, 0, 'weekday');
32883    addFormatToken('E', 0, 0, 'isoWeekday');
32884
32885    // ALIASES
32886
32887    addUnitAlias('day', 'd');
32888    addUnitAlias('weekday', 'e');
32889    addUnitAlias('isoWeekday', 'E');
32890
32891    // PRIORITY
32892    addUnitPriority('day', 11);
32893    addUnitPriority('weekday', 11);
32894    addUnitPriority('isoWeekday', 11);
32895
32896    // PARSING
32897
32898    addRegexToken('d',    match1to2);
32899    addRegexToken('e',    match1to2);
32900    addRegexToken('E',    match1to2);
32901    addRegexToken('dd',   function (isStrict, locale) {
32902        return locale.weekdaysMinRegex(isStrict);
32903    });
32904    addRegexToken('ddd',   function (isStrict, locale) {
32905        return locale.weekdaysShortRegex(isStrict);
32906    });
32907    addRegexToken('dddd',   function (isStrict, locale) {
32908        return locale.weekdaysRegex(isStrict);
32909    });
32910
32911    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
32912        var weekday = config._locale.weekdaysParse(input, token, config._strict);
32913        // if we didn't get a weekday name, mark the date as invalid
32914        if (weekday != null) {
32915            week.d = weekday;
32916        } else {
32917            getParsingFlags(config).invalidWeekday = input;
32918        }
32919    });
32920
32921    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
32922        week[token] = toInt(input);
32923    });
32924
32925    // HELPERS
32926
32927    function parseWeekday(input, locale) {
32928        if (typeof input !== 'string') {
32929            return input;
32930        }
32931
32932        if (!isNaN(input)) {
32933            return parseInt(input, 10);
32934        }
32935
32936        input = locale.weekdaysParse(input);
32937        if (typeof input === 'number') {
32938            return input;
32939        }
32940
32941        return null;
32942    }
32943
32944    function parseIsoWeekday(input, locale) {
32945        if (typeof input === 'string') {
32946            return locale.weekdaysParse(input) % 7 || 7;
32947        }
32948        return isNaN(input) ? null : input;
32949    }
32950
32951    // LOCALES
32952    function shiftWeekdays (ws, n) {
32953        return ws.slice(n, 7).concat(ws.slice(0, n));
32954    }
32955
32956    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
32957    function localeWeekdays (m, format) {
32958        var weekdays = isArray(this._weekdays) ? this._weekdays :
32959            this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone'];
32960        return (m === true) ? shiftWeekdays(weekdays, this._week.dow)
32961            : (m) ? weekdays[m.day()] : weekdays;
32962    }
32963
32964    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
32965    function localeWeekdaysShort (m) {
32966        return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow)
32967            : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
32968    }
32969
32970    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
32971    function localeWeekdaysMin (m) {
32972        return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow)
32973            : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
32974    }
32975
32976    function handleStrictParse$1(weekdayName, format, strict) {
32977        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
32978        if (!this._weekdaysParse) {
32979            this._weekdaysParse = [];
32980            this._shortWeekdaysParse = [];
32981            this._minWeekdaysParse = [];
32982
32983            for (i = 0; i < 7; ++i) {
32984                mom = createUTC([2000, 1]).day(i);
32985                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
32986                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
32987                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
32988            }
32989        }
32990
32991        if (strict) {
32992            if (format === 'dddd') {
32993                ii = indexOf.call(this._weekdaysParse, llc);
32994                return ii !== -1 ? ii : null;
32995            } else if (format === 'ddd') {
32996                ii = indexOf.call(this._shortWeekdaysParse, llc);
32997                return ii !== -1 ? ii : null;
32998            } else {
32999                ii = indexOf.call(this._minWeekdaysParse, llc);
33000                return ii !== -1 ? ii : null;
33001            }
33002        } else {
33003            if (format === 'dddd') {
33004                ii = indexOf.call(this._weekdaysParse, llc);
33005                if (ii !== -1) {
33006                    return ii;
33007                }
33008                ii = indexOf.call(this._shortWeekdaysParse, llc);
33009                if (ii !== -1) {
33010                    return ii;
33011                }
33012                ii = indexOf.call(this._minWeekdaysParse, llc);
33013                return ii !== -1 ? ii : null;
33014            } else if (format === 'ddd') {
33015                ii = indexOf.call(this._shortWeekdaysParse, llc);
33016                if (ii !== -1) {
33017                    return ii;
33018                }
33019                ii = indexOf.call(this._weekdaysParse, llc);
33020                if (ii !== -1) {
33021                    return ii;
33022                }
33023                ii = indexOf.call(this._minWeekdaysParse, llc);
33024                return ii !== -1 ? ii : null;
33025            } else {
33026                ii = indexOf.call(this._minWeekdaysParse, llc);
33027                if (ii !== -1) {
33028                    return ii;
33029                }
33030                ii = indexOf.call(this._weekdaysParse, llc);
33031                if (ii !== -1) {
33032                    return ii;
33033                }
33034                ii = indexOf.call(this._shortWeekdaysParse, llc);
33035                return ii !== -1 ? ii : null;
33036            }
33037        }
33038    }
33039
33040    function localeWeekdaysParse (weekdayName, format, strict) {
33041        var i, mom, regex;
33042
33043        if (this._weekdaysParseExact) {
33044            return handleStrictParse$1.call(this, weekdayName, format, strict);
33045        }
33046
33047        if (!this._weekdaysParse) {
33048            this._weekdaysParse = [];
33049            this._minWeekdaysParse = [];
33050            this._shortWeekdaysParse = [];
33051            this._fullWeekdaysParse = [];
33052        }
33053
33054        for (i = 0; i < 7; i++) {
33055            // make the regex if we don't have it already
33056
33057            mom = createUTC([2000, 1]).day(i);
33058            if (strict && !this._fullWeekdaysParse[i]) {
33059                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
33060                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
33061                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
33062            }
33063            if (!this._weekdaysParse[i]) {
33064                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
33065                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
33066            }
33067            // test the regex
33068            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
33069                return i;
33070            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
33071                return i;
33072            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
33073                return i;
33074            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
33075                return i;
33076            }
33077        }
33078    }
33079
33080    // MOMENTS
33081
33082    function getSetDayOfWeek (input) {
33083        if (!this.isValid()) {
33084            return input != null ? this : NaN;
33085        }
33086        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
33087        if (input != null) {
33088            input = parseWeekday(input, this.localeData());
33089            return this.add(input - day, 'd');
33090        } else {
33091            return day;
33092        }
33093    }
33094
33095    function getSetLocaleDayOfWeek (input) {
33096        if (!this.isValid()) {
33097            return input != null ? this : NaN;
33098        }
33099        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
33100        return input == null ? weekday : this.add(input - weekday, 'd');
33101    }
33102
33103    function getSetISODayOfWeek (input) {
33104        if (!this.isValid()) {
33105            return input != null ? this : NaN;
33106        }
33107
33108        // behaves the same as moment#day except
33109        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
33110        // as a setter, sunday should belong to the previous week.
33111
33112        if (input != null) {
33113            var weekday = parseIsoWeekday(input, this.localeData());
33114            return this.day(this.day() % 7 ? weekday : weekday - 7);
33115        } else {
33116            return this.day() || 7;
33117        }
33118    }
33119
33120    var defaultWeekdaysRegex = matchWord;
33121    function weekdaysRegex (isStrict) {
33122        if (this._weekdaysParseExact) {
33123            if (!hasOwnProp(this, '_weekdaysRegex')) {
33124                computeWeekdaysParse.call(this);
33125            }
33126            if (isStrict) {
33127                return this._weekdaysStrictRegex;
33128            } else {
33129                return this._weekdaysRegex;
33130            }
33131        } else {
33132            if (!hasOwnProp(this, '_weekdaysRegex')) {
33133                this._weekdaysRegex = defaultWeekdaysRegex;
33134            }
33135            return this._weekdaysStrictRegex && isStrict ?
33136                this._weekdaysStrictRegex : this._weekdaysRegex;
33137        }
33138    }
33139
33140    var defaultWeekdaysShortRegex = matchWord;
33141    function weekdaysShortRegex (isStrict) {
33142        if (this._weekdaysParseExact) {
33143            if (!hasOwnProp(this, '_weekdaysRegex')) {
33144                computeWeekdaysParse.call(this);
33145            }
33146            if (isStrict) {
33147                return this._weekdaysShortStrictRegex;
33148            } else {
33149                return this._weekdaysShortRegex;
33150            }
33151        } else {
33152            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
33153                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
33154            }
33155            return this._weekdaysShortStrictRegex && isStrict ?
33156                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
33157        }
33158    }
33159
33160    var defaultWeekdaysMinRegex = matchWord;
33161    function weekdaysMinRegex (isStrict) {
33162        if (this._weekdaysParseExact) {
33163            if (!hasOwnProp(this, '_weekdaysRegex')) {
33164                computeWeekdaysParse.call(this);
33165            }
33166            if (isStrict) {
33167                return this._weekdaysMinStrictRegex;
33168            } else {
33169                return this._weekdaysMinRegex;
33170            }
33171        } else {
33172            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
33173                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
33174            }
33175            return this._weekdaysMinStrictRegex && isStrict ?
33176                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
33177        }
33178    }
33179
33180
33181    function computeWeekdaysParse () {
33182        function cmpLenRev(a, b) {
33183            return b.length - a.length;
33184        }
33185
33186        var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
33187            i, mom, minp, shortp, longp;
33188        for (i = 0; i < 7; i++) {
33189            // make the regex if we don't have it already
33190            mom = createUTC([2000, 1]).day(i);
33191            minp = this.weekdaysMin(mom, '');
33192            shortp = this.weekdaysShort(mom, '');
33193            longp = this.weekdays(mom, '');
33194            minPieces.push(minp);
33195            shortPieces.push(shortp);
33196            longPieces.push(longp);
33197            mixedPieces.push(minp);
33198            mixedPieces.push(shortp);
33199            mixedPieces.push(longp);
33200        }
33201        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
33202        // will match the longer piece.
33203        minPieces.sort(cmpLenRev);
33204        shortPieces.sort(cmpLenRev);
33205        longPieces.sort(cmpLenRev);
33206        mixedPieces.sort(cmpLenRev);
33207        for (i = 0; i < 7; i++) {
33208            shortPieces[i] = regexEscape(shortPieces[i]);
33209            longPieces[i] = regexEscape(longPieces[i]);
33210            mixedPieces[i] = regexEscape(mixedPieces[i]);
33211        }
33212
33213        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
33214        this._weekdaysShortRegex = this._weekdaysRegex;
33215        this._weekdaysMinRegex = this._weekdaysRegex;
33216
33217        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
33218        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
33219        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
33220    }
33221
33222    // FORMATTING
33223
33224    function hFormat() {
33225        return this.hours() % 12 || 12;
33226    }
33227
33228    function kFormat() {
33229        return this.hours() || 24;
33230    }
33231
33232    addFormatToken('H', ['HH', 2], 0, 'hour');
33233    addFormatToken('h', ['hh', 2], 0, hFormat);
33234    addFormatToken('k', ['kk', 2], 0, kFormat);
33235
33236    addFormatToken('hmm', 0, 0, function () {
33237        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
33238    });
33239
33240    addFormatToken('hmmss', 0, 0, function () {
33241        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
33242            zeroFill(this.seconds(), 2);
33243    });
33244
33245    addFormatToken('Hmm', 0, 0, function () {
33246        return '' + this.hours() + zeroFill(this.minutes(), 2);
33247    });
33248
33249    addFormatToken('Hmmss', 0, 0, function () {
33250        return '' + this.hours() + zeroFill(this.minutes(), 2) +
33251            zeroFill(this.seconds(), 2);
33252    });
33253
33254    function meridiem (token, lowercase) {
33255        addFormatToken(token, 0, 0, function () {
33256            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
33257        });
33258    }
33259
33260    meridiem('a', true);
33261    meridiem('A', false);
33262
33263    // ALIASES
33264
33265    addUnitAlias('hour', 'h');
33266
33267    // PRIORITY
33268    addUnitPriority('hour', 13);
33269
33270    // PARSING
33271
33272    function matchMeridiem (isStrict, locale) {
33273        return locale._meridiemParse;
33274    }
33275
33276    addRegexToken('a',  matchMeridiem);
33277    addRegexToken('A',  matchMeridiem);
33278    addRegexToken('H',  match1to2);
33279    addRegexToken('h',  match1to2);
33280    addRegexToken('k',  match1to2);
33281    addRegexToken('HH', match1to2, match2);
33282    addRegexToken('hh', match1to2, match2);
33283    addRegexToken('kk', match1to2, match2);
33284
33285    addRegexToken('hmm', match3to4);
33286    addRegexToken('hmmss', match5to6);
33287    addRegexToken('Hmm', match3to4);
33288    addRegexToken('Hmmss', match5to6);
33289
33290    addParseToken(['H', 'HH'], HOUR);
33291    addParseToken(['k', 'kk'], function (input, array, config) {
33292        var kInput = toInt(input);
33293        array[HOUR] = kInput === 24 ? 0 : kInput;
33294    });
33295    addParseToken(['a', 'A'], function (input, array, config) {
33296        config._isPm = config._locale.isPM(input);
33297        config._meridiem = input;
33298    });
33299    addParseToken(['h', 'hh'], function (input, array, config) {
33300        array[HOUR] = toInt(input);
33301        getParsingFlags(config).bigHour = true;
33302    });
33303    addParseToken('hmm', function (input, array, config) {
33304        var pos = input.length - 2;
33305        array[HOUR] = toInt(input.substr(0, pos));
33306        array[MINUTE] = toInt(input.substr(pos));
33307        getParsingFlags(config).bigHour = true;
33308    });
33309    addParseToken('hmmss', function (input, array, config) {
33310        var pos1 = input.length - 4;
33311        var pos2 = input.length - 2;
33312        array[HOUR] = toInt(input.substr(0, pos1));
33313        array[MINUTE] = toInt(input.substr(pos1, 2));
33314        array[SECOND] = toInt(input.substr(pos2));
33315        getParsingFlags(config).bigHour = true;
33316    });
33317    addParseToken('Hmm', function (input, array, config) {
33318        var pos = input.length - 2;
33319        array[HOUR] = toInt(input.substr(0, pos));
33320        array[MINUTE] = toInt(input.substr(pos));
33321    });
33322    addParseToken('Hmmss', function (input, array, config) {
33323        var pos1 = input.length - 4;
33324        var pos2 = input.length - 2;
33325        array[HOUR] = toInt(input.substr(0, pos1));
33326        array[MINUTE] = toInt(input.substr(pos1, 2));
33327        array[SECOND] = toInt(input.substr(pos2));
33328    });
33329
33330    // LOCALES
33331
33332    function localeIsPM (input) {
33333        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing str
vendor: 11,105 bytes, lines 33333-33649
33333ings like arrays
33334        // Using charAt should be more compatible.
33335        return ((input + '').toLowerCase().charAt(0) === 'p');
33336    }
33337
33338    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
33339    function localeMeridiem (hours, minutes, isLower) {
33340        if (hours > 11) {
33341            return isLower ? 'pm' : 'PM';
33342        } else {
33343            return isLower ? 'am' : 'AM';
33344        }
33345    }
33346
33347
33348    // MOMENTS
33349
33350    // Setting the hour should keep the time, because the user explicitly
33351    // specified which hour they want. So trying to maintain the same hour (in
33352    // a new timezone) makes sense. Adding/subtracting hours does not follow
33353    // this rule.
33354    var getSetHour = makeGetSet('Hours', true);
33355
33356    var baseConfig = {
33357        calendar: defaultCalendar,
33358        longDateFormat: defaultLongDateFormat,
33359        invalidDate: defaultInvalidDate,
33360        ordinal: defaultOrdinal,
33361        dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
33362        relativeTime: defaultRelativeTime,
33363
33364        months: defaultLocaleMonths,
33365        monthsShort: defaultLocaleMonthsShort,
33366
33367        week: defaultLocaleWeek,
33368
33369        weekdays: defaultLocaleWeekdays,
33370        weekdaysMin: defaultLocaleWeekdaysMin,
33371        weekdaysShort: defaultLocaleWeekdaysShort,
33372
33373        meridiemParse: defaultLocaleMeridiemParse
33374    };
33375
33376    // internal storage for locale config files
33377    var locales = {};
33378    var localeFamilies = {};
33379    var globalLocale;
33380
33381    function normalizeLocale(key) {
33382        return key ? key.toLowerCase().replace('_', '-') : key;
33383    }
33384
33385    // pick the locale from the array
33386    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
33387    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
33388    function chooseLocale(names) {
33389        var i = 0, j, next, locale, split;
33390
33391        while (i < names.length) {
33392            split = normalizeLocale(names[i]).split('-');
33393            j = split.length;
33394            next = normalizeLocale(names[i + 1]);
33395            next = next ? next.split('-') : null;
33396            while (j > 0) {
33397                locale = loadLocale(split.slice(0, j).join('-'));
33398                if (locale) {
33399                    return locale;
33400                }
33401                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
33402                    //the next array item is better than a shallower substring of this one
33403                    break;
33404                }
33405                j--;
33406            }
33407            i++;
33408        }
33409        return globalLocale;
33410    }
33411
33412    function loadLocale(name) {
33413        var oldLocale = null;
33414        // TODO: Find a better way to register and load all the locales in Node
33415        if (!locales[name] && (typeof module !== 'undefined') &&
33416                module && module.exports) {
33417            try {
33418                oldLocale = globalLocale._abbr;
33419                var aliasedRequire = require;
33420                aliasedRequire('./locale/' + name);
33421                getSetGlobalLocale(oldLocale);
33422            } catch (e) {}
33423        }
33424        return locales[name];
33425    }
33426
33427    // This function will load locale and then set the global locale.  If
33428    // no arguments are passed in, it will simply return the current global
33429    // locale key.
33430    function getSetGlobalLocale (key, values) {
33431        var data;
33432        if (key) {
33433            if (isUndefined(values)) {
33434                data = getLocale(key);
33435            }
33436            else {
33437                data = defineLocale(key, values);
33438            }
33439
33440            if (data) {
33441                // moment.duration._locale = moment._locale = data;
33442                globalLocale = data;
33443            }
33444            else {
33445                if ((typeof console !==  'undefined') && console.warn) {
33446                    //warn user if arguments are passed but the locale could not be set
33447                    console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
33448                }
33449            }
33450        }
33451
33452        return globalLocale._abbr;
33453    }
33454
33455    function defineLocale (name, config) {
33456        if (config !== null) {
33457            var locale, parentConfig = baseConfig;
33458            config.abbr = name;
33459            if (locales[name] != null) {
33460                deprecateSimple('defineLocaleOverride',
33461                        'use moment.updateLocale(localeName, config) to change ' +
33462                        'an existing locale. moment.defineLocale(localeName, ' +
33463                        'config) should only be used for creating a new locale ' +
33464                        'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
33465                parentConfig = locales[name]._config;
33466            } else if (config.parentLocale != null) {
33467                if (locales[config.parentLocale] != null) {
33468                    parentConfig = locales[config.parentLocale]._config;
33469                } else {
33470                    locale = loadLocale(config.parentLocale);
33471                    if (locale != null) {
33472                        parentConfig = locale._config;
33473                    } else {
33474                        if (!localeFamilies[config.parentLocale]) {
33475                            localeFamilies[config.parentLocale] = [];
33476                        }
33477                        localeFamilies[config.parentLocale].push({
33478                            name: name,
33479                            config: config
33480                        });
33481                        return null;
33482                    }
33483                }
33484            }
33485            locales[name] = new Locale(mergeConfigs(parentConfig, config));
33486
33487            if (localeFamilies[name]) {
33488                localeFamilies[name].forEach(function (x) {
33489                    defineLocale(x.name, x.config);
33490                });
33491            }
33492
33493            // backwards compat for now: also set the locale
33494            // make sure we set the locale AFTER all child locales have been
33495            // created, so we won't end up with the child locale set.
33496            getSetGlobalLocale(name);
33497
33498
33499            return locales[name];
33500        } else {
33501            // useful for testing
33502            delete locales[name];
33503            return null;
33504        }
33505    }
33506
33507    function updateLocale(name, config) {
33508        if (config != null) {
33509            var locale, tmpLocale, parentConfig = baseConfig;
33510            // MERGE
33511            tmpLocale = loadLocale(name);
33512            if (tmpLocale != null) {
33513                parentConfig = tmpLocale._config;
33514            }
33515            config = mergeConfigs(parentConfig, config);
33516            locale = new Locale(config);
33517            locale.parentLocale = locales[name];
33518            locales[name] = locale;
33519
33520            // backwards compat for now: also set the locale
33521            getSetGlobalLocale(name);
33522        } else {
33523            // pass null for config to unupdate, useful for tests
33524            if (locales[name] != null) {
33525                if (locales[name].parentLocale != null) {
33526                    locales[name] = locales[name].parentLocale;
33527                } else if (locales[name] != null) {
33528                    delete locales[name];
33529                }
33530            }
33531        }
33532        return locales[name];
33533    }
33534
33535    // returns locale data
33536    function getLocale (key) {
33537        var locale;
33538
33539        if (key && key._locale && key._locale._abbr) {
33540            key = key._locale._abbr;
33541        }
33542
33543        if (!key) {
33544            return globalLocale;
33545        }
33546
33547        if (!isArray(key)) {
33548            //short-circuit everything else
33549            locale = loadLocale(key);
33550            if (locale) {
33551                return locale;
33552            }
33553            key = [key];
33554        }
33555
33556        return chooseLocale(key);
33557    }
33558
33559    function listLocales() {
33560        return keys(locales);
33561    }
33562
33563    function checkOverflow (m) {
33564        var overflow;
33565        var a = m._a;
33566
33567        if (a && getParsingFlags(m).overflow === -2) {
33568            overflow =
33569                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
33570                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
33571                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
33572                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
33573                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
33574                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
33575                -1;
33576
33577            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
33578                overflow = DATE;
33579            }
33580            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
33581                overflow = WEEK;
33582            }
33583            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
33584                overflow = WEEKDAY;
33585            }
33586
33587            getParsingFlags(m).overflow = overflow;
33588        }
33589
33590        return m;
33591    }
33592
33593    // Pick the first defined of two or three arguments.
33594    function defaults(a, b, c) {
33595        if (a != null) {
33596            return a;
33597        }
33598        if (b != null) {
33599            return b;
33600        }
33601        return c;
33602    }
33603
33604    function currentDateArray(config) {
33605        // hooks is actually the exported moment object
33606        var nowValue = new Date(hooks.now());
33607        if (config._useUTC) {
33608            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
33609        }
33610        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
33611    }
33612
33613    // convert an array to a date.
33614    // the array should mirror the parameters below
33615    // note: all values past the year are optional and will default to the lowest possible value.
33616    // [year, month, day , hour, minute, second, millisecond]
33617    function configFromArray (config) {
33618        var i, date, input = [], currentDate, expectedWeekday, yearToUse;
33619
33620        if (config._d) {
33621            return;
33622        }
33623
33624        currentDate = currentDateArray(config);
33625
33626        //compute day of the year from weeks and weekdays
33627        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
33628            dayOfYearFromWeekInfo(config);
33629        }
33630
33631        //if the day of the year is set, figure out what it is
33632        if (config._dayOfYear != null) {
33633            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
33634
33635            if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
33636                getParsingFlags(config)._overflowDayOfYear = true;
33637            }
33638
33639            date = createUTCDate(yearToUse, 0, config._dayOfYear);
33640            config._a[MONTH] = date.getUTCMonth();
33641            config._a[DATE] = date.getUTCDate();
33642        }
33643
33644        // Default to current date.
33645        // * if no year, month, day of month are given, default to today
33646        // * if day of month is given, default month and year
33647        // * if month is given, default only year
33648        // * if year is given, don't default anything
33649        for (i = 0; i < 3 && config._a[i] == null; ++i) {
vendor: 83,306 bytes, lines 33650-36170
33650            config._a[i] = input[i] = currentDate[i];
33651        }
33652
33653        // Zero out whatever was not defaulted, including time
33654        for (; i < 7; i++) {
33655            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
33656        }
33657
33658        // Check for 24:00:00.000
33659        if (config._a[HOUR] === 24 &&
33660                config._a[MINUTE] === 0 &&
33661                config._a[SECOND] === 0 &&
33662                config._a[MILLISECOND] === 0) {
33663            config._nextDay = true;
33664            config._a[HOUR] = 0;
33665        }
33666
33667        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
33668        expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();
33669
33670        // Apply timezone offset from input. The actual utcOffset can be changed
33671        // with parseZone.
33672        if (config._tzm != null) {
33673            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
33674        }
33675
33676        if (config._nextDay) {
33677            config._a[HOUR] = 24;
33678        }
33679
33680        // check for mismatching day of week
33681        if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
33682            getParsingFlags(config).weekdayMismatch = true;
33683        }
33684    }
33685
33686    function dayOfYearFromWeekInfo(config) {
33687        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;
33688
33689        w = config._w;
33690        if (w.GG != null || w.W != null || w.E != null) {
33691            dow = 1;
33692            doy = 4;
33693
33694            // TODO: We need to take the current isoWeekYear, but that depends on
33695            // how we interpret now (local, utc, fixed offset). So create
33696            // a now version of current config (take local/utc/offset flags, and
33697            // create now).
33698            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
33699            week = defaults(w.W, 1);
33700            weekday = defaults(w.E, 1);
33701            if (weekday < 1 || weekday > 7) {
33702                weekdayOverflow = true;
33703            }
33704        } else {
33705            dow = config._locale._week.dow;
33706            doy = config._locale._week.doy;
33707
33708            var curWeek = weekOfYear(createLocal(), dow, doy);
33709
33710            weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);
33711
33712            // Default to current week.
33713            week = defaults(w.w, curWeek.week);
33714
33715            if (w.d != null) {
33716                // weekday -- low day numbers are considered next week
33717                weekday = w.d;
33718                if (weekday < 0 || weekday > 6) {
33719                    weekdayOverflow = true;
33720                }
33721            } else if (w.e != null) {
33722                // local weekday -- counting starts from beginning of week
33723                weekday = w.e + dow;
33724                if (w.e < 0 || w.e > 6) {
33725                    weekdayOverflow = true;
33726                }
33727            } else {
33728                // default to beginning of week
33729                weekday = dow;
33730            }
33731        }
33732        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
33733            getParsingFlags(config)._overflowWeeks = true;
33734        } else if (weekdayOverflow != null) {
33735            getParsingFlags(config)._overflowWeekday = true;
33736        } else {
33737            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
33738            config._a[YEAR] = temp.year;
33739            config._dayOfYear = temp.dayOfYear;
33740        }
33741    }
33742
33743    // iso 8601 regex
33744    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
33745    var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
33746    var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
33747
33748    var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;
33749
33750    var isoDates = [
33751        ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
33752        ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
33753        ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
33754        ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
33755        ['YYYY-DDD', /\d{4}-\d{3}/],
33756        ['YYYY-MM', /\d{4}-\d\d/, false],
33757        ['YYYYYYMMDD', /[+-]\d{10}/],
33758        ['YYYYMMDD', /\d{8}/],
33759        // YYYYMM is NOT allowed by the standard
33760        ['GGGG[W]WWE', /\d{4}W\d{3}/],
33761        ['GGGG[W]WW', /\d{4}W\d{2}/, false],
33762        ['YYYYDDD', /\d{7}/]
33763    ];
33764
33765    // iso time formats and regexes
33766    var isoTimes = [
33767        ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
33768        ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
33769        ['HH:mm:ss', /\d\d:\d\d:\d\d/],
33770        ['HH:mm', /\d\d:\d\d/],
33771        ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
33772        ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
33773        ['HHmmss', /\d\d\d\d\d\d/],
33774        ['HHmm', /\d\d\d\d/],
33775        ['HH', /\d\d/]
33776    ];
33777
33778    var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
33779
33780    // date from iso format
33781    function configFromISO(config) {
33782        var i, l,
33783            string = config._i,
33784            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
33785            allowTime, dateFormat, timeFormat, tzFormat;
33786
33787        if (match) {
33788            getParsingFlags(config).iso = true;
33789
33790            for (i = 0, l = isoDates.length; i < l; i++) {
33791                if (isoDates[i][1].exec(match[1])) {
33792                    dateFormat = isoDates[i][0];
33793                    allowTime = isoDates[i][2] !== false;
33794                    break;
33795                }
33796            }
33797            if (dateFormat == null) {
33798                config._isValid = false;
33799                return;
33800            }
33801            if (match[3]) {
33802                for (i = 0, l = isoTimes.length; i < l; i++) {
33803                    if (isoTimes[i][1].exec(match[3])) {
33804                        // match[2] should be 'T' or space
33805                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
33806                        break;
33807                    }
33808                }
33809                if (timeFormat == null) {
33810                    config._isValid = false;
33811                    return;
33812                }
33813            }
33814            if (!allowTime && timeFormat != null) {
33815                config._isValid = false;
33816                return;
33817            }
33818            if (match[4]) {
33819                if (tzRegex.exec(match[4])) {
33820                    tzFormat = 'Z';
33821                } else {
33822                    config._isValid = false;
33823                    return;
33824                }
33825            }
33826            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
33827            configFromStringAndFormat(config);
33828        } else {
33829            config._isValid = false;
33830        }
33831    }
33832
33833    // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
33834    var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;
33835
33836    function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
33837        var result = [
33838            untruncateYear(yearStr),
33839            defaultLocaleMonthsShort.indexOf(monthStr),
33840            parseInt(dayStr, 10),
33841            parseInt(hourStr, 10),
33842            parseInt(minuteStr, 10)
33843        ];
33844
33845        if (secondStr) {
33846            result.push(parseInt(secondStr, 10));
33847        }
33848
33849        return result;
33850    }
33851
33852    function untruncateYear(yearStr) {
33853        var year = parseInt(yearStr, 10);
33854        if (year <= 49) {
33855            return 2000 + year;
33856        } else if (year <= 999) {
33857            return 1900 + year;
33858        }
33859        return year;
33860    }
33861
33862    function preprocessRFC2822(s) {
33863        // Remove comments and folding whitespace and replace multiple-spaces with a single space
33864        return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
33865    }
33866
33867    function checkWeekday(weekdayStr, parsedInput, config) {
33868        if (weekdayStr) {
33869            // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
33870            var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
33871                weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
33872            if (weekdayProvided !== weekdayActual) {
33873                getParsingFlags(config).weekdayMismatch = true;
33874                config._isValid = false;
33875                return false;
33876            }
33877        }
33878        return true;
33879    }
33880
33881    var obsOffsets = {
33882        UT: 0,
33883        GMT: 0,
33884        EDT: -4 * 60,
33885        EST: -5 * 60,
33886        CDT: -5 * 60,
33887        CST: -6 * 60,
33888        MDT: -6 * 60,
33889        MST: -7 * 60,
33890        PDT: -7 * 60,
33891        PST: -8 * 60
33892    };
33893
33894    function calculateOffset(obsOffset, militaryOffset, numOffset) {
33895        if (obsOffset) {
33896            return obsOffsets[obsOffset];
33897        } else if (militaryOffset) {
33898            // the only allowed military tz is Z
33899            return 0;
33900        } else {
33901            var hm = parseInt(numOffset, 10);
33902            var m = hm % 100, h = (hm - m) / 100;
33903            return h * 60 + m;
33904        }
33905    }
33906
33907    // date and time from ref 2822 format
33908    function configFromRFC2822(config) {
33909        var match = rfc2822.exec(preprocessRFC2822(config._i));
33910        if (match) {
33911            var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
33912            if (!checkWeekday(match[1], parsedArray, config)) {
33913                return;
33914            }
33915
33916            config._a = parsedArray;
33917            config._tzm = calculateOffset(match[8], match[9], match[10]);
33918
33919            config._d = createUTCDate.apply(null, config._a);
33920            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
33921
33922            getParsingFlags(config).rfc2822 = true;
33923        } else {
33924            config._isValid = false;
33925        }
33926    }
33927
33928    // date from iso format or fallback
33929    function configFromString(config) {
33930        var matched = aspNetJsonRegex.exec(config._i);
33931
33932        if (matched !== null) {
33933            config._d = new Date(+matched[1]);
33934            return;
33935        }
33936
33937        configFromISO(config);
33938        if (config._isValid === false) {
33939            delete config._isValid;
33940        } else {
33941            return;
33942        }
33943
33944        configFromRFC2822(config);
33945        if (config._isValid === false) {
33946            delete config._isValid;
33947        } else {
33948            return;
33949        }
33950
33951        // Final attempt, use Input Fallback
33952        hooks.createFromInputFallback(config);
33953    }
33954
33955    hooks.createFromInputFallback = deprecate(
33956        'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
33957        'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
33958        'discouraged and will be removed in an upcoming major release. Please refer to ' +
33959        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
33960        function (config) {
33961            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
33962        }
33963    );
33964
33965    // constant that refers to the ISO standard
33966    hooks.ISO_8601 = function () {};
33967
33968    // constant that refers to the RFC 2822 form
33969    hooks.RFC_2822 = function () {};
33970
33971    // date from string and format string
33972    function configFromStringAndFormat(config) {
33973        // TODO: Move this to another part of the creation flow to prevent circular deps
33974        if (config._f === hooks.ISO_8601) {
33975            configFromISO(config);
33976            return;
33977        }
33978        if (config._f === hooks.RFC_2822) {
33979            configFromRFC2822(config);
33980            return;
33981        }
33982        config._a = [];
33983        getParsingFlags(config).empty = true;
33984
33985        // This array is used to make a Date, either with `new Date` or `Date.UTC`
33986        var string = '' + config._i,
33987            i, parsedInput, tokens, token, skipped,
33988            stringLength = string.length,
33989            totalParsedInputLength = 0;
33990
33991        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
33992
33993        for (i = 0; i < tokens.length; i++) {
33994            token = tokens[i];
33995            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
33996            // console.log('token', token, 'parsedInput', parsedInput,
33997            //         'regex', getParseRegexForToken(token, config));
33998            if (parsedInput) {
33999                skipped = string.substr(0, string.indexOf(parsedInput));
34000                if (skipped.length > 0) {
34001                    getParsingFlags(config).unusedInput.push(skipped);
34002                }
34003                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
34004                totalParsedInputLength += parsedInput.length;
34005            }
34006            // don't parse if it's not a known token
34007            if (formatTokenFunctions[token]) {
34008                if (parsedInput) {
34009                    getParsingFlags(config).empty = false;
34010                }
34011                else {
34012                    getParsingFlags(config).unusedTokens.push(token);
34013                }
34014                addTimeToArrayFromToken(token, parsedInput, config);
34015            }
34016            else if (config._strict && !parsedInput) {
34017                getParsingFlags(config).unusedTokens.push(token);
34018            }
34019        }
34020
34021        // add remaining unparsed input length to the string
34022        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
34023        if (string.length > 0) {
34024            getParsingFlags(config).unusedInput.push(string);
34025        }
34026
34027        // clear _12h flag if hour is <= 12
34028        if (config._a[HOUR] <= 12 &&
34029            getParsingFlags(config).bigHour === true &&
34030            config._a[HOUR] > 0) {
34031            getParsingFlags(config).bigHour = undefined;
34032        }
34033
34034        getParsingFlags(config).parsedDateParts = config._a.slice(0);
34035        getParsingFlags(config).meridiem = config._meridiem;
34036        // handle meridiem
34037        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
34038
34039        configFromArray(config);
34040        checkOverflow(config);
34041    }
34042
34043
34044    function meridiemFixWrap (locale, hour, meridiem) {
34045        var isPm;
34046
34047        if (meridiem == null) {
34048            // nothing to do
34049            return hour;
34050        }
34051        if (locale.meridiemHour != null) {
34052            return locale.meridiemHour(hour, meridiem);
34053        } else if (locale.isPM != null) {
34054            // Fallback
34055            isPm = locale.isPM(meridiem);
34056            if (isPm && hour < 12) {
34057                hour += 12;
34058            }
34059            if (!isPm && hour === 12) {
34060                hour = 0;
34061            }
34062            return hour;
34063        } else {
34064            // this is not supposed to happen
34065            return hour;
34066        }
34067    }
34068
34069    // date from string and array of format strings
34070    function configFromStringAndArray(config) {
34071        var tempConfig,
34072            bestMoment,
34073
34074            scoreToBeat,
34075            i,
34076            currentScore;
34077
34078        if (config._f.length === 0) {
34079            getParsingFlags(config).invalidFormat = true;
34080            config._d = new Date(NaN);
34081            return;
34082        }
34083
34084        for (i = 0; i < config._f.length; i++) {
34085            currentScore = 0;
34086            tempConfig = copyConfig({}, config);
34087            if (config._useUTC != null) {
34088                tempConfig._useUTC = config._useUTC;
34089            }
34090            tempConfig._f = config._f[i];
34091            configFromStringAndFormat(tempConfig);
34092
34093            if (!isValid(tempConfig)) {
34094                continue;
34095            }
34096
34097            // if there is any input that was not parsed add a penalty for that format
34098            currentScore += getParsingFlags(tempConfig).charsLeftOver;
34099
34100            //or tokens
34101            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
34102
34103            getParsingFlags(tempConfig).score = currentScore;
34104
34105            if (scoreToBeat == null || currentScore < scoreToBeat) {
34106                scoreToBeat = currentScore;
34107                bestMoment = tempConfig;
34108            }
34109        }
34110
34111        extend(config, bestMoment || tempConfig);
34112    }
34113
34114    function configFromObject(config) {
34115        if (config._d) {
34116            return;
34117        }
34118
34119        var i = normalizeObjectUnits(config._i);
34120        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
34121            return obj && parseInt(obj, 10);
34122        });
34123
34124        configFromArray(config);
34125    }
34126
34127    function createFromConfig (config) {
34128        var res = new Moment(checkOverflow(prepareConfig(config)));
34129        if (res._nextDay) {
34130            // Adding is smart enough around DST
34131            res.add(1, 'd');
34132            res._nextDay = undefined;
34133        }
34134
34135        return res;
34136    }
34137
34138    function prepareConfig (config) {
34139        var input = config._i,
34140            format = config._f;
34141
34142        config._locale = config._locale || getLocale(config._l);
34143
34144        if (input === null || (format === undefined && input === '')) {
34145            return createInvalid({nullInput: true});
34146        }
34147
34148        if (typeof input === 'string') {
34149            config._i = input = config._locale.preparse(input);
34150        }
34151
34152        if (isMoment(input)) {
34153            return new Moment(checkOverflow(input));
34154        } else if (isDate(input)) {
34155            config._d = input;
34156        } else if (isArray(format)) {
34157            configFromStringAndArray(config);
34158        } else if (format) {
34159            configFromStringAndFormat(config);
34160        }  else {
34161            configFromInput(config);
34162        }
34163
34164        if (!isValid(config)) {
34165            config._d = null;
34166        }
34167
34168        return config;
34169    }
34170
34171    function configFromInput(config) {
34172        var input = config._i;
34173        if (isUndefined(input)) {
34174            config._d = new Date(hooks.now());
34175        } else if (isDate(input)) {
34176            config._d = new Date(input.valueOf());
34177        } else if (typeof input === 'string') {
34178            configFromString(config);
34179        } else if (isArray(input)) {
34180            config._a = map(input.slice(0), function (obj) {
34181                return parseInt(obj, 10);
34182            });
34183            configFromArray(config);
34184        } else if (isObject(input)) {
34185            configFromObject(config);
34186        } else if (isNumber(input)) {
34187            // from milliseconds
34188            config._d = new Date(input);
34189        } else {
34190            hooks.createFromInputFallback(config);
34191        }
34192    }
34193
34194    function createLocalOrUTC (input, format, locale, strict, isUTC) {
34195        var c = {};
34196
34197        if (locale === true || locale === false) {
34198            strict = locale;
34199            locale = undefined;
34200        }
34201
34202        if ((isObject(input) && isObjectEmpty(input)) ||
34203                (isArray(input) && input.length === 0)) {
34204            input = undefined;
34205        }
34206        // object construction must be done this way.
34207        // https://github.com/moment/moment/issues/1423
34208        c._isAMomentObject = true;
34209        c._useUTC = c._isUTC = isUTC;
34210        c._l = locale;
34211        c._i = input;
34212        c._f = format;
34213        c._strict = strict;
34214
34215        return createFromConfig(c);
34216    }
34217
34218    function createLocal (input, format, locale, strict) {
34219        return createLocalOrUTC(input, format, locale, strict, false);
34220    }
34221
34222    var prototypeMin = deprecate(
34223        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
34224        function () {
34225            var other = createLocal.apply(null, arguments);
34226            if (this.isValid() && other.isValid()) {
34227                return other < this ? this : other;
34228            } else {
34229                return createInvalid();
34230            }
34231        }
34232    );
34233
34234    var prototypeMax = deprecate(
34235        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
34236        function () {
34237            var other = createLocal.apply(null, arguments);
34238            if (this.isValid() && other.isValid()) {
34239                return other > this ? this : other;
34240            } else {
34241                return createInvalid();
34242            }
34243        }
34244    );
34245
34246    // Pick a moment m from moments so that m[fn](other) is true for all
34247    // other. This relies on the function fn to be transitive.
34248    //
34249    // moments should either be an array of moment objects or an array, whose
34250    // first element is an array of moment objects.
34251    function pickBy(fn, moments) {
34252        var res, i;
34253        if (moments.length === 1 && isArray(moments[0])) {
34254            moments = moments[0];
34255        }
34256        if (!moments.length) {
34257            return createLocal();
34258        }
34259        res = moments[0];
34260        for (i = 1; i < moments.length; ++i) {
34261            if (!moments[i].isValid() || moments[i][fn](res)) {
34262                res = moments[i];
34263            }
34264        }
34265        return res;
34266    }
34267
34268    // TODO: Use [].sort instead?
34269    function min () {
34270        var args = [].slice.call(arguments, 0);
34271
34272        return pickBy('isBefore', args);
34273    }
34274
34275    function max () {
34276        var args = [].slice.call(arguments, 0);
34277
34278        return pickBy('isAfter', args);
34279    }
34280
34281    var now = function () {
34282        return Date.now ? Date.now() : +(new Date());
34283    };
34284
34285    var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];
34286
34287    function isDurationValid(m) {
34288        for (var key in m) {
34289            if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
34290                return false;
34291            }
34292        }
34293
34294        var unitHasDecimal = false;
34295        for (var i = 0; i < ordering.length; ++i) {
34296            if (m[ordering[i]]) {
34297                if (unitHasDecimal) {
34298                    return false; // only allow non-integers for smallest unit
34299                }
34300                if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
34301                    unitHasDecimal = true;
34302                }
34303            }
34304        }
34305
34306        return true;
34307    }
34308
34309    function isValid$1() {
34310        return this._isValid;
34311    }
34312
34313    function createInvalid$1() {
34314        return createDuration(NaN);
34315    }
34316
34317    function Duration (duration) {
34318        var normalizedInput = normalizeObjectUnits(duration),
34319            years = normalizedInput.year || 0,
34320            quarters = normalizedInput.quarter || 0,
34321            months = normalizedInput.month || 0,
34322            weeks = normalizedInput.week || normalizedInput.isoWeek || 0,
34323            days = normalizedInput.day || 0,
34324            hours = normalizedInput.hour || 0,
34325            minutes = normalizedInput.minute || 0,
34326            seconds = normalizedInput.second || 0,
34327            milliseconds = normalizedInput.millisecond || 0;
34328
34329        this._isValid = isDurationValid(normalizedInput);
34330
34331        // representation for dateAddRemove
34332        this._milliseconds = +milliseconds +
34333            seconds * 1e3 + // 1000
34334            minutes * 6e4 + // 1000 * 60
34335            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
34336        // Because of dateAddRemove treats 24 hours as different from a
34337        // day when working around DST, we need to store them separately
34338        this._days = +days +
34339            weeks * 7;
34340        // It is impossible to translate months into days without knowing
34341        // which months you are are talking about, so we have to store
34342        // it separately.
34343        this._months = +months +
34344            quarters * 3 +
34345            years * 12;
34346
34347        this._data = {};
34348
34349        this._locale = getLocale();
34350
34351        this._bubble();
34352    }
34353
34354    function isDuration (obj) {
34355        return obj instanceof Duration;
34356    }
34357
34358    function absRound (number) {
34359        if (number < 0) {
34360            return Math.round(-1 * number) * -1;
34361        } else {
34362            return Math.round(number);
34363        }
34364    }
34365
34366    // FORMATTING
34367
34368    function offset (token, separator) {
34369        addFormatToken(token, 0, 0, function () {
34370            var offset = this.utcOffset();
34371            var sign = '+';
34372            if (offset < 0) {
34373                offset = -offset;
34374                sign = '-';
34375            }
34376            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
34377        });
34378    }
34379
34380    offset('Z', ':');
34381    offset('ZZ', '');
34382
34383    // PARSING
34384
34385    addRegexToken('Z',  matchShortOffset);
34386    addRegexToken('ZZ', matchShortOffset);
34387    addParseToken(['Z', 'ZZ'], function (input, array, config) {
34388        config._useUTC = true;
34389        config._tzm = offsetFromString(matchShortOffset, input);
34390    });
34391
34392    // HELPERS
34393
34394    // timezone chunker
34395    // '+10:00' > ['10',  '00']
34396    // '-1530'  > ['-15', '30']
34397    var chunkOffset = /([\+\-]|\d\d)/gi;
34398
34399    function offsetFromString(matcher, string) {
34400        var matches = (string || '').match(matcher);
34401
34402        if (matches === null) {
34403            return null;
34404        }
34405
34406        var chunk   = matches[matches.length - 1] || [];
34407        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
34408        var minutes = +(parts[1] * 60) + toInt(parts[2]);
34409
34410        return minutes === 0 ?
34411          0 :
34412          parts[0] === '+' ? minutes : -minutes;
34413    }
34414
34415    // Return a moment from input, that is local/utc/zone equivalent to model.
34416    function cloneWithOffset(input, model) {
34417        var res, diff;
34418        if (model._isUTC) {
34419            res = model.clone();
34420            diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
34421            // Use low-level api, because this fn is low-level api.
34422            res._d.setTime(res._d.valueOf() + diff);
34423            hooks.updateOffset(res, false);
34424            return res;
34425        } else {
34426            return createLocal(input).local();
34427        }
34428    }
34429
34430    function getDateOffset (m) {
34431        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
34432        // https://github.com/moment/moment/pull/1871
34433        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
34434    }
34435
34436    // HOOKS
34437
34438    // This function will be called whenever a moment is mutated.
34439    // It is intended to keep the offset in sync with the timezone.
34440    hooks.updateOffset = function () {};
34441
34442    // MOMENTS
34443
34444    // keepLocalTime = true means only change the timezone, without
34445    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
34446    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
34447    // +0200, so we adjust the time as needed, to be valid.
34448    //
34449    // Keeping the time actually adds/subtracts (one hour)
34450    // from the actual represented time. That is why we call updateOffset
34451    // a second time. In case it wants us to change the offset again
34452    // _changeInProgress == true case, then we have to adjust, because
34453    // there is no such time in the given timezone.
34454    function getSetOffset (input, keepLocalTime, keepMinutes) {
34455        var offset = this._offset || 0,
34456            localAdjust;
34457        if (!this.isValid()) {
34458            return input != null ? this : NaN;
34459        }
34460        if (input != null) {
34461            if (typeof input === 'string') {
34462                input = offsetFromString(matchShortOffset, input);
34463                if (input === null) {
34464                    return this;
34465                }
34466            } else if (Math.abs(input) < 16 && !keepMinutes) {
34467                input = input * 60;
34468            }
34469            if (!this._isUTC && keepLocalTime) {
34470                localAdjust = getDateOffset(this);
34471            }
34472            this._offset = input;
34473            this._isUTC = true;
34474            if (localAdjust != null) {
34475                this.add(localAdjust, 'm');
34476            }
34477            if (offset !== input) {
34478                if (!keepLocalTime || this._changeInProgress) {
34479                    addSubtract(this, createDuration(input - offset, 'm'), 1, false);
34480                } else if (!this._changeInProgress) {
34481                    this._changeInProgress = true;
34482                    hooks.updateOffset(this, true);
34483                    this._changeInProgress = null;
34484                }
34485            }
34486            return this;
34487        } else {
34488            return this._isUTC ? offset : getDateOffset(this);
34489        }
34490    }
34491
34492    function getSetZone (input, keepLocalTime) {
34493        if (input != null) {
34494            if (typeof input !== 'string') {
34495                input = -input;
34496            }
34497
34498            this.utcOffset(input, keepLocalTime);
34499
34500            return this;
34501        } else {
34502            return -this.utcOffset();
34503        }
34504    }
34505
34506    function setOffsetToUTC (keepLocalTime) {
34507        return this.utcOffset(0, keepLocalTime);
34508    }
34509
34510    function setOffsetToLocal (keepLocalTime) {
34511        if (this._isUTC) {
34512            this.utcOffset(0, keepLocalTime);
34513            this._isUTC = false;
34514
34515            if (keepLocalTime) {
34516                this.subtract(getDateOffset(this), 'm');
34517            }
34518        }
34519        return this;
34520    }
34521
34522    function setOffsetToParsedOffset () {
34523        if (this._tzm != null) {
34524            this.utcOffset(this._tzm, false, true);
34525        } else if (typeof this._i === 'string') {
34526            var tZone = offsetFromString(matchOffset, this._i);
34527            if (tZone != null) {
34528                this.utcOffset(tZone);
34529            }
34530            else {
34531                this.utcOffset(0, true);
34532            }
34533        }
34534        return this;
34535    }
34536
34537    function hasAlignedHourOffset (input) {
34538        if (!this.isValid()) {
34539            return false;
34540        }
34541        input = input ? createLocal(input).utcOffset() : 0;
34542
34543        return (this.utcOffset() - input) % 60 === 0;
34544    }
34545
34546    function isDaylightSavingTime () {
34547        return (
34548            this.utcOffset() > this.clone().month(0).utcOffset() ||
34549            this.utcOffset() > this.clone().month(5).utcOffset()
34550        );
34551    }
34552
34553    function isDaylightSavingTimeShifted () {
34554        if (!isUndefined(this._isDSTShifted)) {
34555            return this._isDSTShifted;
34556        }
34557
34558        var c = {};
34559
34560        copyConfig(c, this);
34561        c = prepareConfig(c);
34562
34563        if (c._a) {
34564            var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
34565            this._isDSTShifted = this.isValid() &&
34566                compareArrays(c._a, other.toArray()) > 0;
34567        } else {
34568            this._isDSTShifted = false;
34569        }
34570
34571        return this._isDSTShifted;
34572    }
34573
34574    function isLocal () {
34575        return this.isValid() ? !this._isUTC : false;
34576    }
34577
34578    function isUtcOffset () {
34579        return this.isValid() ? this._isUTC : false;
34580    }
34581
34582    function isUtc () {
34583        return this.isValid() ? this._isUTC && this._offset === 0 : false;
34584    }
34585
34586    // ASP.NET json date format regex
34587    var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
34588
34589    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
34590    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
34591    // and further modified to allow for strings containing both week and day
34592    var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;
34593
34594    function createDuration (input, key) {
34595        var duration = input,
34596            // matching against regexp is expensive, do it on demand
34597            match = null,
34598            sign,
34599            ret,
34600            diffRes;
34601
34602        if (isDuration(input)) {
34603            duration = {
34604                ms : input._milliseconds,
34605                d  : input._days,
34606                M  : input._months
34607            };
34608        } else if (isNumber(input)) {
34609            duration = {};
34610            if (key) {
34611                duration[key] = input;
34612            } else {
34613                duration.milliseconds = input;
34614            }
34615        } else if (!!(match = aspNetRegex.exec(input))) {
34616            sign = (match[1] === '-') ? -1 : 1;
34617            duration = {
34618                y  : 0,
34619                d  : toInt(match[DATE])                         * sign,
34620                h  : toInt(match[HOUR])                         * sign,
34621                m  : toInt(match[MINUTE])                       * sign,
34622                s  : toInt(match[SECOND])                       * sign,
34623                ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
34624            };
34625        } else if (!!(match = isoRegex.exec(input))) {
34626            sign = (match[1] === '-') ? -1 : 1;
34627            duration = {
34628                y : parseIso(match[2], sign),
34629                M : parseIso(match[3], sign),
34630                w : parseIso(match[4], sign),
34631                d : parseIso(match[5], sign),
34632                h : parseIso(match[6], sign),
34633                m : parseIso(match[7], sign),
34634                s : parseIso(match[8], sign)
34635            };
34636        } else if (duration == null) {// checks for null or undefined
34637            duration = {};
34638        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
34639            diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
34640
34641            duration = {};
34642            duration.ms = diffRes.milliseconds;
34643            duration.M = diffRes.months;
34644        }
34645
34646        ret = new Duration(duration);
34647
34648        if (isDuration(input) && hasOwnProp(input, '_locale')) {
34649            ret._locale = input._locale;
34650        }
34651
34652        return ret;
34653    }
34654
34655    createDuration.fn = Duration.prototype;
34656    createDuration.invalid = createInvalid$1;
34657
34658    function parseIso (inp, sign) {
34659        // We'd normally use ~~inp for this, but unfortunately it also
34660        // converts floats to ints.
34661        // inp may be undefined, so careful calling replace on it.
34662        var res = inp && parseFloat(inp.replace(',', '.'));
34663        // apply sign while we're at it
34664        return (isNaN(res) ? 0 : res) * sign;
34665    }
34666
34667    function positiveMomentsDifference(base, other) {
34668        var res = {};
34669
34670        res.months = other.month() - base.month() +
34671            (other.year() - base.year()) * 12;
34672        if (base.clone().add(res.months, 'M').isAfter(other)) {
34673            --res.months;
34674        }
34675
34676        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
34677
34678        return res;
34679    }
34680
34681    function momentsDifference(base, other) {
34682        var res;
34683        if (!(base.isValid() && other.isValid())) {
34684            return {milliseconds: 0, months: 0};
34685        }
34686
34687        other = cloneWithOffset(other, base);
34688        if (base.isBefore(other)) {
34689            res = positiveMomentsDifference(base, other);
34690        } else {
34691            res = positiveMomentsDifference(other, base);
34692            res.milliseconds = -res.milliseconds;
34693            res.months = -res.months;
34694        }
34695
34696        return res;
34697    }
34698
34699    // TODO: remove 'name' arg after deprecation is removed
34700    function createAdder(direction, name) {
34701        return function (val, period) {
34702            var dur, tmp;
34703            //invert the arguments, but complain about it
34704            if (period !== null && !isNaN(+period)) {
34705                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
34706                'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
34707                tmp = val; val = period; period = tmp;
34708            }
34709
34710            val = typeof val === 'string' ? +val : val;
34711            dur = createDuration(val, period);
34712            addSubtract(this, dur, direction);
34713            return this;
34714        };
34715    }
34716
34717    function addSubtract (mom, duration, isAdding, updateOffset) {
34718        var milliseconds = duration._milliseconds,
34719            days = absRound(duration._days),
34720            months = absRound(duration._months);
34721
34722        if (!mom.isValid()) {
34723            // No op
34724            return;
34725        }
34726
34727        updateOffset = updateOffset == null ? true : updateOffset;
34728
34729        if (months) {
34730            setMonth(mom, get(mom, 'Month') + months * isAdding);
34731        }
34732        if (days) {
34733            set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
34734        }
34735        if (milliseconds) {
34736            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
34737        }
34738        if (updateOffset) {
34739            hooks.updateOffset(mom, days || months);
34740        }
34741    }
34742
34743    var add      = createAdder(1, 'add');
34744    var subtract = createAdder(-1, 'subtract');
34745
34746    function getCalendarFormat(myMoment, now) {
34747        var diff = myMoment.diff(now, 'days', true);
34748        return diff < -6 ? 'sameElse' :
34749                diff < -1 ? 'lastWeek' :
34750                diff < 0 ? 'lastDay' :
34751                diff < 1 ? 'sameDay' :
34752                diff < 2 ? 'nextDay' :
34753                diff < 7 ? 'nextWeek' : 'sameElse';
34754    }
34755
34756    function calendar$1 (time, formats) {
34757        // We want to compare the start of today, vs this.
34758        // Getting start-of-today depends on whether we're local/utc/offset or not.
34759        var now = time || createLocal(),
34760            sod = cloneWithOffset(now, this).startOf('day'),
34761            format = hooks.calendarFormat(this, sod) || 'sameElse';
34762
34763        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);
34764
34765        return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
34766    }
34767
34768    function clone () {
34769        return new Moment(this);
34770    }
34771
34772    function isAfter (input, units) {
34773        var localInput = isMoment(input) ? input : createLocal(input);
34774        if (!(this.isValid() && localInput.isValid())) {
34775            return false;
34776        }
34777        units = normalizeUnits(units) || 'millisecond';
34778        if (units === 'millisecond') {
34779            return this.valueOf() > localInput.valueOf();
34780        } else {
34781            return localInput.valueOf() < this.clone().startOf(units).valueOf();
34782        }
34783    }
34784
34785    function isBefore (input, units) {
34786        var localInput = isMoment(input) ? input : createLocal(input);
34787        if (!(this.isValid() && localInput.isValid())) {
34788            return false;
34789        }
34790        units = normalizeUnits(units) || 'millisecond';
34791        if (units === 'millisecond') {
34792            return this.valueOf() < localInput.valueOf();
34793        } else {
34794            return this.clone().endOf(units).valueOf() < localInput.valueOf();
34795        }
34796    }
34797
34798    function isBetween (from, to, units, inclusivity) {
34799        var localFrom = isMoment(from) ? from : createLocal(from),
34800            localTo = isMoment(to) ? to : createLocal(to);
34801        if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) {
34802            return false;
34803        }
34804        inclusivity = inclusivity || '()';
34805        return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) &&
34806            (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units));
34807    }
34808
34809    function isSame (input, units) {
34810        var localInput = isMoment(input) ? input : createLocal(input),
34811            inputMs;
34812        if (!(this.isValid() && localInput.isValid())) {
34813            return false;
34814        }
34815        units = normalizeUnits(units) || 'millisecond';
34816        if (units === 'millisecond') {
34817            return this.valueOf() === localInput.valueOf();
34818        } else {
34819            inputMs = localInput.valueOf();
34820            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
34821        }
34822    }
34823
34824    function isSameOrAfter (input, units) {
34825        return this.isSame(input, units) || this.isAfter(input, units);
34826    }
34827
34828    function isSameOrBefore (input, units) {
34829        return this.isSame(input, units) || this.isBefore(input, units);
34830    }
34831
34832    function diff (input, units, asFloat) {
34833        var that,
34834            zoneDelta,
34835            output;
34836
34837        if (!this.isValid()) {
34838            return NaN;
34839        }
34840
34841        that = cloneWithOffset(input, this);
34842
34843        if (!that.isValid()) {
34844            return NaN;
34845        }
34846
34847        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
34848
34849        units = normalizeUnits(units);
34850
34851        switch (units) {
34852            case 'year': output = monthDiff(this, that) / 12; break;
34853            case 'month': output = monthDiff(this, that); break;
34854            case 'quarter': output = monthDiff(this, that) / 3; break;
34855            case 'second': output = (this - that) / 1e3; break; // 1000
34856            case 'minute': output = (this - that) / 6e4; break; // 1000 * 60
34857            case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60
34858            case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst
34859            case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst
34860            default: output = this - that;
34861        }
34862
34863        return asFloat ? output : absFloor(output);
34864    }
34865
34866    function monthDiff (a, b) {
34867        // difference in months
34868        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
34869            // b is in (anchor - 1 month, anchor + 1 month)
34870            anchor = a.clone().add(wholeMonthDiff, 'months'),
34871            anchor2, adjust;
34872
34873        if (b - anchor < 0) {
34874            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
34875            // linear across the month
34876            adjust = (b - anchor) / (anchor - anchor2);
34877        } else {
34878            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
34879            // linear across the month
34880            adjust = (b - anchor) / (anchor2 - anchor);
34881        }
34882
34883        //check for negative zero, return zero if negative zero
34884        return -(wholeMonthDiff + adjust) || 0;
34885    }
34886
34887    hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
34888    hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
34889
34890    function toString () {
34891        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
34892    }
34893
34894    function toISOString(keepOffset) {
34895        if (!this.isValid()) {
34896            return null;
34897        }
34898        var utc = keepOffset !== true;
34899        var m = utc ? this.clone().utc() : this;
34900        if (m.year() < 0 || m.year() > 9999) {
34901            return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
34902        }
34903        if (isFunction(Date.prototype.toISOString)) {
34904            // native implementation is ~50x faster, use it when we can
34905            if (utc) {
34906                return this.toDate().toISOString();
34907            } else {
34908                return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
34909            }
34910        }
34911        return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
34912    }
34913
34914    /**
34915     * Return a human readable representation of a moment that can
34916     * also be evaluated to get a new moment which is the same
34917     *
34918     * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
34919     */
34920    function inspect () {
34921        if (!this.isValid()) {
34922            return 'moment.invalid(/* ' + this._i + ' */)';
34923        }
34924        var func = 'moment';
34925        var zone = '';
34926        if (!this.isLocal()) {
34927            func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
34928            zone = 'Z';
34929        }
34930        var prefix = '[' + func + '("]';
34931        var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
34932        var datetime = '-MM-DD[T]HH:mm:ss.SSS';
34933        var suffix = zone + '[")]';
34934
34935        return this.format(prefix + year + datetime + suffix);
34936    }
34937
34938    function format (inputString) {
34939        if (!inputString) {
34940            inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
34941        }
34942        var output = formatMoment(this, inputString);
34943        return this.localeData().postformat(output);
34944    }
34945
34946    function from (time, withoutSuffix) {
34947        if (this.isValid() &&
34948                ((isMoment(time) && time.isValid()) ||
34949                 createLocal(time).isValid())) {
34950            return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
34951        } else {
34952            return this.localeData().invalidDate();
34953        }
34954    }
34955
34956    function fromNow (withoutSuffix) {
34957        return this.from(createLocal(), withoutSuffix);
34958    }
34959
34960    function to (time, withoutSuffix) {
34961        if (this.isValid() &&
34962                ((isMoment(time) && time.isValid()) ||
34963                 createLocal(time).isValid())) {
34964            return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
34965        } else {
34966            return this.localeData().invalidDate();
34967        }
34968    }
34969
34970    function toNow (withoutSuffix) {
34971        return this.to(createLocal(), withoutSuffix);
34972    }
34973
34974    // If passed a locale key, it will set the locale for this
34975    // instance.  Otherwise, it will return the locale configuration
34976    // variables for this instance.
34977    function locale (key) {
34978        var newLocaleData;
34979
34980        if (key === undefined) {
34981            return this._locale._abbr;
34982        } else {
34983            newLocaleData = getLocale(key);
34984            if (newLocaleData != null) {
34985                this._locale = newLocaleData;
34986            }
34987            return this;
34988        }
34989    }
34990
34991    var lang = deprecate(
34992        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
34993        function (key) {
34994            if (key === undefined) {
34995                return this.localeData();
34996            } else {
34997                return this.locale(key);
34998            }
34999        }
35000    );
35001
35002    function localeData () {
35003        return this._locale;
35004    }
35005
35006    var MS_PER_SECOND = 1000;
35007    var MS_PER_MINUTE = 60 * MS_PER_SECOND;
35008    var MS_PER_HOUR = 60 * MS_PER_MINUTE;
35009    var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR;
35010
35011    // actual modulo - handles negative numbers (for dates before 1970):
35012    function mod$1(dividend, divisor) {
35013        return (dividend % divisor + divisor) % divisor;
35014    }
35015
35016    function localStartOfDate(y, m, d) {
35017        // the date constructor remaps years 0-99 to 1900-1999
35018        if (y < 100 && y >= 0) {
35019            // preserve leap years using a full 400 year cycle, then reset
35020            return new Date(y + 400, m, d) - MS_PER_400_YEARS;
35021        } else {
35022            return new Date(y, m, d).valueOf();
35023        }
35024    }
35025
35026    function utcStartOfDate(y, m, d) {
35027        // Date.UTC remaps years 0-99 to 1900-1999
35028        if (y < 100 && y >= 0) {
35029            // preserve leap years using a full 400 year cycle, then reset
35030            return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS;
35031        } else {
35032            return Date.UTC(y, m, d);
35033        }
35034    }
35035
35036    function startOf (units) {
35037        var time;
35038        units = normalizeUnits(units);
35039        if (units === undefined || units === 'millisecond' || !this.isValid()) {
35040            return this;
35041        }
35042
35043        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
35044
35045        switch (units) {
35046            case 'year':
35047                time = startOfDate(this.year(), 0, 1);
35048                break;
35049            case 'quarter':
35050                time = startOfDate(this.year(), this.month() - this.month() % 3, 1);
35051                break;
35052            case 'month':
35053                time = startOfDate(this.year(), this.month(), 1);
35054                break;
35055            case 'week':
35056                time = startOfDate(this.year(), this.month(), this.date() - this.weekday());
35057                break;
35058            case 'isoWeek':
35059                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1));
35060                break;
35061            case 'day':
35062            case 'date':
35063                time = startOfDate(this.year(), this.month(), this.date());
35064                break;
35065            case 'hour':
35066                time = this._d.valueOf();
35067                time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR);
35068                break;
35069            case 'minute':
35070                time = this._d.valueOf();
35071                time -= mod$1(time, MS_PER_MINUTE);
35072                break;
35073            case 'second':
35074                time = this._d.valueOf();
35075                time -= mod$1(time, MS_PER_SECOND);
35076                break;
35077        }
35078
35079        this._d.setTime(time);
35080        hooks.updateOffset(this, true);
35081        return this;
35082    }
35083
35084    function endOf (units) {
35085        var time;
35086        units = normalizeUnits(units);
35087        if (units === undefined || units === 'millisecond' || !this.isValid()) {
35088            return this;
35089        }
35090
35091        var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate;
35092
35093        switch (units) {
35094            case 'year':
35095                time = startOfDate(this.year() + 1, 0, 1) - 1;
35096                break;
35097            case 'quarter':
35098                time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1;
35099                break;
35100            case 'month':
35101                time = startOfDate(this.year(), this.month() + 1, 1) - 1;
35102                break;
35103            case 'week':
35104                time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1;
35105                break;
35106            case 'isoWeek':
35107                time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1;
35108                break;
35109            case 'day':
35110            case 'date':
35111                time = startOfDate(this.year(), this.month(), this.date() + 1) - 1;
35112                break;
35113            case 'hour':
35114                time = this._d.valueOf();
35115                time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1;
35116                break;
35117            case 'minute':
35118                time = this._d.valueOf();
35119                time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1;
35120                break;
35121            case 'second':
35122                time = this._d.valueOf();
35123                time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1;
35124                break;
35125        }
35126
35127        this._d.setTime(time);
35128        hooks.updateOffset(this, true);
35129        return this;
35130    }
35131
35132    function valueOf () {
35133        return this._d.valueOf() - ((this._offset || 0) * 60000);
35134    }
35135
35136    function unix () {
35137        return Math.floor(this.valueOf() / 1000);
35138    }
35139
35140    function toDate () {
35141        return new Date(this.valueOf());
35142    }
35143
35144    function toArray () {
35145        var m = this;
35146        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
35147    }
35148
35149    function toObject () {
35150        var m = this;
35151        return {
35152            years: m.year(),
35153            months: m.month(),
35154            date: m.date(),
35155            hours: m.hours(),
35156            minutes: m.minutes(),
35157            seconds: m.seconds(),
35158            milliseconds: m.milliseconds()
35159        };
35160    }
35161
35162    function toJSON () {
35163        // new Date(NaN).toJSON() === null
35164        return this.isValid() ? this.toISOString() : null;
35165    }
35166
35167    function isValid$2 () {
35168        return isValid(this);
35169    }
35170
35171    function parsingFlags () {
35172        return extend({}, getParsingFlags(this));
35173    }
35174
35175    function invalidAt () {
35176        return getParsingFlags(this).overflow;
35177    }
35178
35179    function creationData() {
35180        return {
35181            input: this._i,
35182            format: this._f,
35183            locale: this._locale,
35184            isUTC: this._isUTC,
35185            strict: this._strict
35186        };
35187    }
35188
35189    // FORMATTING
35190
35191    addFormatToken(0, ['gg', 2], 0, function () {
35192        return this.weekYear() % 100;
35193    });
35194
35195    addFormatToken(0, ['GG', 2], 0, function () {
35196        return this.isoWeekYear() % 100;
35197    });
35198
35199    function addWeekYearFormatToken (token, getter) {
35200        addFormatToken(0, [token, token.length], 0, getter);
35201    }
35202
35203    addWeekYearFormatToken('gggg',     'weekYear');
35204    addWeekYearFormatToken('ggggg',    'weekYear');
35205    addWeekYearFormatToken('GGGG',  'isoWeekYear');
35206    addWeekYearFormatToken('GGGGG', 'isoWeekYear');
35207
35208    // ALIASES
35209
35210    addUnitAlias('weekYear', 'gg');
35211    addUnitAlias('isoWeekYear', 'GG');
35212
35213    // PRIORITY
35214
35215    addUnitPriority('weekYear', 1);
35216    addUnitPriority('isoWeekYear', 1);
35217
35218
35219    // PARSING
35220
35221    addRegexToken('G',      matchSigned);
35222    addRegexToken('g',      matchSigned);
35223    addRegexToken('GG',     match1to2, match2);
35224    addRegexToken('gg',     match1to2, match2);
35225    addRegexToken('GGGG',   match1to4, match4);
35226    addRegexToken('gggg',   match1to4, match4);
35227    addRegexToken('GGGGG',  match1to6, match6);
35228    addRegexToken('ggggg',  match1to6, match6);
35229
35230    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
35231        week[token.substr(0, 2)] = toInt(input);
35232    });
35233
35234    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
35235        week[token] = hooks.parseTwoDigitYear(input);
35236    });
35237
35238    // MOMENTS
35239
35240    function getSetWeekYear (input) {
35241        return getSetWeekYearHelper.call(this,
35242                input,
35243                this.week(),
35244                this.weekday(),
35245                this.localeData()._week.dow,
35246                this.localeData()._week.doy);
35247    }
35248
35249    function getSetISOWeekYear (input) {
35250        return getSetWeekYearHelper.call(this,
35251                input, this.isoWeek(), this.isoWeekday(), 1, 4);
35252    }
35253
35254    function getISOWeeksInYear () {
35255        return weeksInYear(this.year(), 1, 4);
35256    }
35257
35258    function getWeeksInYear () {
35259        var weekInfo = this.localeData()._week;
35260        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
35261    }
35262
35263    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
35264        var weeksTarget;
35265        if (input == null) {
35266            return weekOfYear(this, dow, doy).year;
35267        } else {
35268            weeksTarget = weeksInYear(input, dow, doy);
35269            if (week > weeksTarget) {
35270                week = weeksTarget;
35271            }
35272            return setWeekAll.call(this, input, week, weekday, dow, doy);
35273        }
35274    }
35275
35276    function setWeekAll(weekYear, week, weekday, dow, doy) {
35277        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
35278            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);
35279
35280        this.year(date.getUTCFullYear());
35281        this.month(date.getUTCMonth());
35282        this.date(date.getUTCDate());
35283        return this;
35284    }
35285
35286    // FORMATTING
35287
35288    addFormatToken('Q', 0, 'Qo', 'quarter');
35289
35290    // ALIASES
35291
35292    addUnitAlias('quarter', 'Q');
35293
35294    // PRIORITY
35295
35296    addUnitPriority('quarter', 7);
35297
35298    // PARSING
35299
35300    addRegexToken('Q', match1);
35301    addParseToken('Q', function (input, array) {
35302        array[MONTH] = (toInt(input) - 1) * 3;
35303    });
35304
35305    // MOMENTS
35306
35307    function getSetQuarter (input) {
35308        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
35309    }
35310
35311    // FORMATTING
35312
35313    addFormatToken('D', ['DD', 2], 'Do', 'date');
35314
35315    // ALIASES
35316
35317    addUnitAlias('date', 'D');
35318
35319    // PRIORITY
35320    addUnitPriority('date', 9);
35321
35322    // PARSING
35323
35324    addRegexToken('D',  match1to2);
35325    addRegexToken('DD', match1to2, match2);
35326    addRegexToken('Do', function (isStrict, locale) {
35327        // TODO: Remove "ordinalParse" fallback in next major release.
35328        return isStrict ?
35329          (locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
35330          locale._dayOfMonthOrdinalParseLenient;
35331    });
35332
35333    addParseToken(['D', 'DD'], DATE);
35334    addParseToken('Do', function (input, array) {
35335        array[DATE] = toInt(input.match(match1to2)[0]);
35336    });
35337
35338    // MOMENTS
35339
35340    var getSetDayOfMonth = makeGetSet('Date', true);
35341
35342    // FORMATTING
35343
35344    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
35345
35346    // ALIASES
35347
35348    addUnitAlias('dayOfYear', 'DDD');
35349
35350    // PRIORITY
35351    addUnitPriority('dayOfYear', 4);
35352
35353    // PARSING
35354
35355    addRegexToken('DDD',  match1to3);
35356    addRegexToken('DDDD', match3);
35357    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
35358        config._dayOfYear = toInt(input);
35359    });
35360
35361    // HELPERS
35362
35363    // MOMENTS
35364
35365    function getSetDayOfYear (input) {
35366        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
35367        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
35368    }
35369
35370    // FORMATTING
35371
35372    addFormatToken('m', ['mm', 2], 0, 'minute');
35373
35374    // ALIASES
35375
35376    addUnitAlias('minute', 'm');
35377
35378    // PRIORITY
35379
35380    addUnitPriority('minute', 14);
35381
35382    // PARSING
35383
35384    addRegexToken('m',  match1to2);
35385    addRegexToken('mm', match1to2, match2);
35386    addParseToken(['m', 'mm'], MINUTE);
35387
35388    // MOMENTS
35389
35390    var getSetMinute = makeGetSet('Minutes', false);
35391
35392    // FORMATTING
35393
35394    addFormatToken('s', ['ss', 2], 0, 'second');
35395
35396    // ALIASES
35397
35398    addUnitAlias('second', 's');
35399
35400    // PRIORITY
35401
35402    addUnitPriority('second', 15);
35403
35404    // PARSING
35405
35406    addRegexToken('s',  match1to2);
35407    addRegexToken('ss', match1to2, match2);
35408    addParseToken(['s', 'ss'], SECOND);
35409
35410    // MOMENTS
35411
35412    var getSetSecond = makeGetSet('Seconds', false);
35413
35414    // FORMATTING
35415
35416    addFormatToken('S', 0, 0, function () {
35417        return ~~(this.millisecond() / 100);
35418    });
35419
35420    addFormatToken(0, ['SS', 2], 0, function () {
35421        return ~~(this.millisecond() / 10);
35422    });
35423
35424    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
35425    addFormatToken(0, ['SSSS', 4], 0, function () {
35426        return this.millisecond() * 10;
35427    });
35428    addFormatToken(0, ['SSSSS', 5], 0, function () {
35429        return this.millisecond() * 100;
35430    });
35431    addFormatToken(0, ['SSSSSS', 6], 0, function () {
35432        return this.millisecond() * 1000;
35433    });
35434    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
35435        return this.millisecond() * 10000;
35436    });
35437    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
35438        return this.millisecond() * 100000;
35439    });
35440    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
35441        return this.millisecond() * 1000000;
35442    });
35443
35444
35445    // ALIASES
35446
35447    addUnitAlias('millisecond', 'ms');
35448
35449    // PRIORITY
35450
35451    addUnitPriority('millisecond', 16);
35452
35453    // PARSING
35454
35455    addRegexToken('S',    match1to3, match1);
35456    addRegexToken('SS',   match1to3, match2);
35457    addRegexToken('SSS',  match1to3, match3);
35458
35459    var token;
35460    for (token = 'SSSS'; token.length <= 9; token += 'S') {
35461        addRegexToken(token, matchUnsigned);
35462    }
35463
35464    function parseMs(input, array) {
35465        array[MILLISECOND] = toInt(('0.' + input) * 1000);
35466    }
35467
35468    for (token = 'S'; token.length <= 9; token += 'S') {
35469        addParseToken(token, parseMs);
35470    }
35471    // MOMENTS
35472
35473    var getSetMillisecond = makeGetSet('Milliseconds', false);
35474
35475    // FORMATTING
35476
35477    addFormatToken('z',  0, 0, 'zoneAbbr');
35478    addFormatToken('zz', 0, 0, 'zoneName');
35479
35480    // MOMENTS
35481
35482    function getZoneAbbr () {
35483        return this._isUTC ? 'UTC' : '';
35484    }
35485
35486    function getZoneName () {
35487        return this._isUTC ? 'Coordinated Universal Time' : '';
35488    }
35489
35490    var proto = Moment.prototype;
35491
35492    proto.add               = add;
35493    proto.calendar          = calendar$1;
35494    proto.clone             = clone;
35495    proto.diff              = diff;
35496    proto.endOf             = endOf;
35497    proto.format            = format;
35498    proto.from              = from;
35499    proto.fromNow           = fromNow;
35500    proto.to                = to;
35501    proto.toNow             = toNow;
35502    proto.get               = stringGet;
35503    proto.invalidAt         = invalidAt;
35504    proto.isAfter           = isAfter;
35505    proto.isBefore          = isBefore;
35506    proto.isBetween         = isBetween;
35507    proto.isSame            = isSame;
35508    proto.isSameOrAfter     = isSameOrAfter;
35509    proto.isSameOrBefore    = isSameOrBefore;
35510    proto.isValid           = isValid$2;
35511    proto.lang              = lang;
35512    proto.locale            = locale;
35513    proto.localeData        = localeData;
35514    proto.max               = prototypeMax;
35515    proto.min               = prototypeMin;
35516    proto.parsingFlags      = parsingFlags;
35517    proto.set               = stringSet;
35518    proto.startOf           = startOf;
35519    proto.subtract          = subtract;
35520    proto.toArray           = toArray;
35521    proto.toObject          = toObject;
35522    proto.toDate            = toDate;
35523    proto.toISOString       = toISOString;
35524    proto.inspect           = inspect;
35525    proto.toJSON            = toJSON;
35526    proto.toString          = toString;
35527    proto.unix              = unix;
35528    proto.valueOf           = valueOf;
35529    proto.creationData      = creationData;
35530    proto.year       = getSetYear;
35531    proto.isLeapYear = getIsLeapYear;
35532    proto.weekYear    = getSetWeekYear;
35533    proto.isoWeekYear = getSetISOWeekYear;
35534    proto.quarter = proto.quarters = getSetQuarter;
35535    proto.month       = getSetMonth;
35536    proto.daysInMonth = getDaysInMonth;
35537    proto.week           = proto.weeks        = getSetWeek;
35538    proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
35539    proto.weeksInYear    = getWeeksInYear;
35540    proto.isoWeeksInYear = getISOWeeksInYear;
35541    proto.date       = getSetDayOfMonth;
35542    proto.day        = proto.days             = getSetDayOfWeek;
35543    proto.weekday    = getSetLocaleDayOfWeek;
35544    proto.isoWeekday = getSetISODayOfWeek;
35545    proto.dayOfYear  = getSetDayOfYear;
35546    proto.hour = proto.hours = getSetHour;
35547    proto.minute = proto.minutes = getSetMinute;
35548    proto.second = proto.seconds = getSetSecond;
35549    proto.millisecond = proto.milliseconds = getSetMillisecond;
35550    proto.utcOffset            = getSetOffset;
35551    proto.utc                  = setOffsetToUTC;
35552    proto.local                = setOffsetToLocal;
35553    proto.parseZone            = setOffsetToParsedOffset;
35554    proto.hasAlignedHourOffset = hasAlignedHourOffset;
35555    proto.isDST                = isDaylightSavingTime;
35556    proto.isLocal              = isLocal;
35557    proto.isUtcOffset          = isUtcOffset;
35558    proto.isUtc                = isUtc;
35559    proto.isUTC                = isUtc;
35560    proto.zoneAbbr = getZoneAbbr;
35561    proto.zoneName = getZoneName;
35562    proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
35563    proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
35564    proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
35565    proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
35566    proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);
35567
35568    function createUnix (input) {
35569        return createLocal(input * 1000);
35570    }
35571
35572    function createInZone () {
35573        return createLocal.apply(null, arguments).parseZone();
35574    }
35575
35576    function preParsePostFormat (string) {
35577        return string;
35578    }
35579
35580    var proto$1 = Locale.prototype;
35581
35582    proto$1.calendar        = calendar;
35583    proto$1.longDateFormat  = longDateFormat;
35584    proto$1.invalidDate     = invalidDate;
35585    proto$1.ordinal         = ordinal;
35586    proto$1.preparse        = preParsePostFormat;
35587    proto$1.postformat      = preParsePostFormat;
35588    proto$1.relativeTime    = relativeTime;
35589    proto$1.pastFuture      = pastFuture;
35590    proto$1.set             = set;
35591
35592    proto$1.months            =        localeMonths;
35593    proto$1.monthsShort       =        localeMonthsShort;
35594    proto$1.monthsParse       =        localeMonthsParse;
35595    proto$1.monthsRegex       = monthsRegex;
35596    proto$1.monthsShortRegex  = monthsShortRegex;
35597    proto$1.week = localeWeek;
35598    proto$1.firstDayOfYear = localeFirstDayOfYear;
35599    proto$1.firstDayOfWeek = localeFirstDayOfWeek;
35600
35601    proto$1.weekdays       =        localeWeekdays;
35602    proto$1.weekdaysMin    =        localeWeekdaysMin;
35603    proto$1.weekdaysShort  =        localeWeekdaysShort;
35604    proto$1.weekdaysParse  =        localeWeekdaysParse;
35605
35606    proto$1.weekdaysRegex       =        weekdaysRegex;
35607    proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
35608    proto$1.weekdaysMinRegex    =        weekdaysMinRegex;
35609
35610    proto$1.isPM = localeIsPM;
35611    proto$1.meridiem = localeMeridiem;
35612
35613    function get$1 (format, index, field, setter) {
35614        var locale = getLocale();
35615        var utc = createUTC().set(setter, index);
35616        return locale[field](utc, format);
35617    }
35618
35619    function listMonthsImpl (format, index, field) {
35620        if (isNumber(format)) {
35621            index = format;
35622            format = undefined;
35623        }
35624
35625        format = format || '';
35626
35627        if (index != null) {
35628            return get$1(format, index, field, 'month');
35629        }
35630
35631        var i;
35632        var out = [];
35633        for (i = 0; i < 12; i++) {
35634            out[i] = get$1(format, i, field, 'month');
35635        }
35636        return out;
35637    }
35638
35639    // ()
35640    // (5)
35641    // (fmt, 5)
35642    // (fmt)
35643    // (true)
35644    // (true, 5)
35645    // (true, fmt, 5)
35646    // (true, fmt)
35647    function listWeekdaysImpl (localeSorted, format, index, field) {
35648        if (typeof localeSorted === 'boolean') {
35649            if (isNumber(format)) {
35650                index = format;
35651                format = undefined;
35652            }
35653
35654            format = format || '';
35655        } else {
35656            format = localeSorted;
35657            index = format;
35658            localeSorted = false;
35659
35660            if (isNumber(format)) {
35661                index = format;
35662                format = undefined;
35663            }
35664
35665            format = format || '';
35666        }
35667
35668        var locale = getLocale(),
35669            shift = localeSorted ? locale._week.dow : 0;
35670
35671        if (index != null) {
35672            return get$1(format, (index + shift) % 7, field, 'day');
35673        }
35674
35675        var i;
35676        var out = [];
35677        for (i = 0; i < 7; i++) {
35678            out[i] = get$1(format, (i + shift) % 7, field, 'day');
35679        }
35680        return out;
35681    }
35682
35683    function listMonths (format, index) {
35684        return listMonthsImpl(format, index, 'months');
35685    }
35686
35687    function listMonthsShort (format, index) {
35688        return listMonthsImpl(format, index, 'monthsShort');
35689    }
35690
35691    function listWeekdays (localeSorted, format, index) {
35692        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
35693    }
35694
35695    function listWeekdaysShort (localeSorted, format, index) {
35696        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
35697    }
35698
35699    function listWeekdaysMin (localeSorted, format, index) {
35700        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
35701    }
35702
35703    getSetGlobalLocale('en', {
35704        dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
35705        ordinal : function (number) {
35706            var b = number % 10,
35707                output = (toInt(number % 100 / 10) === 1) ? 'th' :
35708                (b === 1) ? 'st' :
35709                (b === 2) ? 'nd' :
35710                (b === 3) ? 'rd' : 'th';
35711            return number + output;
35712        }
35713    });
35714
35715    // Side effect imports
35716
35717    hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
35718    hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);
35719
35720    var mathAbs = Math.abs;
35721
35722    function abs () {
35723        var data           = this._data;
35724
35725        this._milliseconds = mathAbs(this._milliseconds);
35726        this._days         = mathAbs(this._days);
35727        this._months       = mathAbs(this._months);
35728
35729        data.milliseconds  = mathAbs(data.milliseconds);
35730        data.seconds       = mathAbs(data.seconds);
35731        data.minutes       = mathAbs(data.minutes);
35732        data.hours         = mathAbs(data.hours);
35733        data.months        = mathAbs(data.months);
35734        data.years         = mathAbs(data.years);
35735
35736        return this;
35737    }
35738
35739    function addSubtract$1 (duration, input, value, direction) {
35740        var other = createDuration(input, value);
35741
35742        duration._milliseconds += direction * other._milliseconds;
35743        duration._days         += direction * other._days;
35744        duration._months       += direction * other._months;
35745
35746        return duration._bubble();
35747    }
35748
35749    // supports only 2.0-style add(1, 's') or add(duration)
35750    function add$1 (input, value) {
35751        return addSubtract$1(this, input, value, 1);
35752    }
35753
35754    // supports only 2.0-style subtract(1, 's') or subtract(duration)
35755    function subtract$1 (input, value) {
35756        return addSubtract$1(this, input, value, -1);
35757    }
35758
35759    function absCeil (number) {
35760        if (number < 0) {
35761            return Math.floor(number);
35762        } else {
35763            return Math.ceil(number);
35764        }
35765    }
35766
35767    function bubble () {
35768        var milliseconds = this._milliseconds;
35769        var days         = this._days;
35770        var months       = this._months;
35771        var data         = this._data;
35772        var seconds, minutes, hours, years, monthsFromDays;
35773
35774        // if we have a mix of positive and negative values, bubble down first
35775        // check: https://github.com/moment/moment/issues/2166
35776        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
35777                (milliseconds <= 0 && days <= 0 && months <= 0))) {
35778            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
35779            days = 0;
35780            months = 0;
35781        }
35782
35783        // The following code bubbles up values, see the tests for
35784        // examples of what that means.
35785        data.milliseconds = milliseconds % 1000;
35786
35787        seconds           = absFloor(milliseconds / 1000);
35788        data.seconds      = seconds % 60;
35789
35790        minutes           = absFloor(seconds / 60);
35791        data.minutes      = minutes % 60;
35792
35793        hours             = absFloor(minutes / 60);
35794        data.hours        = hours % 24;
35795
35796        days += absFloor(hours / 24);
35797
35798        // convert days to months
35799        monthsFromDays = absFloor(daysToMonths(days));
35800        months += monthsFromDays;
35801        days -= absCeil(monthsToDays(monthsFromDays));
35802
35803        // 12 months -> 1 year
35804        years = absFloor(months / 12);
35805        months %= 12;
35806
35807        data.days   = days;
35808        data.months = months;
35809        data.years  = years;
35810
35811        return this;
35812    }
35813
35814    function daysToMonths (days) {
35815        // 400 years have 146097 days (taking into account leap year rules)
35816        // 400 years have 12 months === 4800
35817        return days * 4800 / 146097;
35818    }
35819
35820    function monthsToDays (months) {
35821        // the reverse of daysToMonths
35822        return months * 146097 / 4800;
35823    }
35824
35825    function as (units) {
35826        if (!this.isValid()) {
35827            return NaN;
35828        }
35829        var days;
35830        var months;
35831        var milliseconds = this._milliseconds;
35832
35833        units = normalizeUnits(units);
35834
35835        if (units === 'month' || units === 'quarter' || units === 'year') {
35836            days = this._days + milliseconds / 864e5;
35837            months = this._months + daysToMonths(days);
35838            switch (units) {
35839                case 'month':   return months;
35840                case 'quarter': return months / 3;
35841                case 'year':    return months / 12;
35842            }
35843        } else {
35844            // handle milliseconds separately because of floating point math errors (issue #1867)
35845            days = this._days + Math.round(monthsToDays(this._months));
35846            switch (units) {
35847                case 'week'   : return days / 7     + milliseconds / 6048e5;
35848                case 'day'    : return days         + milliseconds / 864e5;
35849                case 'hour'   : return days * 24    + milliseconds / 36e5;
35850                case 'minute' : return days * 1440  + milliseconds / 6e4;
35851                case 'second' : return days * 86400 + milliseconds / 1000;
35852                // Math.floor prevents floating point math errors here
35853                case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
35854                default: throw new Error('Unknown unit ' + units);
35855            }
35856        }
35857    }
35858
35859    // TODO: Use this.as('ms')?
35860    function valueOf$1 () {
35861        if (!this.isValid()) {
35862            return NaN;
35863        }
35864        return (
35865            this._milliseconds +
35866            this._days * 864e5 +
35867            (this._months % 12) * 2592e6 +
35868            toInt(this._months / 12) * 31536e6
35869        );
35870    }
35871
35872    function makeAs (alias) {
35873        return function () {
35874            return this.as(alias);
35875        };
35876    }
35877
35878    var asMilliseconds = makeAs('ms');
35879    var asSeconds      = makeAs('s');
35880    var asMinutes      = makeAs('m');
35881    var asHours        = makeAs('h');
35882    var asDays         = makeAs('d');
35883    var asWeeks        = makeAs('w');
35884    var asMonths       = makeAs('M');
35885    var asQuarters     = makeAs('Q');
35886    var asYears        = makeAs('y');
35887
35888    function clone$1 () {
35889        return createDuration(this);
35890    }
35891
35892    function get$2 (units) {
35893        units = normalizeUnits(units);
35894        return this.isValid() ? this[units + 's']() : NaN;
35895    }
35896
35897    function makeGetter(name) {
35898        return function () {
35899            return this.isValid() ? this._data[name] : NaN;
35900        };
35901    }
35902
35903    var milliseconds = makeGetter('milliseconds');
35904    var seconds      = makeGetter('seconds');
35905    var minutes      = makeGetter('minutes');
35906    var hours        = makeGetter('hours');
35907    var days         = makeGetter('days');
35908    var months       = makeGetter('months');
35909    var years        = makeGetter('years');
35910
35911    function weeks () {
35912        return absFloor(this.days() / 7);
35913    }
35914
35915    var round = Math.round;
35916    var thresholds = {
35917        ss: 44,         // a few seconds to seconds
35918        s : 45,         // seconds to minute
35919        m : 45,         // minutes to hour
35920        h : 22,         // hours to day
35921        d : 26,         // days to month
35922        M : 11          // months to year
35923    };
35924
35925    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
35926    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
35927        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
35928    }
35929
35930    function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
35931        var duration = createDuration(posNegDuration).abs();
35932        var seconds  = round(duration.as('s'));
35933        var minutes  = round(duration.as('m'));
35934        var hours    = round(duration.as('h'));
35935        var days     = round(duration.as('d'));
35936        var months   = round(duration.as('M'));
35937        var years    = round(duration.as('y'));
35938
35939        var a = seconds <= thresholds.ss && ['s', seconds]  ||
35940                seconds < thresholds.s   && ['ss', seconds] ||
35941                minutes <= 1             && ['m']           ||
35942                minutes < thresholds.m   && ['mm', minutes] ||
35943                hours   <= 1             && ['h']           ||
35944                hours   < thresholds.h   && ['hh', hours]   ||
35945                days    <= 1             && ['d']           ||
35946                days    < thresholds.d   && ['dd', days]    ||
35947                months  <= 1             && ['M']           ||
35948                months  < thresholds.M   && ['MM', months]  ||
35949                years   <= 1             && ['y']           || ['yy', years];
35950
35951        a[2] = withoutSuffix;
35952        a[3] = +posNegDuration > 0;
35953        a[4] = locale;
35954        return substituteTimeAgo.apply(null, a);
35955    }
35956
35957    // This function allows you to set the rounding function for relative time strings
35958    function getSetRelativeTimeRounding (roundingFunction) {
35959        if (roundingFunction === undefined) {
35960            return round;
35961        }
35962        if (typeof(roundingFunction) === 'function') {
35963            round = roundingFunction;
35964            return true;
35965        }
35966        return false;
35967    }
35968
35969    // This function allows you to set a threshold for relative time strings
35970    function getSetRelativeTimeThreshold (threshold, limit) {
35971        if (thresholds[threshold] === undefined) {
35972            return false;
35973        }
35974        if (limit === undefined) {
35975            return thresholds[threshold];
35976        }
35977        thresholds[threshold] = limit;
35978        if (threshold === 's') {
35979            thresholds.ss = limit - 1;
35980        }
35981        return true;
35982    }
35983
35984    function humanize (withSuffix) {
35985        if (!this.isValid()) {
35986            return this.localeData().invalidDate();
35987        }
35988
35989        var locale = this.localeData();
35990        var output = relativeTime$1(this, !withSuffix, locale);
35991
35992        if (withSuffix) {
35993            output = locale.pastFuture(+this, output);
35994        }
35995
35996        return locale.postformat(output);
35997    }
35998
35999    var abs$1 = Math.abs;
36000
36001    function sign(x) {
36002        return ((x > 0) - (x < 0)) || +x;
36003    }
36004
36005    function toISOString$1() {
36006        // for ISO strings we do not use the normal bubbling rules:
36007        //  * milliseconds bubble up until they become hours
36008        //  * days do not bubble at all
36009        //  * months bubble up until they become years
36010        // This is because there is no context-free conversion between hours and days
36011        // (think of clock changes)
36012        // and also not between days and months (28-31 days per month)
36013        if (!this.isValid()) {
36014            return this.localeData().invalidDate();
36015        }
36016
36017        var seconds = abs$1(this._milliseconds) / 1000;
36018        var days         = abs$1(this._days);
36019        var months       = abs$1(this._months);
36020        var minutes, hours, years;
36021
36022        // 3600 seconds -> 60 minutes -> 1 hour
36023        minutes           = absFloor(seconds / 60);
36024        hours             = absFloor(minutes / 60);
36025        seconds %= 60;
36026        minutes %= 60;
36027
36028        // 12 months -> 1 year
36029        years  = absFloor(months / 12);
36030        months %= 12;
36031
36032
36033        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
36034        var Y = years;
36035        var M = months;
36036        var D = days;
36037        var h = hours;
36038        var m = minutes;
36039        var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
36040        var total = this.asSeconds();
36041
36042        if (!total) {
36043            // this is the same as C#'s (Noda) and python (isodate)...
36044            // but not other JS (goog.date)
36045            return 'P0D';
36046        }
36047
36048        var totalSign = total < 0 ? '-' : '';
36049        var ymSign = sign(this._months) !== sign(total) ? '-' : '';
36050        var daysSign = sign(this._days) !== sign(total) ? '-' : '';
36051        var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';
36052
36053        return totalSign + 'P' +
36054            (Y ? ymSign + Y + 'Y' : '') +
36055            (M ? ymSign + M + 'M' : '') +
36056            (D ? daysSign + D + 'D' : '') +
36057            ((h || m || s) ? 'T' : '') +
36058            (h ? hmsSign + h + 'H' : '') +
36059            (m ? hmsSign + m + 'M' : '') +
36060            (s ? hmsSign + s + 'S' : '');
36061    }
36062
36063    var proto$2 = Duration.prototype;
36064
36065    proto$2.isValid        = isValid$1;
36066    proto$2.abs            = abs;
36067    proto$2.add            = add$1;
36068    proto$2.subtract       = subtract$1;
36069    proto$2.as             = as;
36070    proto$2.asMilliseconds = asMilliseconds;
36071    proto$2.asSeconds      = asSeconds;
36072    proto$2.asMinutes      = asMinutes;
36073    proto$2.asHours        = asHours;
36074    proto$2.asDays         = asDays;
36075    proto$2.asWeeks        = asWeeks;
36076    proto$2.asMonths       = asMonths;
36077    proto$2.asQuarters     = asQuarters;
36078    proto$2.asYears        = asYears;
36079    proto$2.valueOf        = valueOf$1;
36080    proto$2._bubble        = bubble;
36081    proto$2.clone          = clone$1;
36082    proto$2.get            = get$2;
36083    proto$2.milliseconds   = milliseconds;
36084    proto$2.seconds        = seconds;
36085    proto$2.minutes        = minutes;
36086    proto$2.hours          = hours;
36087    proto$2.days           = days;
36088    proto$2.weeks          = weeks;
36089    proto$2.months         = months;
36090    proto$2.years          = years;
36091    proto$2.humanize       = humanize;
36092    proto$2.toISOString    = toISOString$1;
36093    proto$2.toString       = toISOString$1;
36094    proto$2.toJSON         = toISOString$1;
36095    proto$2.locale         = locale;
36096    proto$2.localeData     = localeData;
36097
36098    proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
36099    proto$2.lang = lang;
36100
36101    // Side effect imports
36102
36103    // FORMATTING
36104
36105    addFormatToken('X', 0, 0, 'unix');
36106    addFormatToken('x', 0, 0, 'valueOf');
36107
36108    // PARSING
36109
36110    addRegexToken('x', matchSigned);
36111    addRegexToken('X', matchTimestamp);
36112    addParseToken('X', function (input, array, config) {
36113        config._d = new Date(parseFloat(input, 10) * 1000);
36114    });
36115    addParseToken('x', function (input, array, config) {
36116        config._d = new Date(toInt(input));
36117    });
36118
36119    // Side effect imports
36120
36121
36122    hooks.version = '2.24.0';
36123
36124    setHookCallback(createLocal);
36125
36126    hooks.fn                    = proto;
36127    hooks.min                   = min;
36128    hooks.max                   = max;
36129    hooks.now                   = now;
36130    hooks.utc                   = createUTC;
36131    hooks.unix                  = createUnix;
36132    hooks.months                = listMonths;
36133    hooks.isDate                = isDate;
36134    hooks.locale                = getSetGlobalLocale;
36135    hooks.invalid               = createInvalid;
36136    hooks.duration              = createDuration;
36137    hooks.isMoment              = isMoment;
36138    hooks.weekdays              = listWeekdays;
36139    hooks.parseZone             = createInZone;
36140    hooks.localeData            = getLocale;
36141    hooks.isDuration            = isDuration;
36142    hooks.monthsShort           = listMonthsShort;
36143    hooks.weekdaysMin           = listWeekdaysMin;
36144    hooks.defineLocale          = defineLocale;
36145    hooks.updateLocale          = updateLocale;
36146    hooks.locales               = listLocales;
36147    hooks.weekdaysShort         = listWeekdaysShort;
36148    hooks.normalizeUnits        = normalizeUnits;
36149    hooks.relativeTimeRounding  = getSetRelativeTimeRounding;
36150    hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
36151    hooks.calendarFormat        = getCalendarFormat;
36152    hooks.prototype             = proto;
36153
36154    // currently HTML5 input type only supports 24-hour formats
36155    hooks.HTML5_FMT = {
36156        DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type="datetime-local" />
36157        DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type="datetime-local" step="1" />
36158        DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type="datetime-local" step="0.001" />
36159        DATE: 'YYYY-MM-DD',                             // <input type="date" />
36160        TIME: 'HH:mm',                                  // <input type="time" />
36161        TIME_SECONDS: 'HH:mm:ss',                       // <input type="time" step="1" />
36162        TIME_MS: 'HH:mm:ss.SSS',                        // <input type="time" step="0.001" />
36163        WEEK: 'GGGG-[W]WW',                             // <input type="week" />
36164        MONTH: 'YYYY-MM'                                // <input type="month" />
36165    };
36166
36167    return hooks;
36168
36169})));
36170
vendor: 2,042 bytes, lines 36171-36216
36171},{}],15:[function(require,module,exports){
36172(function (global){
36173/**!
36174 * @fileOverview Kickass library to create and place poppers near their reference elements.
36175 * @version 1.16.0
36176 * @license
36177 * Copyright (c) 2016 Federico Zivolo and contributors
36178 *
36179 * Permission is hereby granted, free of charge, to any person obtaining a copy
36180 * of this software and associated documentation files (the "Software"), to deal
36181 * in the Software without restriction, including without limitation the rights
36182 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36183 * copies of the Software, and to permit persons to whom the Software is
36184 * furnished to do so, subject to the following conditions:
36185 *
36186 * The above copyright notice and this permission notice shall be included in all
36187 * copies or substantial portions of the Software.
36188 *
36189 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36190 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36191 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36192 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36193 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36194 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36195 * SOFTWARE.
36196 */
36197(function (global, factory) {
36198	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
36199	typeof define === 'function' && define.amd ? define(factory) :
36200	(global.Popper = factory());
36201}(this, (function () { 'use strict';
36202
36203var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';
36204
36205var timeoutDuration = function () {
36206  var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
36207  for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {
36208    if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
36209      return 1;
36210    }
36211  }
36212  return 0;
36213}();
36214
36215function microtaskDebounce(fn) {
36216  var called = false;
vendor: 3,141 bytes, lines 36217-36342
36217  return function () {
36218    if (called) {
36219      return;
36220    }
36221    called = true;
36222    window.Promise.resolve().then(function () {
36223      called = false;
36224      fn();
36225    });
36226  };
36227}
36228
36229function taskDebounce(fn) {
36230  var scheduled = false;
36231  return function () {
36232    if (!scheduled) {
36233      scheduled = true;
36234      setTimeout(function () {
36235        scheduled = false;
36236        fn();
36237      }, timeoutDuration);
36238    }
36239  };
36240}
36241
36242var supportsMicroTasks = isBrowser && window.Promise;
36243
36244/**
36245* Create a debounced version of a method, that's asynchronously deferred
36246* but called in the minimum time possible.
36247*
36248* @method
36249* @memberof Popper.Utils
36250* @argument {Function} fn
36251* @returns {Function}
36252*/
36253var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;
36254
36255/**
36256 * Check if the given variable is a function
36257 * @method
36258 * @memberof Popper.Utils
36259 * @argument {Any} functionToCheck - variable to check
36260 * @returns {Boolean} answer to: is a function?
36261 */
36262function isFunction(functionToCheck) {
36263  var getType = {};
36264  return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
36265}
36266
36267/**
36268 * Get CSS computed property of the given element
36269 * @method
36270 * @memberof Popper.Utils
36271 * @argument {Eement} element
36272 * @argument {String} property
36273 */
36274function getStyleComputedProperty(element, property) {
36275  if (element.nodeType !== 1) {
36276    return [];
36277  }
36278  // NOTE: 1 DOM access here
36279  var window = element.ownerDocument.defaultView;
36280  var css = window.getComputedStyle(element, null);
36281  return property ? css[property] : css;
36282}
36283
36284/**
36285 * Returns the parentNode or the host of the element
36286 * @method
36287 * @memberof Popper.Utils
36288 * @argument {Element} element
36289 * @returns {Element} parent
36290 */
36291function getParentNode(element) {
36292  if (element.nodeName === 'HTML') {
36293    return element;
36294  }
36295  return element.parentNode || element.host;
36296}
36297
36298/**
36299 * Returns the scrolling parent of the given element
36300 * @method
36301 * @memberof Popper.Utils
36302 * @argument {Element} element
36303 * @returns {Element} scroll parent
36304 */
36305function getScrollParent(element) {
36306  // Return body, `getScroll` will take care to get the correct `scrollTop` from it
36307  if (!element) {
36308    return document.body;
36309  }
36310
36311  switch (element.nodeName) {
36312    case 'HTML':
36313    case 'BODY':
36314      return element.ownerDocument.body;
36315    case '#document':
36316      return element.body;
36317  }
36318
36319  // Firefox want us to check `-x` and `-y` variations as well
36320
36321  var _getStyleComputedProp = getStyleComputedProperty(element),
36322      overflow = _getStyleComputedProp.overflow,
36323      overflowX = _getStyleComputedProp.overflowX,
36324      overflowY = _getStyleComputedProp.overflowY;
36325
36326  if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
36327    return element;
36328  }
36329
36330  return getScrollParent(getParentNode(element));
36331}
36332
36333/**
36334 * Returns the reference node of the reference object, or the reference object itself.
36335 * @method
36336 * @memberof Popper.Utils
36337 * @param {Element|Object} reference - the reference element (the popper will be relative to this)
36338 * @returns {Element} parent
36339 */
36340function getReferenceNode(reference) {
36341  return reference && reference.referenceNode ? reference.referenceNode : reference;
36342}
vendor: 3,047 bytes, lines 36342-36448
36342
36343
36344var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);
36345var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);
36346
36347/**
36348 * Determines if the browser is Internet Explorer
36349 * @method
36350 * @memberof Popper.Utils
36351 * @param {Number} version to check
36352 * @returns {Boolean} isIE
36353 */
36354function isIE(version) {
36355  if (version === 11) {
36356    return isIE11;
36357  }
36358  if (version === 10) {
36359    return isIE10;
36360  }
36361  return isIE11 || isIE10;
36362}
36363
36364/**
36365 * Returns the offset parent of the given element
36366 * @method
36367 * @memberof Popper.Utils
36368 * @argument {Element} element
36369 * @returns {Element} offset parent
36370 */
36371function getOffsetParent(element) {
36372  if (!element) {
36373    return document.documentElement;
36374  }
36375
36376  var noOffsetParent = isIE(10) ? document.body : null;
36377
36378  // NOTE: 1 DOM access here
36379  var offsetParent = element.offsetParent || null;
36380  // Skip hidden elements which don't have an offsetParent
36381  while (offsetParent === noOffsetParent && element.nextElementSibling) {
36382    offsetParent = (element = element.nextElementSibling).offsetParent;
36383  }
36384
36385  var nodeName = offsetParent && offsetParent.nodeName;
36386
36387  if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
36388    return element ? element.ownerDocument.documentElement : document.documentElement;
36389  }
36390
36391  // .offsetParent will return the closest TH, TD or TABLE in case
36392  // no offsetParent is present, I hate this job...
36393  if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {
36394    return getOffsetParent(offsetParent);
36395  }
36396
36397  return offsetParent;
36398}
36399
36400function isOffsetContainer(element) {
36401  var nodeName = element.nodeName;
36402
36403  if (nodeName === 'BODY') {
36404    return false;
36405  }
36406  return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;
36407}
36408
36409/**
36410 * Finds the root node (document, shadowDOM root) of the given element
36411 * @method
36412 * @memberof Popper.Utils
36413 * @argument {Element} node
36414 * @returns {Element} root node
36415 */
36416function getRoot(node) {
36417  if (node.parentNode !== null) {
36418    return getRoot(node.parentNode);
36419  }
36420
36421  return node;
36422}
36423
36424/**
36425 * Finds the offset parent common to the two provided nodes
36426 * @method
36427 * @memberof Popper.Utils
36428 * @argument {Element} element1
36429 * @argument {Element} element2
36430 * @returns {Element} common offset parent
36431 */
36432function findCommonOffsetParent(element1, element2) {
36433  // This check is needed to avoid errors in case one of the elements isn't defined for any reason
36434  if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {
36435    return document.documentElement;
36436  }
36437
36438  // Here we make sure to give as "start" the element that comes first in the DOM
36439  var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;
36440  var start = order ? element1 : element2;
36441  var end = order ? element2 : element1;
36442
36443  // Get common ancestor container
36444  var range = document.createRange();
36445  range.setStart(start, 0);
36446  range.setEnd(end, 0);
36447  var commonAncestorContainer = range.commonAncestorContainer;
36448
vendor: 6,175 bytes, lines 36449-36652
36449  // Both nodes are inside #document
36450
36451  if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {
36452    if (isOffsetContainer(commonAncestorContainer)) {
36453      return commonAncestorContainer;
36454    }
36455
36456    return getOffsetParent(commonAncestorContainer);
36457  }
36458
36459  // one of the nodes is inside shadowDOM, find which one
36460  var element1root = getRoot(element1);
36461  if (element1root.host) {
36462    return findCommonOffsetParent(element1root.host, element2);
36463  } else {
36464    return findCommonOffsetParent(element1, getRoot(element2).host);
36465  }
36466}
36467
36468/**
36469 * Gets the scroll value of the given element in the given side (top and left)
36470 * @method
36471 * @memberof Popper.Utils
36472 * @argument {Element} element
36473 * @argument {String} side `top` or `left`
36474 * @returns {number} amount of scrolled pixels
36475 */
36476function getScroll(element) {
36477  var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
36478
36479  var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
36480  var nodeName = element.nodeName;
36481
36482  if (nodeName === 'BODY' || nodeName === 'HTML') {
36483    var html = element.ownerDocument.documentElement;
36484    var scrollingElement = element.ownerDocument.scrollingElement || html;
36485    return scrollingElement[upperSide];
36486  }
36487
36488  return element[upperSide];
36489}
36490
36491/*
36492 * Sum or subtract the element scroll values (left and top) from a given rect object
36493 * @method
36494 * @memberof Popper.Utils
36495 * @param {Object} rect - Rect object you want to change
36496 * @param {HTMLElement} element - The element from the function reads the scroll values
36497 * @param {Boolean} subtract - set to true if you want to subtract the scroll values
36498 * @return {Object} rect - The modifier rect object
36499 */
36500function includeScroll(rect, element) {
36501  var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
36502
36503  var scrollTop = getScroll(element, 'top');
36504  var scrollLeft = getScroll(element, 'left');
36505  var modifier = subtract ? -1 : 1;
36506  rect.top += scrollTop * modifier;
36507  rect.bottom += scrollTop * modifier;
36508  rect.left += scrollLeft * modifier;
36509  rect.right += scrollLeft * modifier;
36510  return rect;
36511}
36512
36513/*
36514 * Helper to detect borders of a given element
36515 * @method
36516 * @memberof Popper.Utils
36517 * @param {CSSStyleDeclaration} styles
36518 * Result of `getStyleComputedProperty` on the given element
36519 * @param {String} axis - `x` or `y`
36520 * @return {number} borders - The borders size of the given axis
36521 */
36522
36523function getBordersSize(styles, axis) {
36524  var sideA = axis === 'x' ? 'Left' : 'Top';
36525  var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
36526
36527  return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10);
36528}
36529
36530function getSize(axis, body, html, computedStyle) {
36531  return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);
36532}
36533
36534function getWindowSizes(document) {
36535  var body = document.body;
36536  var html = document.documentElement;
36537  var computedStyle = isIE(10) && getComputedStyle(html);
36538
36539  return {
36540    height: getSize('Height', body, html, computedStyle),
36541    width: getSize('Width', body, html, computedStyle)
36542  };
36543}
36544
36545var classCallCheck = function (instance, Constructor) {
36546  if (!(instance instanceof Constructor)) {
36547    throw new TypeError("Cannot call a class as a function");
36548  }
36549};
36550
36551var createClass = function () {
36552  function defineProperties(target, props) {
36553    for (var i = 0; i < props.length; i++) {
36554      var descriptor = props[i];
36555      descriptor.enumerable = descriptor.enumerable || false;
36556      descriptor.configurable = true;
36557      if ("value" in descriptor) descriptor.writable = true;
36558      Object.defineProperty(target, descriptor.key, descriptor);
36559    }
36560  }
36561
36562  return function (Constructor, protoProps, staticProps) {
36563    if (protoProps) defineProperties(Constructor.prototype, protoProps);
36564    if (staticProps) defineProperties(Constructor, staticProps);
36565    return Constructor;
36566  };
36567}();
36568
36569
36570
36571
36572
36573var defineProperty = function (obj, key, value) {
36574  if (key in obj) {
36575    Object.defineProperty(obj, key, {
36576      value: value,
36577      enumerable: true,
36578      configurable: true,
36579      writable: true
36580    });
36581  } else {
36582    obj[key] = value;
36583  }
36584
36585  return obj;
36586};
36587
36588var _extends = Object.assign || function (target) {
36589  for (var i = 1; i < arguments.length; i++) {
36590    var source = arguments[i];
36591
36592    for (var key in source) {
36593      if (Object.prototype.hasOwnProperty.call(source, key)) {
36594        target[key] = source[key];
36595      }
36596    }
36597  }
36598
36599  return target;
36600};
36601
36602/**
36603 * Given element offsets, generate an output similar to getBoundingClientRect
36604 * @method
36605 * @memberof Popper.Utils
36606 * @argument {Object} offsets
36607 * @returns {Object} ClientRect like output
36608 */
36609function getClientRect(offsets) {
36610  return _extends({}, offsets, {
36611    right: offsets.left + offsets.width,
36612    bottom: offsets.top + offsets.height
36613  });
36614}
36615
36616/**
36617 * Get bounding client rect of given element
36618 * @method
36619 * @memberof Popper.Utils
36620 * @param {HTMLElement} element
36621 * @return {Object} client rect
36622 */
36623function getBoundingClientRect(element) {
36624  var rect = {};
36625
36626  // IE10 10 FIX: Please, don't ask, the element isn't
36627  // considered in DOM in some circumstances...
36628  // This isn't reproducible in IE10 compatibility mode of IE11
36629  try {
36630    if (isIE(10)) {
36631      rect = element.getBoundingClientRect();
36632      var scrollTop = getScroll(element, 'top');
36633      var scrollLeft = getScroll(element, 'left');
36634      rect.top += scrollTop;
36635      rect.left += scrollLeft;
36636      rect.bottom += scrollTop;
36637      rect.right += scrollLeft;
36638    } else {
36639      rect = element.getBoundingClientRect();
36640    }
36641  } catch (e) {}
36642
36643  var result = {
36644    left: rect.left,
36645    top: rect.top,
36646    width: rect.right - rect.left,
36647    height: rect.bottom - rect.top
36648  };
36649
36650  // subtract scrollbar size from sizes
36651  var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};
36652  var width = sizes.width || element.clientWidth || result.
vendor: 2,119 bytes, lines 36652-36705
36652width;
36653  var height = sizes.height || element.clientHeight || result.height;
36654
36655  var horizScrollbar = element.offsetWidth - width;
36656  var vertScrollbar = element.offsetHeight - height;
36657
36658  // if an hypothetical scrollbar is detected, we must be sure it's not a `border`
36659  // we make this check conditional for performance reasons
36660  if (horizScrollbar || vertScrollbar) {
36661    var styles = getStyleComputedProperty(element);
36662    horizScrollbar -= getBordersSize(styles, 'x');
36663    vertScrollbar -= getBordersSize(styles, 'y');
36664
36665    result.width -= horizScrollbar;
36666    result.height -= vertScrollbar;
36667  }
36668
36669  return getClientRect(result);
36670}
36671
36672function getOffsetRectRelativeToArbitraryNode(children, parent) {
36673  var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
36674
36675  var isIE10 = isIE(10);
36676  var isHTML = parent.nodeName === 'HTML';
36677  var childrenRect = getBoundingClientRect(children);
36678  var parentRect = getBoundingClientRect(parent);
36679  var scrollParent = getScrollParent(children);
36680
36681  var styles = getStyleComputedProperty(parent);
36682  var borderTopWidth = parseFloat(styles.borderTopWidth, 10);
36683  var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10);
36684
36685  // In cases where the parent is fixed, we must ignore negative scroll in offset calc
36686  if (fixedPosition && isHTML) {
36687    parentRect.top = Math.max(parentRect.top, 0);
36688    parentRect.left = Math.max(parentRect.left, 0);
36689  }
36690  var offsets = getClientRect({
36691    top: childrenRect.top - parentRect.top - borderTopWidth,
36692    left: childrenRect.left - parentRect.left - borderLeftWidth,
36693    width: childrenRect.width,
36694    height: childrenRect.height
36695  });
36696  offsets.marginTop = 0;
36697  offsets.marginLeft = 0;
36698
36699  // Subtract margins of documentElement in case it's being used as parent
36700  // we do this only on HTML because it's the only element that behaves
36701  // differently when margins are applied to it. The margins are included in
36702  // the box of the documentElement, in the other cases not.
36703  if (!isIE10 && isHTML) {
36704    var marginTop = parseFloat(styles.marginTop, 10);
36705    var marginLeft = parseFloat(styles.marginLeft, 10
vendor: 17,895 bytes, lines 36705-37266
36705);
36706
36707    offsets.top -= borderTopWidth - marginTop;
36708    offsets.bottom -= borderTopWidth - marginTop;
36709    offsets.left -= borderLeftWidth - marginLeft;
36710    offsets.right -= borderLeftWidth - marginLeft;
36711
36712    // Attach marginTop and marginLeft because in some circumstances we may need them
36713    offsets.marginTop = marginTop;
36714    offsets.marginLeft = marginLeft;
36715  }
36716
36717  if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {
36718    offsets = includeScroll(offsets, parent);
36719  }
36720
36721  return offsets;
36722}
36723
36724function getViewportOffsetRectRelativeToArtbitraryNode(element) {
36725  var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
36726
36727  var html = element.ownerDocument.documentElement;
36728  var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);
36729  var width = Math.max(html.clientWidth, window.innerWidth || 0);
36730  var height = Math.max(html.clientHeight, window.innerHeight || 0);
36731
36732  var scrollTop = !excludeScroll ? getScroll(html) : 0;
36733  var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;
36734
36735  var offset = {
36736    top: scrollTop - relativeOffset.top + relativeOffset.marginTop,
36737    left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,
36738    width: width,
36739    height: height
36740  };
36741
36742  return getClientRect(offset);
36743}
36744
36745/**
36746 * Check if the given element is fixed or is inside a fixed parent
36747 * @method
36748 * @memberof Popper.Utils
36749 * @argument {Element} element
36750 * @argument {Element} customContainer
36751 * @returns {Boolean} answer to "isFixed?"
36752 */
36753function isFixed(element) {
36754  var nodeName = element.nodeName;
36755  if (nodeName === 'BODY' || nodeName === 'HTML') {
36756    return false;
36757  }
36758  if (getStyleComputedProperty(element, 'position') === 'fixed') {
36759    return true;
36760  }
36761  var parentNode = getParentNode(element);
36762  if (!parentNode) {
36763    return false;
36764  }
36765  return isFixed(parentNode);
36766}
36767
36768/**
36769 * Finds the first parent of an element that has a transformed property defined
36770 * @method
36771 * @memberof Popper.Utils
36772 * @argument {Element} element
36773 * @returns {Element} first transformed parent or documentElement
36774 */
36775
36776function getFixedPositionOffsetParent(element) {
36777  // This check is needed to avoid errors in case one of the elements isn't defined for any reason
36778  if (!element || !element.parentElement || isIE()) {
36779    return document.documentElement;
36780  }
36781  var el = element.parentElement;
36782  while (el && getStyleComputedProperty(el, 'transform') === 'none') {
36783    el = el.parentElement;
36784  }
36785  return el || document.documentElement;
36786}
36787
36788/**
36789 * Computed the boundaries limits and return them
36790 * @method
36791 * @memberof Popper.Utils
36792 * @param {HTMLElement} popper
36793 * @param {HTMLElement} reference
36794 * @param {number} padding
36795 * @param {HTMLElement} boundariesElement - Element used to define the boundaries
36796 * @param {Boolean} fixedPosition - Is in fixed position mode
36797 * @returns {Object} Coordinates of the boundaries
36798 */
36799function getBoundaries(popper, reference, padding, boundariesElement) {
36800  var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
36801
36802  // NOTE: 1 DOM access here
36803
36804  var boundaries = { top: 0, left: 0 };
36805  var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
36806
36807  // Handle viewport case
36808  if (boundariesElement === 'viewport') {
36809    boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);
36810  } else {
36811    // Handle other cases based on DOM element used as boundaries
36812    var boundariesNode = void 0;
36813    if (boundariesElement === 'scrollParent') {
36814      boundariesNode = getScrollParent(getParentNode(reference));
36815      if (boundariesNode.nodeName === 'BODY') {
36816        boundariesNode = popper.ownerDocument.documentElement;
36817      }
36818    } else if (boundariesElement === 'window') {
36819      boundariesNode = popper.ownerDocument.documentElement;
36820    } else {
36821      boundariesNode = boundariesElement;
36822    }
36823
36824    var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);
36825
36826    // In case of HTML, we need a different computation
36827    if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {
36828      var _getWindowSizes = getWindowSizes(popper.ownerDocument),
36829          height = _getWindowSizes.height,
36830          width = _getWindowSizes.width;
36831
36832      boundaries.top += offsets.top - offsets.marginTop;
36833      boundaries.bottom = height + offsets.top;
36834      boundaries.left += offsets.left - offsets.marginLeft;
36835      boundaries.right = width + offsets.left;
36836    } else {
36837      // for all the other DOM elements, this one is good
36838      boundaries = offsets;
36839    }
36840  }
36841
36842  // Add paddings
36843  padding = padding || 0;
36844  var isPaddingNumber = typeof padding === 'number';
36845  boundaries.left += isPaddingNumber ? padding : padding.left || 0;
36846  boundaries.top += isPaddingNumber ? padding : padding.top || 0;
36847  boundaries.right -= isPaddingNumber ? padding : padding.right || 0;
36848  boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;
36849
36850  return boundaries;
36851}
36852
36853function getArea(_ref) {
36854  var width = _ref.width,
36855      height = _ref.height;
36856
36857  return width * height;
36858}
36859
36860/**
36861 * Utility used to transform the `auto` placement to the placement with more
36862 * available space.
36863 * @method
36864 * @memberof Popper.Utils
36865 * @argument {Object} data - The data object generated by update method
36866 * @argument {Object} options - Modifiers configuration and options
36867 * @returns {Object} The data object, properly modified
36868 */
36869function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {
36870  var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
36871
36872  if (placement.indexOf('auto') === -1) {
36873    return placement;
36874  }
36875
36876  var boundaries = getBoundaries(popper, reference, padding, boundariesElement);
36877
36878  var rects = {
36879    top: {
36880      width: boundaries.width,
36881      height: refRect.top - boundaries.top
36882    },
36883    right: {
36884      width: boundaries.right - refRect.right,
36885      height: boundaries.height
36886    },
36887    bottom: {
36888      width: boundaries.width,
36889      height: boundaries.bottom - refRect.bottom
36890    },
36891    left: {
36892      width: refRect.left - boundaries.left,
36893      height: boundaries.height
36894    }
36895  };
36896
36897  var sortedAreas = Object.keys(rects).map(function (key) {
36898    return _extends({
36899      key: key
36900    }, rects[key], {
36901      area: getArea(rects[key])
36902    });
36903  }).sort(function (a, b) {
36904    return b.area - a.area;
36905  });
36906
36907  var filteredAreas = sortedAreas.filter(function (_ref2) {
36908    var width = _ref2.width,
36909        height = _ref2.height;
36910    return width >= popper.clientWidth && height >= popper.clientHeight;
36911  });
36912
36913  var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;
36914
36915  var variation = placement.split('-')[1];
36916
36917  return computedPlacement + (variation ? '-' + variation : '');
36918}
36919
36920/**
36921 * Get offsets to the reference element
36922 * @method
36923 * @memberof Popper.Utils
36924 * @param {Object} state
36925 * @param {Element} popper - the popper element
36926 * @param {Element} reference - the reference element (the popper will be relative to this)
36927 * @param {Element} fixedPosition - is in fixed position mode
36928 * @returns {Object} An object containing the offsets which will be applied to the popper
36929 */
36930function getReferenceOffsets(state, popper, reference) {
36931  var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
36932
36933  var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
36934  return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);
36935}
36936
36937/**
36938 * Get the outer sizes of the given element (offset size + margins)
36939 * @method
36940 * @memberof Popper.Utils
36941 * @argument {Element} element
36942 * @returns {Object} object containing width and height properties
36943 */
36944function getOuterSizes(element) {
36945  var window = element.ownerDocument.defaultView;
36946  var styles = window.getComputedStyle(element);
36947  var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);
36948  var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);
36949  var result = {
36950    width: element.offsetWidth + y,
36951    height: element.offsetHeight + x
36952  };
36953  return result;
36954}
36955
36956/**
36957 * Get the opposite placement of the given one
36958 * @method
36959 * @memberof Popper.Utils
36960 * @argument {String} placement
36961 * @returns {String} flipped placement
36962 */
36963function getOppositePlacement(placement) {
36964  var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
36965  return placement.replace(/left|right|bottom|top/g, function (matched) {
36966    return hash[matched];
36967  });
36968}
36969
36970/**
36971 * Get offsets to the popper
36972 * @method
36973 * @memberof Popper.Utils
36974 * @param {Object} position - CSS position the Popper will get applied
36975 * @param {HTMLElement} popper - the popper element
36976 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
36977 * @param {String} placement - one of the valid placement options
36978 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
36979 */
36980function getPopperOffsets(popper, referenceOffsets, placement) {
36981  placement = placement.split('-')[0];
36982
36983  // Get popper node sizes
36984  var popperRect = getOuterSizes(popper);
36985
36986  // Add position, width and height to our offsets object
36987  var popperOffsets = {
36988    width: popperRect.width,
36989    height: popperRect.height
36990  };
36991
36992  // depending by the popper placement we have to compute its offsets slightly differently
36993  var isHoriz = ['right', 'left'].indexOf(placement) !== -1;
36994  var mainSide = isHoriz ? 'top' : 'left';
36995  var secondarySide = isHoriz ? 'left' : 'top';
36996  var measurement = isHoriz ? 'height' : 'width';
36997  var secondaryMeasurement = !isHoriz ? 'height' : 'width';
36998
36999  popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;
37000  if (placement === secondarySide) {
37001    popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];
37002  } else {
37003    popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];
37004  }
37005
37006  return popperOffsets;
37007}
37008
37009/**
37010 * Mimics the `find` method of Array
37011 * @method
37012 * @memberof Popper.Utils
37013 * @argument {Array} arr
37014 * @argument prop
37015 * @argument value
37016 * @returns index or -1
37017 */
37018function find(arr, check) {
37019  // use native find if supported
37020  if (Array.prototype.find) {
37021    return arr.find(check);
37022  }
37023
37024  // use `filter` to obtain the same behavior of `find`
37025  return arr.filter(check)[0];
37026}
37027
37028/**
37029 * Return the index of the matching object
37030 * @method
37031 * @memberof Popper.Utils
37032 * @argument {Array} arr
37033 * @argument prop
37034 * @argument value
37035 * @returns index or -1
37036 */
37037function findIndex(arr, prop, value) {
37038  // use native findIndex if supported
37039  if (Array.prototype.findIndex) {
37040    return arr.findIndex(function (cur) {
37041      return cur[prop] === value;
37042    });
37043  }
37044
37045  // use `find` + `indexOf` if `findIndex` isn't supported
37046  var match = find(arr, function (obj) {
37047    return obj[prop] === value;
37048  });
37049  return arr.indexOf(match);
37050}
37051
37052/**
37053 * Loop trough the list of modifiers and run them in order,
37054 * each of them will then edit the data object.
37055 * @method
37056 * @memberof Popper.Utils
37057 * @param {dataObject} data
37058 * @param {Array} modifiers
37059 * @param {String} ends - Optional modifier name used as stopper
37060 * @returns {dataObject}
37061 */
37062function runModifiers(modifiers, data, ends) {
37063  var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));
37064
37065  modifiersToRun.forEach(function (modifier) {
37066    if (modifier['function']) {
37067      // eslint-disable-line dot-notation
37068      console.warn('`modifier.function` is deprecated, use `modifier.fn`!');
37069    }
37070    var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation
37071    if (modifier.enabled && isFunction(fn)) {
37072      // Add properties to offsets to make them a complete clientRect object
37073      // we do this before each modifier to make sure the previous one doesn't
37074      // mess with these values
37075      data.offsets.popper = getClientRect(data.offsets.popper);
37076      data.offsets.reference = getClientRect(data.offsets.reference);
37077
37078      data = fn(data, modifier);
37079    }
37080  });
37081
37082  return data;
37083}
37084
37085/**
37086 * Updates the position of the popper, computing the new offsets and applying
37087 * the new style.<br />
37088 * Prefer `scheduleUpdate` over `update` because of performance reasons.
37089 * @method
37090 * @memberof Popper
37091 */
37092function update() {
37093  // if popper is destroyed, don't perform any further update
37094  if (this.state.isDestroyed) {
37095    return;
37096  }
37097
37098  var data = {
37099    instance: this,
37100    styles: {},
37101    arrowStyles: {},
37102    attributes: {},
37103    flipped: false,
37104    offsets: {}
37105  };
37106
37107  // compute reference element offsets
37108  data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);
37109
37110  // compute auto placement, store placement inside the data object,
37111  // modifiers will be able to edit `placement` if needed
37112  // and refer to originalPlacement to know the original value
37113  data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);
37114
37115  // store the computed placement inside `originalPlacement`
37116  data.originalPlacement = data.placement;
37117
37118  data.positionFixed = this.options.positionFixed;
37119
37120  // compute the popper offsets
37121  data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);
37122
37123  data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';
37124
37125  // run the modifiers
37126  data = runModifiers(this.modifiers, data);
37127
37128  // the first `update` will call `onCreate` callback
37129  // the other ones will call `onUpdate` callback
37130  if (!this.state.isCreated) {
37131    this.state.isCreated = true;
37132    this.options.onCreate(data);
37133  } else {
37134    this.options.onUpdate(data);
37135  }
37136}
37137
37138/**
37139 * Helper used to know if the given modifier is enabled.
37140 * @method
37141 * @memberof Popper.Utils
37142 * @returns {Boolean}
37143 */
37144function isModifierEnabled(modifiers, modifierName) {
37145  return modifiers.some(function (_ref) {
37146    var name = _ref.name,
37147        enabled = _ref.enabled;
37148    return enabled && name === modifierName;
37149  });
37150}
37151
37152/**
37153 * Get the prefixed supported property name
37154 * @method
37155 * @memberof Popper.Utils
37156 * @argument {String} property (camelCase)
37157 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)
37158 */
37159function getSupportedPropertyName(property) {
37160  var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];
37161  var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
37162
37163  for (var i = 0; i < prefixes.length; i++) {
37164    var prefix = prefixes[i];
37165    var toCheck = prefix ? '' + prefix + upperProp : property;
37166    if (typeof document.body.style[toCheck] !== 'undefined') {
37167      return toCheck;
37168    }
37169  }
37170  return null;
37171}
37172
37173/**
37174 * Destroys the popper.
37175 * @method
37176 * @memberof Popper
37177 */
37178function destroy() {
37179  this.state.isDestroyed = true;
37180
37181  // touch DOM only if `applyStyle` modifier is enabled
37182  if (isModifierEnabled(this.modifiers, 'applyStyle')) {
37183    this.popper.removeAttribute('x-placement');
37184    this.popper.style.position = '';
37185    this.popper.style.top = '';
37186    this.popper.style.left = '';
37187    this.popper.style.right = '';
37188    this.popper.style.bottom = '';
37189    this.popper.style.willChange = '';
37190    this.popper.style[getSupportedPropertyName('transform')] = '';
37191  }
37192
37193  this.disableEventListeners();
37194
37195  // remove the popper if user explicitly asked for the deletion on destroy
37196  // do not use `remove` because IE11 doesn't support it
37197  if (this.options.removeOnDestroy) {
37198    this.popper.parentNode.removeChild(this.popper);
37199  }
37200  return this;
37201}
37202
37203/**
37204 * Get the window associated with the element
37205 * @argument {Element} element
37206 * @returns {Window}
37207 */
37208function getWindow(element) {
37209  var ownerDocument = element.ownerDocument;
37210  return ownerDocument ? ownerDocument.defaultView : window;
37211}
37212
37213function attachToScrollParents(scrollParent, event, callback, scrollParents) {
37214  var isBody = scrollParent.nodeName === 'BODY';
37215  var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;
37216  target.addEventListener(event, callback, { passive: true });
37217
37218  if (!isBody) {
37219    attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);
37220  }
37221  scrollParents.push(target);
37222}
37223
37224/**
37225 * Setup needed event listeners used to update the popper position
37226 * @method
37227 * @memberof Popper.Utils
37228 * @private
37229 */
37230function setupEventListeners(reference, options, state, updateBound) {
37231  // Resize event listener on window
37232  state.updateBound = updateBound;
37233  getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });
37234
37235  // Scroll event listener on scroll parents
37236  var scrollElement = getScrollParent(reference);
37237  attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);
37238  state.scrollElement = scrollElement;
37239  state.eventsEnabled = true;
37240
37241  return state;
37242}
37243
37244/**
37245 * It will add resize/scroll events and start recalculating
37246 * position of the popper element when they are triggered.
37247 * @method
37248 * @memberof Popper
37249 */
37250function enableEventListeners() {
37251  if (!this.state.eventsEnabled) {
37252    this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);
37253  }
37254}
37255
37256/**
37257 * Remove event listeners used to update the popper position
37258 * @method
37259 * @memberof Popper.Utils
37260 * @private
37261 */
37262function removeEventListeners(reference, state) {
37263  // Remove resize event listener on window
37264  getWindow(reference).removeEventListener('resize', state.updateBound);
37265
37266  // Remove scroll event listener on scroll parents
vendor: 54,378 bytes, lines 37267-38795
37267  state.scrollParents.forEach(function (target) {
37268    target.removeEventListener('scroll', state.updateBound);
37269  });
37270
37271  // Reset state
37272  state.updateBound = null;
37273  state.scrollParents = [];
37274  state.scrollElement = null;
37275  state.eventsEnabled = false;
37276  return state;
37277}
37278
37279/**
37280 * It will remove resize/scroll events and won't recalculate popper position
37281 * when they are triggered. It also won't trigger `onUpdate` callback anymore,
37282 * unless you call `update` method manually.
37283 * @method
37284 * @memberof Popper
37285 */
37286function disableEventListeners() {
37287  if (this.state.eventsEnabled) {
37288    cancelAnimationFrame(this.scheduleUpdate);
37289    this.state = removeEventListeners(this.reference, this.state);
37290  }
37291}
37292
37293/**
37294 * Tells if a given input is a number
37295 * @method
37296 * @memberof Popper.Utils
37297 * @param {*} input to check
37298 * @return {Boolean}
37299 */
37300function isNumeric(n) {
37301  return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
37302}
37303
37304/**
37305 * Set the style to the given popper
37306 * @method
37307 * @memberof Popper.Utils
37308 * @argument {Element} element - Element to apply the style to
37309 * @argument {Object} styles
37310 * Object with a list of properties and values which will be applied to the element
37311 */
37312function setStyles(element, styles) {
37313  Object.keys(styles).forEach(function (prop) {
37314    var unit = '';
37315    // add unit if the value is numeric and is one of the following
37316    if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {
37317      unit = 'px';
37318    }
37319    element.style[prop] = styles[prop] + unit;
37320  });
37321}
37322
37323/**
37324 * Set the attributes to the given popper
37325 * @method
37326 * @memberof Popper.Utils
37327 * @argument {Element} element - Element to apply the attributes to
37328 * @argument {Object} styles
37329 * Object with a list of properties and values which will be applied to the element
37330 */
37331function setAttributes(element, attributes) {
37332  Object.keys(attributes).forEach(function (prop) {
37333    var value = attributes[prop];
37334    if (value !== false) {
37335      element.setAttribute(prop, attributes[prop]);
37336    } else {
37337      element.removeAttribute(prop);
37338    }
37339  });
37340}
37341
37342/**
37343 * @function
37344 * @memberof Modifiers
37345 * @argument {Object} data - The data object generated by `update` method
37346 * @argument {Object} data.styles - List of style properties - values to apply to popper element
37347 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
37348 * @argument {Object} options - Modifiers configuration and options
37349 * @returns {Object} The same data object
37350 */
37351function applyStyle(data) {
37352  // any property present in `data.styles` will be applied to the popper,
37353  // in this way we can make the 3rd party modifiers add custom styles to it
37354  // Be aware, modifiers could override the properties defined in the previous
37355  // lines of this modifier!
37356  setStyles(data.instance.popper, data.styles);
37357
37358  // any property present in `data.attributes` will be applied to the popper,
37359  // they will be set as HTML attributes of the element
37360  setAttributes(data.instance.popper, data.attributes);
37361
37362  // if arrowElement is defined and arrowStyles has some properties
37363  if (data.arrowElement && Object.keys(data.arrowStyles).length) {
37364    setStyles(data.arrowElement, data.arrowStyles);
37365  }
37366
37367  return data;
37368}
37369
37370/**
37371 * Set the x-placement attribute before everything else because it could be used
37372 * to add margins to the popper margins needs to be calculated to get the
37373 * correct popper offsets.
37374 * @method
37375 * @memberof Popper.modifiers
37376 * @param {HTMLElement} reference - The reference element used to position the popper
37377 * @param {HTMLElement} popper - The HTML element used as popper
37378 * @param {Object} options - Popper.js options
37379 */
37380function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {
37381  // compute reference element offsets
37382  var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);
37383
37384  // compute auto placement, store placement inside the data object,
37385  // modifiers will be able to edit `placement` if needed
37386  // and refer to originalPlacement to know the original value
37387  var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);
37388
37389  popper.setAttribute('x-placement', placement);
37390
37391  // Apply `position` to popper before anything else because
37392  // without the position applied we can't guarantee correct computations
37393  setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });
37394
37395  return options;
37396}
37397
37398/**
37399 * @function
37400 * @memberof Popper.Utils
37401 * @argument {Object} data - The data object generated by `update` method
37402 * @argument {Boolean} shouldRound - If the offsets should be rounded at all
37403 * @returns {Object} The popper's position offsets rounded
37404 *
37405 * The tale of pixel-perfect positioning. It's still not 100% perfect, but as
37406 * good as it can be within reason.
37407 * Discussion here: https://github.com/FezVrasta/popper.js/pull/715
37408 *
37409 * Low DPI screens cause a popper to be blurry if not using full pixels (Safari
37410 * as well on High DPI screens).
37411 *
37412 * Firefox prefers no rounding for positioning and does not have blurriness on
37413 * high DPI screens.
37414 *
37415 * Only horizontal placement and left/right values need to be considered.
37416 */
37417function getRoundedOffsets(data, shouldRound) {
37418  var _data$offsets = data.offsets,
37419      popper = _data$offsets.popper,
37420      reference = _data$offsets.reference;
37421  var round = Math.round,
37422      floor = Math.floor;
37423
37424  var noRound = function noRound(v) {
37425    return v;
37426  };
37427
37428  var referenceWidth = round(reference.width);
37429  var popperWidth = round(popper.width);
37430
37431  var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;
37432  var isVariation = data.placement.indexOf('-') !== -1;
37433  var sameWidthParity = referenceWidth % 2 === popperWidth % 2;
37434  var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;
37435
37436  var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;
37437  var verticalToInteger = !shouldRound ? noRound : round;
37438
37439  return {
37440    left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),
37441    top: verticalToInteger(popper.top),
37442    bottom: verticalToInteger(popper.bottom),
37443    right: horizontalToInteger(popper.right)
37444  };
37445}
37446
37447var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);
37448
37449/**
37450 * @function
37451 * @memberof Modifiers
37452 * @argument {Object} data - The data object generated by `update` method
37453 * @argument {Object} options - Modifiers configuration and options
37454 * @returns {Object} The data object, properly modified
37455 */
37456function computeStyle(data, options) {
37457  var x = options.x,
37458      y = options.y;
37459  var popper = data.offsets.popper;
37460
37461  // Remove this legacy support in Popper.js v2
37462
37463  var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {
37464    return modifier.name === 'applyStyle';
37465  }).gpuAcceleration;
37466  if (legacyGpuAccelerationOption !== undefined) {
37467    console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');
37468  }
37469  var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;
37470
37471  var offsetParent = getOffsetParent(data.instance.popper);
37472  var offsetParentRect = getBoundingClientRect(offsetParent);
37473
37474  // Styles
37475  var styles = {
37476    position: popper.position
37477  };
37478
37479  var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);
37480
37481  var sideA = x === 'bottom' ? 'top' : 'bottom';
37482  var sideB = y === 'right' ? 'left' : 'right';
37483
37484  // if gpuAcceleration is set to `true` and transform is supported,
37485  //  we use `translate3d` to apply the position to the popper we
37486  // automatically use the supported prefixed version if needed
37487  var prefixedProperty = getSupportedPropertyName('transform');
37488
37489  // now, let's make a step back and look at this code closely (wtf?)
37490  // If the content of the popper grows once it's been positioned, it
37491  // may happen that the popper gets misplaced because of the new content
37492  // overflowing its reference element
37493  // To avoid this problem, we provide two options (x and y), which allow
37494  // the consumer to define the offset origin.
37495  // If we position a popper on top of a reference element, we can set
37496  // `x` to `top` to make the popper grow towards its top instead of
37497  // its bottom.
37498  var left = void 0,
37499      top = void 0;
37500  if (sideA === 'bottom') {
37501    // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)
37502    // and not the bottom of the html element
37503    if (offsetParent.nodeName === 'HTML') {
37504      top = -offsetParent.clientHeight + offsets.bottom;
37505    } else {
37506      top = -offsetParentRect.height + offsets.bottom;
37507    }
37508  } else {
37509    top = offsets.top;
37510  }
37511  if (sideB === 'right') {
37512    if (offsetParent.nodeName === 'HTML') {
37513      left = -offsetParent.clientWidth + offsets.right;
37514    } else {
37515      left = -offsetParentRect.width + offsets.right;
37516    }
37517  } else {
37518    left = offsets.left;
37519  }
37520  if (gpuAcceleration && prefixedProperty) {
37521    styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
37522    styles[sideA] = 0;
37523    styles[sideB] = 0;
37524    styles.willChange = 'transform';
37525  } else {
37526    // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties
37527    var invertTop = sideA === 'bottom' ? -1 : 1;
37528    var invertLeft = sideB === 'right' ? -1 : 1;
37529    styles[sideA] = top * invertTop;
37530    styles[sideB] = left * invertLeft;
37531    styles.willChange = sideA + ', ' + sideB;
37532  }
37533
37534  // Attributes
37535  var attributes = {
37536    'x-placement': data.placement
37537  };
37538
37539  // Update `data` attributes, styles and arrowStyles
37540  data.attributes = _extends({}, attributes, data.attributes);
37541  data.styles = _extends({}, styles, data.styles);
37542  data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);
37543
37544  return data;
37545}
37546
37547/**
37548 * Helper used to know if the given modifier depends from another one.<br />
37549 * It checks if the needed modifier is listed and enabled.
37550 * @method
37551 * @memberof Popper.Utils
37552 * @param {Array} modifiers - list of modifiers
37553 * @param {String} requestingName - name of requesting modifier
37554 * @param {String} requestedName - name of requested modifier
37555 * @returns {Boolean}
37556 */
37557function isModifierRequired(modifiers, requestingName, requestedName) {
37558  var requesting = find(modifiers, function (_ref) {
37559    var name = _ref.name;
37560    return name === requestingName;
37561  });
37562
37563  var isRequired = !!requesting && modifiers.some(function (modifier) {
37564    return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;
37565  });
37566
37567  if (!isRequired) {
37568    var _requesting = '`' + requestingName + '`';
37569    var requested = '`' + requestedName + '`';
37570    console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');
37571  }
37572  return isRequired;
37573}
37574
37575/**
37576 * @function
37577 * @memberof Modifiers
37578 * @argument {Object} data - The data object generated by update method
37579 * @argument {Object} options - Modifiers configuration and options
37580 * @returns {Object} The data object, properly modified
37581 */
37582function arrow(data, options) {
37583  var _data$offsets$arrow;
37584
37585  // arrow depends on keepTogether in order to work
37586  if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
37587    return data;
37588  }
37589
37590  var arrowElement = options.element;
37591
37592  // if arrowElement is a string, suppose it's a CSS selector
37593  if (typeof arrowElement === 'string') {
37594    arrowElement = data.instance.popper.querySelector(arrowElement);
37595
37596    // if arrowElement is not found, don't run the modifier
37597    if (!arrowElement) {
37598      return data;
37599    }
37600  } else {
37601    // if the arrowElement isn't a query selector we must check that the
37602    // provided DOM node is child of its popper node
37603    if (!data.instance.popper.contains(arrowElement)) {
37604      console.warn('WARNING: `arrow.element` must be child of its popper element!');
37605      return data;
37606    }
37607  }
37608
37609  var placement = data.placement.split('-')[0];
37610  var _data$offsets = data.offsets,
37611      popper = _data$offsets.popper,
37612      reference = _data$offsets.reference;
37613
37614  var isVertical = ['left', 'right'].indexOf(placement) !== -1;
37615
37616  var len = isVertical ? 'height' : 'width';
37617  var sideCapitalized = isVertical ? 'Top' : 'Left';
37618  var side = sideCapitalized.toLowerCase();
37619  var altSide = isVertical ? 'left' : 'top';
37620  var opSide = isVertical ? 'bottom' : 'right';
37621  var arrowElementSize = getOuterSizes(arrowElement)[len];
37622
37623  //
37624  // extends keepTogether behavior making sure the popper and its
37625  // reference have enough pixels in conjunction
37626  //
37627
37628  // top/left side
37629  if (reference[opSide] - arrowElementSize < popper[side]) {
37630    data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);
37631  }
37632  // bottom/right side
37633  if (reference[side] + arrowElementSize > popper[opSide]) {
37634    data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];
37635  }
37636  data.offsets.popper = getClientRect(data.offsets.popper);
37637
37638  // compute center of the popper
37639  var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
37640
37641  // Compute the sideValue using the updated popper offsets
37642  // take popper margin in account because we don't have this info available
37643  var css = getStyleComputedProperty(data.instance.popper);
37644  var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10);
37645  var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10);
37646  var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;
37647
37648  // prevent arrowElement from being placed not contiguously to its popper
37649  sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
37650
37651  data.arrowElement = arrowElement;
37652  data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);
37653
37654  return data;
37655}
37656
37657/**
37658 * Get the opposite placement variation of the given one
37659 * @method
37660 * @memberof Popper.Utils
37661 * @argument {String} placement variation
37662 * @returns {String} flipped placement variation
37663 */
37664function getOppositeVariation(variation) {
37665  if (variation === 'end') {
37666    return 'start';
37667  } else if (variation === 'start') {
37668    return 'end';
37669  }
37670  return variation;
37671}
37672
37673/**
37674 * List of accepted placements to use as values of the `placement` option.<br />
37675 * Valid placements are:
37676 * - `auto`
37677 * - `top`
37678 * - `right`
37679 * - `bottom`
37680 * - `left`
37681 *
37682 * Each placement can have a variation from this list:
37683 * - `-start`
37684 * - `-end`
37685 *
37686 * Variations are interpreted easily if you think of them as the left to right
37687 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`
37688 * is right.<br />
37689 * Vertically (`left` and `right`), `start` is top and `end` is bottom.
37690 *
37691 * Some valid examples are:
37692 * - `top-end` (on top of reference, right aligned)
37693 * - `right-start` (on right of reference, top aligned)
37694 * - `bottom` (on bottom, centered)
37695 * - `auto-end` (on the side with more space available, alignment depends by placement)
37696 *
37697 * @static
37698 * @type {Array}
37699 * @enum {String}
37700 * @readonly
37701 * @method placements
37702 * @memberof Popper
37703 */
37704var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];
37705
37706// Get rid of `auto` `auto-start` and `auto-end`
37707var validPlacements = placements.slice(3);
37708
37709/**
37710 * Given an initial placement, returns all the subsequent placements
37711 * clockwise (or counter-clockwise).
37712 *
37713 * @method
37714 * @memberof Popper.Utils
37715 * @argument {String} placement - A valid placement (it accepts variations)
37716 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise
37717 * @returns {Array} placements including their variations
37718 */
37719function clockwise(placement) {
37720  var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
37721
37722  var index = validPlacements.indexOf(placement);
37723  var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));
37724  return counter ? arr.reverse() : arr;
37725}
37726
37727var BEHAVIORS = {
37728  FLIP: 'flip',
37729  CLOCKWISE: 'clockwise',
37730  COUNTERCLOCKWISE: 'counterclockwise'
37731};
37732
37733/**
37734 * @function
37735 * @memberof Modifiers
37736 * @argument {Object} data - The data object generated by update method
37737 * @argument {Object} options - Modifiers configuration and options
37738 * @returns {Object} The data object, properly modified
37739 */
37740function flip(data, options) {
37741  // if `inner` modifier is enabled, we can't use the `flip` modifier
37742  if (isModifierEnabled(data.instance.modifiers, 'inner')) {
37743    return data;
37744  }
37745
37746  if (data.flipped && data.placement === data.originalPlacement) {
37747    // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
37748    return data;
37749  }
37750
37751  var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);
37752
37753  var placement = data.placement.split('-')[0];
37754  var placementOpposite = getOppositePlacement(placement);
37755  var variation = data.placement.split('-')[1] || '';
37756
37757  var flipOrder = [];
37758
37759  switch (options.behavior) {
37760    case BEHAVIORS.FLIP:
37761      flipOrder = [placement, placementOpposite];
37762      break;
37763    case BEHAVIORS.CLOCKWISE:
37764      flipOrder = clockwise(placement);
37765      break;
37766    case BEHAVIORS.COUNTERCLOCKWISE:
37767      flipOrder = clockwise(placement, true);
37768      break;
37769    default:
37770      flipOrder = options.behavior;
37771  }
37772
37773  flipOrder.forEach(function (step, index) {
37774    if (placement !== step || flipOrder.length === index + 1) {
37775      return data;
37776    }
37777
37778    placement = data.placement.split('-')[0];
37779    placementOpposite = getOppositePlacement(placement);
37780
37781    var popperOffsets = data.offsets.popper;
37782    var refOffsets = data.offsets.reference;
37783
37784    // using floor because the reference offsets may contain decimals we are not going to consider here
37785    var floor = Math.floor;
37786    var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);
37787
37788    var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
37789    var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
37790    var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
37791    var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);
37792
37793    var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;
37794
37795    // flip the variation if required
37796    var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
37797
37798    // flips variation if reference element overflows boundaries
37799    var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);
37800
37801    // flips variation if popper content overflows boundaries
37802    var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);
37803
37804    var flippedVariation = flippedVariationByRef || flippedVariationByContent;
37805
37806    if (overlapsRef || overflowsBoundaries || flippedVariation) {
37807      // this boolean to detect any flip loop
37808      data.flipped = true;
37809
37810      if (overlapsRef || overflowsBoundaries) {
37811        placement = flipOrder[index + 1];
37812      }
37813
37814      if (flippedVariation) {
37815        variation = getOppositeVariation(variation);
37816      }
37817
37818      data.placement = placement + (variation ? '-' + variation : '');
37819
37820      // this object contains `position`, we want to preserve it along with
37821      // any additional property we may add in the future
37822      data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));
37823
37824      data = runModifiers(data.instance.modifiers, data, 'flip');
37825    }
37826  });
37827  return data;
37828}
37829
37830/**
37831 * @function
37832 * @memberof Modifiers
37833 * @argument {Object} data - The data object generated by update method
37834 * @argument {Object} options - Modifiers configuration and options
37835 * @returns {Object} The data object, properly modified
37836 */
37837function keepTogether(data) {
37838  var _data$offsets = data.offsets,
37839      popper = _data$offsets.popper,
37840      reference = _data$offsets.reference;
37841
37842  var placement = data.placement.split('-')[0];
37843  var floor = Math.floor;
37844  var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
37845  var side = isVertical ? 'right' : 'bottom';
37846  var opSide = isVertical ? 'left' : 'top';
37847  var measurement = isVertical ? 'width' : 'height';
37848
37849  if (popper[side] < floor(reference[opSide])) {
37850    data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];
37851  }
37852  if (popper[opSide] > floor(reference[side])) {
37853    data.offsets.popper[opSide] = floor(reference[side]);
37854  }
37855
37856  return data;
37857}
37858
37859/**
37860 * Converts a string containing value + unit into a px value number
37861 * @function
37862 * @memberof {modifiers~offset}
37863 * @private
37864 * @argument {String} str - Value + unit string
37865 * @argument {String} measurement - `height` or `width`
37866 * @argument {Object} popperOffsets
37867 * @argument {Object} referenceOffsets
37868 * @returns {Number|String}
37869 * Value in pixels, or original string if no values were extracted
37870 */
37871function toValue(str, measurement, popperOffsets, referenceOffsets) {
37872  // separate value from unit
37873  var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);
37874  var value = +split[1];
37875  var unit = split[2];
37876
37877  // If it's not a number it's an operator, I guess
37878  if (!value) {
37879    return str;
37880  }
37881
37882  if (unit.indexOf('%') === 0) {
37883    var element = void 0;
37884    switch (unit) {
37885      case '%p':
37886        element = popperOffsets;
37887        break;
37888      case '%':
37889      case '%r':
37890      default:
37891        element = referenceOffsets;
37892    }
37893
37894    var rect = getClientRect(element);
37895    return rect[measurement] / 100 * value;
37896  } else if (unit === 'vh' || unit === 'vw') {
37897    // if is a vh or vw, we calculate the size based on the viewport
37898    var size = void 0;
37899    if (unit === 'vh') {
37900      size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
37901    } else {
37902      size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
37903    }
37904    return size / 100 * value;
37905  } else {
37906    // if is an explicit pixel unit, we get rid of the unit and keep the value
37907    // if is an implicit unit, it's px, and we return just the value
37908    return value;
37909  }
37910}
37911
37912/**
37913 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.
37914 * @function
37915 * @memberof {modifiers~offset}
37916 * @private
37917 * @argument {String} offset
37918 * @argument {Object} popperOffsets
37919 * @argument {Object} referenceOffsets
37920 * @argument {String} basePlacement
37921 * @returns {Array} a two cells array with x and y offsets in numbers
37922 */
37923function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {
37924  var offsets = [0, 0];
37925
37926  // Use height if placement is left or right and index is 0 otherwise use width
37927  // in this way the first offset will use an axis and the second one
37928  // will use the other one
37929  var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;
37930
37931  // Split the offset string to obtain a list of values and operands
37932  // The regex addresses values with the plus or minus sign in front (+10, -20, etc)
37933  var fragments = offset.split(/(\+|\-)/).map(function (frag) {
37934    return frag.trim();
37935  });
37936
37937  // Detect if the offset string contains a pair of values or a single one
37938  // they could be separated by comma or space
37939  var divider = fragments.indexOf(find(fragments, function (frag) {
37940    return frag.search(/,|\s/) !== -1;
37941  }));
37942
37943  if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
37944    console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');
37945  }
37946
37947  // If divider is found, we divide the list of values and operands to divide
37948  // them by ofset X and Y.
37949  var splitRegex = /\s*,\s*|\s+/;
37950  var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];
37951
37952  // Convert the values with units to absolute pixels to allow our computations
37953  ops = ops.map(function (op, index) {
37954    // Most of the units rely on the orientation of the popper
37955    var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';
37956    var mergeWithPrevious = false;
37957    return op
37958    // This aggregates any `+` or `-` sign that aren't considered operators
37959    // e.g.: 10 + +5 => [10, +, +5]
37960    .reduce(function (a, b) {
37961      if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
37962        a[a.length - 1] = b;
37963        mergeWithPrevious = true;
37964        return a;
37965      } else if (mergeWithPrevious) {
37966        a[a.length - 1] += b;
37967        mergeWithPrevious = false;
37968        return a;
37969      } else {
37970        return a.concat(b);
37971      }
37972    }, [])
37973    // Here we convert the string values into number values (in px)
37974    .map(function (str) {
37975      return toValue(str, measurement, popperOffsets, referenceOffsets);
37976    });
37977  });
37978
37979  // Loop trough the offsets arrays and execute the operations
37980  ops.forEach(function (op, index) {
37981    op.forEach(function (frag, index2) {
37982      if (isNumeric(frag)) {
37983        offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
37984      }
37985    });
37986  });
37987  return offsets;
37988}
37989
37990/**
37991 * @function
37992 * @memberof Modifiers
37993 * @argument {Object} data - The data object generated by update method
37994 * @argument {Object} options - Modifiers configuration and options
37995 * @argument {Number|String} options.offset=0
37996 * The offset value as described in the modifier description
37997 * @returns {Object} The data object, properly modified
37998 */
37999function offset(data, _ref) {
38000  var offset = _ref.offset;
38001  var placement = data.placement,
38002      _data$offsets = data.offsets,
38003      popper = _data$offsets.popper,
38004      reference = _data$offsets.reference;
38005
38006  var basePlacement = placement.split('-')[0];
38007
38008  var offsets = void 0;
38009  if (isNumeric(+offset)) {
38010    offsets = [+offset, 0];
38011  } else {
38012    offsets = parseOffset(offset, popper, reference, basePlacement);
38013  }
38014
38015  if (basePlacement === 'left') {
38016    popper.top += offsets[0];
38017    popper.left -= offsets[1];
38018  } else if (basePlacement === 'right') {
38019    popper.top += offsets[0];
38020    popper.left += offsets[1];
38021  } else if (basePlacement === 'top') {
38022    popper.left += offsets[0];
38023    popper.top -= offsets[1];
38024  } else if (basePlacement === 'bottom') {
38025    popper.left += offsets[0];
38026    popper.top += offsets[1];
38027  }
38028
38029  data.popper = popper;
38030  return data;
38031}
38032
38033/**
38034 * @function
38035 * @memberof Modifiers
38036 * @argument {Object} data - The data object generated by `update` method
38037 * @argument {Object} options - Modifiers configuration and options
38038 * @returns {Object} The data object, properly modified
38039 */
38040function preventOverflow(data, options) {
38041  var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);
38042
38043  // If offsetParent is the reference element, we really want to
38044  // go one step up and use the next offsetParent as reference to
38045  // avoid to make this modifier completely useless and look like broken
38046  if (data.instance.reference === boundariesElement) {
38047    boundariesElement = getOffsetParent(boundariesElement);
38048  }
38049
38050  // NOTE: DOM access here
38051  // resets the popper's position so that the document size can be calculated excluding
38052  // the size of the popper element itself
38053  var transformProp = getSupportedPropertyName('transform');
38054  var popperStyles = data.instance.popper.style; // assignment to help minification
38055  var top = popperStyles.top,
38056      left = popperStyles.left,
38057      transform = popperStyles[transformProp];
38058
38059  popperStyles.top = '';
38060  popperStyles.left = '';
38061  popperStyles[transformProp] = '';
38062
38063  var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);
38064
38065  // NOTE: DOM access here
38066  // restores the original style properties after the offsets have been computed
38067  popperStyles.top = top;
38068  popperStyles.left = left;
38069  popperStyles[transformProp] = transform;
38070
38071  options.boundaries = boundaries;
38072
38073  var order = options.priority;
38074  var popper = data.offsets.popper;
38075
38076  var check = {
38077    primary: function primary(placement) {
38078      var value = popper[placement];
38079      if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {
38080        value = Math.max(popper[placement], boundaries[placement]);
38081      }
38082      return defineProperty({}, placement, value);
38083    },
38084    secondary: function secondary(placement) {
38085      var mainSide = placement === 'right' ? 'left' : 'top';
38086      var value = popper[mainSide];
38087      if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {
38088        value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));
38089      }
38090      return defineProperty({}, mainSide, value);
38091    }
38092  };
38093
38094  order.forEach(function (placement) {
38095    var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
38096    popper = _extends({}, popper, check[side](placement));
38097  });
38098
38099  data.offsets.popper = popper;
38100
38101  return data;
38102}
38103
38104/**
38105 * @function
38106 * @memberof Modifiers
38107 * @argument {Object} data - The data object generated by `update` method
38108 * @argument {Object} options - Modifiers configuration and options
38109 * @returns {Object} The data object, properly modified
38110 */
38111function shift(data) {
38112  var placement = data.placement;
38113  var basePlacement = placement.split('-')[0];
38114  var shiftvariation = placement.split('-')[1];
38115
38116  // if shift shiftvariation is specified, run the modifier
38117  if (shiftvariation) {
38118    var _data$offsets = data.offsets,
38119        reference = _data$offsets.reference,
38120        popper = _data$offsets.popper;
38121
38122    var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
38123    var side = isVertical ? 'left' : 'top';
38124    var measurement = isVertical ? 'width' : 'height';
38125
38126    var shiftOffsets = {
38127      start: defineProperty({}, side, reference[side]),
38128      end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
38129    };
38130
38131    data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);
38132  }
38133
38134  return data;
38135}
38136
38137/**
38138 * @function
38139 * @memberof Modifiers
38140 * @argument {Object} data - The data object generated by update method
38141 * @argument {Object} options - Modifiers configuration and options
38142 * @returns {Object} The data object, properly modified
38143 */
38144function hide(data) {
38145  if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
38146    return data;
38147  }
38148
38149  var refRect = data.offsets.reference;
38150  var bound = find(data.instance.modifiers, function (modifier) {
38151    return modifier.name === 'preventOverflow';
38152  }).boundaries;
38153
38154  if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {
38155    // Avoid unnecessary DOM access if visibility hasn't changed
38156    if (data.hide === true) {
38157      return data;
38158    }
38159
38160    data.hide = true;
38161    data.attributes['x-out-of-boundaries'] = '';
38162  } else {
38163    // Avoid unnecessary DOM access if visibility hasn't changed
38164    if (data.hide === false) {
38165      return data;
38166    }
38167
38168    data.hide = false;
38169    data.attributes['x-out-of-boundaries'] = false;
38170  }
38171
38172  return data;
38173}
38174
38175/**
38176 * @function
38177 * @memberof Modifiers
38178 * @argument {Object} data - The data object generated by `update` method
38179 * @argument {Object} options - Modifiers configuration and options
38180 * @returns {Object} The data object, properly modified
38181 */
38182function inner(data) {
38183  var placement = data.placement;
38184  var basePlacement = placement.split('-')[0];
38185  var _data$offsets = data.offsets,
38186      popper = _data$offsets.popper,
38187      reference = _data$offsets.reference;
38188
38189  var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
38190
38191  var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
38192
38193  popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);
38194
38195  data.placement = getOppositePlacement(placement);
38196  data.offsets.popper = getClientRect(popper);
38197
38198  return data;
38199}
38200
38201/**
38202 * Modifier function, each modifier can have a function of this type assigned
38203 * to its `fn` property.<br />
38204 * These functions will be called on each update, this means that you must
38205 * make sure they are performant enough to avoid performance bottlenecks.
38206 *
38207 * @function ModifierFn
38208 * @argument {dataObject} data - The data object generated by `update` method
38209 * @argument {Object} options - Modifiers configuration and options
38210 * @returns {dataObject} The data object, properly modified
38211 */
38212
38213/**
38214 * Modifiers are plugins used to alter the behavior of your poppers.<br />
38215 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities
38216 * needed by the library.
38217 *
38218 * Usually you don't want to override the `order`, `fn` and `onLoad` props.
38219 * All the other properties are configurations that could be tweaked.
38220 * @namespace modifiers
38221 */
38222var modifiers = {
38223  /**
38224   * Modifier used to shift the popper on the start or end of its reference
38225   * element.<br />
38226   * It will read the variation of the `placement` property.<br />
38227   * It can be one either `-end` or `-start`.
38228   * @memberof modifiers
38229   * @inner
38230   */
38231  shift: {
38232    /** @prop {number} order=100 - Index used to define the order of execution */
38233    order: 100,
38234    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
38235    enabled: true,
38236    /** @prop {ModifierFn} */
38237    fn: shift
38238  },
38239
38240  /**
38241   * The `offset` modifier can shift your popper on both its axis.
38242   *
38243   * It accepts the following units:
38244   * - `px` or unit-less, interpreted as pixels
38245   * - `%` or `%r`, percentage relative to the length of the reference element
38246   * - `%p`, percentage relative to the length of the popper element
38247   * - `vw`, CSS viewport width unit
38248   * - `vh`, CSS viewport height unit
38249   *
38250   * For length is intended the main axis relative to the placement of the popper.<br />
38251   * This means that if the placement is `top` or `bottom`, the length will be the
38252   * `width`. In case of `left` or `right`, it will be the `height`.
38253   *
38254   * You can provide a single value (as `Number` or `String`), or a pair of values
38255   * as `String` divided by a comma or one (or more) white spaces.<br />
38256   * The latter is a deprecated method because it leads to confusion and will be
38257   * removed in v2.<br />
38258   * Additionally, it accepts additions and subtractions between different units.
38259   * Note that multiplications and divisions aren't supported.
38260   *
38261   * Valid examples are:
38262   * ```
38263   * 10
38264   * '10%'
38265   * '10, 10'
38266   * '10%, 10'
38267   * '10 + 10%'
38268   * '10 - 5vh + 3%'
38269   * '-10px + 5vh, 5px - 6%'
38270   * ```
38271   * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap
38272   * > with their reference element, unfortunately, you will have to disable the `flip` modifier.
38273   * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).
38274   *
38275   * @memberof modifiers
38276   * @inner
38277   */
38278  offset: {
38279    /** @prop {number} order=200 - Index used to define the order of execution */
38280    order: 200,
38281    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
38282    enabled: true,
38283    /** @prop {ModifierFn} */
38284    fn: offset,
38285    /** @prop {Number|String} offset=0
38286     * The offset value as described in the modifier description
38287     */
38288    offset: 0
38289  },
38290
38291  /**
38292   * Modifier used to prevent the popper from being positioned outside the boundary.
38293   *
38294   * A scenario exists where the reference itself is not within the boundaries.<br />
38295   * We can say it has "escaped the boundaries" — or just "escaped".<br />
38296   * In this case we need to decide whether the popper should either:
38297   *
38298   * - detach from the reference and remain "trapped" in the boundaries, or
38299   * - if it should ignore the boundary and "escape with its reference"
38300   *
38301   * When `escapeWithReference` is set to`true` and reference is completely
38302   * outside its boundaries, the popper will overflow (or completely leave)
38303   * the boundaries in order to remain attached to the edge of the reference.
38304   *
38305   * @memberof modifiers
38306   * @inner
38307   */
38308  preventOverflow: {
38309    /** @prop {number} order=300 - Index used to define the order of execution */
38310    order: 300,
38311    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
38312    enabled: true,
38313    /** @prop {ModifierFn} */
38314    fn: preventOverflow,
38315    /**
38316     * @prop {Array} [priority=['left','right','top','bottom']]
38317     * Popper will try to prevent overflow following these priorities by default,
38318     * then, it could overflow on the left and on top of the `boundariesElement`
38319     */
38320    priority: ['left', 'right', 'top', 'bottom'],
38321    /**
38322     * @prop {number} padding=5
38323     * Amount of pixel used to define a minimum distance between the boundaries
38324     * and the popper. This makes sure the popper always has a little padding
38325     * between the edges of its container
38326     */
38327    padding: 5,
38328    /**
38329     * @prop {String|HTMLElement} boundariesElement='scrollParent'
38330     * Boundaries used by the modifier. Can be `scrollParent`, `window`,
38331     * `viewport` or any DOM element.
38332     */
38333    boundariesElement: 'scrollParent'
38334  },
38335
38336  /**
38337   * Modifier used to make sure the reference and its popper stay near each other
38338   * without leaving any gap between the two. Especially useful when the arrow is
38339   * enabled and you want to ensure that it points to its reference element.
38340   * It cares only about the first axis. You can still have poppers with margin
38341   * between the popper and its reference element.
38342   * @memberof modifiers
38343   * @inner
38344   */
38345  keepTogether: {
38346    /** @prop {number} order=400 - Index used to define the order of execution */
38347    order: 400,
38348    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
38349    enabled: true,
38350    /** @prop {ModifierFn} */
38351    fn: keepTogether
38352  },
38353
38354  /**
38355   * This modifier is used to move the `arrowElement` of the popper to make
38356   * sure it is positioned between the reference element and its popper element.
38357   * It will read the outer size of the `arrowElement` node to detect how many
38358   * pixels of conjunction are needed.
38359   *
38360   * It has no effect if no `arrowElement` is provided.
38361   * @memberof modifiers
38362   * @inner
38363   */
38364  arrow: {
38365    /** @prop {number} order=500 - Index used to define the order of execution */
38366    order: 500,
38367    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
38368    enabled: true,
38369    /** @prop {ModifierFn} */
38370    fn: arrow,
38371    /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */
38372    element: '[x-arrow]'
38373  },
38374
38375  /**
38376   * Modifier used to flip the popper's placement when it starts to overlap its
38377   * reference element.
38378   *
38379   * Requires the `preventOverflow` modifier before it in order to work.
38380   *
38381   * **NOTE:** this modifier will interrupt the current update cycle and will
38382   * restart it if it detects the need to flip the placement.
38383   * @memberof modifiers
38384   * @inner
38385   */
38386  flip: {
38387    /** @prop {number} order=600 - Index used to define the order of execution */
38388    order: 600,
38389    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
38390    enabled: true,
38391    /** @prop {ModifierFn} */
38392    fn: flip,
38393    /**
38394     * @prop {String|Array} behavior='flip'
38395     * The behavior used to change the popper's placement. It can be one of
38396     * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid
38397     * placements (with optional variations)
38398     */
38399    behavior: 'flip',
38400    /**
38401     * @prop {number} padding=5
38402     * The popper will flip if it hits the edges of the `boundariesElement`
38403     */
38404    padding: 5,
38405    /**
38406     * @prop {String|HTMLElement} boundariesElement='viewport'
38407     * The element which will define the boundaries of the popper position.
38408     * The popper will never be placed outside of the defined boundaries
38409     * (except if `keepTogether` is enabled)
38410     */
38411    boundariesElement: 'viewport',
38412    /**
38413     * @prop {Boolean} flipVariations=false
38414     * The popper will switch placement variation between `-start` and `-end` when
38415     * the reference element overlaps its boundaries.
38416     *
38417     * The original placement should have a set variation.
38418     */
38419    flipVariations: false,
38420    /**
38421     * @prop {Boolean} flipVariationsByContent=false
38422     * The popper will switch placement variation between `-start` and `-end` when
38423     * the popper element overlaps its reference boundaries.
38424     *
38425     * The original placement should have a set variation.
38426     */
38427    flipVariationsByContent: false
38428  },
38429
38430  /**
38431   * Modifier used to make the popper flow toward the inner of the reference element.
38432   * By default, when this modifier is disabled, the popper will be placed outside
38433   * the reference element.
38434   * @memberof modifiers
38435   * @inner
38436   */
38437  inner: {
38438    /** @prop {number} order=700 - Index used to define the order of execution */
38439    order: 700,
38440    /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */
38441    enabled: false,
38442    /** @prop {ModifierFn} */
38443    fn: inner
38444  },
38445
38446  /**
38447   * Modifier used to hide the popper when its reference element is outside of the
38448   * popper boundaries. It will set a `x-out-of-boundaries` attribute which can
38449   * be used to hide with a CSS selector the popper when its reference is
38450   * out of boundaries.
38451   *
38452   * Requires the `preventOverflow` modifier before it in order to work.
38453   * @memberof modifiers
38454   * @inner
38455   */
38456  hide: {
38457    /** @prop {number} order=800 - Index used to define the order of execution */
38458    order: 800,
38459    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
38460    enabled: true,
38461    /** @prop {ModifierFn} */
38462    fn: hide
38463  },
38464
38465  /**
38466   * Computes the style that will be applied to the popper element to gets
38467   * properly positioned.
38468   *
38469   * Note that this modifier will not touch the DOM, it just prepares the styles
38470   * so that `applyStyle` modifier can apply it. This separation is useful
38471   * in case you need to replace `applyStyle` with a custom implementation.
38472   *
38473   * This modifier has `850` as `order` value to maintain backward compatibility
38474   * with previous versions of Popper.js. Expect the modifiers ordering method
38475   * to change in future major versions of the library.
38476   *
38477   * @memberof modifiers
38478   * @inner
38479   */
38480  computeStyle: {
38481    /** @prop {number} order=850 - Index used to define the order of execution */
38482    order: 850,
38483    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
38484    enabled: true,
38485    /** @prop {ModifierFn} */
38486    fn: computeStyle,
38487    /**
38488     * @prop {Boolean} gpuAcceleration=true
38489     * If true, it uses the CSS 3D transformation to position the popper.
38490     * Otherwise, it will use the `top` and `left` properties
38491     */
38492    gpuAcceleration: true,
38493    /**
38494     * @prop {string} [x='bottom']
38495     * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.
38496     * Change this if your popper should grow in a direction different from `bottom`
38497     */
38498    x: 'bottom',
38499    /**
38500     * @prop {string} [x='left']
38501     * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.
38502     * Change this if your popper should grow in a direction different from `right`
38503     */
38504    y: 'right'
38505  },
38506
38507  /**
38508   * Applies the computed styles to the popper element.
38509   *
38510   * All the DOM manipulations are limited to this modifier. This is useful in case
38511   * you want to integrate Popper.js inside a framework or view library and you
38512   * want to delegate all the DOM manipulations to it.
38513   *
38514   * Note that if you disable this modifier, you must make sure the popper element
38515   * has its position set to `absolute` before Popper.js can do its work!
38516   *
38517   * Just disable this modifier and define your own to achieve the desired effect.
38518   *
38519   * @memberof modifiers
38520   * @inner
38521   */
38522  applyStyle: {
38523    /** @prop {number} order=900 - Index used to define the order of execution */
38524    order: 900,
38525    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
38526    enabled: true,
38527    /** @prop {ModifierFn} */
38528    fn: applyStyle,
38529    /** @prop {Function} */
38530    onLoad: applyStyleOnLoad,
38531    /**
38532     * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier
38533     * @prop {Boolean} gpuAcceleration=true
38534     * If true, it uses the CSS 3D transformation to position the popper.
38535     * Otherwise, it will use the `top` and `left` properties
38536     */
38537    gpuAcceleration: undefined
38538  }
38539};
38540
38541/**
38542 * The `dataObject` is an object containing all the information used by Popper.js.
38543 * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
38544 * @name dataObject
38545 * @property {Object} data.instance The Popper.js instance
38546 * @property {String} data.placement Placement applied to popper
38547 * @property {String} data.originalPlacement Placement originally defined on init
38548 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
38549 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper
38550 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
38551 * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)
38552 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)
38553 * @property {Object} data.boundaries Offsets of the popper boundaries
38554 * @property {Object} data.offsets The measurements of popper, reference and arrow elements
38555 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
38556 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
38557 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0
38558 */
38559
38560/**
38561 * Default options provided to Popper.js constructor.<br />
38562 * These can be overridden using the `options` argument of Popper.js.<br />
38563 * To override an option, simply pass an object with the same
38564 * structure of the `options` object, as the 3rd argument. For example:
38565 * ```
38566 * new Popper(ref, pop, {
38567 *   modifiers: {
38568 *     preventOverflow: { enabled: false }
38569 *   }
38570 * })
38571 * ```
38572 * @type {Object}
38573 * @static
38574 * @memberof Popper
38575 */
38576var Defaults = {
38577  /**
38578   * Popper's placement.
38579   * @prop {Popper.placements} placement='bottom'
38580   */
38581  placement: 'bottom',
38582
38583  /**
38584   * Set this to true if you want popper to position it self in 'fixed' mode
38585   * @prop {Boolean} positionFixed=false
38586   */
38587  positionFixed: false,
38588
38589  /**
38590   * Whether events (resize, scroll) are initially enabled.
38591   * @prop {Boolean} eventsEnabled=true
38592   */
38593  eventsEnabled: true,
38594
38595  /**
38596   * Set to true if you want to automatically remove the popper when
38597   * you call the `destroy` method.
38598   * @prop {Boolean} removeOnDestroy=false
38599   */
38600  removeOnDestroy: false,
38601
38602  /**
38603   * Callback called when the popper is created.<br />
38604   * By default, it is set to no-op.<br />
38605   * Access Popper.js instance with `data.instance`.
38606   * @prop {onCreate}
38607   */
38608  onCreate: function onCreate() {},
38609
38610  /**
38611   * Callback called when the popper is updated. This callback is not called
38612   * on the initialization/creation of the popper, but only on subsequent
38613   * updates.<br />
38614   * By default, it is set to no-op.<br />
38615   * Access Popper.js instance with `data.instance`.
38616   * @prop {onUpdate}
38617   */
38618  onUpdate: function onUpdate() {},
38619
38620  /**
38621   * List of modifiers used to modify the offsets before they are applied to the popper.
38622   * They provide most of the functionalities of Popper.js.
38623   * @prop {modifiers}
38624   */
38625  modifiers: modifiers
38626};
38627
38628/**
38629 * @callback onCreate
38630 * @param {dataObject} data
38631 */
38632
38633/**
38634 * @callback onUpdate
38635 * @param {dataObject} data
38636 */
38637
38638// Utils
38639// Methods
38640var Popper = function () {
38641  /**
38642   * Creates a new Popper.js instance.
38643   * @class Popper
38644   * @param {Element|referenceObject} reference - The reference element used to position the popper
38645   * @param {Element} popper - The HTML / XML element used as the popper
38646   * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)
38647   * @return {Object} instance - The generated Popper.js instance
38648   */
38649  function Popper(reference, popper) {
38650    var _this = this;
38651
38652    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
38653    classCallCheck(this, Popper);
38654
38655    this.scheduleUpdate = function () {
38656      return requestAnimationFrame(_this.update);
38657    };
38658
38659    // make update() debounced, so that it only runs at most once-per-tick
38660    this.update = debounce(this.update.bind(this));
38661
38662    // with {} we create a new object with the options inside it
38663    this.options = _extends({}, Popper.Defaults, options);
38664
38665    // init state
38666    this.state = {
38667      isDestroyed: false,
38668      isCreated: false,
38669      scrollParents: []
38670    };
38671
38672    // get reference and popper elements (allow jQuery wrappers)
38673    this.reference = reference && reference.jquery ? reference[0] : reference;
38674    this.popper = popper && popper.jquery ? popper[0] : popper;
38675
38676    // Deep merge modifiers options
38677    this.options.modifiers = {};
38678    Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
38679      _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});
38680    });
38681
38682    // Refactoring modifiers' list (Object => Array)
38683    this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
38684      return _extends({
38685        name: name
38686      }, _this.options.modifiers[name]);
38687    })
38688    // sort the modifiers by order
38689    .sort(function (a, b) {
38690      return a.order - b.order;
38691    });
38692
38693    // modifiers have the ability to execute arbitrary code when Popper.js get inited
38694    // such code is executed in the same order of its modifier
38695    // they could add new properties to their options configuration
38696    // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!
38697    this.modifiers.forEach(function (modifierOptions) {
38698      if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {
38699        modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);
38700      }
38701    });
38702
38703    // fire the first update to position the popper in the right place
38704    this.update();
38705
38706    var eventsEnabled = this.options.eventsEnabled;
38707    if (eventsEnabled) {
38708      // setup event listeners, they will take care of update the position in specific situations
38709      this.enableEventListeners();
38710    }
38711
38712    this.state.eventsEnabled = eventsEnabled;
38713  }
38714
38715  // We can't use class properties because they don't get listed in the
38716  // class prototype and break stuff like Sinon stubs
38717
38718
38719  createClass(Popper, [{
38720    key: 'update',
38721    value: function update$$1() {
38722      return update.call(this);
38723    }
38724  }, {
38725    key: 'destroy',
38726    value: function destroy$$1() {
38727      return destroy.call(this);
38728    }
38729  }, {
38730    key: 'enableEventListeners',
38731    value: function enableEventListeners$$1() {
38732      return enableEventListeners.call(this);
38733    }
38734  }, {
38735    key: 'disableEventListeners',
38736    value: function disableEventListeners$$1() {
38737      return disableEventListeners.call(this);
38738    }
38739
38740    /**
38741     * Schedules an update. It will run on the next UI update available.
38742     * @method scheduleUpdate
38743     * @memberof Popper
38744     */
38745
38746
38747    /**
38748     * Collection of utilities useful when writing custom modifiers.
38749     * Starting from version 1.7, this method is available only if you
38750     * include `popper-utils.js` before `popper.js`.
38751     *
38752     * **DEPRECATION**: This way to access PopperUtils is deprecated
38753     * and will be removed in v2! Use the PopperUtils module directly instead.
38754     * Due to the high instability of the methods contained in Utils, we can't
38755     * guarantee them to follow semver. Use them at your own risk!
38756     * @static
38757     * @private
38758     * @type {Object}
38759     * @deprecated since version 1.8
38760     * @member Utils
38761     * @memberof Popper
38762     */
38763
38764  }]);
38765  return Popper;
38766}();
38767
38768/**
38769 * The `referenceObject` is an object that provides an interface compatible with Popper.js
38770 * and lets you use it as replacement of a real DOM node.<br />
38771 * You can use this method to position a popper relatively to a set of coordinates
38772 * in case you don't have a DOM node to use as reference.
38773 *
38774 * ```
38775 * new Popper(referenceObject, popperNode);
38776 * ```
38777 *
38778 * NB: This feature isn't supported in Internet Explorer 10.
38779 * @name referenceObject
38780 * @property {Function} data.getBoundingClientRect
38781 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.
38782 * @property {number} data.clientWidth
38783 * An ES6 getter that will return the width of the virtual reference element.
38784 * @property {number} data.clientHeight
38785 * An ES6 getter that will return the height of the virtual reference element.
38786 */
38787
38788
38789Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;
38790Popper.placements = placements;
38791Popper.Defaults = Defaults;
38792
38793return Popper;
38794
38795})));
38796
38797
38798}
vendor: 6,571 bytes, lines 38798-39017
38798).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
38799},{}],16:[function(require,module,exports){
38800// shim for using process in browser
38801var process = module.exports = {};
38802
38803// cached from whatever global is present so that test runners that stub it
38804// don't break things.  But we need to wrap it in a try catch in case it is
38805// wrapped in strict mode code which doesn't define any globals.  It's inside a
38806// function because try/catches deoptimize in certain engines.
38807
38808var cachedSetTimeout;
38809var cachedClearTimeout;
38810
38811function defaultSetTimout() {
38812    throw new Error('setTimeout has not been defined');
38813}
38814function defaultClearTimeout () {
38815    throw new Error('clearTimeout has not been defined');
38816}
38817(function () {
38818    try {
38819        if (typeof setTimeout === 'function') {
38820            cachedSetTimeout = setTimeout;
38821        } else {
38822            cachedSetTimeout = defaultSetTimout;
38823        }
38824    } catch (e) {
38825        cachedSetTimeout = defaultSetTimout;
38826    }
38827    try {
38828        if (typeof clearTimeout === 'function') {
38829            cachedClearTimeout = clearTimeout;
38830        } else {
38831            cachedClearTimeout = defaultClearTimeout;
38832        }
38833    } catch (e) {
38834        cachedClearTimeout = defaultClearTimeout;
38835    }
38836} ())
38837function runTimeout(fun) {
38838    if (cachedSetTimeout === setTimeout) {
38839        //normal enviroments in sane situations
38840        return setTimeout(fun, 0);
38841    }
38842    // if setTimeout wasn't available but was latter defined
38843    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
38844        cachedSetTimeout = setTimeout;
38845        return setTimeout(fun, 0);
38846    }
38847    try {
38848        // when when somebody has screwed with setTimeout but no I.E. maddness
38849        return cachedSetTimeout(fun, 0);
38850    } catch(e){
38851        try {
38852            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
38853            return cachedSetTimeout.call(null, fun, 0);
38854        } catch(e){
38855            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
38856            return cachedSetTimeout.call(this, fun, 0);
38857        }
38858    }
38859
38860
38861}
38862function runClearTimeout(marker) {
38863    if (cachedClearTimeout === clearTimeout) {
38864        //normal enviroments in sane situations
38865        return clearTimeout(marker);
38866    }
38867    // if clearTimeout wasn't available but was latter defined
38868    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
38869        cachedClearTimeout = clearTimeout;
38870        return clearTimeout(marker);
38871    }
38872    try {
38873        // when when somebody has screwed with setTimeout but no I.E. maddness
38874        return cachedClearTimeout(marker);
38875    } catch (e){
38876        try {
38877            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
38878            return cachedClearTimeout.call(null, marker);
38879        } catch (e){
38880            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
38881            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
38882            return cachedClearTimeout.call(this, marker);
38883        }
38884    }
38885
38886
38887
38888}
38889var queue = [];
38890var draining = false;
38891var currentQueue;
38892var queueIndex = -1;
38893
38894function cleanUpNextTick() {
38895    if (!draining || !currentQueue) {
38896        return;
38897    }
38898    draining = false;
38899    if (currentQueue.length) {
38900        queue = currentQueue.concat(queue);
38901    } else {
38902        queueIndex = -1;
38903    }
38904    if (queue.length) {
38905        drainQueue();
38906    }
38907}
38908
38909function drainQueue() {
38910    if (draining) {
38911        return;
38912    }
38913    var timeout = runTimeout(cleanUpNextTick);
38914    draining = true;
38915
38916    var len = queue.length;
38917    while(len) {
38918        currentQueue = queue;
38919        queue = [];
38920        while (++queueIndex < len) {
38921            if (currentQueue) {
38922                currentQueue[queueIndex].run();
38923            }
38924        }
38925        queueIndex = -1;
38926        len = queue.length;
38927    }
38928    currentQueue = null;
38929    draining = false;
38930    runClearTimeout(timeout);
38931}
38932
38933process.nextTick = function (fun) {
38934    var args = new Array(arguments.length - 1);
38935    if (arguments.length > 1) {
38936        for (var i = 1; i < arguments.length; i++) {
38937            args[i - 1] = arguments[i];
38938        }
38939    }
38940    queue.push(new Item(fun, args));
38941    if (queue.length === 1 && !draining) {
38942        runTimeout(drainQueue);
38943    }
38944};
38945
38946// v8 likes predictible objects
38947function Item(fun, array) {
38948    this.fun = fun;
38949    this.array = array;
38950}
38951Item.prototype.run = function () {
38952    this.fun.apply(null, this.array);
38953};
38954process.title = 'browser';
38955process.browser = true;
38956process.env = {};
38957process.argv = [];
38958process.version = ''; // empty string to avoid regexp issues
38959process.versions = {};
38960
38961function noop() {}
38962
38963process.on = noop;
38964process.addListener = noop;
38965process.once = noop;
38966process.off = noop;
38967process.removeListener = noop;
38968process.removeAllListeners = noop;
38969process.emit = noop;
38970process.prependListener = noop;
38971process.prependOnceListener = noop;
38972
38973process.listeners = function (name) { return [] }
38974
38975process.binding = function (name) {
38976    throw new Error('process.binding is not supported');
38977};
38978
38979process.cwd = function () { return '/' };
38980process.chdir = function (dir) {
38981    throw new Error('process.chdir is not supported');
38982};
38983process.umask = function() { return 0; };
38984
38985},{}],17:[function(require,module,exports){
38986if (typeof Object.create === 'function') {
38987  // implementation from standard node.js 'util' module
38988  module.exports = function inherits(ctor, superCtor) {
38989    ctor.super_ = superCtor
38990    ctor.prototype = Object.create(superCtor.prototype, {
38991      constructor: {
38992        value: ctor,
38993        enumerable: false,
38994        writable: true,
38995        configurable: true
38996      }
38997    });
38998  };
38999} else {
39000  // old school shim for old browsers
39001  module.exports = function inherits(ctor, superCtor) {
39002    ctor.super_ = superCtor
39003    var TempCtor = function () {}
39004    TempCtor.prototype = superCtor.prototype
39005    ctor.prototype = new TempCtor()
39006    ctor.prototype.constructor = ctor
39007  }
39008}
39009
39010},{}],18:[function(require,module,exports){
39011module.exports = function isBuffer(arg) {
39012  return arg && typeof arg === 'object'
39013    && typeof arg.copy === 'function'
39014    && typeof arg.fill === 'function'
39015    && typeof arg.readUInt8 === 'function';
39016}
39017},{}],19
vendor: 15,808 bytes, lines 39017-39607
39017:[function(require,module,exports){
39018(function (process,global){
39019// Copyright Joyent, Inc. and other Node contributors.
39020//
39021// Permission is hereby granted, free of charge, to any person obtaining a
39022// copy of this software and associated documentation files (the
39023// "Software"), to deal in the Software without restriction, including
39024// without limitation the rights to use, copy, modify, merge, publish,
39025// distribute, sublicense, and/or sell copies of the Software, and to permit
39026// persons to whom the Software is furnished to do so, subject to the
39027// following conditions:
39028//
39029// The above copyright notice and this permission notice shall be included
39030// in all copies or substantial portions of the Software.
39031//
39032// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
39033// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39034// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
39035// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
39036// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
39037// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
39038// USE OR OTHER DEALINGS IN THE SOFTWARE.
39039
39040var formatRegExp = /%[sdj%]/g;
39041exports.format = function(f) {
39042  if (!isString(f)) {
39043    var objects = [];
39044    for (var i = 0; i < arguments.length; i++) {
39045      objects.push(inspect(arguments[i]));
39046    }
39047    return objects.join(' ');
39048  }
39049
39050  var i = 1;
39051  var args = arguments;
39052  var len = args.length;
39053  var str = String(f).replace(formatRegExp, function(x) {
39054    if (x === '%%') return '%';
39055    if (i >= len) return x;
39056    switch (x) {
39057      case '%s': return String(args[i++]);
39058      case '%d': return Number(args[i++]);
39059      case '%j':
39060        try {
39061          return JSON.stringify(args[i++]);
39062        } catch (_) {
39063          return '[Circular]';
39064        }
39065      default:
39066        return x;
39067    }
39068  });
39069  for (var x = args[i]; i < len; x = args[++i]) {
39070    if (isNull(x) || !isObject(x)) {
39071      str += ' ' + x;
39072    } else {
39073      str += ' ' + inspect(x);
39074    }
39075  }
39076  return str;
39077};
39078
39079
39080// Mark that a method should not be used.
39081// Returns a modified function which warns once by default.
39082// If --no-deprecation is set, then it is a no-op.
39083exports.deprecate = function(fn, msg) {
39084  // Allow for deprecating things in the process of starting up.
39085  if (isUndefined(global.process)) {
39086    return function() {
39087      return exports.deprecate(fn, msg).apply(this, arguments);
39088    };
39089  }
39090
39091  if (process.noDeprecation === true) {
39092    return fn;
39093  }
39094
39095  var warned = false;
39096  function deprecated() {
39097    if (!warned) {
39098      if (process.throwDeprecation) {
39099        throw new Error(msg);
39100      } else if (process.traceDeprecation) {
39101        console.trace(msg);
39102      } else {
39103        console.error(msg);
39104      }
39105      warned = true;
39106    }
39107    return fn.apply(this, arguments);
39108  }
39109
39110  return deprecated;
39111};
39112
39113
39114var debugs = {};
39115var debugEnviron;
39116exports.debuglog = function(set) {
39117  if (isUndefined(debugEnviron))
39118    debugEnviron = process.env.NODE_DEBUG || '';
39119  set = set.toUpperCase();
39120  if (!debugs[set]) {
39121    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
39122      var pid = process.pid;
39123      debugs[set] = function() {
39124        var msg = exports.format.apply(exports, arguments);
39125        console.error('%s %d: %s', set, pid, msg);
39126      };
39127    } else {
39128      debugs[set] = function() {};
39129    }
39130  }
39131  return debugs[set];
39132};
39133
39134
39135/**
39136 * Echos the value of a value. Trys to print the value out
39137 * in the best way possible given the different types.
39138 *
39139 * @param {Object} obj The object to print out.
39140 * @param {Object} opts Optional options object that alters the output.
39141 */
39142/* legacy: obj, showHidden, depth, colors*/
39143function inspect(obj, opts) {
39144  // default options
39145  var ctx = {
39146    seen: [],
39147    stylize: stylizeNoColor
39148  };
39149  // legacy...
39150  if (arguments.length >= 3) ctx.depth = arguments[2];
39151  if (arguments.length >= 4) ctx.colors = arguments[3];
39152  if (isBoolean(opts)) {
39153    // legacy...
39154    ctx.showHidden = opts;
39155  } else if (opts) {
39156    // got an "options" object
39157    exports._extend(ctx, opts);
39158  }
39159  // set default options
39160  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
39161  if (isUndefined(ctx.depth)) ctx.depth = 2;
39162  if (isUndefined(ctx.colors)) ctx.colors = false;
39163  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
39164  if (ctx.colors) ctx.stylize = stylizeWithColor;
39165  return formatValue(ctx, obj, ctx.depth);
39166}
39167exports.inspect = inspect;
39168
39169
39170// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
39171inspect.colors = {
39172  'bold' : [1, 22],
39173  'italic' : [3, 23],
39174  'underline' : [4, 24],
39175  'inverse' : [7, 27],
39176  'white' : [37, 39],
39177  'grey' : [90, 39],
39178  'black' : [30, 39],
39179  'blue' : [34, 39],
39180  'cyan' : [36, 39],
39181  'green' : [32, 39],
39182  'magenta' : [35, 39],
39183  'red' : [31, 39],
39184  'yellow' : [33, 39]
39185};
39186
39187// Don't use 'blue' not visible on cmd.exe
39188inspect.styles = {
39189  'special': 'cyan',
39190  'number': 'yellow',
39191  'boolean': 'yellow',
39192  'undefined': 'grey',
39193  'null': 'bold',
39194  'string': 'green',
39195  'date': 'magenta',
39196  // "name": intentionally not styling
39197  'regexp': 'red'
39198};
39199
39200
39201function stylizeWithColor(str, styleType) {
39202  var style = inspect.styles[styleType];
39203
39204  if (style) {
39205    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
39206           '\u001b[' + inspect.colors[style][1] + 'm';
39207  } else {
39208    return str;
39209  }
39210}
39211
39212
39213function stylizeNoColor(str, styleType) {
39214  return str;
39215}
39216
39217
39218function arrayToHash(array) {
39219  var hash = {};
39220
39221  array.forEach(function(val, idx) {
39222    hash[val] = true;
39223  });
39224
39225  return hash;
39226}
39227
39228
39229function formatValue(ctx, value, recurseTimes) {
39230  // Provide a hook for user-specified inspect functions.
39231  // Check that value is an object with an inspect function on it
39232  if (ctx.customInspect &&
39233      value &&
39234      isFunction(value.inspect) &&
39235      // Filter out the util module, it's inspect function is special
39236      value.inspect !== exports.inspect &&
39237      // Also filter out any prototype objects using the circular check.
39238      !(value.constructor && value.constructor.prototype === value)) {
39239    var ret = value.inspect(recurseTimes, ctx);
39240    if (!isString(ret)) {
39241      ret = formatValue(ctx, ret, recurseTimes);
39242    }
39243    return ret;
39244  }
39245
39246  // Primitive types cannot have properties
39247  var primitive = formatPrimitive(ctx, value);
39248  if (primitive) {
39249    return primitive;
39250  }
39251
39252  // Look up the keys of the object.
39253  var keys = Object.keys(value);
39254  var visibleKeys = arrayToHash(keys);
39255
39256  if (ctx.showHidden) {
39257    keys = Object.getOwnPropertyNames(value);
39258  }
39259
39260  // IE doesn't make error fields non-enumerable
39261  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
39262  if (isError(value)
39263      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
39264    return formatError(value);
39265  }
39266
39267  // Some type of object without properties can be shortcutted.
39268  if (keys.length === 0) {
39269    if (isFunction(value)) {
39270      var name = value.name ? ': ' + value.name : '';
39271      return ctx.stylize('[Function' + name + ']', 'special');
39272    }
39273    if (isRegExp(value)) {
39274      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
39275    }
39276    if (isDate(value)) {
39277      return ctx.stylize(Date.prototype.toString.call(value), 'date');
39278    }
39279    if (isError(value)) {
39280      return formatError(value);
39281    }
39282  }
39283
39284  var base = '', array = false, braces = ['{', '}'];
39285
39286  // Make Array say that they are Array
39287  if (isArray(value)) {
39288    array = true;
39289    braces = ['[', ']'];
39290  }
39291
39292  // Make functions say that they are functions
39293  if (isFunction(value)) {
39294    var n = value.name ? ': ' + value.name : '';
39295    base = ' [Function' + n + ']';
39296  }
39297
39298  // Make RegExps say that they are RegExps
39299  if (isRegExp(value)) {
39300    base = ' ' + RegExp.prototype.toString.call(value);
39301  }
39302
39303  // Make dates with properties first say the date
39304  if (isDate(value)) {
39305    base = ' ' + Date.prototype.toUTCString.call(value);
39306  }
39307
39308  // Make error with message first say the error
39309  if (isError(value)) {
39310    base = ' ' + formatError(value);
39311  }
39312
39313  if (keys.length === 0 && (!array || value.length == 0)) {
39314    return braces[0] + base + braces[1];
39315  }
39316
39317  if (recurseTimes < 0) {
39318    if (isRegExp(value)) {
39319      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
39320    } else {
39321      return ctx.stylize('[Object]', 'special');
39322    }
39323  }
39324
39325  ctx.seen.push(value);
39326
39327  var output;
39328  if (array) {
39329    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
39330  } else {
39331    output = keys.map(function(key) {
39332      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
39333    });
39334  }
39335
39336  ctx.seen.pop();
39337
39338  return reduceToSingleString(output, base, braces);
39339}
39340
39341
39342function formatPrimitive(ctx, value) {
39343  if (isUndefined(value))
39344    return ctx.stylize('undefined', 'undefined');
39345  if (isString(value)) {
39346    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
39347                                             .replace(/'/g, "\\'")
39348                                             .replace(/\\"/g, '"') + '\'';
39349    return ctx.stylize(simple, 'string');
39350  }
39351  if (isNumber(value))
39352    return ctx.stylize('' + value, 'number');
39353  if (isBoolean(value))
39354    return ctx.stylize('' + value, 'boolean');
39355  // For some reason typeof null is "object", so special case here.
39356  if (isNull(value))
39357    return ctx.stylize('null', 'null');
39358}
39359
39360
39361function formatError(value) {
39362  return '[' + Error.prototype.toString.call(value) + ']';
39363}
39364
39365
39366function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
39367  var output = [];
39368  for (var i = 0, l = value.length; i < l; ++i) {
39369    if (hasOwnProperty(value, String(i))) {
39370      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
39371          String(i), true));
39372    } else {
39373      output.push('');
39374    }
39375  }
39376  keys.forEach(function(key) {
39377    if (!key.match(/^\d+$/)) {
39378      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
39379          key, true));
39380    }
39381  });
39382  return output;
39383}
39384
39385
39386function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
39387  var name, str, desc;
39388  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
39389  if (desc.get) {
39390    if (desc.set) {
39391      str = ctx.stylize('[Getter/Setter]', 'special');
39392    } else {
39393      str = ctx.stylize('[Getter]', 'special');
39394    }
39395  } else {
39396    if (desc.set) {
39397      str = ctx.stylize('[Setter]', 'special');
39398    }
39399  }
39400  if (!hasOwnProperty(visibleKeys, key)) {
39401    name = '[' + key + ']';
39402  }
39403  if (!str) {
39404    if (ctx.seen.indexOf(desc.value) < 0) {
39405      if (isNull(recurseTimes)) {
39406        str = formatValue(ctx, desc.value, null);
39407      } else {
39408        str = formatValue(ctx, desc.value, recurseTimes - 1);
39409      }
39410      if (str.indexOf('\n') > -1) {
39411        if (array) {
39412          str = str.split('\n').map(function(line) {
39413            return '  ' + line;
39414          }).join('\n').substr(2);
39415        } else {
39416          str = '\n' + str.split('\n').map(function(line) {
39417            return '   ' + line;
39418          }).join('\n');
39419        }
39420      }
39421    } else {
39422      str = ctx.stylize('[Circular]', 'special');
39423    }
39424  }
39425  if (isUndefined(name)) {
39426    if (array && key.match(/^\d+$/)) {
39427      return str;
39428    }
39429    name = JSON.stringify('' + key);
39430    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
39431      name = name.substr(1, name.length - 2);
39432      name = ctx.stylize(name, 'name');
39433    } else {
39434      name = name.replace(/'/g, "\\'")
39435                 .replace(/\\"/g, '"')
39436                 .replace(/(^"|"$)/g, "'");
39437      name = ctx.stylize(name, 'string');
39438    }
39439  }
39440
39441  return name + ': ' + str;
39442}
39443
39444
39445function reduceToSingleString(output, base, braces) {
39446  var numLinesEst = 0;
39447  var length = output.reduce(function(prev, cur) {
39448    numLinesEst++;
39449    if (cur.indexOf('\n') >= 0) numLinesEst++;
39450    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
39451  }, 0);
39452
39453  if (length > 60) {
39454    return braces[0] +
39455           (base === '' ? '' : base + '\n ') +
39456           ' ' +
39457           output.join(',\n  ') +
39458           ' ' +
39459           braces[1];
39460  }
39461
39462  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
39463}
39464
39465
39466// NOTE: These type checking functions intentionally don't use `instanceof`
39467// because it is fragile and can be easily faked with `Object.create()`.
39468function isArray(ar) {
39469  return Array.isArray(ar);
39470}
39471exports.isArray = isArray;
39472
39473function isBoolean(arg) {
39474  return typeof arg === 'boolean';
39475}
39476exports.isBoolean = isBoolean;
39477
39478function isNull(arg) {
39479  return arg === null;
39480}
39481exports.isNull = isNull;
39482
39483function isNullOrUndefined(arg) {
39484  return arg == null;
39485}
39486exports.isNullOrUndefined = isNullOrUndefined;
39487
39488function isNumber(arg) {
39489  return typeof arg === 'number';
39490}
39491exports.isNumber = isNumber;
39492
39493function isString(arg) {
39494  return typeof arg === 'string';
39495}
39496exports.isString = isString;
39497
39498function isSymbol(arg) {
39499  return typeof arg === 'symbol';
39500}
39501exports.isSymbol = isSymbol;
39502
39503function isUndefined(arg) {
39504  return arg === void 0;
39505}
39506exports.isUndefined = isUndefined;
39507
39508function isRegExp(re) {
39509  return isObject(re) && objectToString(re) === '[object RegExp]';
39510}
39511exports.isRegExp = isRegExp;
39512
39513function isObject(arg) {
39514  return typeof arg === 'object' && arg !== null;
39515}
39516exports.isObject = isObject;
39517
39518function isDate(d) {
39519  return isObject(d) && objectToString(d) === '[object Date]';
39520}
39521exports.isDate = isDate;
39522
39523function isError(e) {
39524  return isObject(e) &&
39525      (objectToString(e) === '[object Error]' || e instanceof Error);
39526}
39527exports.isError = isError;
39528
39529function isFunction(arg) {
39530  return typeof arg === 'function';
39531}
39532exports.isFunction = isFunction;
39533
39534function isPrimitive(arg) {
39535  return arg === null ||
39536         typeof arg === 'boolean' ||
39537         typeof arg === 'number' ||
39538         typeof arg === 'string' ||
39539         typeof arg === 'symbol' ||  // ES6 symbol
39540         typeof arg === 'undefined';
39541}
39542exports.isPrimitive = isPrimitive;
39543
39544exports.isBuffer = require('./support/isBuffer');
39545
39546function objectToString(o) {
39547  return Object.prototype.toString.call(o);
39548}
39549
39550
39551function pad(n) {
39552  return n < 10 ? '0' + n.toString(10) : n.toString(10);
39553}
39554
39555
39556var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
39557              'Oct', 'Nov', 'Dec'];
39558
39559// 26 Feb 16:19:34
39560function timestamp() {
39561  var d = new Date();
39562  var time = [pad(d.getHours()),
39563              pad(d.getMinutes()),
39564              pad(d.getSeconds())].join(':');
39565  return [d.getDate(), months[d.getMonth()], time].join(' ');
39566}
39567
39568
39569// log is just a thin wrapper to console.log that prepends a timestamp
39570exports.log = function() {
39571  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
39572};
39573
39574
39575/**
39576 * Inherit the prototype methods from one constructor into another.
39577 *
39578 * The Function.prototype.inherits from lang.js rewritten as a standalone
39579 * function (not on Function.prototype). NOTE: If this file is to be loaded
39580 * during bootstrapping this function needs to be rewritten using some native
39581 * functions as prototype setup using normal JavaScript does not work as
39582 * expected during bootstrapping (see mirror.js in r114903).
39583 *
39584 * @param {function} ctor Constructor function which needs to inherit the
39585 *     prototype.
39586 * @param {function} superCtor Constructor function to inherit prototype from.
39587 */
39588exports.inherits = require('inherits');
39589
39590exports._extend = function(origin, add) {
39591  // Don't do anything if add isn't an object
39592  if (!add || !isObject(add)) return origin;
39593
39594  var keys = Object.keys(add);
39595  var i = keys.length;
39596  while (i--) {
39597    origin[keys[i]] = add[keys[i]];
39598  }
39599  return origin;
39600};
39601
39602function hasOwnProperty(obj, prop) {
39603  return Object.prototype.hasOwnProperty.call(obj, prop);
39604}
39605
39606}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
39607},{"./support/isBuffer":
3960718,"_process":16,"inherits":17}],20:[function(require,module,exports){
39608"use strict";
39609Object.defineProperty(exports, "__esModule", { value: true });
39610const util_1 = require("util");
39611window.addEventListener("DOMContentLoaded", function () {
39612    const deleting = (el) => {
39613        // return function since this is a callback
39614        return function () {
39615            if (document.getElementsByName(document.getElementById(el.getAttribute("id").replace(/(delButton)/, "div")).getAttribute("name")).length !== 1) {
39616                const form = document.getElementById("update");
39617                const div = document.getElementById(el.getAttribute("id").replace(/(delButton)/, "div"));
39618                form.removeChild(div);
39619            }
39620        };
39621    };
39622    const adding = (el) => {
39623        // return function since this is a callback
39624        return function () {
39625            const idOfDiv = el.getAttribute("id").replace(/(addButton)/, "div");
39626            const div = document.getElementById(idOfDiv);
39627            const newDiv = div.cloneNode(true);
39628            // Find the number in the id and cast to number
39629            let stringNumbers = "";
39630            idOfDiv.match(/([0-9]+)/g).forEach((element) => {
39631                stringNumbers += element;
39632            });
39633            let number = Number(stringNumbers);
39634            // Create a unique id. Must check if the number is occupied by anyone else. If it is then increment until an unoccupied id is found. 
39635            while (!util_1.isNullOrUndefined(document.getElementById(idOfDiv.replace(stringNumbers, String(number))))) {
39636                number = number + 1;
39637            }
39638            // Replace ids for the elements
39639            // Unfortunately div is a node and children of elements are nodes. A workaround is to find any of their children and go back to the parentElement since this is an element. Very messy
39640            newDiv.firstChild.parentElement.setAttribute("id", idOfDiv.replace(stringNumbers, String(number)));
39641            newDiv.childNodes[1].childNodes[0].firstChild.parentElement.setAttribute("id", idOfDiv.replace(stringNumbers + "div", String(number)));
39642            newDiv.childNodes[2].childNodes[0].firstChild.parentElement.setAttribute("id", idOfDiv.replace(stringNumbers + "div", String(number) + "addButton"));
39643            newDiv.childNodes[2].childNodes[0].firstChild.parentElement.addEventListener("click", adding(newDiv.childNodes[2].childNodes[0].firstChild.parentElement));
39644            newDiv.childNodes[2].childNodes[2].firstChild.parentElement.setAttribute("id", idOfDiv.replace(stringNumbers + "div", String(number) + "delButton"));
39645            newDiv.childNodes[2].childNodes[2].firstChild.parentElement.addEventListener("click", deleting(newDiv.childNodes[2].childNodes[2].firstChild.parentElement));
39646            div.parentNode.insertBefore(newDiv, div.nextSibling);
39647        };
39648    };
39649    // const removeUser = (el: HTMLElement) => {
39650    // 	console.log("Setup: " + el.id);
39651    // 	return function() {
39652    // 		console.log("Cicked: " + el.id);
39653    // 	};
39654    // };
39655    const addElements = document.getElementsByName("addButton");
39656    Array.prototype.forEach.call(addElements, function (el) {
39657        el.addEventListener("click", adding(el));
39658    });
39659    const delElements = document.getElementsByName("delButton");
39660    Array.prototype.forEach.call(delElements, function (el) {
39661        el.addEventListener("click", deleting(el));
39662    });
39663    // const removeUserButtons = document.getElementsByName("removeButton");
39664    // Array.prototype.forEach.call(removeUserButtons, function(el: HTMLElement) {
39665    // 	el.addEventListener("click", removeUser(el));
39666    // });
39667});
39668
39669},{"util":19}],21:[function(require,module,exports){
39670"use strict";
39671var __importDefault = (this && this.__importDefault) || function (mod) {
39672    return (mod && mod.__esModule) ? mod : { "default": mod };
39673};
39674Object.defineProperty(exports, "__esModule", { value: true });
39675const aos_1 = __importDefault(require("aos"));
39676// Animate elements on your page as you scroll
39677aos_1.default.init();
39678
39679},{"aos":9}],22:[function(require,module,exports){
39680"use strict";
39681var __importDefault = (this && this.__importDefault) || function (mod) {
39682    return (mod && mod.__esModule) ? mod : { "default": mod };
39683};
39684Object.defineProperty(exports, "__esModule", { value: true });
39685const blazy_1 = __importDefault(require("blazy"));
39686// Lazy loading and multi-serving images
39687new blazy_1.default({
39688    breakpoints: [{
39689            width: 420 // Max-width
39690            ,
39691            src: "data-src-small"
39692        }],
39693    success: (element) => {
39694        setTimeout(function () {
39695            // We want to remove the loader gif now.
39696            // First we find the parent container
39697            // then we remove the "loading" class which holds the loader image
39698            const parent = element.parentNode;
39699            parent.className = parent.className.replace(/\bloading\b/, "");
39700        }, 200);
39701    }
39702});
39703
39704},{"blazy":10}],23:[function(require,module,exports){
39705"use strict";
39706var __importDefault = (this && this.__importDefault) || function (mod) {
39707    return (mod && mod.__esModule) ? mod : { "default": mod };
39708};
39709Object.defineProperty(exports, "__esModule", { value: true });
39710const moment_1 = require("moment");
39711const core_1 = require("@fullcalendar/core");
39712const interaction_1 = __importDefault(require("@fullcalendar/interaction"));
39713const daygrid_1 = __importDefault(require("@fullcalendar/daygrid"));
39714const timegrid_1 = __importDefault(require("@fullcalendar/timegrid"));
39715const list_1 = __importDefault(require("@fullcalendar/list"));
39716const bootstrap_1 = __importDefault(require("@fullcalendar/bootstrap"));
39717const moment_2 = __importDefault(require("@fullcalendar/moment"));
39718const google_calendar_1 = __importDefault(require("@fullcalendar/google-calendar"));
39719const util_1 = require("util");
39720const jquery_1 = __importDefault(require("jquery"));
39721require("daterangepicker");
39722require("bootstrap");
39723document.addEventListener("DOMContentLoaded", function () {
39724    if (!util_1.isNullOrUndefined(document.getElementById("calendar"))) {
39725        const calendarEl = document.getElementById("calendar");
39726        const calendar = new core_1.Calendar(calendarEl, {
39727            plugins: [interaction_1.default, daygrid_1.default, timegrid_1.default, list_1.default, bootstrap_1.default, moment_2.default, google_calendar_1.default],
39728            themeSystem: "bootstrap",
39729            locale: document.getElementById("language").getAttribute("value").toString() === "da" ? "da" : "en",
39730            timeZone: "Europe/Copenhagen",
39731            googleCalendarApiKey: "AIzaSyD8flgO6cGM0jTra1m21Fk06ryIzF1lqg8",
39732            header: {
39733                left: "prev,next today",
39734                center: "title",
39735                right: "dayGridMonth,timeGridWeek,listWeek"
39736            },
39737            firstDay: 1,
39738            navLinks: true,
39739            selectable: true,
39740            eventLimit: true,
39741            eventSources: [
39742                JSON.parse(document.getElementById("variableName").getAttribute("value").toString()),
39743                (document.getElementById("googleCalID").getAttribute("value") ? {
39744                    googleCalendarId: document.getElementById("googleCalID").getAttribute("value")
39745                } : {})
39746            ],
39747            eventRender: (info) => {
39748                info.el.setAttribute("data-toggle", "modal");
39749                info.el.setAttribute("data-target", "#fullCalModal");
39750            },
39751            select: (info) => {
39752                jquery_1.default("#createEventModal").modal("show");
39753                document.getElementById("eventStartDate").setAttribute("value", moment_1.utc(info.start).format("DD/MM/YYYY, HH:mm"));
39754                document.getElementById("eventEndDate").setAttribute("value", moment_1.utc(info.end).format("DD/MM/YYYY, HH:mm"));
39755                document.getElementById("eventPlace").setAttribute("value", document.getElementById("placeDisplay").getAttribute("value").toString());
39756                jquery_1.default("input[name='eventStartDate']").daterangepicker({
39757                    singleDatePicker: true,
39758                    timePicker: true,
39759                    timePicker24Hour: true,
39760                    locale: {
39761                        format: "DD/MM/YYYY, HH:mm"
39762                    },
39763                    startDate: info.start
39764                });
39765                jquery_1.default("input[name='eventEndDate']").daterangepicker({
39766                    singleDatePicker: true,
39767                    timePicker: true,
39768                    timePicker24Hour: true,
39769                    locale: {
39770                        format: "DD/MM/YYYY, HH:mm"
39771                    },
39772                    startDate: info.end
39773                });
39774                jquery_1.default("input[name='eventStartDate'],input[name='eventEndDate']").on("apply.daterangepicker", (ev, picker) => {
39775                    jquery_1.default(this).val(picker.startDate.format("DD/MM/YYYY, HH:mm"));
39776                });
39777            },
39778            eventClick: (info) => {
39779                console.log(info.event);
39780                document.getElementById("modalTitle").innerHTML = info.event.title;
39781                document.getElementById("showId").setAttribute("value", info.event.id);
39782                info.event.extendedProps.description ? document.getElementById("showDescription").setAttribute("value", info.event.extendedProps.description) : document.getElementById("showDescription").setAttribute("value", info.event.url);
39783                document.getElementById("showStartDate").setAttribute("value", moment_1.utc(info.event.start, "DD/MM/YYYY, HH:mm").format("DD/MM/YYYY, HH:mm"));
39784                document.getElementById("showEndDate").setAttribute("value", moment_1.utc(info.event.end, "DD/MM/YYYY, HH:mm").format("DD/MM/YYYY, HH:mm"));
39785                info.event.extendedProps.name ? document.getElementById("showUser").setAttribute("value", info.event.extendedProps.name) : document.getElementById("showUser").setAttribute("value", "");
39786            }
39787        });
39788        jquery_1.default("#removeEventButton").click(function () {
39789            jquery_1.default("#removeEvent").submit();
39790        });
39791        jquery_1.default("#addEventButton").click(function () {
39792            jquery_1.default("#addEvent").submit();
39793        });
39794        calendar.render();
39795    }
39796});
39797
39798},{"@fullcalendar/bootstrap":1,"@fullcalendar/core":2,"@fullcalendar/daygri
39798d":3,"@fullcalendar/google-calendar":4,"@fullcalendar/interaction":5,"@fullcalendar/list":6,"@fullcalendar/moment":7,"@fullcalendar/timegrid":8,"bootstrap":11,"daterangepicker":12,"jquery":13,"moment":14,"util":19}],24:[function(require,module,exports){
39799"use strict";
39800var __importDefault = (this && this.__importDefault) || function (mod) {
39801    return (mod && mod.__esModule) ? mod : { "default": mod };
39802};
39803Object.defineProperty(exports, "__esModule", { value: true });
39804const moment_1 = __importDefault(require("moment"));
39805const jquery_1 = __importDefault(require("jquery"));
39806require("daterangepicker");
39807moment_1.default.locale(window.navigator.language);
39808jquery_1.default("input[name='birthDay'],input[name='movedInDate']").daterangepicker({
39809    singleDatePicker: true,
39810    locale: {
39811        format: "DD/MM/YYYY"
39812    }
39813});
39814jquery_1.default("input[name='birthDay'],input[name='movedInDate']").on("apply.daterangepicker", (ev, picker) => {
39815    picker.startDate.locale(window.navigator.language);
39816    jquery_1.default(this).val(picker.startDate.format("DD/MM/YYYY"));
39817});
39818jquery_1.default("input[name='birthDay'],input[name='movedInDate']").on("cancel.daterangepicker", (ev, picker) => {
39819    jquery_1.default(this).val("");
39820});
39821
39822},{"daterangepicker":12,"jquery":13,"moment":14}],25:[function(require,module,exports){
39823"use strict";
39824Object.defineProperty(exports, "__esModule", { value: true });
39825const util_1 = require("util");
39826window.onload = function () {
39827    if (!util_1.isNullOrUndefined(document.getElementById("googleMap"))) {
39828        const styledMapType = new google.maps.StyledMapType([
39829            {
39830                elementType: "geometry", stylers: [{ color: "#ebe3cd" }]
39831            },
39832            {
39833                elementType: "labels.text.fill", stylers: [{ color: "#523735" }]
39834            },
39835            {
39836                elementType: "labels.text.stroke", stylers: [{ color: "#f5f1e6" }]
39837            },
39838            {
39839                featureType: "administrative",
39840                elementType: "geometry.stroke",
39841                stylers: [{ color: "#c9b2a6" }]
39842            },
39843            {
39844                featureType: "administrative.land_parcel",
39845                elementType: "geometry.stroke",
39846                stylers: [{ color: "#dcd2be" }]
39847            },
39848            {
39849                featureType: "administrative.land_parcel",
39850                elementType: "labels.text.fill",
39851                stylers: [{ color: "#ae9e90" }]
39852            },
39853            {
39854                featureType: "landscape.natural",
39855                elementType: "geometry",
39856                stylers: [{ color: "#dfd2ae" }]
39857            },
39858            {
39859                featureType: "poi",
39860                elementType: "geometry",
39861                stylers: [{ color: "#dfd2ae" }]
39862            },
39863            {
39864                featureType: "poi",
39865                elementType: "labels.text.fill",
39866                stylers: [{ color: "#93817c" }]
39867            },
39868            {
39869                featureType: "poi.park",
39870                elementType: "geometry.fill",
39871                stylers: [{ color: "#a5b076" }]
39872            },
39873            {
39874                featureType: "poi.park",
39875                elementType: "labels.text.fill",
39876                stylers: [{ color: "#447530" }]
39877            },
39878            {
39879                featureType: "road",
39880                elementType: "geometry",
39881                stylers: [{ color: "#f5f1e6" }]
39882            },
39883            {
39884                featureType: "road.arterial",
39885                elementType: "geometry",
39886                stylers: [{ color: "#fdfcf8" }]
39887            },
39888            {
39889                featureType: "road.highway",
39890                elementType: "geometry",
39891                stylers: [{ color: "#f8c967" }]
39892            },
39893            {
39894                featureType: "road.highway",
39895                elementType: "geometry.stroke",
39896                stylers: [{ color: "#e9bc62" }]
39897            },
39898            {
39899                featureType: "road.highway.controlled_access",
39900                elementType: "geometry",
39901                stylers: [{ color: "#e98d58" }]
39902            },
39903            {
39904                featureType: "road.highway.controlled_access",
39905                elementType: "geometry.stroke",
39906                stylers: [{ color: "#db8555" }]
39907            },
39908            {
39909                featureType: "road.local",
39910                elementType: "labels.text.fill",
39911                stylers: [{ color: "#806b63" }]
39912            },
39913            {
39914                featureType: "transit.line",
39915                elementType: "geometry",
39916                stylers: [{ color: "#dfd2ae" }]
39917            },
39918            {
39919                featureType: "transit.line",
39920                elementType: "labels.text.fill",
39921                stylers: [{ color: "#8f7d77" }]
39922            },
39923            {
39924                featureType: "transit.line",
39925                elementType: "labels.text.stroke",
39926                stylers: [{ color: "#ebe3cd" }]
39927            },
39928            {
39929                featureType: "transit.station",
39930                elementType: "geometry",
39931                stylers: [{ color: "#dfd2ae" }]
39932            },
39933            {
39934                featureType: "water",
39935                elementType: "geometry.fill",
39936                stylers: [{ color: "#b9d3c2" }]
39937            },
39938            {
39939                featureType: "water",
39940                elementType: "labels.text.fill",
39941                stylers: [{ color: "#92998d" }]
39942            }
39943        ], { name: "Styled Map" });
39944        const map = new google.maps.Map(document.getElementById("googleMap"), {
39945            center: new google.maps.LatLng(55.682376, 12.5736143),
39946            zoom: 16,
39947            tilt: 45,
39948            disableDefaultUI: true,
39949            scrollwheel: false,
39950            draggable: false,
39951            mapTypeControlOptions: {
39952                mapTypeIds: ["roadmap", "satellite", "hybrid", "terrain", "styled_map"]
39953            }
39954        });
39955        const marker = new google.maps.Marker({
39956            position: { lat: 55.681112, lng: 12.575585 },
39957            animation: google.maps.Animation.DROP,
39958            title: "Regensen"
39959        });
39960        // Associate the styled map with the MapTypeId and set it to display.
39961        map.mapTypes.set("styled_map", styledMapType);
39962        marker.setMap(map);
39963        map.setMapTypeId("styled_map");
39964    }
39965};
39966
39967},{"util":19}]},{},[20,21,22,23,24,25]);

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.